Example #1
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());
        }
Example #2
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);
        }
Example #3
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);
        }
Example #4
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);
        }
Example #5
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);
        }