Пример #1
0
        public void RtShallowCopy()
        {
            NPCRuntimeData newRt = runtime.ShallowCopy();

            Assert.IsTrue(newRt.curHp == 300);
            Assert.IsTrue(newRt.crit == 0.1F);
        }
Пример #2
0
        public void Suffer(ServerNPC caster, ServerNPC sufferer, SelfDescribed des, WarServerNpcMgr npcMgr)
        {
            //拿到算子
            InjuryOp CoreS = OperatorMgr.instance.getImplement <InjuryOp>(EffectOp.Injury);

            //TODO: find buff
            EffectConfigData[] help = null;

            handled = new Treat {
                treatValue = des.targetEnd.param1,
                treatType  = (SkillTypeClass)des.targetEnd.param3,
                isCritical = des.targetEnd.param2 == 1,
            };

            SufTreat res = CoreS.toSufferTreat(ref handled, sufferer.data, caster.data, help);

            if (res.isCureProtectioin)
            {
                //TODO : add Info here.
            }

            ///
            /// 最终结果的计算
            ///
            NPCRuntimeData rtdata = sufferer.data.rtData;

            rtdata.curHp += (int)handled.treatValue;
            rtdata.curHp  = rtdata.curHp > rtdata.totalHp ? rtdata.totalHp : rtdata.curHp;
        }
Пример #3
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);
        }
Пример #4
0
        public void Init()
        {
            cfg = new NPCConfigData()
            {
                type        = LifeNPCType.Build,
                moveable    = Moveable.BeStatic,
                skill       = new int[] { 1, 2, 3 },
                crit        = 0.1f,
                ID          = 3,
                healthpoint = 300,
            };

            runtime = new NPCRuntimeData(cfg);
        }
Пример #5
0
        CreatNpcDepandency ctorToShowcase(NPCRuntimeData rt, NPCConfigData cfg, int[] BuffIDList, UVec3 TargetVec3)
        {
            NPCData data = new NPCData()
            {
                configData = cfg,
                rtData     = rt,
            };

            //有碰撞
            bool Collide = true;
            CreatNpcDepandency depandency = new CreatNpcDepandency()
            {
                IsCollide     = Collide,
                Source        = data,
                Buff_IDs      = BuffIDList,
                TargetVector3 = new List <Vec3F>(),
            };

            depandency.TargetVector3.Add(TargetVec3.toCustomVec3());

            return(depandency);
        }
