コード例 #1
0
ファイル: PriorityHero.cs プロジェクト: wxl-007/ShadowDota
        ExistFlag LifeNpcType2ExistFlag(LifeNPCType type, BuildNPCType bldType)
        {
            ExistFlag flag = ExistFlag.None;

            switch (type)
            {
            case LifeNPCType.Hero:
                flag = ExistFlag.Hero;
                break;

            case LifeNPCType.Build:
                switch (bldType)
                {
                case BuildNPCType.Tower:
                    flag = ExistFlag.Tower;
                    break;

                case BuildNPCType.Barrank:
                case BuildNPCType.Base:
                    flag = ExistFlag.Building;
                    break;
                }
                break;

            case LifeNPCType.Soldier:
                flag = ExistFlag.minion;
                break;

            case LifeNPCType.Summon:
                flag = ExistFlag.Summoner;
                break;
            }

            return(flag);
        }
コード例 #2
0
        public List <ServerNPC> GetNPCByType(LifeNPCType type, CAMP camp)
        {
            List <ServerNPC> list = null;

            foreach (KeyValuePair <int, ServerNPC> itor in npcDic)
            {
                if (itor.Value != null && itor.Value.data != null && itor.Value.data.configData.type == type)
                {
                    if (camp == CAMP.None || camp == CAMP.All)
                    {
                        if (list == null)
                        {
                            list = new List <ServerNPC> ();
                        }
                        list.Add(itor.Value);
                    }
                    else if (itor.Value.Camp == camp)
                    {
                        if (list == null)
                        {
                            list = new List <ServerNPC> ();
                        }
                        list.Add(itor.Value);
                    }
                }
            }
            return(list);
        }
コード例 #3
0
        ExistFlag NPCToFlag(ServerNPC npc, WarServerNpcMgr npcMgr, LifeNPCType type)
        {
            ExistFlag tar1 = ExistFlag.None;
            ExistFlag tar2 = ExistFlag.None;

            switch (type)
            {
            case LifeNPCType.Hero:
                tar1 = ExistFlag.Hostile_Hero;
                tar2 = ExistFlag.Hostile_Hero_ATK_Self_Hero;
                break;

            case LifeNPCType.Summon:
                tar1 = ExistFlag.Hostile_Summoner;
                tar2 = ExistFlag.Hostile_Summoner_ATK_Self_Hero;
                break;

            case LifeNPCType.Soldier:
                tar1 = ExistFlag.Hostile_Minion;
                tar2 = ExistFlag.Hostile_Minion_ATK_Self_Hero;
                break;
            }


            ExistFlag toTest = ExistFlag.None;

            //没有攻击过的目标
            if (npc.TargetID == -1)
            {
                toTest = tar1;
            }
            else
            {
                ServerNPC targetNpc = npcMgr.GetNPCByUniqueID(npc.TargetID);
                if (targetNpc != null)
                {
                    ///
                    /// 发现目标是Hero,则会判定为攻击了英雄
                    ///
                    NPCConfigData tarCfg = targetNpc.data.configData;
                    if (tarCfg.type.check(LifeNPCType.Hero))
                    {
                        toTest = tar2;
                    }
                    else
                    {
                        toTest = tar1;
                    }
                }
                else
                {
                    toTest = tar1;
                }
            }

            return(toTest);
        }
コード例 #4
0
        /// <summary>
        /// 选择的规则是:
        /// 1. 判定EffectTarget(范围)
        /// 2. 判定flag-剔除友军,敌军等概念, 进入战斗状态的则再最后判定(状态可能目前并不会去设定)
        /// 3. 判定EffectTargetType-剔除
        /// 4. 每个NPC的概率
        /// 5. 判定EffectTargetStatusReject-剔除
        /// 6. 选择目标的数量不能超过上限
        ///
        /// </summary>
        /// <param name="caster">Caster.</param>
        /// <param name="targets">Targets.</param>
        /// <param name="efCfg">Ef cfg.</param>
        public IEnumerable <ServerNPC> Select(ServerNPC caster, IEnumerable <ServerNPC> targets, EffectConfigData efCfg)
        {
                        #if DEBUG
            Utils.Assert(efCfg == null, "Effect Selector can't find target unless EffectConfigData isn't null");
                        #endif

            List <ServerNPC>        reTarget = null;
            IEnumerable <ServerNPC> itor     = null;

            /// 1. 判定EffectTarget(范围)2. 判定flag-剔除友军,敌军等概念
            reTarget = areaSelector.SelectArea(caster, targets, efCfg);

            /// 3. 判定EffectTargetType-剔除 建筑物
            LifeNPCType lifeType = efCfg.EffectTargetType.toPositive();
            itor = reTarget.Where(n => lifeType.check(n.data.configData.type));

            /// 4. 每个NPC的概率   5.判定EffectTargetStatusReject
            itor = itor.Where(n => {
                ServerLifeNpc lifeTar = n as ServerLifeNpc;
                bool ok = random.happen(efCfg.Prob);
                if (lifeTar != null)
                {
                    if (ok)
                    {
                        return(!lifeTar.curStatus.AnySame(efCfg.EffectTargetStatusReject));
                    }
                    else
                    {
                        return(ok);
                    }
                }
                else
                {
                    return(ok);
                }
            }
                              );

            ///6. 选择的目标数量不能超过上限
            if (efCfg.EffectLimit > 0)
            {
                itor = itor.Take(efCfg.EffectLimit);
            }
            else if (efCfg.EffectLimit == 0)
            {
                itor = new List <ServerNPC>().AsEnumerable <ServerNPC>();
            }

            return(itor);
        }
