Пример #1
0
        ///
        /// 释放技能, pos的第几个技能
        ///
        public void Cast(ServerNPC caster, short pos, Action <MsgParam> Report)
        {
                        #if DEBUG
            Utils.Assert(caster == null, "Caster is null when cast skill.");
                        #endif

            ServerLifeNpc src = caster as ServerLifeNpc;
            if (src.IsAlive == false)
            {
                return;
            }

            RtSkData rtSk = src.runSkMd.getRuntimeSkill(pos);
            ///
            /// 冷却时间好了吗, 死亡了吗
            ///
            if (rtSk != null && rtSk.canCast)
            {
                //进入Skill释放的状态
                src.curStatus = src.curStatus.set(NpcStatus.InSkill);

                IEnumerable <ServerNPC> targets = SelectS.Select(caster, rtSk, Sight.NearSight);
                EfCastor.Cast(caster, targets, rtSk, Report);
            }
        }
Пример #2
0
        void castBuff_Skill(RtBufData rtbf, BuffPhase phase)
        {
            container.Clear();

            RtSkData skill = null;

            switch (phase)
            {
            case BuffPhase.Start:
                skill = rtbf.OnStartSkill;
                break;

            case BuffPhase.End:
                skill = rtbf.OnEndSkill;
                break;

            case BuffPhase.Cycle:
                skill = rtbf.onCycleskill;
                break;
            }

            if (skill != null)
            {
                ServerNPC castor = BFSelector.locateCastor(rtbf);
                ServerNPC target = BFSelector.locateTarget(rtbf);

                List <ServerNPC> Targets = new List <ServerNPC>();
                Targets.Add(target);
                IEnumerable <ServerNPC> itor = Targets.AsEnumerable <ServerNPC>();

                EfCastor.Cast(castor, itor, skill, container, false);

                dispatchMsg(container, skill);
            }
        }
Пример #3
0
        /// <summary>
        /// 挑出TimeOut的判定
        /// </summary>
        /// <returns>The up.</returns>
        /// <param name="sk">Sk.</param>
        ConditionConfigure pickUp(RtSkData sk)
        {
            ConditionConfigure ConCfg = null;

            //获取激活的判定规则ID列表
            int[] IncideCon = sk.skillCfg.Incite;
            if (IncideCon != null && IncideCon.Length > 0)
            {
                int len = IncideCon.Length;
                for (int i = 0; i < len; ++i)
                {
                    //获取激活的判定规则ID
                    int CondiId = IncideCon[i];
                    if (CondiId > 0)
                    {
                        ConCfg = ConModel.get(CondiId);
                        if (ConCfg.ConditionType == SkConditionType.TimeOut)
                        {
                            break;
                        }
                    }
                }
            }

            return(ConCfg);
        }
