コード例 #1
0
    /// <summary>
    /// 检查技能释放
    /// </summary>
    /// <param name="fsm"></param>
    /// <returns></returns>
    public static bool CheckSkillRelease(SoldierFSMSystem fsm)
    {
        var searchData = fsm.Display.ClusterData;
        // 攻击范围内是否有敌人
        var checkPos = new Vector2(fsm.Display.ClusterData.X, fsm.Display.ClusterData.Y);

        // 不可释放技能
        if (!searchData.AllData.MemberData.CouldReleaseSkill)
        {
            return(false);
        }
        var list = TargetSelecter.TargetFilter(searchData,
                                               ClusterManager.Single.CheckRange(checkPos, searchData.AllData.MemberData.SkillRange, searchData.AllData.MemberData.Camp, true));

        Utils.DrawGraphics(new CircleGraphics(checkPos, searchData.AllData.MemberData.SkillRange), Color.yellow);
        if (list != null && list.Count > 0)
        {
            // 攻击目标
            fsm.TargetIsLoseEfficacy = false;
            // 检测技能
            // TODO 技能的单位列表根据单位范围进行筛选
            if (CheckSkill(fsm, list))
            {
                fsm.IsCanInPutonggongji = false;
                fsm.IsCanInJinenggongji = true;
                return(true);
            }
        }

        return(false);
    }
コード例 #2
0
    /// <summary>
    /// 单元搜寻目标
    /// </summary>
    private void ScanTarget()
    {
        // 遍历对象,
        //foreach (var item in MemberList.List)
        //{

        var item       = _leader;
        var memberData = item.AllData.MemberData;
        // 根据对象的搜寻外径获取对向列表
        var itemRect = new RectGraphics(new Vector2(item.X, item.Y), memberData.AttackRange,
                                        memberData.AttackRange, 0);

        Utils.DrawGraphics(itemRect, Color.red);

        // 根据策略筛选目标
        var targetList = TargetSelecter.TargetFilter(item, MemberList.QuadTree);

        // 连线
        foreach (var targetItem in targetList)
        {
            Debug.DrawLine(new Vector3(item.X, 0, item.Y), new Vector3(targetItem.X, 0, targetItem.Y));
        }

        foreach (var memberItem in MemberList.List)
        {
            if (TargetSelecter.IsCollisionItem(memberItem, item.X, item.Y, memberData.AttackRange * 0.5f))
            {
                Utils.DrawRect(new Vector3(memberItem.X, 0, memberItem.Y), memberData.SpaceSet + 1, memberData.SpaceSet + 1, 0, Color.red);
            }
        }
        Utils.DrawCircle(new Vector3(item.X, 0, item.Y), memberData.AttackRange * 0.5f, Color.red);

        //}
    }
コード例 #3
0
 /// <summary>
 /// 设置扫描单位
 /// </summary>
 private void Scan()
 {
     if (scaner != null)
     {
         var resultList = TargetSelecter.GetCollisionItemList(itemList, scaner.X, scaner.Y, scaner.AllData.MemberData.AttackRange * 0.5f);
         Utils.DrawCircle(new Vector3(scaner.X, 0, scaner.Y), scaner.AllData.MemberData.AttackRange * 0.5f, Color.white);
         for (var i = 0; i < resultList.Count; i++)
         {
             var item = resultList[i];
             Utils.DrawCircle(new Vector3(item.X, 0, item.Y), item.AllData.MemberData.SpaceSet * 0.5f, Color.white);
         }
     }
 }
