예제 #1
0
        /// <summary>
        /// Suffer the specified caster, target and damage.
        /// 收到伤害的时候,没有返回值.
        /// </summary>
        /// <param name="caster">释放者</param>
        /// <param name="target">目标者</param>
        /// <param name="damage">伤害值</param>
        public void Suffer(ServerNPC caster, ServerNPC sufferer, SelfDescribed des, WarServerNpcMgr npcMgr)
        {
            //拿到算子
            InjuryOp sufOp = OperatorMgr.instance.getImplement <InjuryOp>(EffectOp.Injury);

            handled = new Dmg {
                dmgValue   = des.targetEnd.param1,
                dmgType    = (SkillTypeClass)des.targetEnd.param3,
                isCritical = des.targetEnd.param2 == 1,
                hitCls     = (HurtHitClass)Enum.ToObject(typeof(HurtHitClass), des.targetEnd.param4),
            };

            //TODO: find buff
            EffectConfigData[] help = null;
            suf = sufOp.toSuffer(ref handled, sufferer.data, caster.data, help);
            ///
            ///更多的事情发生了,比如护盾,吸血,反弹
            ///
            report(caster.UniqueID, sufferer.UniqueID, suf, npcMgr);

            ///
            /// --------- 最终结算 --------
            ///
            sufferer.data.rtData.curHp -= (int)handled.dmgValue;


            ///
            /// --------- 通知Trigger,OnKilled ----------
            ///
            toTriggerMsg(caster, sufferer, npcMgr);
        }
예제 #2
0
        public Dmg toTargetDmg(NPCData self, NPCData target, EffectConfigData cfg)
        {
            ///-------- 物理伤害强度------
            ///先计算自己的物理伤害,
            float bphyselfhit = Physical_Hit(self, cfg);

            ///-------- 魔法伤害强度 -------
            /// 先计算自己的魔法伤害,
            float bMagselfhit = Magical_Hit(self, cfg);

            ///-------- NPC的总攻击强度,是cfg.EffectClass 类型-------
            float hit = bphyselfhit + bMagselfhit;

            //---------- 开始计算伤害 ---------
            float dmg = 0f;

            switch (cfg.EffectClass)
            {
            case SkillTypeClass.Holly:
                //神圣伤害不减少伤害
                dmg = hit;
                break;

            case SkillTypeClass.Magical:
                float magenemyavoid = Magical_Avoid(target, self);
                dmg = hit * (1.0f - magenemyavoid);
                break;

            case SkillTypeClass.Physical:
                float avdenemyratio = Physical_Avoid(target, self);
                dmg = hit * (1.0f - avdenemyratio);
                break;
            }

            /// --------- 暴击伤害 ----------
            ///
            float critialRatio = CriticalRatio(self, target, cfg);
            bool  isCri        = PseudoRandom.getInstance().happen(critialRatio);

            if (isCri)
            {
                float addtion = AdditionRatio(self, cfg);
                dmg = dmg * addtion;
            }

            Dmg final = new Dmg()
            {
                dmgValue   = dmg,
                dmgType    = cfg.EffectClass,
                isCritical = isCri,
                hitCls     = HurtHitClass.None,
            };

            return(final);
        }