Пример #4
0
        public void EnterIncite(RtSkData sk, EffectConfigData efCfg, ServerNPC caster, IEnumerable <ServerNPC> targets)
        {
            bool canEnter = CheckIncite(sk, efCfg);

            if (canEnter)
            {
                bool injured = CheckBeHead(sk);
                if (injured)
                {
                    float Delay = 0.6F;
                    ///
                    /// 检测伤害类的还需要至少延迟了两个FixedUpdate,因为承受伤害的逻辑,还没开始执行
                    /// 所以,目标血量的判定还不能开始
                    ///
                    DelayedSkData data = new DelayedSkData()
                    {
                        caster = caster,
                        chosen = targets,
                        rtsk   = sk,
                    };
                    SkAsyncRunner.AysncRun(EnterIncite, Delay, data);
                }
                else
                {
                    EnterIncite(sk, caster, targets);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// 检测有没有斩首的逻辑,如果有伤害逻辑,就得要延迟执行
        /// </summary>
        /// <returns><c>true</c>, if be head was checked, <c>false</c> otherwise.</returns>
        /// <param name="sk">Sk.</param>
        bool CheckBeHead(RtSkData sk)
        {
            bool hasInjury = false;

            ConditionConfigure ConCfg = null;

            //获取激活的判定规则ID列表
            int[] IncideCon = sk.skillCfg.Incite;
            if (IncideCon != null && IncideCon.Length > 0)
            {
                int len = IncideCon.Length;
                for (int i = 0; i < len; ++i)
                {
                    //获取激活的判定规则ID
                    int CondiId = IncideCon[i];
                    if (CondiId > 0)
                    {
                        ConCfg = ConModel.get(CondiId);
                        if (ConCfg.ConditionType == SkConditionType.BeHead || ConCfg.ConditionType == SkConditionType.BeHead2 ||
                            ConCfg.ConditionType == SkConditionType.BeHeadReset || ConCfg.ConditionType == SkConditionType.BeHead2Reset)
                        {
                            hasInjury = true;
                            break;
                        }
                    }
                }
            }

            return(hasInjury);
        }
Пример #6
0
        void EnterIncite(RtSkData sk, ServerNPC caster, IEnumerable <ServerNPC> targets)
        {
            ConditionConfigure ConCfg = null;

            //获取激活的判定规则ID列表
            int[] IncideCon = sk.skillCfg.Incite;
            if (IncideCon != null && IncideCon.Length > 0)
            {
                int len = IncideCon.Length;
                for (int i = 0; i < len; ++i)
                {
                    //获取激活的判定规则ID
                    int CondiId = IncideCon[i];
                    if (CondiId > 0)
                    {
                        ConCfg = ConModel.get(CondiId);

                        Utils.Assert(ConCfg == null, "Can't find Condition Configure. Condition ID = " + ConCfg);
                        //判定器--- 如果成功就跳出
                        ICondition decider = Mgr.getImplement(ConCfg.ConditionType);
                        bool       suc     = decider.check(sk, ConCfg, caster, targets);
                        if (suc)
                        {
                            ServerLifeNpc life    = caster as ServerLifeNpc;
                            bool          isReset = ConCfg.ConditionClass == SkConditionClass.ResetSkill;
                            life.runSkMd.switchToSkill(sk.pos, ConCfg.TargetSkID, isReset);
                            break;
                        }
                    }
                }
            }
        }
Пример #7
0
        /// <summary>
        /// pos 普通攻击的第几步
        /// </summary>
        public List <MsgParam> NormalAttack(ServerNPC caster, short pos)
        {
            container.Clear();

                        #if DEBUG
            Utils.Assert(caster == null, "Caster is null when cast skill.");
                        #endif

            ServerLifeNpc src = caster as ServerLifeNpc;
            if (src.IsAlive == false)
            {
                return(container);
            }

            RtSkData rtSk = src.runSkMd.getAttack(pos);
            if (rtSk != null)
            {
                IEnumerable <ServerNPC> targets = SelectS.Select(caster, rtSk, Sight.NearSight);
                EfCastor.Cast(caster, targets, rtSk, container);
            }

            int cnt = container.Count;
            if (cnt > 0)
            {
                for (int i = 0; i < cnt; ++i)
                {
                    ((WarMsgParam)container[i]).cmdType = WarMsg_Type.Attack;
                }
            }

            return(container);
        }
Пример #8
0
        /// <summary>
        /// 检测是否符合逻辑
        /// </summary>
        /// <param name="sk">技能</param>
        /// <param name="cfg">条件配置技能</param>
        /// <param name="caster">施法者忽略</param>
        /// <param name="targets">目标者们忽略</param>
        public bool check(RtSkData sk, ConditionConfigure cfg, ServerNPC caster, IEnumerable <ServerNPC> targets)
        {
                        #if DEBUG
            Utils.Assert(sk == null, "Skill is null in TimeoutCondition.");
            Utils.Assert(cfg == null, "ConditionConfigure is null in TimeoutCondition.");
                        #endif

            bool Condi = false;

            ///
            /// 1. 判定是否符合关心的BeHead类型
            ///
            var self           = this.GetType();
            var classAttribute = (ConditionAttribute)Attribute.GetCustomAttribute(self, typeof(ConditionAttribute));
            if (cfg.ConditionType == classAttribute.Con)
            {
                RtFakeSkData fakeSk = sk as RtFakeSkData;
                if (fakeSk != null)
                {
                    float TimeOut = cfg.Param1 * Consts.OneThousand;
                    ///
                    ///2.判定是否超时
                    ///
                    Condi = fakeSk.aliveDur >= TimeOut;

                    ///3.判定概率
                    if (Condi)
                    {
                        Condi = PseudoRandom.getInstance().happen(cfg.Prop);
                    }
                }
            }

            return(Condi);
        }
Пример #9
0
        public void Cast(ServerNPC caster, IEnumerable <ServerNPC> chosen, RtSkData rtSk, List <MsgParam> MsgContainer, bool skDirecHurt)
        {
                        #if DEBUG
            Utils.Assert(caster == null, "Effect Castor");
            Utils.Assert(rtSk == null, "Effect Castor");
                        #endif
            List <EffectConfigData> effCfg = new List <EffectConfigData>();
            foreach (EffectConfigData cfg in rtSk.effectCfgDic.Values)
            {
                effCfg.Add(cfg);
            }

            ICastEffect[] castor = effMgr.getImplements(effCfg.ToArray(), rtSk.skillCfg);
            if (castor != null)
            {
                int len = castor.Length;
                for (int i = 0; i < len; ++i)
                {
                    IEnumerable <ServerNPC> reTarget = selector.Select(caster, chosen, effCfg[i]);
                    castor[i].Cast(caster, chosen, reTarget, skDirecHurt, MsgContainer);
                    effMgr.Recycle(effCfg[i], castor[i]);
                }
            }
            castor = null;
        }
Пример #10
0
        /// <summary>
        /// 数据的初始化
        /// </summary>
        /// <param name="go">Go.</param>
        /// <param name="num">Number.</param>
        /// <param name="id">Identifier.</param>
        /// <param name="camp">Camp.</param>
        void DynamicDataInit(ServerNPC curHero, NPCConfigData econfig, CAMP camp)
        {
            ///
            /// 填充阵营
            ///
            curHero.Camp = camp;

            ///
            /// 填充NPC数据
            ///
            NPCData dynamicData = new NPCData();

            dynamicData.rtData     = new NPCRuntimeData(econfig);
            dynamicData.configData = econfig;
            dynamicData.btData     = new NPCBattleData();
            curHero.data           = dynamicData;

            ///
            /// 向WarManager注册
            ///
            serNpcMgr.SignID(curHero);

            WarServerManager warMgr = WarServerManager.Instance;
            ///
            /// 填充技能数据
            ///
            RtNpcSkillModel skMd = new RtNpcSkillModel(econfig.ID, curHero.UniqueID);
            ServerLifeNpc   life = curHero as ServerLifeNpc;

            if (life != null)
            {
                life.runSkMd = skMd;
            }

            ///
            /// 填充默认的buff
            ///
            for (short i = 0; i < Consts.MAX_SKILL_COUNT; ++i)
            {
                RtSkData sk = skMd.getRuntimeSkill(i);
                if (sk != null)
                {
                    int passive = sk.skillCfg.PassiveBuff;
                    if (passive > 0)
                    {
                        BuffCtorParam ctor = new BuffCtorParam()
                        {
                            bufNum    = passive,
                            fromNpcId = curHero.UniqueID,
                            toNpcId   = curHero.UniqueID,
                            origin    = OriginOfBuff.BornWithSkill,
                            initLayer = 1,
                            duration  = Consts.USE_BUFF_CONFIG_DURATION,
                        };
                        warMgr.bufMgr.createBuff(ctor);
                    }
                }
            }
        }
Пример #11
0
        bool CheckIncite(RtSkData sk, EffectConfigData efCfg)
        {
                        #if DEBUG
            Utils.Assert(sk == null, "RtSkData is null in CheckIncite.");
            Utils.Assert(efCfg == null, "EffectConfigData is null in CheckIncite.");
                        #endif

            return(sk.skillCfg.InciteEffectID == efCfg.ID);
        }
Пример #12
0
        /// <summary>
        /// 检测回复技能
        ///
        /// 检测逻辑和上面的并不太一致
        /// 判定顺序是:
        /// 0. 判定技能的类型
        /// 1. 判定施法者的状态
        /// 2. 选在施法的距离(特定范围)内血最少的 英雄 NPC
        /// </summary>
        /// <returns><c>true</c>, if cast was caned, <c>false</c> otherwise.</returns>
        /// <param name="caster">Caster.</param>
        public bool canCast(ServerNPC caster, RtSkData rtOne)
        {
            bool can = true;

                        #if DEBUG
            Utils.Assert(caster == null, "Can't know whether can cast skill unless caster 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 == 1;
            if (can == false)
            {
                return(can);
            }

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

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

            /// 2. 选在施法的距离(特定范围)内血最少的 英雄 NPC
            List <ServerNPC> friendlyArmy = SelectorTools.GetNpcWithInRange(caster, skillCfg.Distance, NpcMgr, caster.Camp, KindOfNPC.Life, LifeNPCType.Hero);
            if (friendlyArmy != null && friendlyArmy.Count > 0)
            {
                //选择血最少的
                ServerNPC friend = friendlyArmy.OrderBy(npc => (npc.data.rtData.curHp * 1.0f / npc.data.rtData.totalHp)).FirstOrDefault();
                if (friend != null)
                {
                    NPCRuntimeData npcRtdt = friend.data.rtData;
                    float          factor  = npcRtdt.curHp * 1.0f / npcRtdt.totalHp;
                    //低于20%的
                    if (factor > 0.2f)
                    {
                        can = false;
                    }
                }
            }

            return(can);
        }
Пример #13
0
        /// <summary>
        /// 检测是否符合逻辑
        /// </summary>
        /// <param name="sk">技能忽略</param>
        /// <param name="cfg">条件配置技能忽略</param>
        /// <param name="caster">施法者忽略</param>
        /// <param name="targets">目标者们忽略</param>
        public bool check(RtSkData sk, ConditionConfigure cfg, ServerNPC caster, IEnumerable <ServerNPC> targets)
        {
                        #if DEBUG
            Utils.Assert(cfg == null, "ConditionConfigure is null in PropCondition.");
                        #endif

            ///1.判定概率
            bool Condi = PseudoRandom.getInstance().happen(cfg.Prop);

            return(Condi);
        }
Пример #14
0
        /// <summary>
        /// 这个是给技能使用的,可能不会立即有结果
        /// </summary>
        /// <param name="caster">Caster.</param>
        /// <param name="chosen">Chosen.</param>
        /// <param name="rtSk">技能</param>
        /// <param name="pos">技能的索引</param>
        /// <param name="Report">Report.</param>
        public void Cast(ServerNPC Caster, IEnumerable <ServerNPC> Chosen, RtSkData RtSk, Action <MsgParam> ReportFunc)
        {
                        #if DEBUG
            Utils.Assert(Caster == null, "Effect Castor");
            Utils.Assert(RtSk == null, "Effect Castor");
                        #endif

            List <EffectConfigData> effCfg = new List <EffectConfigData>();
            foreach (EffectConfigData cfg in RtSk.effectCfgDic.Values)
            {
                effCfg.Add(cfg);
            }
            //虚假的Buff桩对象
            EffectConfigData stub = ctorStubEffCfg(RtSk);
            if (stub != null)
            {
                effCfg.Add(stub);
            }

            ICastEffect[] castor = effMgr.getImplements(effCfg.ToArray(), RtSk.skillCfg);
            if (castor != null)
            {
                int len = castor.Length;
                for (int i = 0; i < len; ++i)
                {
                    if (castor[i] == null)
                    {
                        ConsoleEx.DebugLog("ICastEffect Not Implement. ID = " + effCfg[i].ID, ConsoleEx.YELLOW);
                    }
                    else
                    {
                        float Delay = RtSk.skillCfg.EffectDelayTime[i];
                        if (Delay > 0)
                        {
                            DelayedSkData data = new DelayedSkData()
                            {
                                caster = Caster,
                                chosen = Chosen,
                                castor = castor[i],
                                cfg    = effCfg[i],
                                Report = ReportFunc,
                                rtsk   = RtSk,
                            };
                            SkAsyncRunner.AysncRun(DelayCast, Delay, data);
                        }
                        else
                        {
                            DelayCast(Caster, Chosen, castor[i], effCfg[i], RtSk, ReportFunc);
                        }
                    }
                }
            }
            castor = null;
        }
Пример #15
0
        public void cast(ServerNPC castor, IEnumerable <ServerNPC> targets, TriggerConfigData triCfg)
        {
                        #if DEBUG
            Utils.Assert(castor == null, "TriggerCastor can't cask if castor is null.");
            Utils.Assert(targets == null, "TriggerCastor can't cask if target is null.");
            Utils.Assert(triCfg == null, "TriggerCastor can't cask if TriggerConfigData is null.");
                        #endif

            RtSkData skill = new RtSkData(triCfg.SkillID, -1);
            targets = filtor(targets, triCfg);
            container.Clear();
            EfCastor.Cast(castor, targets, skill, container, false);
            dispatchMsg(container, skill);
        }
Пример #16
0
        /// <summary>
        /// 返回可以释放的技能, 这个要一直检测
        /// 这个只检查4个技能,不检查普通攻击
        /// </summary>
        /// <returns>The cast.</returns>
        /// <param name="caster">Caster.</param>
        /// <param name="target">Target.</param>
        public List <short> canCast(ServerNPC caster, ServerNPC target)
        {
            List <short> skNumList = new List <short>();

                        #if DEBUG
            Utils.Assert(caster == null, "Caster is null when check whether can cast skill.");
            Utils.Assert(target == null, "Target is null when check whether can cast skill.");
                        #endif

            ServerLifeNpc castLife = caster as ServerLifeNpc;
            if (castLife.IsAlive == false)
            {
                return(skNumList);
            }

            short pos = 0;
            for ( ; pos < Consts.MAX_SKILL_COUNT; ++pos)
            {
                RtSkData rtsk = castLife.runSkMd.getRuntimeSkill(pos);
                if (rtsk != null)
                {
                    bool can = false;
                    ///
                    /// 冷却时间好了吗
                    ///
                    can = rtsk.canCast;

                    SkillConfigData skCfg = rtsk.skillCfg;
                    if (skCfg.DamageType == (short)1)
                    {
                        can = can & CanCast.canCast(caster, rtsk);
                    }
                    else if (skCfg.DamageType == (short)0)
                    {
                        can = can & CanCast.canCast(caster, target, rtsk);
                    }

                    //如果可以则加入可释放列表
                    if (can)
                    {
                        skNumList.Add(pos);
                    }
                }
            }

            return(skNumList);
        }
Пример #17
0
        /// <summary>
        /// 检测是否符合逻辑
        /// </summary>
        /// <param name="sk">技能,忽略</param>
        /// <param name="caster">施法者,忽略</param>
        /// <param name="targets">目标者们</param>
        public bool check(RtSkData sk, ConditionConfigure cfg, ServerNPC caster, IEnumerable <ServerNPC> targets)
        {
                        #if DEBUG
            Utils.Assert(cfg == null, "ConditionConfigure is null in BeHeadCondition.");
            Utils.Assert(targets == null, "Targets are null in BeHeadCondition.");
                        #endif

            bool Condi = false;

            ///
            /// 1. 判定是否符合关心的BeHead类型
            ///
            var self           = this.GetType();
            var classAttribute = (ConditionAttribute)Attribute.GetCustomAttribute(self, typeof(ConditionAttribute));
            if (cfg.ConditionType == classAttribute.Con)
            {
                //血线
                float hpLineFactor = cfg.Param1 * Consts.OneThousand;
                //满足的个数
                int Count = cfg.Param2;

                int curCnt = 0;

                foreach (ServerNPC npc in targets)
                {
                    float hpLine = (int)hpLineFactor * npc.data.rtData.totalHp;
                    if (npc.data.rtData.curHp <= hpLine)
                    {
                        curCnt++;
                    }
                }

                if (curCnt >= Count)
                {
                    Condi = true;
                }

                //判定概率
                if (Condi)
                {
                    Condi = PseudoRandom.getInstance().happen(cfg.Prop);
                }
            }

            return(Condi);
        }
Пример #18
0
        //判断target是否是skData的一个有效技能使用目标(不包括cd和距离,值判断能否对target使用)
        public bool IsValidTarget(ServerNPC caster, ServerNPC target, RtSkData rtsk)
        {
            bool          isValid  = false;
            ServerLifeNpc castLife = caster as ServerLifeNpc;

            if (castLife.IsAlive == false)
            {
                return(isValid);
            }

            if (rtsk != null)
            {
                isValid = CanCast.canCast(caster, target, rtsk, true);
            }

            return(isValid);
        }
Пример #19
0
        public override void OnStart()
        {
            for (short i = 0; i < 4; i++)
            {
                RtSkData sk = myHero.runSkMd.getRuntimeSkill(i);
                if (sk != null && sk.skillCfg.ID == curSkill.Value.skillCfg.ID)
                {
                    skillIdx = i;
                    break;
                }
            }

            if (skillIdx == -1)
            {
                ConsoleEx.DebugError(myHero.name + "  not find skill idx ::  " + curSkill.Value.skillCfg.Name);
            }
        }
Пример #20
0
        //不检查CD,不检查距离
        public bool isVaild(ServerNPC caster, ServerNPC target, short pos)
        {
            bool          isValid  = false;
            ServerLifeNpc castLife = caster as ServerLifeNpc;

            if (castLife.IsAlive == false)
            {
                return(isValid);
            }

            RtSkData rtsk = castLife.runSkMd.getRuntimeSkill(pos);

            if (rtsk != null)
            {
                isValid = CanCast.canCast(caster, target, rtsk, true);
            }

            return(isValid);
        }
Пример #21
0
        /// <summary>
        /// 检测是否符合逻辑
        /// </summary>
        /// <param name="sk">技能</param>
        /// <param name="cfg">条件配置技能, 忽略</param>
        /// <param name="caster">施法者, 忽略</param>
        /// <param name="targets">目标者们, 忽略</param>
        public bool check(RtSkData sk, ConditionConfigure cfg, ServerNPC caster, IEnumerable <ServerNPC> targets)
        {
                        #if DEBUG
            Utils.Assert(sk == null, "Skill is null in CountingCondition.");
            Utils.Assert(cfg == null, "ConditionConfigure is null in CountingCondition.");
                        #endif

            bool Condi = false;

            ///
            /// 1. 判定是否符合关心的Counting类型
            ///
            var self           = this.GetType();
            var classAttribute = (ConditionAttribute)Attribute.GetCustomAttribute(self, typeof(ConditionAttribute));
            if (cfg.ConditionType == classAttribute.Con)
            {
                ///
                /// 2. 只有RtFakeSkData才有计算功能
                ///
                RtFakeSkData fakeSk = sk as RtFakeSkData;
                if (fakeSk != null)
                {
                    ///
                    /// 3. 判定计数
                    ///
                    if (fakeSk.curCounting >= cfg.Param1)
                    {
                        Condi = true;
                    }

                    ///4.判定概率
                    if (Condi)
                    {
                        Condi = PseudoRandom.getInstance().happen(cfg.Prop);
                    }
                }
            }

            return(Condi);
        }
Пример #22
0
        ///
        /// 引导Buff是可以被打断的
        /// 创建假的Effect的配置(桩对象)
        ///
        EffectConfigData ctorStubEffCfg(RtSkData RtSk)
        {
            EffectConfigData stub = null;

            if (RtSk.ChannelBuff != null)
            {
                stub = new EffectConfigData()
                {
                    ID                       = -1,
                    Flags                    = EffectFlag.None,
                    EffectClass              = SkillTypeClass.Magical,
                    EffectTarget             = EffectTargetClass.SkillTarget,
                    EffectTargetType         = TargetSubClass.AllTarget,
                    EffectTargetStatusReject = NpcStatus.None,
                    EffectType               = EffectOp.DotHot,
                    Param1                   = RtSk.ChannelBuff.ID,
                    Prob                     = 1000,
                    EffectLimit              = -1,
                };
            }
            return(stub);
        }
Пример #23
0
        /// <summary>
        /// 搜索攻击目标
        /// </summary>
        /// <returns>The atk targets.</returns>
        public IEnumerable <ServerNPC> FindAtkTargets(ServerNPC caster, short pos, Sight sight)
        {
                        #if DEBUG
            Utils.Assert(caster == null, "Caster is null when cast skill.");
                        #endif

            ServerLifeNpc src = caster as ServerLifeNpc;
            if (src.IsAlive == false)
            {
                return(null);
            }

            RtSkData rtSk = src.runSkMd.getAttack(pos);
            if (rtSk != null)
            {
                IEnumerable <ServerNPC> targets = SelectS.Select(caster, rtSk, sight);
                return(targets);
            }
            else
            {
                return(null);
            }
        }
Пример #24
0
        /// <summary>
        /// // 判断skData能否对target使用
        /// </summary>
        /// <returns><c>true</c>, if cast was caned, <c>false</c> otherwise.</returns>
        /// <param name="caster">施法者.</param>
        /// <param name="target">技能使用目标.</param>
        /// <param name="skData">使用的技能.</param>
        public bool canCast(ServerNPC caster, ServerNPC target, RtSkData rtsk)
        {
            if (rtsk != null)
            {
                bool can = false;
                ///
                /// 冷却时间好了吗
                ///
                can = rtsk.canCast;

                SkillConfigData skCfg = rtsk.skillCfg;
                if (skCfg.DamageType == (short)1)
                {
                    can = can & CanCast.canCast(caster, rtsk);
                }
                else if (skCfg.DamageType == (short)0)
                {
                    can = can & CanCast.canCast(caster, target, rtsk);
                }

                return(can);
            }
            return(false);
        }
Пример #25
0
        /// <summary>
        /// 派发出去消息
        /// </summary>
        /// <param name="outMsg">Out message.</param>
        void dispatchMsg(List <MsgParam> outMsg, RtSkData skill)
        {
            if (outMsg != null && outMsg.Count > 0)
            {
                int count = outMsg.Count;

                for (int i = 0; i < count; ++i)
                {
                    MsgParam     msg    = outMsg[i];
                    WarAnimParam warMsg = msg as WarAnimParam;
                    warMsg.cmdType = WarMsg_Type.UseBuff;
                    warMsg.SkillId = skill == null ? -1 : skill.Num;

                    if (warMsg != null && warMsg.described != null)
                    {
                        SelfDescribed des = warMsg.described;
                                                #if DEBUG
                        ConsoleEx.DebugLog("Buff Msg is going out : " + fastJSON.JSON.Instance.ToJSON(des), ConsoleEx.YELLOW);
                                                #endif
                        msgMgr.SendMessageAsync(des.src, des.target, warMsg);
                    }
                }
            }
        }
Пример #26
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);
        }
Пример #27
0
 public override void SetValue(object value)
 {
     mValue = (RtSkData)value;
 }
Пример #28
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);
        }