コード例 #4
0
    /// <summary>
    /// 是否可以技能攻击
    /// </summary>
    /// <param name="fsm"></param>
    /// <param name="res">目标列表</param>
    /// <returns></returns>
    public static bool CheckSkill(SoldierFSMSystem fsm, IList <PositionObject> res)
    {
        var result = false;

        // 判断主动技能是否可释放, 可释放则释放技能, 否则普通攻击
        var skillInfoList = fsm.Display.ClusterData.AllData.SkillInfoList;

        if (skillInfoList.Count > 0)
        {
            // 判断技能CD的长短, 释放技能最长的
            foreach (var skill in skillInfoList)
            {
                // 技能目标选择器
                // 是否为主动技能
                // 技能没有在CD中
                if (!skill.IsActive ||
                    CDTimer.Instance().IsInCD(skill.Num, fsm.Display.ClusterData.AllData.MemberData.ObjID.ID, skill.CDGroup))
                {
                    continue;
                }
                // 判断技能是否符合释放条件(范围内有适合的单位)
                if (skill.WeightData != null)
                {
                    res = TargetSelecter.TargetFilter(skill.WeightData, skill.ReleaseMember.ClusterData, res);
                }

                if (res != null && res.Count > 0)
                {
                    fsm.Skill = skill;
                    result    = true;
                    break;
                }
            }
        }

        if (result)
        {
            // 确定释放技能, 设置目标
            //System.Random ran = new System.Random();
            var target = res[0];
            fsm.EnemyTarget = DisplayerManager.Single.GetElementByPositionObject(target);
        }

        return(result);
    }
コード例 #5
0
    ///// <summary>
    ///// 检测条件
    ///// </summary>
    ///// <param name="fsm"></param>
    ///// <returns></returns>
    //public override bool CheckTrigger(SoldierFSMSystem fsm)
    //{
    //    return Check(fsm);
    //}



    public static bool Check(SoldierFSMSystem fsm)
    {
        switch (fsm.CurrentStateID)
        {
        // 行进切追击
        case SoldierStateID.Xingjin:
        {
            // 如果正在技能攻击或普通攻击则不进入追击状态
            if (fsm.IsCanInJinenggongji || fsm.IsCanInPutonggongji)
            {
                return(false);
            }
            var clusterData = fsm.Display.ClusterData;
            //var objId = clusterData.MemberData.ObjID;
            // 视野范围内是否有敌人
            var pos = new Vector2(clusterData.X, clusterData.Y);
            // 范围内符合阵营条件的单位列表
            var scopeMemberList = ClusterManager.Single.CheckRange(pos, clusterData.AllData.MemberData.SightRange,
                                                                   clusterData.AllData.MemberData.Camp, true);
            // 按照权重与是否可攻击单位选择
            var filtedlist = TargetSelecter.TargetFilter(clusterData, scopeMemberList);
            Utils.DrawGraphics(new CircleGraphics(pos, clusterData.AllData.MemberData.SightRange), Color.yellow);
            //fsm.Display.ClusterData.MemberData.SightRange
            if (filtedlist != null && filtedlist.Count > 0)
            {
                // 追击目标
                // 设置状态 切追击状态
                fsm.IsZhuiJi = true;
                return(SetTarget(fsm, filtedlist));
            }

            return(fsm.IsZhuiJi);
        }
        }

        return(false);
    }
コード例 #6
0
    /// <summary>
    /// 检查普通攻击
    /// </summary>
    /// <param name="fsm"></param>
    /// <returns></returns>
    public static bool CheckNormalAttack(SoldierFSMSystem fsm)
    {
        var searchData = fsm.Display.ClusterData;
        // 攻击范围内是否有敌人
        var checkPos = new Vector2(fsm.Display.ClusterData.X, fsm.Display.ClusterData.Y);
        // 目标选择器选择目标列表
        var list = TargetSelecter.TargetFilter(searchData,
                                               ClusterManager.Single.CheckRange(checkPos, searchData.AllData.MemberData.AttackRange, searchData.AllData.MemberData.Camp, true));

        Utils.DrawGraphics(new CircleGraphics(checkPos, searchData.AllData.MemberData.AttackRange), Color.yellow);
        if (list != null && list.Count > 0)
        {
            // 攻击目标
            fsm.TargetIsLoseEfficacy = false;
            // 检测普通攻击
            if (SetTarget(fsm, list))
            {
                fsm.IsCanInJinenggongji = false;
                fsm.IsCanInPutonggongji = true;
                return(true);
            }
        }
        return(false);
    }