コード例 #5
0
ファイル: DataEnum.cs プロジェクト: wxl-007/ShadowDota
        public static LifeNPCType toPositive(this TargetSubClass flags)
        {
            bool ok = flags == TargetSubClass.AllTarget;

            if (ok)
            {
                return(LifeNPCType.SkTarAll);
            }

            //默认所有的都选择出来
            LifeNPCType type = LifeNPCType.SkTarAll;

            //不要建筑物
            ok = flags.check(TargetSubClass.Forbid_Building);
            if (ok)
            {
                type = type.clear(LifeNPCType.Build);
            }

            //不要小兵
            ok = flags.check(TargetSubClass.Forbid_Unit);
            if (ok)
            {
                type = type.clear(LifeNPCType.Soldier);
            }

            //不要英雄
            ok = flags.check(TargetSubClass.Forbid_Hero);
            if (ok)
            {
                type = type.clear(LifeNPCType.Hero);
            }

            //不要召唤物
            ok = flags.check(TargetSubClass.Forbid_Summon);
            if (ok)
            {
                type = type.clear(LifeNPCType.Summon);
            }

            return(type);
        }
コード例 #6
0
        /// <summary>
        /// 根据LifeNPCType类型和camp得到npc
        /// </summary>
        /// <returns>The life NPC by type.</returns>
        /// <param name="type">Type.</param>
        /// <param name="camp">Camp.</param>
        public List <ServerLifeNpc> GetLifeNPCByType(LifeNPCType type, CAMP camp)
        {
            List <ServerLifeNpc> list = new List <ServerLifeNpc> ();

            foreach (KeyValuePair <int, ServerNPC> itor in npcDic)
            {
                ServerLifeNpc lifenpc = itor.Value as ServerLifeNpc;
                if (lifenpc != null && lifenpc.WhatTypeOf == type)
                {
                    if (camp == CAMP.None)
                    {
                        list.Add(lifenpc);
                    }
                    else if (lifenpc.Camp == camp)
                    {
                        list.Add(lifenpc);
                    }
                }
            }
            return(list);
        }