예제 #3
0
        //收到伤害
        protected void BeInjured(WarTarAnimParam param)
        {
            if (param == null)
            {
                ConsoleEx.DebugWarning("BeInjured :: BeInjured :: param is null");
                return;
            }


            if (param.described != null)
            {
                SufferInjureEffect sufInjury = warServerMgr.sufMgr.getImplement <SufferInjureEffect>(EffectOp.Injury);
                SelfDescribed      des       = param.described;

                //记录攻击自己的人的ID
                data.btData.atkerID = des.src;

                if (des.target == UniqueId && IsAlive)
                {
                    ServerNPC caster = npcMgr.GetNPCByUniqueID(des.src);
                    sufInjury.Suffer(caster, this, des, npcMgr);
                    Dmg oneDmg = sufInjury.getHandled;

                    hpMsg.uniqueId = UniqueID;
                    hpMsg.deltaHp  = (int)oneDmg.dmgValue;
                    hpMsg.curHp    = data.rtData.curHp;
                    hpMsg.totalHp  = data.rtData.totalHp;
                    hpMsg.isDamage = true;
                    hpMsg.srcID    = des.src;
                    warServerMgr.realServer.proxyCli.NPChp(hpMsg);

//                    if (caster.UniqueID == npcMgr.ActiveHero.UniqueId)
//                    {
//                        if (OnHitByActiveHero != null)
//                        {
//                            Vector3 posIn2D = Vector3.zero;
//                            Vector3 posIn3D = transform.position;
//                            posIn3D.y += 3.5f;
//                            wmMgr.GetUIPos_Ref3DPos (posIn3D, ref posIn2D);
//                            OnHitByActiveHero ((int)oneDmg.dmgValue, true, oneDmg.isCritical, posIn2D);
//                        }
//                    }

                    //检查自己是否被杀
                    if (data.rtData.curHp <= 0)
                    {
                        BeKillded();
                    }
                }
            }
        }
예제 #4
0
        SelfDescribed record(int CasterId, int SufferId, Dmg damage, int i)
        {
            //统计数据
            SelfDescribed des = new SelfDescribed()
            {
                src       = CasterId,
                target    = SufferId,
                act       = Verb.Strike,
                srcEnd    = null,
                targetEnd = new EndResult()
                {
                    param1 = (int)damage.dmgValue,
                    param2 = damage.isCritical ? 1 : 0,
                    param3 = (int)damage.dmgType,
                    param4 = (int)damage.hitCls,
                }
            };

            return(des);
        }
예제 #5
0
        public Suf toSuffer(ref Dmg damage, NPCData suffer, NPCData from, EffectConfigData[] resis)
        {
                        #if DEBUG
            Utils.Assert(suffer == null, "NPCData suffer can't be null.");
            Utils.Assert(suffer == null, "NPCData attacker can't be null.");
                        #endif

            ///
            /// --------------- Suffer 获取Dot/Hot -------------
            ///

            bool forbid_die = damage.hitCls.check(HurtHitClass.Forbid_Die);
            if (forbid_die)
            {
                if (damage.dmgValue >= suffer.rtData.curHp)
                {
                    damage.dmgValue = suffer.rtData.curHp - 1;
                }
            }

            //TODO : 错误逻辑,仅仅是测试使用
            bool forbid_shield = damage.hitCls.check(HurtHitClass.Forbid_ProtectionShield);
            if (!forbid_shield)              //不无视护盾

            {
            }

            //要计算反弹吗?
            bool rebound = false;
            switch (damage.dmgType)
            {
            case SkillTypeClass.Rebound_Hol:
            case SkillTypeClass.Rebound_Mag:
            case SkillTypeClass.Rebound_Phy:
                rebound = false;
                break;

            case SkillTypeClass.Holly:
            case SkillTypeClass.Magical:
            case SkillTypeClass.Physical:
                rebound = true;
                break;
            }

            if (rebound)              //计算反弹

            {
            }


            ///
            /// ---- 计算吸血 ------
            ///

            Suf suf = new Suf()
            {
                sufValue   = damage,
                rebValue   = null,
                bdyValue   = null,
                protectVal = null,
                resDmgType = ResistanteClass.None,
            };
            return(suf);
        }