コード例 #7
0
    /// <summary>
    /// 生成行为单元
    /// </summary>
    /// <returns>行为单元对象</returns>
    public override IFormula GetFormula(FormulaParamsPacker paramsPacker)
    {
        if (paramsPacker == null)
        {
            return(null);
        }
        IFormula result = null;

        // 替换替换符的数据
        ReplaceData(paramsPacker);

        // 数据本地化
        var myReceivePos  = ReceivePos;
        var myTargetCamps = TargetCamps;
        var clusterData   = paramsPacker.ReleaseMember.ClusterData;
        var myFormulaType = FormulaType;
        var myScopeType   = ScopeType;
        var myTargetCount = TargetCount;
        var myIsFollowDir = IsFollowDir;

        // 目标权重筛选数据
        var targetSelectData = TargetSelectDataId > 0 ? new SelectWeightData(SData_armyaim_c.Single.GetDataOfID(TargetSelectDataId)) : null;

        result = new Formula((callback, scope) =>
        {
            // 检测范围
            ICollisionGraphics graphics = null;

            var pos       = Utils.V3ToV2WithouY(GetPosByType(myReceivePos, paramsPacker, scope));
            var plusAngle = 0f;
            if (myIsFollowDir)
            {
                plusAngle = Utils.GetAngleWithZ(clusterData.Direction);
            }
            // 获取图形对象
            switch (myScopeType)
            {
            case GraphicType.Circle:
                // 圆形
                graphics = new CircleGraphics(pos, Arg1);
                break;

            case GraphicType.Rect:
                // 矩形
                graphics = new RectGraphics(pos, Arg1, Arg2, Arg3 + plusAngle);
                break;

            case GraphicType.Sector:
                // 扇形
                graphics = new SectorGraphics(pos, Arg3 + plusAngle, Arg1, Arg2);
                break;
            }

            // 获取周围单位DisplayOwner列表
            var packerList = FormulaParamsPackerFactroy.Single.GetFormulaParamsPackerList(graphics,
                                                                                          paramsPacker.StartPos,
                                                                                          myTargetCamps,
                                                                                          paramsPacker.Skill,
                                                                                          paramsPacker.TargetMaxCount);

            // 根据权重数据筛选目标
            if (targetSelectData != null)
            {
                packerList = TargetSelecter.TargetFilter(targetSelectData, clusterData, packerList);

                // 对他们释放技能(技能编号)
                if (packerList != null)
                {
                    var counter       = 0;
                    var completeCount = 0;
                    var allCount      = packerList.Count;
                    foreach (var packer in packerList)
                    {
                        // 如果设置了数量上限, 并且超过数量上限则跳出
                        if (myTargetCount > 0 && counter >= myTargetCount)
                        {
                            break;
                        }
                        // 执行子行为链
                        if (SubFormulaItem != null)
                        {
                            var subSkill = new SkillInfo(packer.SkillNum);
                            FormulaParamsPackerFactroy.Single.CopyPackerData(paramsPacker, packer);
                            subSkill.DataList = packer.DataList;
                            subSkill.AddActionFormulaItem(SubFormulaItem);
                            //subSkill.GetFormula(packer);
                            SkillManager.Single.DoSkillInfo(subSkill, packer, true, () =>
                            {
                                // 执行完成, 回调
                                completeCount++;
                                if (completeCount >= myTargetCount || completeCount >= allCount)
                                {
                                    callback();
                                }
                            });
                        }
                        counter++;
                    }
                }
            }
        }, myFormulaType);


        return(result);
    }
