From c4bd9d8c587bd1401f0fb2f60c34a4964d7afe20 Mon Sep 17 00:00:00 2001
From: asmrobot <asmrobot@hotmail.com>
Date: Sun, 27 Oct 2019 16:02:50 +0000
Subject: [PATCH] o

---
 src/RichCreator/StateMachines/KillMonsterStateMachine.cs |  937 ++++++++++++++++++++++++++++++----------------------------
 1 files changed, 487 insertions(+), 450 deletions(-)

diff --git a/src/RichCreator/StateMachines/KillMonsterStateMachine.cs b/src/RichCreator/StateMachines/KillMonsterStateMachine.cs
index b88eb92..dec152b 100644
--- a/src/RichCreator/StateMachines/KillMonsterStateMachine.cs
+++ b/src/RichCreator/StateMachines/KillMonsterStateMachine.cs
@@ -16,40 +16,49 @@
 using RichCreator.StateMachines;
 using RichCreator.Utilitys;
 using static RichCreator.Utilitys.AttackRectangle;
-using Utils= RichCreator.Utilitys.Utils;
+using Utils = RichCreator.Utilitys.Utils;
 using ZTImage.Collections;
 
 namespace RichCreator.Jobs.StateMachines
 {
     /// <summary>
-    /// 状态动作 
-    /// </summary>
-    /// <param name=""></param>
-    /// <param name=""></param>
-    /// <param name=""></param>
-    /// <returns></returns>
-    public delegate KillMonsterStateResult StateAction(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage);
-
-    /// <summary>
     /// 杀怪状态机
     /// </summary>
-    public class KillMonsterStateMachine:StateMachineBase
+    public class KillMonsterStateMachine : StateMachineBase
     {
         private const Int32 NoMoveMaxMillSecond = 2000;//最大未移动容忍毫秒数
-        private StateAction[] states;//状态动作列表
-        private MapHouse house;//当前房间
+
+        private HouseInfo house;//当前房间
         private ZTPoint miniMapStart;//小地图区域
-        private ZTRectangle gameRect;//游戏区域
+        private ZTRectangle GameRect;//游戏区域
         private Int32 preHouseIndex = 0;//上一房间编号
         private MoveState moveState;//移动状态
-        private OutOfBounds outOfBounds;//是否在禁区
-        private bool exitResult;//退出结果
+        private OutOfBounds outOfBounds;//禁区
+        private bool isSuccess;//退出结果
 
-        
-        private ZTPoint roleLastPosition=ZTPoint.Empty;//角色最后位置
+
+        private ZTPoint roleLastPosition = ZTPoint.Empty;//角色最后位置
         private Int32 runningStep = RunningStep.None;//是否恢复的状态
 
+        //当前状态
+        private KillMonsterStates currentState = KillMonsterStates.Start;
+        //是否截图屏幕
+        private bool captureScreen = false;
 
+        //怪
+        private ZTPoint[] stateMonsters;
+
+        private System.Drawing.Bitmap bitmap = null;
+        //原图
+        private Image<Rgb, byte> image = null;
+
+        //图像是否改变
+        private bool imageIsChange = false;
+
+        //色彩hsv
+        private Image<Hsv, byte> hsvImage = null;
+        //取消令牌
+        private CancellationToken cancellationToken = CancellationToken.None;
         #region Find Door Info
         //门坐标
         private ZTPoint stateDoorPosition;
@@ -59,26 +68,34 @@
         private Direction stateDoorLevelDirect = Direction.None;
         //定位点方框
         private MultiList<ZTRectangle, Int32> stateLocationRectangle = new MultiList<ZTRectangle, int>();
-        //怪
-        private ZTPoint[] stateMonsters;
 
 
+        
+       
         #endregion
 
 
-        public KillMonsterStateMachine(MapHouse house, ZTPoint miniMapStart, ZTRectangle gameRect,Int32 preHouseIndex,Int32 runningStep)
+        public KillMonsterStateMachine(HouseInfo house, ZTPoint miniMapStart, ZTRectangle gameRect, Int32 preHouseIndex, Int32 runningStep, CancellationToken cancellationToken)
         {
             this.runningStep = runningStep;
             this.house = house;
             this.miniMapStart = miniMapStart;
-            this.gameRect = gameRect;
+            this.GameRect = gameRect;
             this.preHouseIndex = preHouseIndex;
-            moveState = new MoveState(this.gameRect, this.house);
-            outOfBounds = new OutOfBounds(this.gameRect,moveState);
-
-            InitStates();
+            this.cancellationToken = cancellationToken;
+            moveState = new MoveState(this.GameRect, this.house);
+            outOfBounds = new OutOfBounds(this.GameRect, moveState);
+            hsvImage = new Image<Hsv, byte>(gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1);
         }
-        
+
+
+
+        private void SetState(KillMonsterStates current, bool capture)
+        {
+            currentState = current;
+            captureScreen = capture;
+        }
+
         /// <summary>
         /// 状态机开始
         /// </summary>
@@ -86,23 +103,17 @@
         /// <param name="cancellationToken"></param>
         /// <param name="timeoutMillSecond"></param>
         /// <returns></returns>
-        public ZTResult Work(CancellationToken cancellationToken, Int32 timeoutMillSecond)
+        public ZTResult Work(Int32 timeoutMillSecond)
         {
             DateTime expireTime = DateTime.Now.AddMilliseconds(timeoutMillSecond);
-            KillMonsterStateResult result = new KillMonsterStateResult(STATE_Start, false);
             if (this.runningStep > RunningStep.None)
             {
-                result = new KillMonsterStateResult(STATE_FindMonster, true);
+                SetState(KillMonsterStates.FindMonster, true);
             }
-            System.Drawing.Bitmap bitmap;
-            //原图
-            Image<Rgb, byte> image = null;
-            //色彩hsv
-            Image<Hsv, byte> hsvImage = new Image<Hsv, byte>(gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1);
+
 
             while (true)
             {
-                byte currentState = result.NextState;
                 if (cancellationToken.IsCancellationRequested)
                 {
                     G.Instance.DebugWriter("取消刷图");
@@ -116,216 +127,425 @@
                     this.moveState.StopMove();
                     return ZTResult.Timeout;
                 }
-                if (result.NextState == STATE_Exit)
-                {
-                    G.Instance.DebugWriter("退出状态");
-                    this.moveState.StopMove();
-                    if (this.exitResult)
-                    {
-                        return ZTResult.Success;
-                    }
-                    return ZTResult.Failed;
-                    
-                }
 
-                bool refreshScreen = result.RefreshScreen;
-                if (refreshScreen)
+                if (captureScreen)
                 {
                     using (bitmap = ScreenCapture.Instance.CaptureScreen())
                     {
-                        image = new Image<Rgb, byte>(bitmap);
-                        image = image.GetSubRect(new System.Drawing.Rectangle(gameRect.Start.X, gameRect.Start.Y, gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1));
-                        CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv);
-                    }
-
-                    if (this.house.Index != 15)
-                    {
-                        //计算是否进入其它房间
-                        Int32 houseIndex;
-                        if (!LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart))
+                        if (image != null)
                         {
-                            //得不到房间
-                            if (!FuncUtils.TimeoutCancelableWrap(30 * 1000, cancellationToken, () => {
-                                using (bitmap = ScreenCapture.Instance.CaptureScreen())
-                                {
-                                    image = new Image<Rgb, byte>(bitmap);
-                                    image = image.GetSubRect(new System.Drawing.Rectangle(gameRect.Start.X, gameRect.Start.Y, gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1));
-                                    return LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart);
-                                }
-                            }, 50))
-                            {
-                                return ZTResult.Failed;
-                            }
+                            image.Dispose();
                         }
-                        if (houseIndex != this.house.Index)
+                        image = new Image<Rgb, byte>(bitmap);
+                        image = image.GetSubRect(new System.Drawing.Rectangle(GameRect.Start.X, GameRect.Start.Y, GameRect.End.X - GameRect.Start.X + 1, GameRect.End.Y - GameRect.Start.Y + 1));
+                        imageIsChange = true;
+                    }
+                }
+                
+                switch (currentState)
+                {
+                    case KillMonsterStates.Start:
+                        //开始
+                        SingleEntryHouseSkill.ReleaseSkill(this.house.Index, this.preHouseIndex, this.moveState);
+                        SetState(KillMonsterStates.IsLastHouse, true);
+                        break;
+                    case KillMonsterStates.IsLastHouse:
+                        //是否最后一个房间
+                        if (!imageIsChange)
                         {
-                            this.moveState.StopMove();
+                            //图片没变,不用判断
+                            SetState(KillMonsterStates.FindRole, false);
+                            break;
+                        }
+                        if (this.house.Index == 15)
+                        {
+                            SetState(KillMonsterStates.HasRewardWindow, false);
+                        }
+                        else
+                        {
+                            SetState(KillMonsterStates.IsOtherHouse, false);
+                        }                        
+                        break;
+                    case KillMonsterStates.HasRewardWindow:
+                        //是否有奖励界面
+                        if (DnfCVHelper.IsJiangli(image, this.GameRect))
+                        {
+                            SetState(KillMonsterStates.TurnAroundCard, false);
+                        }
+                        else
+                        {
+                            SetState(KillMonsterStates.IsCompletePage, false);
+                        }
+                        break;
+                    case KillMonsterStates.TurnAroundCard:
+                        //翻牌
+                        Fanpai();
+                        Thread.Sleep(5000);
+                        this.isSuccess = true;
+                        SetState(KillMonsterStates.Exit, false);
+                        break;
+                    case KillMonsterStates.IsCompletePage:
+                        //是否刷完界面
+                        if (DnfCVHelper.IsCompleteRoom(image, this.GameRect))
+                        {
+                            this.isSuccess = true;
+                            SetState(KillMonsterStates.Exit, false);
+                        }
+                        else
+                        {
+                            SetState(KillMonsterStates.FindRole, false);
+                        }
+                        break;
+                    case KillMonsterStates.IsOtherHouse:
+                        //是否进入其它房间
+                        if (HouseIsChange())
+                        {
+                            this.isSuccess = true;
+                            SetState(KillMonsterStates.Exit, false);
+                        }
+                        else
+                        {
+                            //是否需要截图
+                            SetState(KillMonsterStates.FindRole, false);
+                        }
+                        break;
+                    case KillMonsterStates.FindRole:
+                        //主角
+                        CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv);
+
+                        //定位点
+                        if (!DnfCVHelper.GetLocationPoint(out stateLocationRectangle, hsvImage, this.GameRect))
+                        {
+                            //找不到定位点
+                            G.Instance.InfoWriter("找不到定位点");
+                            SetState(KillMonsterStates.IsLastHouse, true);
+                            break;
+                        }
+
+
+
+
+                        this.stateRolePosition = DnfCVHelper.FindRole(hsvImage, this.GameRect);
+                        if (this.stateRolePosition == ZTPoint.Empty)
+                        {
+                            SetState(KillMonsterStates.FindRoleMove, false);
+                        }
+                        else
+                        {
+                            if (this.moveState.IsFindRoleMoving)
+                            {
+                                this.moveState.StopMove();
+                            }
+                            SetState(KillMonsterStates.FindMonster, false);
+                        }
+                        break;
+                    case KillMonsterStates.FindRoleMove:
+                        //todo:让主角移动(原:有怪攻击一下,无怪移动一下)
+                        FindRoleMove();
+                        break;
+                    case KillMonsterStates.FindMonster:
+                        //找怪                        
+                        this.stateMonsters = LindongCVHelper.FindMonster(hsvImage, this.GameRect);
+                        
+                        if (this.stateMonsters.Length > 0)
+                        {
+                            G.Instance.DebugWriter(string.Format("已找到{0}个怪", this.stateMonsters.Length));
+                            SetState(KillMonsterStates.CalcAttackDistance, false);
+                        }
+                        else
+                        {
+                            SetState(KillMonsterStates.PickupThing, false);
+                        }
+                        break;
+                    case KillMonsterStates.PickupThing:
+                        //拾取物品
+                        SetState(KillMonsterStates.FindDoor, false);
+                        //todo: PickupThing();
+                        break;
+                    case KillMonsterStates.FindDoor:
+                        //查找门, 是否找到门
+                        FindDoor();
+                        break;
+                    case KillMonsterStates.EntryDoor:
+                        //向门移动, 进门
+                        EntryDoor();
+                        break;
+                    case KillMonsterStates.FindDoorMove:
+                        //todo:找门移动
+                        FindDoorMove();
+                        break;
+                    case KillMonsterStates.CalcAttackDistance:
+                        //判断使用何技能,计算攻击移动距离, 是否需要移动
+                        CalcAttackDistance();
+                        break;
+                    case KillMonsterStates.ReleaseSkill:
+                        //调整朝向, 释放技能,
+                        ReleaseSkill();
+                        break;
+                    case KillMonsterStates.AttackMove:
+                        //todo:攻击移动
+                        AttackMove();
+                        break;
+                    case KillMonsterStates.Exit:
+                        //结束
+                        G.Instance.DebugWriter("退出状态");
+                        this.moveState.StopMove();
+                        if (this.isSuccess)
+                        {
                             return ZTResult.Success;
                         }
-                    }                    
+                        return ZTResult.Failed;
+                        
+                    
                 }