예제 #6
0
        ///
        /// 带AI的伤害技能的实现
        ///      但是要不要减伤
        ///
        ///     〖物理伤害〗_敌=〖物理攻击力〗_敌×(1-〖物理免伤〗_自  )
        ///     〖法术伤害〗_敌=〖法术攻击力〗_敌×(1-〖法术免伤〗_自  )
        /// 〖伤害〗_敌=〖物理伤害〗_敌+〖法术伤害〗_敌
        ///
        /// Self 对 target的技能伤害
        /// 只考虑了输出值,并不考虑后续的反弹,护盾等情况
        ///
        public Dmg toTargetDmg(NPCData self, NPCData target, EffectConfigData cfg)
        {
            ///-------- 物理伤害强度------
            ///先计算自己的物理伤害,
            float bphyselfhit = Physical_Hit(self, cfg);

            ///-------- 魔法伤害强度 -------
            /// 先计算自己的魔法伤害,
            float bMagselfhit = Magical_Hit(self, cfg);

            ///-------- NPC的总攻击强度,是cfg.EffectClass 类型-------
            float hit = bphyselfhit + bMagselfhit + cfg.Param3;

            HurtHitClass hitType = (HurtHitClass)Enum.ToObject(typeof(HurtHitClass), cfg.Param7);

            ///
            /// --------- 检测 不计算减伤 -----------
            ///
            bool forbidArmer = hitType.check(HurtHitClass.Forbid_Armer);

            float dmg = 0f;

            if (forbidArmer)
            {
                dmg = hit;
            }
            else
            {
                switch (cfg.EffectClass)
                {
                case SkillTypeClass.Holly:
                    //神圣伤害不减少伤害
                    dmg = hit;
                    break;

                case SkillTypeClass.Magical:
                    float magenemyavoid = Magical_Avoid(target, self);
                    dmg = hit * (1.0f - magenemyavoid);
                    break;

                case SkillTypeClass.Physical:
                    float avdenemyratio = Physical_Avoid(target, self);
                    dmg = hit * (1.0f - avdenemyratio);
                    break;
                }
            }

            dmg = dmg * (1 + cfg.Param4 * Consts.OneThousand);

            /// --------- 暴击伤害 ----------
            ///
            float critialRatio = CriticalRatio(self, target, cfg);
            bool  isCri        = PseudoRandom.getInstance().happen(critialRatio);

            if (isCri)
            {
                float addtion = AdditionRatio(self, cfg);
                dmg = dmg * addtion;
            }

            Dmg final = new Dmg()
            {
                dmgValue   = dmg,
                dmgType    = cfg.EffectClass,
                isCritical = isCri,
                hitCls     = hitType,
            };

            return(final);
        }
예제 #7
0
        /// <summary>
        /// 处理主动打击其他NPC的时候,触发的事情
        /// </summary>
        /// <param name="CasterId">施法者ID</param>
        /// <param name="SufferId">撞击者ID</param>
        /// <param name="idx">几个被撞击者</param>
        /// <param name="finalTar">是否最终目标</param>
        /// <param name="maxDis">是否最大距离</param>
        /// <param name="returnback">返回原处</param>
        /// <param name="EffectId">效果ID</param>
        /// <param name="npcMgr">Npc mgr.</param>
        void HandleOnAttack(int CasterId, int SufferId, int idx, bool finalTar, bool maxDis, bool returnback, int EffectId, WarServerNpcMgr npcMgr)
        {
            ServerNPC caster = npcMgr.GetNPCByUniqueID(CasterId);
            ServerNPC suffer = npcMgr.GetNPCByUniqueID(SufferId);

            ///
            /// -------- 获取Effect的配置 -------
            ///
            EffectModel      efModel = Core.Data.getIModelConfig <EffectModel>();
            EffectConfigData efCfg   = efModel.get(EffectId);

            Utils.Assert(efCfg == null, "Can't find Effect Configure. effect ID = " + EffectId);

            if (efSelector == null)
            {
                efSelector = EffectSufferShared.get(npcMgr);
            }

            ///
            /// 先做技能
            ///
            IEnumerable <ServerNPC> filter = efSelector.Select(caster, new List <ServerNPC> {
                suffer
            }, efCfg);

            if (filter.Any())
            {
                //消失的时候,触发可能的位移
                HookNpcDisappearType disappearType = (HookNpcDisappearType)Enum.ToObject(typeof(HookNpcDisappearType), efCfg.Param2);
                //HookNpcDmgType hookDmgType = (HookNpcDmgType) Enum.ToObject(typeof(HookNpcDmgType), efCfg.Param8);
                HookNpcMoveType moveType = (HookNpcMoveType)Enum.ToObject(typeof(HookNpcMoveType), efCfg.Param5);

                ///
                /// 一定会有伤害,之后,先判定是否消失,如果消失,则再次判定是否移动
                ///

                ///
                /// ------- 开始运算BulletOp --------
                ///
                OperatorMgr OpMgr = OperatorMgr.instance;
                BulletNpcOp op    = OpMgr.getImplement <BulletNpcOp>(EffectOp.Bullet_NPC);

                Dmg  dmg           = op.toTargetDmg(caster.data, suffer.data, efCfg);
                int  moveDirection = 0;
                bool dis           = Disappear(disappearType, idx, finalTar, maxDis, returnback);
                if (dis)
                {
                    moveDirection = (int)moveType;
                }

                SelfDescribed   des   = record(CasterId, SufferId, dmg, dis, moveDirection);
                WarTarAnimParam param = new WarTarAnimParam()
                {
                    OP        = EffectOp.Injury,
                    OringinOP = EffectOp.HookNpc,
                    described = des,
                };
                ///发送消息
                npcMgr.SendMessageAsync(CasterId, SufferId, param);
            }
        }