コード例 #8
0
    /// <summary>
    /// 获取行为节点
    /// </summary>
    /// <param name="paramsPacker">目标数据</param>
    /// <returns>滑动碰撞检测行为节点</returns>
    public override IFormula GetFormula(FormulaParamsPacker paramsPacker)
    {
        if (Speed < Utils.ApproachZero)
        {
            throw new Exception("滑动碰撞检测的速度不能小于等于0");
        }

        // 替换数据
        ReplaceData(paramsPacker);

        // 数据本地化
        var mySpeed       = Speed;
        var myCheckTime   = CheckTime;
        var myLength      = Length;
        var myTargetCamps = TargetCamps;
        var myFormulaType = FormulaType;
        var myTargetPos   = TargetPos;
        var myStartPos    = StartPos;

        var clusterData = paramsPacker.ReleaseMember.ClusterData;

        // 上一次列表
        List <FormulaParamsPacker>  prvPackerList = new List <FormulaParamsPacker>();
        IList <FormulaParamsPacker> tmpPackerList = null;

        IFormula result = new Formula((callback, scope) =>
        {
            // 当前长度
            var nowLength = 0f;

            // 目标点
            var targetPos = GetPosByType(myTargetPos, paramsPacker, scope);
            // 起始点
            var startPos = GetPosByType(myStartPos, paramsPacker, scope);

            // 计时器
            var timer = new Timer(myCheckTime, true);
            // 计时器行为
            Action completeCallback = () =>
            {
                // 是否到达目标
                if (nowLength < Length)
                {
                    // 搜索位置+1
                    nowLength += mySpeed;
                    // 从发射位置向目标位置一节一节搜索目标
                    // 速度影响单次搜索的长度
                    var diffPos = targetPos - startPos;
                    var pos     = (diffPos) * nowLength / myLength + startPos;
                    // 创建图形
                    var diffPosNoY = new Vector3(diffPos.x, 0, diffPos.z);
                    // 求旋转角度
                    var rotation = Vector3.Angle(Vector3.forward, diffPosNoY);
                    // 求旋转方向
                    float dir = (Vector3.Dot(Vector3.up, Vector3.Cross(Vector3.forward, diffPosNoY)) < 0 ? 1 : -1);
                    // 获得图形
                    var graphics = new RectGraphics(new Vector2(pos.x, pos.z), Width, mySpeed, rotation * dir);
                    Utils.DrawGraphics(graphics, Color.white);
                    // 搜索当前节范围内的单位
                    tmpPackerList = FormulaParamsPackerFactroy.Single.GetFormulaParamsPackerList(graphics,
                                                                                                 startPos,
                                                                                                 myTargetCamps,
                                                                                                 paramsPacker.Skill,
                                                                                                 paramsPacker.TargetMaxCount);

                    // 执行子技能
                    if (tmpPackerList != null && tmpPackerList.Count > 0 && SubFormulaItem != null)
                    {
                        // 排除不可选择目标
                        for (var i = 0; i < tmpPackerList.Count; i++)
                        {
                            var nowPacker = tmpPackerList[i];
                            if (!TargetSelecter.CouldSelectTarget(clusterData, nowPacker.ReceiverMenber.ClusterData))
                            {
                                tmpPackerList.RemoveAt(i);
                                i--;
                            }
                        }

                        // 排除上次被攻击过的目标
                        bool isExist;
                        for (var j = 0; j < prvPackerList.Count; j++)
                        {
                            isExist       = false;
                            var prvPacker = prvPackerList[j];
                            // 判断是否存在上次被攻击的对象
                            // 从列表中删除重复对象
                            for (var i = 0; i < tmpPackerList.Count; i++)
                            {
                                var nowPacker = tmpPackerList[i];
                                if (prvPacker.ReceiverMenber.Equals(nowPacker.ReceiverMenber))
                                {
                                    // 删除本次攻击中上次攻击存在的单位
                                    tmpPackerList.RemoveAt(i);
                                    i--;
                                    isExist = true;
                                    break;
                                }
                            }

                            // 删除上次攻击中本次攻击不存在的单位
                            if (!isExist)
                            {
                                prvPackerList.RemoveAt(j);
                                j--;
                            }
                        }

                        prvPackerList.AddRange(tmpPackerList);

                        foreach (var packer in tmpPackerList)
                        {
                            var subSkill = new SkillInfo(packer.SkillNum);
                            FormulaParamsPackerFactroy.Single.CopyPackerData(paramsPacker, packer);
                            subSkill.DataList = paramsPacker.DataList;
                            subSkill.AddActionFormulaItem(SubFormulaItem);
                            //subSkill.GetFormula(packer);
                            SkillManager.Single.DoSkillInfo(subSkill, packer, true);
                        }
                    }
                }
                else
                {
                    // 结束计时
                    timer.Kill();
                    // 完成回调
                    callback();
                }
            };

            timer.OnCompleteCallback(completeCallback);
            timer.Start();
        }, myFormulaType);

        return(result);
    }