Пример #29
0
        void DelayCast(ServerNPC caster, IEnumerable <ServerNPC> chosen, ICastEffect castor, EffectConfigData cfg, RtSkData RtSk, Action <MsgParam> Report)
        {
            bool            skDirecHurt  = true;
            List <MsgParam> MsgContainer = new List <MsgParam>();

            IEnumerable <ServerNPC> reTarget = selector.Select(caster, chosen, cfg);

            castor.Cast(caster, chosen, reTarget, skDirecHurt, MsgContainer);
            effMgr.Recycle(cfg, castor);

            ///
            /// ----  进入激活判定器 ----
            ///
            conDicder.EnterIncite(RtSk, cfg, caster, chosen);

            short pos = RtSk.pos;

            ///
            ///  回报数据,区分一条数据和多条数据
            ///
            HowToReport(MsgContainer, pos, Report);
        }
Пример #30
0
        /// <summary>
        /// Cast the specified caster, chosen, rtSk and MsgContainer.
        /// 这个是给普通攻击使用的,其实就是立即有结果的模式
        /// 没有激活判定器
        /// </summary>
        /// <param name="caster">Caster.</param>
        /// <param name="chosen">Chosen.可以为空</param>
        /// <param name="rtSk">Rt sk.</param>
        /// <param name="MsgContainer">Message container.</param>
        public void Cast(ServerNPC caster, IEnumerable <ServerNPC> chosen, RtSkData rtSk, List <MsgParam> MsgContainer)
        {
            bool skDirectlyHurt = true;

            Cast(caster, chosen, rtSk, MsgContainer, skDirectlyHurt);
        }