예제 #8
0
        /// <summary>
        /// 处理主动打击其他NPC的时候,触发的事情
        /// </summary>
        void HandleOnAttack(MsgParam msg, WarServerNpcMgr npcMgr)
        {
            WarMsgParam warMsg = msg as WarMsgParam;

            if (warMsg != null)
            {
                if (efSelector == null)
                {
                    efSelector = EffectSufferShared.get(npcMgr);
                }

                int CasterId = warMsg.Sender;
                int SufferId = warMsg.Receiver;
                int EffectId = warMsg.arg1;
                int FinalId  = warMsg.arg2;
                //是否是最终目标
                bool IsfinalTarget = SufferId == FinalId;
                ///
                /// -------- 获取Effect的配置 -------
                ///
                EffectModel      efModel = Core.Data.getIModelConfig <EffectModel>();
                EffectConfigData efCfg   = efModel.get(EffectId);
                Utils.Assert(efCfg == null, "Can't find Effect Configure. effect ID = " + EffectId);
                //半径
                float radius = efCfg.Param9 * Consts.oneHundred;

                ServerNPC caster = npcMgr.GetNPCByUniqueID(CasterId);
                ServerNPC suffer = npcMgr.GetNPCByUniqueID(SufferId);

                ///
                /// ----------- 先坐第一步的选择和解析 ------------
                ///
                IEnumerable <ServerNPC> filter = efSelector.Select(caster, new List <ServerNPC> {
                    suffer
                }, efCfg);
                if (filter.Count() > 0)
                {
                    BulletHurtType   HurtType = (BulletHurtType)Enum.ToObject(typeof(BulletHurtType), efCfg.Param8);
                    List <ServerNPC> targets  = selectTarget(HurtType, suffer, IsfinalTarget, npcMgr, radius);

                    int tarCnt = targets.Count;
                    if (tarCnt > 0)
                    {
                        ///
                        /// ------- 开始运算BulletOp --------
                        ///
                        OperatorMgr OpMgr = OperatorMgr.instance;
                        BulletNpcOp op    = OpMgr.getImplement <BulletNpcOp>(EffectOp.Bullet_NPC);

                        for (int i = 0; i < tarCnt; ++i)
                        {
                            ServerNPC target = targets[i];
                            //alive ?
                            if (target.data.rtData.curHp > 0)
                            {
                                Dmg           damage = op.toTargetDmg(caster.data, target.data, efCfg);
                                SelfDescribed des    = record(CasterId, SufferId, damage, i);

                                WarTarAnimParam param = new WarTarAnimParam()
                                {
                                    OP        = EffectOp.Injury,
                                    OringinOP = EffectOp.Bullet_NPC,
                                    described = des,
                                };
                                ///发送消息
                                npcMgr.SendMessageAsync(CasterId, SufferId, param);
                            }
                        }
                    }
                }
            }
        }