Пример #6
0
        /// <summary>
        /// 释放技能效果
        /// </summary>
        /// <param name="src">效果发起者</param>
        /// <param name="skTarget">技能选择的目标</param>
        /// <param name="target">技能先选择目标后,再次Effect选择后的目标</param>
        /// <param name="skDirectHurt">是否是技能的直接伤害</param>
        /// <param name="container">所有数据展现的容器,本次Effect施法的效果会依次加入</param>
        public void Cast(ServerNPC src, IEnumerable <ServerNPC> skTarget, IEnumerable <ServerNPC> target, bool skDirectHurt, List <MsgParam> container)
        {
                        #if DEBUG
            Utils.Assert(cfg == null, "Effect Configure is null in SwitchNpcEffect.");
                        #endif

            int       SwitchToId = cfg.Param1;
            UVec3     Locale     = src.transform.position;
            NPCAIType AI         = (NPCAIType)Enum.ToObject(typeof(NPCAIType), cfg.Param2);

            //数据源
            CtorNpcSource datasrc  = (CtorNpcSource)Enum.ToObject(typeof(CtorNpcSource), cfg.Param3);
            int           chargeOf = cfg.Param4;
            float         duration = cfg.Param5 * Consts.OneThousand;

            //参数10,是否继承普通攻击
            bool inheritNorAtk = cfg.Param10 == 0;

            NPCConfigData  npcCfg = null;
            NPCRuntimeData npcRt  = null;

            //获取参数配置
            NPCModel model = Core.Data.getIModelConfig <NPCModel>();
            switch (datasrc)
            {
            case CtorNpcSource.NPC_Castor_Init:
                npcCfg = src.data.configData.ShallowCopy();
                break;

            case CtorNpcSource.NPC_Castro_Cur:
                npcCfg = src.data.configData.ShallowCopy();
                npcRt  = src.data.rtData.ShallowCopy();
                break;

            case CtorNpcSource.NPC_Table:
                npcCfg = model.get(SwitchToId);
                Utils.Assert(npcCfg == null, "Can't find NPC configure. NPC ID = " + SwitchToId);
                break;
            }

            if (inheritNorAtk == false)
            {
                NPCConfigData swtNpcCfg = model.get(SwitchToId);
                Utils.Assert(swtNpcCfg == null, "Can't find NPC configure. NPC ID = " + SwitchToId);
                npcCfg.ID        = SwitchToId;
                npcCfg.normalHit = swtNpcCfg.normalHit;
            }

            npcRt = npcRt ?? new NPCRuntimeData(npcCfg);

            //额外的属性修改
            NPCAttributeModel AttModel = Core.Data.getIModelConfig <NPCAttributeModel>();
            AttrbuteConfig    att1     = AttModel.get(cfg.Param6);
            AttrbuteConfig    att2     = AttModel.get(cfg.Param8);

            //参数
            float param1 = cfg.Param7 * Consts.OneThousand;
            float param2 = cfg.Param9 * Consts.OneThousand;

            //修正属性的值
            if (att1 != null)
            {
                if (att1.type == "int")
                {
                    npcRt.addIntegerValue(att1.note, param1);
                }
                else if (att1.type == "float")
                {
                    npcRt.addFloatValue(att1.note, param1);
                }
            }

            if (att2 != null)
            {
                if (att2.type == "int")
                {
                    npcRt.addIntegerValue(att2.note, param2);
                }
                else if (att2.type == "float")
                {
                    npcRt.addFloatValue(att2.note, param2);
                }
            }

            //Buff的列表
            int[] BuffIds = cfg.Param11;

            ///
            /// 统计信息
            ///
            WarSrcAnimParam SrcParam = new WarSrcAnimParam()
            {
                OP             = EffectOp.SwitchNpc,
                ShootAction    = skCfg.ShootAction,
                ShootEventTime = skCfg.ShootEventTime,
                ShootTime      = skCfg.ShootTime,
                described      = new SelfDescribed()
                {
                    src    = src.UniqueID,
                    target = src.UniqueID,
                    act    = Verb.Creature,
                    srcEnd = new EndResult {
                        param1 = SwitchToId,
                        param2 = (int)AI,
                        param3 = chargeOf,
                        param8 = duration,
                    },
                    targetEnd = null,
                },

                SkillId   = skCfg.ID,
                OringinOP = EffectOp.SwitchNpc,
            };

            SrcParam.described.srcEnd.obj = ctorToShowcase(npcRt, npcCfg, BuffIds, Locale);

            container.Add(SrcParam);
        }