-
-                StateAction action = states[currentState];
-                result =action(image, hsvImage);
-                if (refreshScreen)
-                {
-                    image.Dispose();
-                }
-                G.Instance.DebugWriter("next state:" + result.NextState.ToString());
+                
+                G.Instance.DebugWriter("next state:" + currentState.ToString());
             }
         }
-        
-        #region States
 
-        private const byte STATE_FindMonster = 0;//找怪
-        private const byte STATE_PrepareReleaseSkill = 1;//释放技能预处理,计算位置
-        private const byte STATE_ReleaseSkill = 2;//释放技能
-        private const byte STATE_DetectDoorIsOpen = 3;//查找进入下一房间的门是否开了
-        private const byte STATE_MoveToDoor = 4;//移动进门
-
-        private const byte STATE_Start = 8;//开始状态 
-        private const byte STATE_Exit = 9;//完成状态
-        
-
+        #region States        
         /// <summary>
-        /// 初始化状态
+        /// 让主角移动(原:有怪攻击一下,无怪移动一下)
         /// </summary>
-        private void InitStates()
+        private void FindRoleMove()
         {
-            //状态列表
-            states = new StateAction[STATE_Exit+1];
-            states[STATE_FindMonster] = FindMonster;
-            states[STATE_PrepareReleaseSkill] = PrepareReleaseSkill;
-            states[STATE_ReleaseSkill] = ReleaseSkill;
-            states[STATE_DetectDoorIsOpen] = DetectDoorIsOpen;
-            states[STATE_MoveToDoor] = MoveToDoor;
-            states[STATE_Start] = StartState;
-        }
+            this.moveState.FindRoleMove();
+            SetState(KillMonsterStates.FindRole, true);
 