예제 #9
0
        public void Cast(ServerNPC src, IEnumerable <ServerNPC> skTarget, IEnumerable <ServerNPC> target, bool skDirectHurt, List <MsgParam> container)
        {
                        #if DEBUG
            Utils.Assert(src == null, "Injury Effect can't find attacker.");
            Utils.Assert(skCfg == null, "Skill Configure is null in Injury Effect .");
                        #endif

            //发起者的信息
            WarSrcAnimParam SrcParam = new WarSrcAnimParam()
            {
                OP             = EffectOp.Injury,
                ShootAction    = skCfg.ShootAction,
                ShootTime      = skCfg.ShootTime,
                ShootEventTime = skCfg.ShootEventTime,
                //Debug信息
                SkillId = skCfg == null ? -1 : skCfg.ID,
            };

            SelfDescribed SrcDes = new SelfDescribed()
            {
                src       = src.UniqueID,
                target    = src.UniqueID,
                act       = Verb.Punch,
                srcEnd    = null,
                targetEnd = new EndResult()
                {
                    param1 = 0,
                    param2 = 0,
                    param3 = 0,
                    param4 = 0,
                    param8 = skCfg.MissileSpeed,
                    param9 = skCfg.Distance,
                },
            };

            SrcParam.described = SrcDes;

            List <ServerNPC> effTarget = target.ToList();
            int count = effTarget.Count;
            //如果没有目标的时候
            if (count == 0)
            {
                SrcParam.InjureTar = null;
                //新建一个目标为空的序列,主要告知skCfg.MissileSpeed 和 skCfg.Distance
                //该技能没有目标去命中
                container.Add(SrcParam);
                return;
            }
            //如果存在目标的时候
            InjuryOp cal = OpMgr.getImplement <InjuryOp>(EffectOp.Injury);

            List <ServerNPC> skillTarget = skTarget.ToList();

            ///
            /// ---- 获取主目标
            ///
            int MainTargetID = 0;
            int skcount      = skillTarget.Count;
            if (skcount > 0)
            {
                ServerNPC npc = skillTarget[0];
                MainTargetID = npc.UniqueID;
            }

            //count 必定 > 0
            //如果是技能直接的伤害
            if (skDirectHurt)
            {
                WarTarAnimParam[] TarList = new WarTarAnimParam[count];

                for (int i = 0; i < count; ++i)
                {
                    WarTarAnimParam TarParam = new WarTarAnimParam()
                    {
                        OP        = EffectOp.Injury,
                        HitAction = cfg.HitAction,
                        SkillId   = skCfg.ID,
                    };

                    ServerNPC     tar = effTarget[i];
                    Dmg           dmg = cal.toTargetDmg(src.data, tar.data, cfg);
                    SelfDescribed des = new SelfDescribed()
                    {
                        src       = src.UniqueID,
                        target    = tar.UniqueID,
                        act       = Verb.Punch,
                        srcEnd    = null,
                        targetEnd = new EndResult()
                        {
                            param1 = (int)dmg.dmgValue,
                            param2 = dmg.isCritical ? 1 : 0,
                            param3 = (int)dmg.dmgType,
                            param4 = (int)dmg.hitCls,
                            param5 = MainTargetID,
                            param8 = skCfg.MissileSpeed,
                            param9 = skCfg.Distance,
                        },
                    };
                    TarParam.described = des;

                    TarList[i] = TarParam;
                }

                SrcParam.InjureTar = TarList;
                container.Add(SrcParam);
            }
            else
            {
                container.Add(SrcParam);
                //如果不是技能的伤害,而是buff或者Trigger的伤害
                for (int i = 0; i < count; ++i)
                {
                    WarTarAnimParam TarParam = new WarTarAnimParam()
                    {
                        OP        = EffectOp.Injury,
                        HitAction = cfg.HitAction,
                        SkillId   = skCfg.ID,
                    };

                    ServerNPC     tar = effTarget[i];
                    Dmg           dmg = cal.toTargetDmg(src.data, tar.data, cfg);
                    SelfDescribed des = new SelfDescribed()
                    {
                        src       = src.UniqueID,
                        target    = tar.UniqueID,
                        act       = Verb.Punch,
                        srcEnd    = null,
                        targetEnd = new EndResult()
                        {
                            param1 = (int)dmg.dmgValue,
                            param2 = dmg.isCritical ? 1 : 0,
                            param3 = (int)dmg.dmgType,
                            param4 = (int)dmg.hitCls,
                            param5 = MainTargetID,
                            param8 = skCfg.MissileSpeed,
                            param9 = skCfg.Distance,
                        },
                    };

                    TarParam.described = des;

                    container.Add(TarParam);
                }
            }
        }