Пример #7
0
        /// <summary>
        /// 释放技能效果
        /// </summary>
        /// <param name="src">效果发起者</param>
        /// <param name="skTarget">技能选择的目标, 无意义</param>
        /// <param name="target">技能先选择目标后,再次Effect选择后的目标</param>
        /// <param name="skDirectHurt">是否是技能的直接伤害, 这个没有伤害</param>
        /// <param name="container">所有数据展现的容器,本次Effect施法的效果会依次加入</param>
        public void Cast(ServerNPC src, IEnumerable <ServerNPC> skTarget, IEnumerable <ServerNPC> target, bool skDirectHurt, List <MsgParam> container)
        {
                        #if DEBUG
            Utils.Assert(skCfg == null, "Skill Configure is null in BulletNpcEffect routine.");
                        #endif

            WarSrcAnimParam SrcParam = new WarSrcAnimParam()
            {
                OP             = EffectOp.CtorNPC,
                ShootAction    = skCfg.ShootAction,
                ShootTime      = skCfg.ShootTime,
                ShootEventTime = skCfg.ShootEventTime,
            };

            int   CtorNpcId = cfg.Param1;
            float LifeTime  = cfg.Param2 * Consts.OneThousand;

            CtorNpcPos pos = (CtorNpcPos)Enum.ToObject(typeof(CtorNpcPos), cfg.Param3);

            //碰撞
            bool Collide = cfg.Param4 == 1;
            int  AI_ID   = cfg.Param5;

            int param_1 = cfg.Param8;
            int param_2 = cfg.Param10;

            //会有的Buff
            int[] BuffIDList = cfg.Param11;

            //数据源
            CtorNpcSource datasrc = (CtorNpcSource)Enum.ToObject(typeof(CtorNpcSource), cfg.Param6);

            //数据源的修正
            CtorNpcAttri attr_1 = (CtorNpcAttri)Enum.ToObject(typeof(CtorNpcAttri), cfg.Param7);
            CtorNpcAttri attr_2 = (CtorNpcAttri)Enum.ToObject(typeof(CtorNpcAttri), cfg.Param9);

            ///
            /// 获取数据源
            ///
            NPCData        data = new NPCData();
            NPCConfigData  cfgD = null;
            NPCRuntimeData rtD  = null;

            if (datasrc == CtorNpcSource.NPC_Table)
            {
                NPCModel model = Core.Data.getIModelConfig <NPCModel>();
                cfgD = model.get(CtorNpcId);
                Utils.Assert(cfgD == null, "Can't find NPC configure. NPC ID = " + CtorNpcId);
            }
            else if (datasrc == CtorNpcSource.NPC_Castro_Cur)
            {
                cfgD = src.data.configData;
                rtD  = src.data.rtData.ShallowCopy();
            }
            else if (datasrc == CtorNpcSource.NPC_Castor_Init)
            {
                cfgD = src.data.configData;
            }

            rtD = rtD ?? new NPCRuntimeData(cfgD);

            List <String> changed_1 = attr_1.SwitchTo();
            List <String> changed_2 = attr_2.SwitchTo();

            int cnt = changed_1.Count;
            if (cnt > 0)
            {
                for (int i = 0; i < cnt; ++i)
                {
                    rtD.setValue(changed_1[i], (Int32Fog)param_1);
                }
            }

            cnt = changed_2.Count;
            if (cnt > 0)
            {
                for (int i = 0; i < cnt; ++i)
                {
                    rtD.setValue(changed_2[i], (Int32Fog)param_2);
                }
            }

            data.configData = cfgD;
            data.rtData     = rtD;

            ///
            /// 获取目标位置
            ///
            List <UVec3> TargetVec3 = new List <UVec3>();
            if (pos == CtorNpcPos.Castor_Forward)
            {
                TargetVec3.Add(src.transform.forward);
            }
            else if (pos == CtorNpcPos.Target)
            {
                foreach (ServerNPC t in target)
                {
                    TargetVec3.Add(t.transform.position);
                }
            }
            else if (pos == CtorNpcPos.Castor_Surround)
            {
                TargetVec3.Add(src.transform.position);
            }


            ///
            /// ------ 获取统计信息 ------
            ///
            SelfDescribed des = new SelfDescribed()
            {
                src    = src.UniqueID,
                target = src.UniqueID,
                act    = Verb.Creature,
                srcEnd = new EndResult {
                    param1 = CtorNpcId,
                    param2 = AI_ID,
                    param8 = LifeTime,
                },
                targetEnd = null,
            };

            des.srcEnd.obj     = ctorToShowcase(Collide, data, BuffIDList, TargetVec3, src);
            SrcParam.SkillId   = skCfg.ID;
            SrcParam.described = des;

            container.Add(SrcParam);
        }
Пример #8
0
        //发送给Trigger的数据
        void toTriggerMsg(ServerNPC caster, ServerNPC sufferer, WarServerNpcMgr npcMgr)
        {
            ServerNPC tri = npcMgr.TagNpc("Trigger");

            NPCData        sfData = sufferer.data;
            NPCRuntimeData sfRt   = sfData.rtData;

            if (sfRt.curHp > 0)
            {
                /// TODO: add OnAttack,在释放出添加, 不在这里

                /// TODO: add BeAttack
                SelfDescribed des = new SelfDescribed()
                {
                    srcEnd = new EndResult()
                    {
                        param1 = caster.UniqueID,
                        param2 = sufferer.UniqueID,
                    },
                    targetEnd = null,
                };
                WarAnimParam param = new WarAnimParam()
                {
                    cmdType   = WarMsg_Type.BeAttacked,
                    described = des,
                };

                npcMgr.SendMessageAsync(sufferer.UniqueID, tri.UniqueID, param);
            }

            if (sfRt.curHp <= 0)
            {
                /// TODO: add OnKilled
                SelfDescribed des = new SelfDescribed()
                {
                    srcEnd = new EndResult()
                    {
                        param1 = caster.UniqueID,
                        param2 = sufferer.UniqueID,
                    },
                    targetEnd = null,
                };
                WarAnimParam param = new WarAnimParam()
                {
                    cmdType   = WarMsg_Type.OnKilled,
                    described = des,
                };

                npcMgr.SendMessageAsync(sufferer.UniqueID, tri.UniqueID, param);

                /// TODO: add BeKilled
                SelfDescribed des2 = new SelfDescribed()
                {
                    srcEnd = new EndResult()
                    {
                        param1 = caster.UniqueID,
                        param2 = sufferer.UniqueID,
                    },
                    targetEnd = null,
                };
                WarAnimParam param2 = new WarAnimParam()
                {
                    cmdType   = WarMsg_Type.BeKilled,
                    described = des2,
                };

                npcMgr.SendMessageAsync(sufferer.UniqueID, tri.UniqueID, param2);
            }
        }