-
-        private KillMonsterStateResult StartState(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage)
-        {
-            SingleEntryHouseSkill.ReleaseSkill(this.house.Index, this.preHouseIndex,this.moveState);
-            return new KillMonsterStateResult(STATE_FindMonster, true);
-        }
-
-        /// <summary>
-        /// 0.找怪
-        /// </summary>
-        /// <param name="image"></param>
-        /// <param name="hsvImage"></param>
-        /// <returns></returns>
-        private KillMonsterStateResult FindMonster(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage)
-        {
-            #region coll
-            //while (true)
+            //if (this.stateMonsters.Length > 0)
             //{
-            //    image = ScreenCapture.Instance.CaptureScreenReturnImage();
-            //    image = image.GetSubRect(new System.Drawing.Rectangle(gameRect.Start.X, gameRect.Start.Y, gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1));
-            //    CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv);
-            //    ZTPoint start=DnfCVHelper.FindRole(hsvImage, this.gameRect);
-
-            //    Int32 dur = RandomUtils.KeyPressDuration;
-            //    G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false,HIDCode.LeftArrow);
-            //    Thread.Sleep(dur);
-            //    G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false);
-            //    Thread.Sleep(dur);
-            //    G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, HIDCode.LeftArrow);
-            //    Thread.Sleep(dur);
-            //    G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false);
-
-            //    image = ScreenCapture.Instance.CaptureScreenReturnImage();
-            //    image = image.GetSubRect(new System.Drawing.Rectangle(gameRect.Start.X, gameRect.Start.Y, gameRect.End.X - gameRect.Start.X + 1, gameRect.End.Y - gameRect.Start.Y + 1));
-            //    CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv);
-            //    ZTPoint end = DnfCVHelper.FindRole(hsvImage, this.gameRect);
-            //    G.Instance.InfoWriter($"dur:{dur},start:{start},end{end},distance:{end.X - start.X}");
-            //    Thread.Sleep(2000);
-
+            //    this.moveState.StopMove();
+            //    G.Instance.DebugWriter("找不到角色,Send X");
+            //    G.Instance.InputControl.PressKey(1000, HIDCode.X);
+            //    SetState(KillMonsterStates.FindMonster, true);
+            //    return;
             //}
-            #endregion
-            //怪
-            this.stateMonsters = LindongCVHelper.FindMonster(hsvImage,this.gameRect);
-            //主角
-            this.stateRolePosition = DnfCVHelper.FindRole(hsvImage, this.gameRect);
-            //定位点
-            DnfCVHelper.GetLocationPoint(out stateLocationRectangle, hsvImage, this.gameRect);
+            //else
+            //{
+            //    this.moveState.FindRoleMove();
+            //    SetState(KillMonsterStates.IsLastHouse, true);
+            //}
+        }
 