예제 #10
0
        void report(int CasterId, int SufferId, Suf suf, WarServerNpcMgr npcMgr)
        {
            //检测护盾
            if (suf.resDmgType.check(ResistanteClass.Protection))
            {
                if (suf.protectVal != null)
                {
                    //统计数据
                    SelfDescribed des = new SelfDescribed()
                    {
                        src    = CasterId,
                        target = SufferId,                         //SufferId 应该变为真实的护盾的NPC
                        act    = Verb.Punch,
                        srcEnd = null,
                    };

                    EndResult tarEnd = new EndResult();

                    Dmg protectDmg = suf.protectVal.Value;
                    tarEnd.param1 = (int)protectDmg.dmgValue;
                    tarEnd.param2 = protectDmg.isCritical ? 1 : 0;
                    tarEnd.param3 = (int)protectDmg.dmgType;
                    tarEnd.param4 = (int)HurtHitClass.None;

                    des.targetEnd = tarEnd;

                    WarTarAnimParam param = new WarTarAnimParam()
                    {
                        OP        = EffectOp.Injury,
                        OringinOP = EffectOp.Injury,
                        described = des,
                    };

                    npcMgr.SendMessageAsync(des.src, des.target, param);
                }
            }

            if (suf.resDmgType.check(ResistanteClass.Bloody) || suf.resDmgType.check(ResistanteClass.Rebound))
            {
                //反弹不为空
                if (suf.rebValue != null)
                {
                    //统计数据
                    SelfDescribed des = new SelfDescribed()
                    {
                        src    = SufferId,
                        target = CasterId,
                        act    = Verb.Punch,
                        srcEnd = null,
                    };

                    EndResult tarEnd = new EndResult();

                    Dmg rebDmg = suf.rebValue.Value;
                    tarEnd.param1 = (int)rebDmg.dmgValue;
                    tarEnd.param2 = rebDmg.isCritical ? 1 : 0;
                    tarEnd.param3 = (int)rebDmg.dmgType;
                    tarEnd.param4 = (int)HurtHitClass.None;

                    des.targetEnd = tarEnd;

                    WarTarAnimParam param = new WarTarAnimParam()
                    {
                        OP        = EffectOp.Injury,
                        OringinOP = EffectOp.Injury,
                        described = des,
                    };

                    npcMgr.SendMessageAsync(des.src, des.target, param);
                }

                //吸血不为空
                if (suf.bdyValue != null)
                {
                    //统计数据
                    SelfDescribed des = new SelfDescribed()
                    {
                        src    = SufferId,
                        target = CasterId,
                        act    = Verb.Recover,
                        srcEnd = null,
                    };

                    EndResult tarEnd = new EndResult();

                    Dmg bdyDmg = suf.bdyValue.Value;
                    tarEnd.param1 = (int)bdyDmg.dmgValue;
                    tarEnd.param2 = bdyDmg.isCritical ? 1 : 0;
                    tarEnd.param3 = (int)bdyDmg.dmgType;
                    tarEnd.param4 = (int)HurtHitClass.None;

                    des.targetEnd = tarEnd;

                    WarTarAnimParam param = new WarTarAnimParam()
                    {
                        OP        = EffectOp.Treat,
                        OringinOP = EffectOp.Treat,
                        described = des,
                    };

                    npcMgr.SendMessageAsync(des.src, des.target, param);
                }
            }
        }