コード例 #7
0
        /// <summary>
        /// 选择的规则是:
        ///  多目标判定规则
        /// 1. 判定施法者的状态
        /// 2. 判定施法者的上次目标,如果目标在攻击范围内,则选择为最优先目标
        /// 3. 判定施法的范围类型
        /// 4. 目标的状态
        /// 5. 根据施法的距离选择出目标
        /// 6. 根据血量选择出目标
        /// 7. 目标的优先级
        /// 8. 单体攻击敌方,并且有最高优先级的目标
        ///
        ///
        /// 单目标判定规则
        ///
        ///
        ///
        /// </summary>
        /// <returns><c>true</c>, if cast was caned, <c>false</c> otherwise.</returns>
        public IEnumerable <ServerNPC> Select(ServerNPC caster, RtSkData rtOne, Sight sight)
        {
            //枚举器
            IEnumerable <ServerNPC> itor = null, itor1 = null;

                        #if DEBUG
            Utils.Assert(caster == null, "Can't find target unless caster isn't null");
            Utils.Assert(rtOne == null, "Can't find target unless runtime skill isn't null");
                        #endif


            SkillConfigData skillCfg = rtOne.skillCfg;

            /// 视野范围 -- 决定索敌范围
            float CheckDistance = 0F;
            if (sight == Sight.NearSight)
            {
                CheckDistance = skillCfg.Distance;
            }
            else
            {
                CheckDistance = caster.data.rtData.seekRange;
            }

            bool castcan = true;
            //只有LifeNPC才检查施法者的状态
            //1. 判定施法者的状态
            ServerLifeNpc castlife = caster as ServerLifeNpc;
            if (castlife != null)
            {
                if (castlife.curStatus.AnySame(skillCfg.CasterStatusReject))
                {
                    //不可施法
                    castcan = false;
                }
            }

            if (castcan == false)
            {
                return(new List <ServerNPC>().AsEnumerable <ServerNPC>());
            }
            //能进入CD
            rtOne.EnterCD();

            ///
            /// 3. 判定施法的范围类型 .
            /// 单体和AOE都需要在技能配置里选择出目标 , 再次到Effect里面选择目标。 -- 叫做前置判定
            /// 方向性则不需要选择目标,该类型的技能可对空地释放,再次到EffectTarget的目标是skill的目标 -- 叫做后置判定
            ///

            TargetClass rtTargetCls = skillCfg.SkillTarget;

            if (skillCfg.RangeType == RangeClass.Direction)
            {
                //后置判定
                return(new List <ServerNPC>().AsEnumerable <ServerNPC>());
            }

            bool isMultiTarget = skillCfg.RangeType != RangeClass.SingleTarget;
            bool isNoPriority  = skillCfg.TargetPriority == SkTargetPriority.NonePriority;
            bool isTargetSelf  = rtTargetCls.AnySame(TargetClass.Self);
            //单目标
            ServerNPC singlePriority = null;

            LifeNPCType type = skillCfg.TargetType.toPositive();
            ///
            /// 是否为多目标的战斗, 或者是没有优先级的单目标
            ///
            if (isMultiTarget || isNoPriority || isTargetSelf)
            {
                ///
                /// 4. 目标的状态
                ///
                if (rtTargetCls.AnySame(TargetClass.Friendly))
                {
                    //友方
                    itor1 = SelectorTools.GetNPCValideStatus(caster, npcMgr, KindOfNPC.Life, rtTargetCls, NpcStatus.None, type);
                }
                else if (rtTargetCls.AnySame(TargetClass.Hostile))
                {
                    //敌方
                    itor1 = SelectorTools.GetNPCValideStatus(caster, npcMgr, KindOfNPC.Life, rtTargetCls, skillCfg.TargetStatusReject, type);
                }
                else if (rtTargetCls.AnySame(TargetClass.Self))
                {
                    //自己
                    List <ServerNPC> targets = new List <ServerNPC>();
                    targets.Add(caster);
                    itor = targets.AsEnumerable <ServerNPC>();
                    return(targets);
                }
                else
                {
                    itor1 = SelectorTools.GetNPCValideStatus(caster, npcMgr, KindOfNPC.Life, rtTargetCls, skillCfg.TargetStatusReject, type);
                    ConsoleEx.DebugLog("Warning : We should have a Camp. But sometimes, it's Ok.", ConsoleEx.RED);
                }

                ///
                /// 5. 根据施法的距离选择出目标
                ///

                itor1 = SelectorTools.GetNPCInRadius(caster, CheckDistance, rtTargetCls, itor1);

                ///
                /// 6. 根据血量选择出目标
                ///
                itor1 = SelectorTools.GetNPCByHp(caster, rtTargetCls, itor1);

                if (isNoPriority)
                {
                    singlePriority = itor1.FirstOrDefault();
                }
            }
            else
            {
                ///
                /// 获取单目标
                ///

                singlePriority = SelectorTools.GetPrioritiedNpc(caster, rtTargetCls, npcMgr, CheckDistance, skillCfg.TargetStatusReject, skillCfg.TargetPriority, priorityMgr, type);

                //单目标的友方,有可能选择到自己(但并不属于 TargetClass 64.就针对自己)
                if (!rtTargetCls.AnySame(TargetClass.Hostile))
                {
                    List <ServerNPC> broker = new List <ServerNPC>();
                    if (singlePriority != null)
                    {
                        broker.Add(singlePriority);
                    }
                    itor1 = broker.AsEnumerable <ServerNPC>();
                }
            }

            if (isMultiTarget == false)
            {
                ///
                /// 9. 单体攻击敌方,只有打敌方单体的时候,TargetID才会被重新设定
                ///
                if (rtTargetCls.AnySame(TargetClass.Hostile))
                {
                    ServerLifeNpc HighestPriority = null;
                    ///
                    /// 检测嘲讽
                    ///
                    int tarId = caster.getHighestHatred;
                    if (tarId != -1)
                    {
                        //有被嘲讽的目标
                        HighestPriority = npcMgr.GetNPCByUniqueID(tarId) as ServerLifeNpc;
                    }
                    else
                    {
                        //没有被嘲讽的目标

                        ///
                        ///  判定施法者的上次目标,则选择为最优先目标
                        ///  此逻辑,能保证追击残血逃跑的
                        ///

                        if (caster.TargetID != -1)
                        {
                            HighestPriority = npcMgr.GetNPCByUniqueID(caster.TargetID) as ServerLifeNpc;
                            if (HighestPriority != null)
                            {
                                ///
                                /// 如果单一目标的是英雄,
                                ///
                                if (singlePriority != null && singlePriority.data.configData.type == LifeNPCType.Hero &&
                                    HighestPriority.data.configData.type != LifeNPCType.Hero)
                                {
                                    HighestPriority = null;
                                    caster.TargetID = -1;
                                }
                                else
                                {
                                    bool validate1 = true, validate2 = true, validate3 = true;
                                    /// 生命判定
                                    if (HighestPriority.data.rtData.curHp <= 0)
                                    {
                                        validate1 = false;
                                    }

                                    /// 距离判定
                                    float distance = SelectorTools.GetDistance(HighestPriority.transform.position, caster.transform.position);
                                    distance = distance - HighestPriority.data.configData.radius - caster.data.configData.radius;

                                    /// 视野范围
                                    if (distance > CheckDistance)
                                    {
                                        validate2 = false;
                                    }

                                    ///如果有相同的状态,则不让释放技能
                                    validate3 = !HighestPriority.curStatus.AnySame(skillCfg.TargetStatusReject);

                                    /// 失败的判定
                                    bool validate = validate1 & validate2 & validate3;
                                    if (!validate)
                                    {
                                        HighestPriority = null;
                                        caster.TargetID = -1;
                                    }
                                    else
                                    {
                                        caster.RstTimeout();
                                    }
                                }
                            }
                            else
                            {
                                caster.TargetID = -1;
                            }
                        }
                    }

                    //找到普通选择出的目标
                    if (HighestPriority == null)
                    {
                        ServerNPC target = singlePriority;
                        caster.TargetID = target != null ? target.UniqueID : -1;
                        HighestPriority = target as ServerLifeNpc;
                    }

                    List <ServerNPC> high = new List <ServerNPC>();
                    if (HighestPriority != null)
                    {
                        high.Add(HighestPriority);
                    }
                    itor1 = high.AsEnumerable <ServerNPC>();
                }
                else
                {
                    ///
                    /// 10.单体友方
                    ///
                    if (itor1.Any())
                    {
                        itor1 = itor1.Take(1);
                    }
                }
            }


            itor = itor1;
            return(itor);
        }