-            if (this.stateMonsters.Length > 0)
+        /// <summary>
+        /// 拾取物品
+        /// </summary>
+        private void PickupThing()
+        {
+            //拾取物品,获取最近一个物品位置并步行过去
+            ZTPoint thingItemPosition = GetNearlyThingItem(image, stateRolePosition);
+            if (thingItemPosition != ZTPoint.Empty)
             {
-                G.Instance.DebugWriter(string.Format("已找到{0}个怪", this.stateMonsters.Length));
-                //未找到主角
-                if (stateRolePosition == ZTPoint.Empty)
+                if (this.moveState.IsMoving && !this.moveState.IsPickupMoving)
                 {
                     this.moveState.StopMove();
-                    G.Instance.DebugWriter("找不到角色,Send X");
-                    G.Instance.InputControl.PressKey(1000, HIDCode.X);
-                    return new KillMonsterStateResult(STATE_FindMonster, true);
                 }
 
-                return new KillMonsterStateResult(STATE_PrepareReleaseSkill, false);
+                this.moveState.PickupMove(this.stateRolePosition, thingItemPosition);
+                //return new KillMonsterStateResult(STATE_FindMonster, true);
+            }
+
+            if (this.moveState.IsPickupMoving)
+            {
+                this.moveState.StopMove();
+            }
+        }
+
+        /// <summary>
+        /// 查找门, 是否找到门
+        /// </summary>
+        private void FindDoor()
+        {
+            //查找真实的门
+            this.stateDoorPosition = LindongCVHelper.FindDoor(out stateDoorLevelDirect, hsvImage, this.house.DoorDirection, this.GameRect);
+            if (this.stateDoorPosition != ZTPoint.Empty)
+            {
+                //找到门,向门移动  
+                if (this.moveState.IsFindDoorMoving)
+                {
+                    this.moveState.StopMove();
+                }
+                G.Instance.InfoWriter("已找到门,位置:" + stateDoorPosition.ToString());
+                SetState(KillMonsterStates.EntryDoor, false);
             }
             else
             {
-                //未查找到主角
-                
-
-                if (stateRolePosition == ZTPoint.Empty)
-                {
-                    if (this.moveState.IsMoving && !this.moveState.IsFindRoleMoving)
-                    {
-                        this.moveState.StopMove();
-                    }
-
-
-                    //是否刷完
-                    if (IsComplete(image))
-                    {
-                        return new KillMonsterStateResult(STATE_Exit, false);
-                    }
-
-                    this.moveState.FindRoleMove();
-                    return new KillMonsterStateResult(STATE_FindMonster, true);
-                }
-                return new KillMonsterStateResult(STATE_DetectDoorIsOpen, true);
+                //未找到门,循环移动
+                SetState(KillMonsterStates.FindDoorMove, false);
             }
-
-            
         }
