asmrobot
2019-11-25 2aeab450471cb80b59002da7da80faf251a0c4f4
src/RichCreator/Dnf/DnfRole.cs
@@ -1,4 +1,5 @@
using RichCreator.Utility;
using RichCreator.Models;
using RichCreator.Utility;
using RichCreator.Utility.Dnf;
using RichCreator.Utility.InputControl;
using RichCreator.Utility.Maps;
@@ -30,8 +31,6 @@
        /// </summary>
        public static readonly ZTPoint RoleHalfOffset = new ZTPoint(0, 88);
        public DnfRole(ZTRectangle gameRect)
        {
            this.gameRect = gameRect;
@@ -42,8 +41,12 @@
        private SpeedProvider speed;//速度
        private HouseInfo house;//所在房间
        private ZTRectangle gameRect = ZTRectangle.Empty;        
        private MoveIntent movingIntent = MoveIntent.AttackMove;//移动意图
        public MoveIntent movingIntent = MoveIntent.AttackMove;//移动意图
        private CancellationTokenSource moveCancelToken;//移动取消令牌
        private Int32 findRoleDir = 0;//寻找角色行走的方向
        private DateTime findRoleMoveTimeout = DateTime.MinValue;//方向移动过期时间
        /// <summary>
        /// 角色色块位置
@@ -85,6 +88,7 @@
        public void SetHouse(HouseInfo house)
        {
            this.house = house;
            toNextGate = true;
        }
        /// <summary>
@@ -105,7 +109,7 @@
            this.RoleCBPosition = roleCBPosition;
        }
        private bool isMoving = false;
        /// <summary>
        /// 是否移动中
        /// </summary>
@@ -113,7 +117,8 @@
        {
            get
            {
                return pressKeys[0] != HIDCode.NoEvent || pressKeys[1] != HIDCode.NoEvent;
                return isMoving;
                //return pressKeys[0] != HIDCode.NoEvent || pressKeys[1] != HIDCode.NoEvent;
            }
        }
@@ -131,64 +136,23 @@
            return false;
        }
        
        /// <summary>
        /// 攻击移动
        /// </summary>
        /// <param name="moveDistance"></param>
        public void AttackMove(ZTSize moveDistance)
        {
            PutDirectionKey(moveDistance);
            movingIntent = MoveIntent.AttackMove;
        }
        /// <summary>
        /// 攻击移动至
        /// </summary>
        /// <param name="skillReleasePoint"></param>
        public void AttackMoveTo(ZTPoint skillReleasePoint,ParametersPoint locationPoint)
        public void AttackMove(ZTPoint skillReleasePoint, ParametersPoint screenLocation)
        {
            //屏幕坐标转地图坐标
            ZTPoint start= this.house.ScreenToMapCoordinate(this.Position, locationPoint);
            ZTPoint end = this.house.ScreenToMapCoordinate(DnfRole.HalfToFootPosition(skillReleasePoint), locationPoint);
            ZTPoint start = this.house.ScreenToMapCoordinate(this.Position, screenLocation);
            ZTPoint end = this.house.ScreenToMapCoordinate(DnfRole.HalfToFootPosition(skillReleasePoint), screenLocation);
            List<ZTPoint> paths = this.house.FindPath(start, end);
            MovePaths(start, paths);
        }
        /// <summary>
        /// 移动到指定地图点
        /// </summary>
        public void MoveToMapPoint(ZTPoint start,ZTPoint end)
            this.movingIntent = MoveIntent.AttackMove;
            isMoving = true;
            ThreadPool.QueueUserWorkItem((obj) =>
        {
            List<ZTPoint> paths = this.house.FindPath(start, end);
            MovePaths(start, paths);
                this.MovePaths(start, paths, this.moveCancelToken.Token,"attack move");
            }, null);
        }
        /// <summary>
        /// 移动指定路径
        /// </summary>
        /// <param name="start"></param>
        /// <param name="paths"></param>
        public void MovePaths(ZTPoint start, List<ZTPoint> paths)
        {
            ZTPoint lastPoint = start;
            if (paths != null && paths.Count > 0)
            {
                for (int i = 0; i < paths.Count; i++)
                {
                    ZTPoint distance = paths[i].Sub(lastPoint);
                    this.SyncMove(distance);
                    lastPoint = paths[i];
                }
            }
        }
        private Int32 findRoleDir = 0;//寻找角色行走的方向
        private DateTime findRoleMoveTimeout = DateTime.MinValue;//方向移动过期时间
        private static HIDCode[][] dir = new HIDCode[][] { new HIDCode[] { HIDCode.LeftArrow ,HIDCode.NoEvent}, new HIDCode[] { HIDCode.NoEvent, HIDCode.UpArrow }, new HIDCode[] { HIDCode.RightArrow, HIDCode.NoEvent }, new HIDCode[] { HIDCode.NoEvent, HIDCode.DownArrow } };
        /// <summary>
        /// 查找主角移动