Пример #9
0
        //百分比交换
        void PercentExchange(List <AttrbuteConfig> used, NPCData self, NPCData tar, float Min, WarSrcAnimParam SrcParam, WarTarAnimParam TarParam)
        {
            int cnt = used.Count;

            if (cnt <= 0)
            {
                return;
            }

            for (int i = 0; i < cnt; ++i)
            {
                AttrbuteConfig att = used[i];

                NPCRuntimeData selfRt = self.rtData;
                NPCRuntimeData tarRt  = tar.rtData;

                NPCConfigData selfCfg = self.configData;
                NPCConfigData tarCfg  = tar.configData;

                float selfCfgVal = selfCfg.getValue <float>(att.note);
                float tarCfgVal  = tarCfg.getValue <float>(att.note);

                float selfRtVal = selfRt.getFloatValue(att.note);
                float tarRtVal  = tarRt.getFloatValue(att.note);
                //自己的值
                float self_att1_per = selfRtVal / selfCfgVal;
                //敌人的值
                float tar_att1_per = tarRtVal / tarCfgVal;
                //敌人值的下限
                float tar_att1_per_min = Min;


                float tarVal = 0f;
                //如果传递过去的百分比大于下限,则将自己的值和敌人直接替换
                if (self_att1_per > tar_att1_per_min)
                {
                    tarVal = tarCfgVal * self_att1_per;
                }
                else
                {
                    tarVal = tarCfgVal * tar_att1_per_min;
                }

                if (att.type == "float")
                {
                    tarRt.setValue(att.note, tarVal);
                }
                else
                {
                    tarRt.setValue(att.note, (int)tarVal);
                }

                float selfVal = selfCfgVal * tar_att1_per;
                if (att.type == "float")
                {
                    selfRt.setValue(att.note, selfVal);
                }
                else
                {
                    selfRt.setValue(att.note, (int)selfVal);
                }

                ///
                /// 血量的信息需要特别的传递给UI
                ///
                if (att.note == "curHp")
                {
                    SrcParam.described.srcEnd = new EndResult()
                    {
                        param1 = (int)(selfVal - selfRtVal),
                        param2 = TarParam.described.target,
                    };

                    TarParam.described.targetEnd = new EndResult()
                    {
                        param1 = (int)(tarVal - tarRtVal),
                        param2 = TarParam.described.target,
                    };
                }
            }
        }
Пример #10
0
        //固定比例交换
        void FixtureExchange(List <AttrbuteConfig> used, NPCRuntimeData selfRt, NPCRuntimeData tarRt, int Min, WarSrcAnimParam SrcParam, WarTarAnimParam TarParam)
        {
            int cnt = used.Count;

            if (cnt <= 0)
            {
                return;
            }

            for (int i = 0; i < cnt; ++i)
            {
                AttrbuteConfig att = used[i];
                //自己的值
                float self_att1_val = selfRt.getFloatValue(att.note);
                //敌人的值
                float tar_att1_val = tarRt.getFloatValue(att.note);
                //敌人值的下限
                float tar_att1_val_min = (float)Min;

                float final_tar_val = 0F;

                //如果传递过去的值大于下限,则将自己的值和敌人直接替换
                if (self_att1_val > tar_att1_val_min)
                {
                    final_tar_val = self_att1_val;
                }
                else
                {
                    //如果传递过去的值小于下限,则将敌人的值给自己,敌人的为最低下限
                    final_tar_val = tar_att1_val_min;
                }

                //敌人
                if (att.type == "float")
                {
                    tarRt.setValue(att.note, (FloatFog)final_tar_val);
                }
                else
                {
                    tarRt.setValue(att.note, (Int32Fog)final_tar_val);
                }

                //自己
                if (att.type == "float")
                {
                    selfRt.setValue(att.note, (FloatFog)tar_att1_val);
                }
                else
                {
                    selfRt.setValue(att.note, (Int32Fog)tar_att1_val);
                }

                ///
                /// 血量的信息需要特别的传递给UI
                ///
                if (att.note == "curHp")
                {
                    SrcParam.described.srcEnd = new EndResult()
                    {
                        param1 = (int)(tar_att1_val - self_att1_val),
                        param2 = TarParam.described.target,
                    };

                    TarParam.described.targetEnd = new EndResult()
                    {
                        param1 = (int)(final_tar_val - tar_att1_val),
                        param2 = TarParam.described.target,
                    };
                }
            }
        }