+
+        /// <summary>
+        /// 向门移动, 进门
+        /// </summary>
+        private void EntryDoor()
+        {
+            const Int32 XLevelOffset = 200;
+            const Int32 YLevelOffset = 100;
+            Int32 limitLine = 0;
+            Int32 diff = 0;
+            //传过来人物坐标和门的坐标,根据门的朝向计算人物走向
+            switch (stateDoorLevelDirect)
+            {
+                case Direction.Up:
+                    //门在上方
+                    limitLine = stateDoorPosition.Y + YLevelOffset;
+                    if (stateRolePosition.Y < limitLine)
+                    {
+                        //下移
+                        this.moveState.SyncMove(new ZTPoint(0, limitLine - stateRolePosition.Y));
+                    }
+
+                    //垂直对齐
+                    diff = stateDoorPosition.X - stateRolePosition.X;
+                    this.moveState.SyncMove(new ZTPoint(diff, 0));
+
+                    //移动y,进入
+                    this.moveState.SyncMove(new ZTPoint(0, this.GameRect.Start.Y - stateRolePosition.Y));
+                    break;
+
+                case Direction.Right:
+                    //门在右侧
+                    limitLine = stateDoorPosition.X - XLevelOffset;
+                    if (stateRolePosition.X > limitLine)
+                    {
+                        //如果角色位于门右侧,先向左移
+                        this.moveState.SyncMove(new ZTPoint(limitLine - stateRolePosition.X, 0));
+                    }
+
+                    //水平对齐
+                    diff = stateDoorPosition.Y - stateRolePosition.Y;
+                    this.moveState.SyncMove(new ZTPoint(0, diff));
+
+                    //移动x,进入
+                    this.moveState.SyncMove(new ZTPoint(this.GameRect.End.X - stateRolePosition.X, 0));
+                    break;
+
+                case Direction.Bottom:
+                    //门在下方
+                    limitLine = stateDoorPosition.Y - YLevelOffset;
+                    if (stateRolePosition.Y > limitLine)
+                    {
+                        //如果角色在门下方,先向上移
+                        this.moveState.SyncMove(new ZTPoint(0, limitLine - stateRolePosition.Y));
+                    }
+
+                    //垂直对齐
+                    diff = stateDoorPosition.X - stateRolePosition.X;
+                    this.moveState.SyncMove(new ZTPoint(diff, 0));
+
+                    //移动y,进入
+                    this.moveState.SyncMove(new ZTPoint(0, this.GameRect.End.Y - stateRolePosition.Y));
+                    break;
+
+                case Direction.Left:
+                    //门在左侧
+                    limitLine = stateDoorPosition.X + XLevelOffset;
+                    if (stateRolePosition.X < limitLine)
+                    {
+                        //如果角色位于门左侧,先向右移
+                        this.moveState.SyncMove(new ZTPoint(limitLine - stateRolePosition.X, 0));
+                    }
+
+                    //水平对齐
+                    diff = stateDoorPosition.Y - stateRolePosition.Y;
+                    this.moveState.SyncMove(new ZTPoint(0, diff));
+
+                    //移动x,进入
+                    this.moveState.SyncMove(new ZTPoint(this.GameRect.Start.X - stateRolePosition.X, 0));
+                    break;
+            }
+            SetState(KillMonsterStates.IsLastHouse, true);
+            return;
+        }
+
+        /// <summary>
+        /// 找门移动
+        /// </summary>
+        private void FindDoorMove()
+        {
+            Int32 areaID = 0;
+            if (this.outOfBounds.InOutOfBound(this.house.Index, stateRolePosition, out areaID))
+            {
+                this.outOfBounds.MoveToCommonBound(areaID);
+            }
+            else
+            {
+                this.moveState.FindDoorMove(stateRolePosition);
+            }
+            SetState(KillMonsterStates.IsLastHouse, true);
+        }
+
+
 
         private DateTime FindRoleLastNoMoveTime = DateTime.MaxValue;//最后没移动时间
         private bool FindRoleLastNoMoveStart = false;//没移动是否开始计时
+        private ZTSize attackMoveDistance = ZTSize.Empty;
+        private HIDCode roleDirection = HIDCode.NoEvent;
         /// <summary>
-        /// 1.释放技能预处理,计算位置
+        /// 判断使用何技能,计算攻击移动距离, 是否需要移动
         /// </summary>