コード例 #8
0
ファイル: DataEnum.cs プロジェクト: wxl-007/ShadowDota
 public static LifeNPCType clear(this LifeNPCType flags, LifeNPCType totest)
 {
     return(flags & ~totest);
 }
コード例 #9
0
ファイル: DataEnum.cs プロジェクト: wxl-007/ShadowDota
 public static LifeNPCType set(this LifeNPCType flags, LifeNPCType totest)
 {
     return(flags | totest);
 }
コード例 #10
0
ファイル: DataEnum.cs プロジェクト: wxl-007/ShadowDota
 public static bool check(this LifeNPCType flags, LifeNPCType totest)
 {
     return((flags & totest) == totest);
 }
コード例 #11
0
        /// <summary>
        /// 检测伤害技能能否释放,
        /// 回血,恢复之类的技能不做检测
        ///
        /// 判定顺序是:
        /// 0. 判定技能的类型
        /// 1. 判定是否是相同的阵营
        /// 2. 判定施法者的状态
        /// 3. 判定目标是什么类型的NPC(比如建筑物,英雄。。。)
        /// 3. 判定施法的距离
        /// 5. 目标的状态
        ///
        /// </summary>
        /// <returns><c>true</c>, if cast was caned, <c>false</c> otherwise.</returns>
        public bool canCast(ServerNPC caster, ServerNPC target, RtSkData rtOne, bool ignoreDis = false)
        {
            bool can = true;

                        #if DEBUG
            Utils.Assert(caster == null, "Can't know whether can cast skill unless caster isn't null.");
            Utils.Assert(target == null, "Can't know whether can cast skill unless target isn't null.");
            Utils.Assert(rtOne == null, "Can't know whether can cast skill unless runtime skill isn't null");
                        #endif

            SkillConfigData skillCfg = rtOne.skillCfg;
            /// 0. 判定技能的类型
            can = skillCfg.DamageType == 0;
            if (can == false)
            {
                return(can);
            }

            /// 1.判定是否是相同的阵营
            can = caster.Camp != target.Camp;
            if (can == false)
            {
                return(can);
            }

            /// 2. 判定施法者的状态

            //只有LifeNPC才检查施法者的状态
            ServerLifeNpc castlife = caster as ServerLifeNpc;
            if (castlife != null)
            {
                if (skillCfg.CasterStatusReject.AnySame(castlife.curStatus))
                {
                    //不可施法
                    can = false;
                }
            }
            if (can == false)
            {
                return(can);
            }

            /// 3. 判定目标是什么类型的NPC
            LifeNPCType type = skillCfg.TargetType.toPositive();
            can = type.check(target.data.configData.type);

            if (can == false)
            {
                return(can);
            }

            /// 4. 判定施法的距离
            if (ignoreDis == false)
            {
                can = AITools.IsInRange(caster.transform.position, skillCfg.Distance, target.transform);
                if (can == false)
                {
                    return(can);
                }
            }

            /// 5. 目标的状态

            ServerLifeNpc targetLife = target as ServerLifeNpc;
            if (targetLife != null)
            {
                if (targetLife.curStatus.AnySame(skillCfg.TargetStatusReject))
                {
                    //不可施法
                    can = false;
                }
            }

            return(can);
        }