@@ -196,74 +160,159 @@
        /// <param name="moveDistance"></param>
        public void FindRoleMove()
        {
            if (IsMoving &&  !IsMoveIntent(MoveIntent.FindRoleMove))
            {
                StopMove();
            }
            if (DateTime.Now >= findRoleMoveTimeout)
            {
                //转换方向
                findRoleDir++;
                HIDCode[]  tempKeys = dir[findRoleDir % 4];
                Int32 stepms = 0, runms = 0;
                PutDirectionKey(out stepms, out runms, tempKeys[0], tempKeys[1], true);
                findRoleMoveTimeout = DateTime.Now.AddMilliseconds(speed.RandomMoveMillSecond);
                ZTSize distance = ZTSize.Empty;
                switch (findRoleDir % 4)
                {
                    case 0:
                        //右
                        distance = new ZTSize(SpeedProvider.RandomMoveDistance, 0);
                        break;
                    case 1:
                        //下
                        distance = new ZTSize(0,SpeedProvider.RandomMoveDistance);
                        break;
                    case 2:
                        //左
                        distance = new ZTSize(-SpeedProvider.RandomMoveDistance, 0);
                        break;
                    case 3:
                        //上
                        distance = new ZTSize(0,-SpeedProvider.RandomMoveDistance);
                        break;
            }
            
            movingIntent = MoveIntent.FindRoleMove;
                isMoving = true;
                ThreadPool.QueueUserWorkItem((state) => {
                    CancellationToken ctoken = (CancellationToken)state;
                    this.SyncMoveKeyPress(distance);
                    if (!ctoken.IsCancellationRequested)
                    {
                        //如果没有取消则停止
                        StopMove("find role mvoe");
                    }
                }, this.moveCancelToken.Token);
        }
        public void EntryDoorMove()
        }
        /// <summary>
        /// 进门移动
        /// </summary>
        public void EntryDoorMove(ZTPoint doorScreenPosition, ParametersPoint screenLocation, Direction doorDirect)
        {
            if (IsMoving && !IsMoveIntent(MoveIntent.EntryDoor))
            //先到进门点
            ZTPoint roleMapPoint = this.house.ScreenToMapCoordinate(this.Position, screenLocation);
            ZTPoint nextGatePoint = this.house.GetNextGatePoint(doorDirect);
            List<ZTPoint> paths = this.house.FindPath(roleMapPoint, DnfRole.HalfToFootPosition(nextGatePoint));
            //再到门后50像素
            ZTPoint dp = this.house.ScreenToMapCoordinate(doorScreenPosition, screenLocation);
            ZTPoint doorPoint = DnfRole.HalfToFootPosition(dp);
            switch (doorDirect)
            {
                StopMove();
                case Direction.Up:
                    doorPoint = doorPoint.Add(0, -50);
                    break;
                case Direction.Right:
                    doorPoint = doorPoint.Add(50, 0);
                    break;
                case Direction.Bottom:
                    doorPoint = doorPoint.Add(0, 50);
                    break;
                case Direction.Left:
                    doorPoint = doorPoint.Add(-50, 0);
                    break;
            }
            paths.Add(doorPoint);
            this.movingIntent = MoveIntent.EntryDoor;
            isMoving = true;
            this.MovePaths(roleMapPoint, paths, this.moveCancelToken.Token,"entry move");
        }
        private bool toNextGate = true;
        private Int32 nextGate = 0;
        /// <summary>
        /// 移至巡逻点
        /// </summary>
        public void LoopMove(ParametersPoint screenLocation)
        {
            ZTPoint start = ZTPoint.Empty, end = ZTPoint.Empty;
            ZTPoint halfMapPosition= this.house.ScreenToMapCoordinate(this.HalfPosition, screenLocation);
            ZTPoint footMapPosition= this.house.ScreenToMapCoordinate(this.Position, screenLocation);
            if (toNextGate)
            {
                //判断当前是否进门点
                ZTPoint nextGatePoint=this.house.HousePathInfo.NextGates[nextGate].Point;
                ZTRectangle nextGateRect = new ZTRectangle(nextGatePoint.X - 20, nextGatePoint.Y - 20, nextGatePoint.X + 20, nextGatePoint.Y + 20);
                if (GeoHelper.IsInRect(halfMapPosition, nextGateRect))
                {
                    nextGate++;
                    nextGate = nextGate % this.house.HousePathInfo.NextGates.Count;
                    toNextGate = false;
                }
            }
            else
            {
                //判断当前是否在巡逻点
                ZTPoint loopPoint = this.house.HousePathInfo.LoopPoint;
                ZTRectangle loopRect = new ZTRectangle(loopPoint.X - 20, loopPoint.Y - 20, loopPoint.X + 20, loopPoint.Y + 20);
                if (GeoHelper.IsInRect(footMapPosition, loopRect))
                {
                    toNextGate = true;
            }
        }
        public void ToLoopMove()
            if (toNextGate)
        {
            if (IsMoving && !IsMoveIntent(MoveIntent.ToLoopPoint))
            {
                StopMove();
                //向进门点移动
                start = halfMapPosition;
                end=this.house.HousePathInfo.NextGates[nextGate].Point;
                G.Instance.InfoWriter($"nextgate->screen location:{screenLocation},start:{start},end:{end}");
            }
            else
            {
                //向巡逻点移动
                start = footMapPosition;
                end= this.house.HousePathInfo.LoopPoint;
                G.Instance.InfoWriter($"loop:screen location:{screenLocation},start:{start},end:{end}");
        }
        public void ToNextGateMove()
            List<ZTPoint> paths = this.house.FindPath(start,end);
            this.movingIntent = MoveIntent.ToLoop;
            isMoving = true;
            ThreadPool.QueueUserWorkItem((obj) =>
        {
            if (IsMoving && !IsMoveIntent(MoveIntent.ToNextGatePoint))
            {
                StopMove();
                this.MovePaths(start, paths, this.moveCancelToken.Token, "loop move");
            }, null);
            }
        }
        /// <summary>
        /// 拾起物品移动
        /// </summary>
        public void PickupMove(ZTPoint rolePosition, ZTPoint thingItemPosition)
        public void PickupMove(ZTPoint screenThingPosition,ParametersPoint screenLocation)
        {
            if (IsMoving && !IsMoveIntent(MoveIntent.PickupMove))
            //屏幕坐标转地图坐标
            ZTPoint start = this.house.ScreenToMapCoordinate(this.Position, screenLocation);
            ZTPoint end = this.house.ScreenToMapCoordinate(screenThingPosition, screenLocation);
            List<ZTPoint> paths = this.house.FindPath(start, end);
            this.movingIntent = MoveIntent.PickupMove;
            isMoving = true;
            //未被打断移动至色块后,拾取
            if (this.MovePaths(start, paths, this.moveCancelToken.Token,"pickup"))
            {
                StopMove();
            }
            ZTSize moveDistance = new ZTSize(thingItemPosition.X - rolePosition.X, thingItemPosition.Y - rolePosition.Y - 97);
            if (Math.Abs(moveDistance.Width) < 100 && Math.Abs(moveDistance.Height) < 100)
            {
                //距离允许,就近距离移动并X
                G.Instance.DebugWriter("distance ok");
                SyncMove(new ZTPoint(moveDistance.Width,moveDistance.Height));
                G.Instance.InputControl.PressKey(RandomUtils.G(400, 500), HIDCode.X);
                return;
            }
            //G.Instance.DebugWriter("pickup distance:" + moveDistance.ToString());
            PutDirectionKey(moveDistance);
            movingIntent = MoveIntent.PickupMove;
        }
        
        /// <summary>
        /// 同步移动指定距离
@@ -272,6 +321,50 @@
        public void SyncMove(ZTPoint size)
        {
            ZTSize distance = new ZTSize(size.X, size.Y);
            isMoving = true;
            SyncMoveKeyPress(distance);
            StopMove("sync move");
        }
        /// <summary>
        /// 移动指定路径
        /// </summary>
        /// <param name="start"></param>
        /// <param name="paths"></param>
        /// <returns>true:完成移动,false:中间被打断</returns>
        private bool MovePaths(ZTPoint start, List<ZTPoint> paths, CancellationToken cancelToken,string from)
        {
            ZTPoint lastPoint = start;
            if (paths != null && paths.Count > 0)
            {
                for (int i = 0; i < paths.Count; i++)
                {
                    if (cancelToken.IsCancellationRequested)
                    {
                        break;
                    }
                    ZTPoint distance = paths[i].Sub(lastPoint);
                    this.SyncMoveKeyPress(new ZTSize(distance.X, distance.Y));
                    lastPoint = paths[i];
                }
            }
            if (!cancelToken.IsCancellationRequested)
            {
                //停止
                StopMove("move path,"+from);
                return true;
            }
            return false;
        }
        /// <summary>
        /// 同步移动指定距离的按键
        /// </summary>
        /// <param name="distance"></param>
        private void SyncMoveKeyPress(ZTSize distance)
        {
            HIDCode horizontal = HIDCode.NoEvent;
            HIDCode vertical = HIDCode.NoEvent;
            bool isRun = false;
@@ -345,28 +438,25 @@
                PutDirectionKey(out stepms, out runms, HIDCode.NoEvent, vertical, false);
                Thread.Sleep(ytime);
            }
            //StopMove();
            G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false);
            pressKeys[0] = HIDCode.NoEvent;
            pressKeys[1] = HIDCode.NoEvent;
            isRun = false;
        }
        
        /// <summary>
        /// 停止移动
        /// </summary>
        public void StopMove()
        public void StopMove(string from)
        {
            if (IsMoving)
            {
                G.Instance.InfoWriter("stop move from:"+from);
                this.moveCancelToken.Cancel();
                this.moveCancelToken = new CancellationTokenSource();
                //停止
                StateProvider.Instance.DirectionKey = "无";
                G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false);
                pressKeys[0] = HIDCode.NoEvent;
                pressKeys[1] = HIDCode.NoEvent;
                isMoving = false;
                isRun = false;
            }
        }
@@ -482,7 +572,12 @@
                        runMS += tempwait;
                        Thread.Sleep(tempwait);
                        G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal, vertical);
                        //StateProvider.Instance.DirectionKey = "跑," + horizontal.ToString() + "," + vertical.ToString();
                    }
                    //else
                    //{
                    //    StateProvider.Instance.DirectionKey = "跑," + horizontal.ToString();
                    //}
                }
                else
@@ -495,10 +590,12 @@
                        if (keyCount == 1)
                        {
                            G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal);
                            //StateProvider.Instance.DirectionKey = "走," + horizontal.ToString();
                        }
                        else
                        {
                            G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal, vertical);
                            //StateProvider.Instance.DirectionKey = "走," + horizontal.ToString() + "," + vertical.ToString();
                        }
                    }
@@ -541,7 +638,6 @@
            }
            return true;
        }
        #endregion