-        /// <param name="image"></param>
-        /// <param name="hsvImage"></param>
-        /// <returns></returns>
-        private KillMonsterStateResult PrepareReleaseSkill(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage)
+        private void CalcAttackDistance()
         {
-            if (this.moveState.IsMoving&&!this.moveState.IsAttackMoving)
-            {
-                this.moveState.StopMove();
-            }
-            SkillInfo skill = this.house.Skills.SyncPeek();
-            
+            SkillInfo attackSkill = this.house.Skills.SyncPeek();
 
+            
             //计算攻击移动距离
-            HIDCode dir = HIDCode.RightArrow;
             bool needMove = false;
-            ZTSize moveDistance = AttackRectangle.GetMoveDistance(this.gameRect, stateRolePosition, stateMonsters, skill, out dir, out needMove);
+            attackMoveDistance = AttackRectangle.GetMoveDistance(this.GameRect, stateRolePosition, stateMonsters, attackSkill, out roleDirection, out needMove);
             if (!needMove)
             {
-                this.roleLastPosition = ZTPoint.Empty;
-                //不需要移动
-                if (dir != HIDCode.NoEvent)
-                {
-                    G.Instance.InputControl.PressKey(100, dir);
-                }
-                this.moveState.StopMove();
-                G.Instance.DebugWriter(string.Format("不需移动直接发技能,距离:{0}", moveDistance.ToString()));
-                return new KillMonsterStateResult(STATE_ReleaseSkill, false);
+                G.Instance.DebugWriter(string.Format("不需移动直接发技能,距离:{0}", attackMoveDistance.ToString()));
+                SetState(KillMonsterStates.ReleaseSkill, false);
             }
+            else
+            {
+                SetState(KillMonsterStates.AttackMove, false);
+            }
+        }
+
+        /// <summary>
+        /// 调整朝向, 释放技能
+        /// </summary>
+        private void ReleaseSkill()
+        {
+            SkillInfo skill = this.house.Skills.SyncDeQueue();
+
+
+            this.roleLastPosition = ZTPoint.Empty;
+            if (roleDirection != HIDCode.NoEvent)
+            {
+                G.Instance.InputControl.PressKey(100, roleDirection);
+            }
+            this.moveState.StopMove();
+
             
+
+
+            if (skill.Key == HIDCode.X)
+            {
+                for (int i = 0; i < 5; i++)
+                {
+                    G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, skill.Key);
+                    Thread.Sleep(200);
+                }
+            }
+            else
+            {
+                G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, skill.Key);
+                Thread.Sleep((Int32)skill.ReleaseTime);
+            }
+
+            G.Instance.DebugWriter(string.Format("发完技能,技能按键:{0},技能名称:{1}", skill.Key, skill.SkillName));
+            SetState(KillMonsterStates.IsLastHouse, true);
+        }
+
+        /// <summary>
+        /// 攻击移动
+        /// </summary>
+        private void AttackMove()
+        {
+            SkillInfo attackSkill = this.house.Skills.SyncPeek();
             //没有移动,可能有障碍物
             if (stateRolePosition == this.roleLastPosition)
             {
@@ -350,203 +570,10 @@
                 this.roleLastPosition = stateRolePosition;
                 FindRoleLastNoMoveStart = false;
             }
-            
-            G.Instance.DebugWriter("attack move :"+moveDistance.ToString()+",role:"+stateRolePosition.ToString()+",monster1:"+stateMonsters[0].ToString()+",skill:"+skill.Key.ToString());
-            this.moveState.AttackMove(moveDistance);
-            return new KillMonsterStateResult(STATE_FindMonster, true);
-        }
 