コード例 #12
0
        /// <summary>
        /// Gets the npc with in range.
        /// </summary>
        /// <returns>The npc with in range.</returns>
        /// <param name="anchor">起点</param>
        /// <param name="range">范围</param>
        /// <param name="NpcSource">NPC 容器</param>
        /// <param name="capm">阵营</param>
        /// <param name="kind">是否是lifeNpc</param>
        /// <param name="type">如果是LifeNpc的时候,又是什么子类型</param>
        public static List <ServerNPC> GetNpcWithInRange(ServerNPC caster, float range, WarServerNpcMgr NpcSource, CAMP camp, KindOfNPC kind, LifeNPCType type = LifeNPCType.SkTarAll)
        {
            IEnumerable <ServerNPC> filter = NpcSource.getCampBnpc(camp);

            if (kind == KindOfNPC.Life)
            {
                filter = filter.Where(n => (n.WhatKindOf() == kind) &&
                                      (type.check(((ServerLifeNpc)n).WhatTypeOf)));
            }
            else if (kind == KindOfNPC.NonLife)
            {
                filter = filter.Where(n => n.WhatKindOf() == kind);
            }

            int count = filter.Count();

            if (count > 0)
            {
                Vector3 anchor = caster.transform.position;
                float   radius = caster.data.configData.radius;
                filter = filter.Where(n => IsInRange(anchor, n.data.configData.radius + range + radius, n.transform));
            }

            return(filter.ToList());
        }
