/// <summary>
 /// 发送命令
 /// </summary>
 /// <param name="cmd"></param>
 public void SendCmd(IOptionCommand cmd)
 {
     // 如果有等待的命令则等待
     if (waitingOptionDic.Any((kv) => kv.Value > 0))
     {
         return;
     }
     MemberManager.SendCmd(cmd);
     if (cmd.OpType == OptionType.Create)
     {
         return;
     }
     // 添加到等待列表
     if (waitingOptionDic.ContainsKey(cmd.OpType))
     {
         waitingOptionDic[cmd.OpType]++;
     }
     else
     {
         waitingOptionDic.Add(cmd.OpType, 1);
     }
 }
        /// <summary>
        /// 执行命令
        /// </summary>
        public void Dispatch(IOptionCommand cmd)
        {
            // 检测等待状态
            if (waitingOptionDic.ContainsKey(cmd.OpType))
            {
                waitingOptionDic[cmd.OpType]--;
                if (waitingOptionDic[cmd.OpType] < 0)
                {
                    waitingOptionDic[cmd.OpType] = 0;
                }
            }
            // 进行操作
            switch (cmd.OpType)
            {
            case OptionType.Attack:
                // 单位攻击
            {
                // 攻击目标
                var atkId = int.Parse(cmd.Param["atkId"]);
                // 攻击方式
                var atkType = int.Parse(cmd.Param["atkType"]);
                // 攻击伤害
                var dmg = int.Parse(cmd.Param["dmg"]);
                Hp -= dmg;

                Debug.Log(" 攻击Id" + atkId + " 被攻击Id:" + Id + " Hp:" + dmg + " 攻击方式:" + atkType);
                // 检查是否死亡

                if (Hp <= 0)
                {
                    MemberManager.Remove(this);
                    Debug.Log("单位死亡Id:" + Id);
                    return;
                }
            }
            break;

            case OptionType.Move:
                // 单位移动
            {
                // 移动目标
                var toX = int.Parse(cmd.Param["toX"]);
                var toY = int.Parse(cmd.Param["toY"]);
                // 移动来源
                var fromX = int.Parse(cmd.Param["fromX"]);
                var fromY = int.Parse(cmd.Param["fromY"]);
                // 验证来源
                if (this.X != fromX || Y != fromY)
                {
                    Debug.LogError(Id + "数据异常, 刷新位置" + X + "," + Y + "-" + fromX + "," + fromY);
                }
                Move(fromX, fromY, toX, toY);
            }
            break;

            case OptionType.None:
                // 无操作
            {
                Debug.LogError("无操作");
            }
            break;
            }
        }
        /// <summary>
        /// 执行
        /// </summary>
        /// <param name="frame"></param>
        /// <param name="blackBoard"></param>
        public void OnceFrame(long frame, IBlackBoard blackBoard)
        {
            actionFrame = frame;

            // 检查是否死亡
            if (Hp <= 0)
            {
                MemberManager.Remove(this);
                Debug.Log("单位死亡Id:" + Id);
                return;
            }
            if (IsLocal && IsAI)
            {
                if (pathList != null && pathList.Count > 0)
                {
                    // 继续前进
                    var nextNode = pathList.Pop();
                    Debug.Log("继续前进:" + nextNode.X + "," + nextNode.Y);
                    // 跑出显示命令, 并等待显示部分反馈的帧数
                    SendCmd(new Commend(MemberManager.FrameCount, Id, OptionType.Move)
                    {
                        Param = new Dictionary <string, string>()
                        {
                            { "fromX", "" + X },
                            { "fromY", "" + Y },
                            { "toX", "" + nextNode.X },
                            { "toY", "" + nextNode.Y },
                        }
                    });
                }
                else
                {
                    var width  = blackBoard.MapBase.MapWidth;
                    var height = blackBoard.MapBase.MapHeight;

                    var couldNotPass = true;
                    int targetX      = 0;
                    int targetY      = 0;

                    while (couldNotPass)
                    {
                        // 随机获取目标位置
                        targetX = RandomPacker.Single.GetRangeI(0, width);
                        targetY = RandomPacker.Single.GetRangeI(0, height);


                        var path = AStarPathFinding.SearchRoad(
                            BlackBoard.Single.MapBase.GetMapArray(MapManager.MapObstacleLayer),
                            X, Y,
                            targetX, targetY, 1, 1);

                        if (path != null && path.Count > 0)
                        {
                            couldNotPass = false;
                            pathList     = new Stack <Node>(path.ToArray());
                        }

                        var index = RandomPacker.Single.GetRangeI(0, MemberManager.MemberCount);

                        // 随机攻击一个目标
                        var targetMember = MemberManager.Get(index);
                        if (targetMember != null)
                        {
                            SendCmd(new Commend(MemberManager.FrameCount, targetMember.Id, OptionType.Attack)
                            {
                                Param = new Dictionary <string, string>()
                                {
                                    { "atkId", "" + Id },
                                    { "atkType", "" + 1 },
                                    { "dmg", "" + 10 },
                                }
                            });
                        }
                    }

                    // 向目标寻路, 如果不可达继续寻路
                    var nextNode = pathList.Pop();
                    Debug.Log("重新寻路前进:" + nextNode.X + "," + nextNode.Y);

                    // 跑出显示命令, 并等待显示部分反馈的帧数
                    SendCmd(new Commend(MemberManager.FrameCount, Id, OptionType.Move)
                    {
                        Param = new Dictionary <string, string>()
                        {
                            { "fromX", "" + X },
                            { "fromY", "" + Y },
                            { "toX", "" + nextNode.X },
                            { "toY", "" + nextNode.Y },
                        }
                    });
                }
            }
        }