-        /// <summary>
-        /// 2.释放技能
-        /// </summary>
-        /// <param name="image"></param>
-        /// <param name="hsvImage"></param>
-        /// <returns></returns>
-        private KillMonsterStateResult ReleaseSkill(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage)
-        {
-            SkillInfo skill = this.house.Skills.SyncDeQueue();
-            if (skill.Key == HIDCode.X)
-            {
-                for (int i = 0; i < 5; i++)
-                {
-                    G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, skill.Key);
-                    Thread.Sleep(200);
-                }
-            }
-            else
-            {
-                G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, skill.Key);
-                Thread.Sleep((Int32)skill.ReleaseTime);
-            }
-            
-            G.Instance.DebugWriter(string.Format("发完技能,技能按键:{0},技能名称:{1}", skill.Key, skill.SkillName));            
-            return new KillMonsterStateResult(STATE_FindMonster, true);
-        }
-
-        
-        /// <summary>
-        /// 3.检测进入下一房间的门是否开了
-        /// </summary>
-        /// <returns></returns>
-        private KillMonsterStateResult DetectDoorIsOpen(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage)
-        {
-            if (this.moveState.IsAttackMoving|| this.moveState.IsFindRoleMoving)
-            {
-                this.moveState.StopMove();
-            }
-
-            ////查找当前房间编号,看是否进入其它房间
-            //Int32 houseIndex;
-            //if (!LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart))
-            //{
-            if (IsComplete(image))
-            {
-                return new KillMonsterStateResult(STATE_Exit, false);
-            }
-
-            //    G.Instance.DebugWriter("检测是否进入下一房间时,未发现小地图中有人物标记,id"+this.house.Index+",isend:"+this.house.IsEnd.ToString());
-            //    return new KillMonsterStateResult(STATE_FindMonster, true);
-            //}
-
-            //if (houseIndex != this.house.Index)
-            //{
-            //    //已进入其它房间
-            //    this.moveState.StopMove();
-            //    this.exitResult = true;
-            //    return new KillMonsterStateResult(STATE_Exit, false);
-            //}
-
-            ////拾取物品,获取最近一个物品位置并步行过去
-            //ZTPoint thingItemPosition = GetNearlyThingItem(image, rolePosition);
-            //if (thingItemPosition != ZTPoint.Empty)
-            //{
-            //    if (this.moveState.IsMoving && !this.moveState.IsPickupMoving)
-            //    {
-            //        this.moveState.StopMove();
-            //    }
-
-            //    this.moveState.PickupMove(rolePosition, thingItemPosition);
-            //    return new KillMonsterStateResult(STATE_FindMonster, true);
-            //}
-
-            //if (this.moveState.IsPickupMoving)
-            //{
-            //    this.moveState.StopMove();
-            //}
-
-            //查找真实的门
-            ZTPoint doorPosition = LindongCVHelper.FindDoor(out stateDoorLevelDirect,hsvImage, this.house.DoorDirection,this.gameRect);
-            if (doorPosition != ZTPoint.Empty)
-            {
-                G.Instance.InfoWriter("door find:"+doorPosition.ToString());
-                this.moveState.StopMove();
-                this.stateDoorPosition = doorPosition;
-                
-                //找到门,向门移动          
-                return new KillMonsterStateResult(STATE_MoveToDoor, false);
-            }
-            else
-            {
-                //未找到门,循环移动
-                Int32 areaID = 0;
-                if (this.outOfBounds.InOutOfBound(this.house.Index, stateRolePosition, out areaID))
-                {
-                    this.outOfBounds.MoveToCommonBound(areaID);
-                }
-                else
-                {
-                    this.moveState.FindDoorMove(stateRolePosition);
-                }
-            }
-            
-            return new KillMonsterStateResult(STATE_FindMonster, true);
-        }
-        
-        private const Int32 XDoorLevelOffset = 200;
-        private const Int32 YDoorLevelOffset = 100;
-        /// <summary>
-        /// 4.找门
-        /// </summary>
-        /// <param name="image"></param>
-        /// <param name="hsvImage"></param>
-        /// <returns></returns>
-        private KillMonsterStateResult MoveToDoor(Image<Rgb, byte> image, Image<Hsv, byte> hsvImage)
-        {
-            Int32 limitLine = 0;
-            Int32 diff = 0;
-            //传过来人物坐标和门的坐标,根据门的朝向计算人物走向
-            switch (stateDoorLevelDirect)
-            {
-                case Direction.Up:
-                    //门在上方
-                    limitLine = stateDoorPosition.Y + YDoorLevelOffset;                    
-                    if (stateRolePosition.Y < limitLine)
-                    {
-                        //下移
-                        this.moveState.SyncMove(new ZTPoint(0, limitLine - stateRolePosition.Y));
-                    }
-
-                    //垂直对齐
-                    diff = stateDoorPosition.X - stateRolePosition.X;
-                    this.moveState.SyncMove(new ZTPoint(diff, 0));
-
-                    //移动y,进入
-                    this.moveState.SyncMove(new ZTPoint(0, this.gameRect.Start.Y - stateRolePosition.Y));
-                    break;
-
-                case Direction.Right:
-                    //门在右侧
-                    limitLine = stateDoorPosition.X - XDoorLevelOffset;
-                    if (stateRolePosition.X > limitLine)
-                    {
-                        //如果角色位于门右侧,先向左移
-                        this.moveState.SyncMove(new ZTPoint(limitLine - stateRolePosition.X, 0));
-                    }
-
-                    //水平对齐
-                    diff = stateDoorPosition.Y - stateRolePosition.Y;
-                    this.moveState.SyncMove(new ZTPoint(0, diff));
-
-                    //移动x,进入
-                    this.moveState.SyncMove(new ZTPoint(this.gameRect.End.X - stateRolePosition.X, 0));
-                    break;
-
-                case Direction.Bottom:
-                    //门在下方
-                    limitLine = stateDoorPosition.Y - YDoorLevelOffset;
-                    if (stateRolePosition.Y > limitLine)
-                    {
-                        //如果角色在门下方,先向上移
-                        this.moveState.SyncMove(new ZTPoint(0,limitLine- stateRolePosition.Y));
-                    }
-
-                    //垂直对齐
-                    diff = stateDoorPosition.X - stateRolePosition.X;
-                    this.moveState.SyncMove(new ZTPoint(diff, 0));
-
-                    //移动y,进入
-                    this.moveState.SyncMove(new ZTPoint(0, this.gameRect.End.Y - stateRolePosition.Y));
-                    break;
-
-                case Direction.Left:
-                    //门在左侧
-                    limitLine = stateDoorPosition.X + XDoorLevelOffset;
-                    if (stateRolePosition.X < limitLine)
-                    {
-                        //如果角色位于门左侧,先向右移
-                        this.moveState.SyncMove(new ZTPoint(limitLine - stateRolePosition.X, 0));
-                    }
-
-                    //水平对齐
-                    diff = stateDoorPosition.Y - stateRolePosition.Y;
-                    this.moveState.SyncMove(new ZTPoint(0, diff));
-
-                    //移动x,进入
-                    this.moveState.SyncMove(new ZTPoint(this.gameRect.Start.X- stateRolePosition.X, 0));
-                    break;
-            }
-            
-            return new KillMonsterStateResult(STATE_DetectDoorIsOpen, true);
+            G.Instance.DebugWriter("attack move :" + attackMoveDistance.ToString() + ",role:" + stateRolePosition.ToString() + ",monster1:" + stateMonsters[0].ToString() + ",skill:" + attackSkill.Key.ToString());
+            this.moveState.AttackMove(attackMoveDistance);
+            SetState(KillMonsterStates.FindRole, true);
         }
         #endregion
 
@@ -555,9 +582,9 @@
         /// </summary>
         /// <param name="image"></param>
         /// <returns></returns>