コード例 #13
0
        //可以选择单个目标,也可以是多个目标
        //提供给SkillSelecotr使用
        public static IEnumerable <ServerNPC> GetNPCInRange(ServerNPC caster, float range, WarServerNpcMgr NpcSource, KindOfNPC kind,
                                                            TargetClass target, NpcStatus TarStatusInCfg, LifeNPCType type = LifeNPCType.SkTarAll)
        {
            List <ServerNPC> found = new List <ServerNPC>();
            ///
            ///  枚举器,其实不用返回特定类型,返回枚举器就可以了。(在不需要Copy容器里面的数据时,就是用枚举器)
            ///
            IEnumerable <ServerNPC> Itor = found.AsEnumerable();
            // 临时枚举器
            IEnumerable <ServerNPC> Itor1 = null;

            Vector3   anchor = caster.transform.position;
            Transform trans  = caster.transform;

            ServerNPC nearest = null;

            CAMP camp = CAMP.None;

            if (target.AnySame(TargetClass.Friendly))
            {
                camp = caster.Camp;
            }
            else if (target.AnySame(TargetClass.Hostile))
            {
                camp = caster.Camp.Hostile();
            }

            Itor1 = NpcSource.getCampBnpc(camp);

            if (kind == KindOfNPC.Life)
            {
                Itor1 = Itor1.Where(n => (n.WhatKindOf() == kind) &&
                                    (type.check(((ServerLifeNpc)n).WhatTypeOf)));
            }
            else if (kind == KindOfNPC.NonLife)
            {
                Itor1 = Itor1.Where(n => n.WhatKindOf() == kind);
            }

            bool any = Itor1 != null?Itor1.Any() : false;

            if (any)
            {
                ///
                /// --- 筛选出有效状态的NPC ----
                ///
                Itor1 = Itor1.Where(n => {
                    ServerLifeNpc lifeTar = n as ServerLifeNpc;
                    if (lifeTar != null)
                    {
                        return(!lifeTar.curStatus.AnySame(TarStatusInCfg));
                    }
                    else
                    {
                        return(true);
                    }
                });

                ///
                /// --- 再次根据距离条件筛选出NPC ----
                ///
                float radius = caster.data.configData.radius;
                Itor1 = Itor1.Where(n => IsInRange(anchor, n.data.configData.radius + radius + range, n.transform));

                if (target.AnySame(TargetClass.FarAwary))
                {
                    nearest = Itor1.OrderByDescending(n => GetVirtualDistance(trans, n.transform)).FirstOrDefault();
                    if (nearest != null)
                    {
                        found.Add(nearest);
                    }
                }
                else if (target.AnySame(TargetClass.Nearest))
                {
                    nearest = Itor1.OrderBy(n => GetVirtualDistance(trans, n.transform)).FirstOrDefault();
                    if (nearest != null)
                    {
                        found.Add(nearest);
                    }
                }
                else
                {
                    Itor = Itor1;
                }


                ///
                /// --- 判定最大,最小生命值的NPC -----
                ///

                if (target.AnySame(TargetClass.HpLowest))
                {
                    ServerNPC lowest = Itor1.OrderBy(n => n.data.rtData.CurHpNested).FirstOrDefault();
                    if (lowest != null)
                    {
                        found.Add(lowest);
                    }
                }
                else if (target.AnySame(TargetClass.HpHighest))
                {
                    ServerNPC highest = Itor1.OrderByDescending(n => n.data.rtData.CurHpNested).FirstOrDefault();
                    if (highest != null)
                    {
                        found.Add(highest);
                    }
                }
            }

            return(Itor);
        }
コード例 #14
0
        //此方法仅仅对单体目标有效,多目标的选择不走优先级排序逻辑
        //且不能对自己生效和无优先级
        //排序完了之后,按照“血量或距离”筛选出合适的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);
        }
コード例 #15
0
        /// <summary>
        /// 获取特定的KindOfNPC,敌友方,有效状态的, 是建筑物还是什么的  活着的NPC
        /// </summary>
        /// <returns>ServerNPC 列表</returns>
        /// <param name="caster">Caster.</param>
        /// <param name="NpcSource">Npc source.</param>
        /// <param name="kind">KindOfNPC</param>
        /// <param name="target">TargetClass</param>
        /// <param name="TarStatusInCfg">NpcStatus</param>
        /// <param name="type">LifeNPCType.</param>
        public static IEnumerable <ServerNPC> GetNPCValideStatus(ServerNPC caster, WarServerNpcMgr NpcSource, KindOfNPC kind, TargetClass target,
                                                                 NpcStatus TarStatusInCfg, LifeNPCType type = LifeNPCType.SkTarAll)
        {
            // 临时枚举器
            IEnumerable <ServerNPC> Itor1 = null;

            CAMP camp = CAMP.None;

            if (target.AnySame(TargetClass.Friendly))
            {
                camp = caster.Camp;
            }
            else if (target.AnySame(TargetClass.Hostile))
            {
                camp = caster.Camp.Hostile();
            }
            else
            {
                //全阵营
                camp = CAMP.All;
            }

            Itor1 = NpcSource.getCampBnpc(camp);

            if (kind == KindOfNPC.Life)
            {
                Itor1 = Itor1.Where(n => (n.WhatKindOf() == kind) &&
                                    (type.check(((ServerLifeNpc)n).WhatTypeOf)));
            }
            else if (kind == KindOfNPC.NonLife)
            {
                Itor1 = Itor1.Where(n => n.WhatKindOf() == kind);
            }

            ///
            /// --- 筛选出有效状态的NPC ----
            ///
            Itor1 = Itor1.Where(n => {
                ServerLifeNpc lifeTar = n as ServerLifeNpc;
                if (lifeTar != null)
                {
                    return(!lifeTar.curStatus.AnySame(TarStatusInCfg));
                }
                else
                {
                    return(true);
                }
            });

            return(Itor1);
        }