-        public ZTPoint GetNearlyThingItem(Image<Rgb, byte> image,ZTPoint rolePosition)
+        public ZTPoint GetNearlyThingItem(Image<Rgb, byte> image, ZTPoint rolePosition)
         {
-            List<ZTPoint> points=DnfCVHelper.GetThingItemPoints(image, this.gameRect);
+            List<ZTPoint> points = DnfCVHelper.GetThingItemPoints(image, this.GameRect);
             if (points.Count <= 0)
             {
                 return ZTPoint.Empty;
@@ -567,7 +594,7 @@
             {
                 return points[0];
             }
-            
+
             double distance = 0;
             ZTPoint result = ZTPoint.Empty;
             for (int i = 0; i < points.Count; i++)
@@ -589,39 +616,8 @@
 
             return result;
         }
-
-        /// <summary>
-        /// 是否完成
-        /// </summary>
-        /// <param name="image"></param>
-        /// <returns></returns>
-        public bool IsComplete(Image<Rgb,byte> image)
-        {
-            if (this.house.IsEnd)
-            {
-
-                if (DnfCVHelper.IsJiangli(image, this.gameRect))
-                {
-                    //翻牌
-                    this.moveState.StopMove();
-                    Fanpai();
-                    Thread.Sleep(5000);
-                    this.exitResult = true;
-                    return true;
-                }
-
-                if (DnfCVHelper.IsCompleteRoom(image, this.gameRect))
-                {
-                    //已经刷完
-                    this.moveState.StopMove();
-                    this.exitResult = true;
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        #region 翻牌
+        
+        
         /// <summary>
         /// 牌的位置
         /// </summary>
@@ -648,34 +644,75 @@
         {
             Thread.Sleep(2000);
             Int32 number = RandomUtils.G(1, 4);
-            ZTPoint willPosition = this.gameRect.Start.Add(CardList[number - 1]);
-            G.Instance.InputControl.MoveToAndClick(RandomUtils.PointRange(willPosition,10));
+            ZTPoint willPosition = this.GameRect.Start.Add(CardList[number - 1]);
+            G.Instance.InputControl.MoveToAndClick(RandomUtils.PointRange(willPosition, 10));
 
             //判断黄金版是否可以翻
-            if (DnfCVHelper.HasMowangqiyueCard(this.gameRect))
+            if (DnfCVHelper.HasMowangqiyueCard(this.GameRect))
             {
                 number = RandomUtils.G(5, 8);
-                willPosition = this.gameRect.Start.Add(CardList[number - 1]);
+                willPosition = this.GameRect.Start.Add(CardList[number - 1]);
                 G.Instance.InputControl.MoveToAndClick(RandomUtils.PointRange(willPosition, 10));
             }
 
         }
-        #endregion
+        
+
+        /// <summary>
+        /// 是否改变房间
+        /// </summary>
+        /// <param name="cancellationToken"></param>
+        /// <returns></returns>
+        private bool HouseIsChange()
+        {
+            Int32 houseIndex;
+            if (!LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart))
+            {
+                //得不到房间
+                if (!FuncUtils.TimeoutCancelableWrap(30 * 1000, cancellationToken, () =>
+                {
+                    using (bitmap = ScreenCapture.Instance.CaptureScreen())
+                    {
+                        image = new Image<Rgb, byte>(bitmap);
+                        image = image.GetSubRect(new System.Drawing.Rectangle(GameRect.Start.X, GameRect.Start.Y, GameRect.End.X - GameRect.Start.X + 1, GameRect.End.Y - GameRect.Start.Y + 1));
+                        return LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart);
+                    }
+                }, 50))
+                {
+                    throw new Exception("找不到默认房间");
+                }
+            }
+            if (houseIndex != this.house.Index)
+            {
+                this.moveState.StopMove();
+                return true;
+            }
+            return false;
+        }
 
 
         /// <summary>
         /// 杀怪状态
         /// </summary>
-        public enum KillMonsterStates:Int32
+        public enum KillMonsterStates : Int32
         {
-                FindMonster = 0,//找怪
-                PrepareReleaseSkill = 1,//释放技能预处理,计算位置
-                ReleaseSkill = 2,//释放技能
-                DetectDoorIsOpen = 3,//查找进入下一房间的门是否开了
-                MoveToDoor = 4,//移动进门
-
-                Start = 8,//开始状态 
-                Exit = 9,//完成状态
-    }
+            Start,//开始状态 
+            Exit,//完成状态
+            IsLastHouse,//是否最后一个房间
+            HasRewardWindow,//是否有奖励界面
+            TurnAroundCard,//翻牌
+            IsCompletePage,//是否刷完界面
+            IsOtherHouse,//是否进入其它房间
+            FindRole,//找主角
+            FindRoleMove,//让主角移动(原:有怪攻击一下,无怪移动一下)
+            FindMonster,//找怪
+            PickupThing,//拾取物品
+            FindDoor,//查找门, 是否找到门
+            EntryDoor,//向门移动, 进门
+            FindDoorMove,//找门移动
+            CalcAttackDistance,//判断使用何技能,计算攻击移动距离, 是否需要移动
+            ReleaseSkill,//调整朝向, 释放技能,
+            AttackMove,//攻击移动
+        }
     }
 }

--
Gitblit v1.9.3