From 576b92fd82f568572bc4beb125fa0ba0191a602f Mon Sep 17 00:00:00 2001
From: asmrobot <asmrobot@hotmail.com>
Date: Wed, 13 Nov 2019 14:59:52 +0000
Subject: [PATCH] add map editor

---
 src/RichCreator/StateMachines/KillMonsterStateMachine.cs |  229 ++++++++++++++++++++++++++------------------------------
 1 files changed, 106 insertions(+), 123 deletions(-)

diff --git a/src/RichCreator/StateMachines/KillMonsterStateMachine.cs b/src/RichCreator/StateMachines/KillMonsterStateMachine.cs
index 7510a43..b2faf21 100644
--- a/src/RichCreator/StateMachines/KillMonsterStateMachine.cs
+++ b/src/RichCreator/StateMachines/KillMonsterStateMachine.cs
@@ -1,22 +1,19 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
+using Emgu.CV;
+using Emgu.CV.Structure;
+using RichCreator.Dnf;
+using RichCreator.Maps.Kalete;
+using RichCreator.StateMachines;
 using RichCreator.Utility;
 using RichCreator.Utility.Captures;
 using RichCreator.Utility.CV;
 using RichCreator.Utility.InputControl;
+using RichCreator.Utility.Maps;
+using RichCreator.Utility.Skills;
 using RichCreator.Utility.Structs;
-using Emgu.CV;
-using Emgu.CV.Structure;
-using RichCreator.Maps;
-using RichCreator.Maps.Lindong;
-using RichCreator.StateMachines;
 using RichCreator.Utilitys;
-using static RichCreator.Utilitys.AttackRectangle;
-using Utils = RichCreator.Utilitys.Utils;
+using System;
+using System.Collections.Generic;
+using System.Threading;
 using ZTImage.Collections;
 
 namespace RichCreator.Jobs.StateMachines
@@ -27,12 +24,11 @@
     public class KillMonsterStateMachine : StateMachineBase
     {
         private const Int32 NoMoveMaxMillSecond = 2000;//最大未移动容忍毫秒数
-
+        private MapInfo map;//地图
         private HouseInfo house;//当前房间
-        private ZTPoint miniMapStart;//小地图区域
-        private ZTRectangle GameRect;//游戏区域
+        private DnfRole role;//当前角色控制
+        
         private Int32 preHouseIndex = 0;//上一房间编号
-        private MoveState moveState;//移动状态
         private OutOfBounds outOfBounds;//禁区
         private bool isSuccess;//退出结果
 
@@ -43,7 +39,7 @@
         //当前状态
         private KillMonsterStates currentState = KillMonsterStates.Start;
         //是否截图屏幕
-        private bool captureScreen = false;
+        private bool needCaptureScreen = false;
 
         //怪
         private ZTPoint[] stateMonsters;
@@ -57,35 +53,31 @@
 
         //色彩hsv
         private Image<Hsv, byte> hsvImage = null;
-        //取消令牌
-        private CancellationToken cancellationToken = CancellationToken.None;
         #region Find Door Info
         //门坐标
         private ZTPoint stateDoorPosition;
-        //角色位置
-        private ZTPoint stateRolePosition;
+        
         //离开的门朝向
         private Direction stateDoorLevelDirect = Direction.None;
-        //定位点方框
-        private MultiList<ZTRectangle, Int32> stateLocationRectangle = new MultiList<ZTRectangle, int>();
-
+        
+        //屏幕定位点
+        private ParametersPoint stateScreenLocation = new ParametersPoint();
 
         
        
         #endregion
 
 
-        public KillMonsterStateMachine(HouseInfo house, ZTPoint miniMapStart, ZTRectangle gameRect, Int32 preHouseIndex, Int32 runningStep, CancellationToken cancellationToken)
+        public KillMonsterStateMachine(MapInfo map,HouseInfo house, DnfRole role,Int32 preHouseIndex, Int32 runningStep)
         {
-            this.runningStep = runningStep;
+            this.map = map;
             this.house = house;
-            this.miniMapStart = miniMapStart;
-            this.GameRect = gameRect;
+            this.role = role;
+            this.runningStep = runningStep;
             this.preHouseIndex = preHouseIndex;
-            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);
+            
+            outOfBounds = new OutOfBounds(map.GameRect, role);
+            hsvImage = new Image<Hsv, byte>(map.GameRect.End.X - map.GameRect.Start.X + 1, map.GameRect.End.Y - map.GameRect.Start.Y + 1);
         }
 
 
@@ -93,7 +85,7 @@
         private void SetState(KillMonsterStates current, bool capture)
         {
             currentState = current;
-            captureScreen = capture;
+            needCaptureScreen = capture;
         }
 
         /// <summary>
@@ -111,24 +103,26 @@
                 SetState(KillMonsterStates.FindMonster, true);
             }
 
+            //定位方框列表
+            MultiList<ZTRectangle, Int32> locationRectangles = new MultiList<ZTRectangle, int>();
 
             while (true)
             {
-                if (cancellationToken.IsCancellationRequested)
+                if (map.CancelToken.IsCancellationRequested)
                 {
                     G.Instance.DebugWriter("取消刷图");
-                    this.moveState.StopMove();
+                    this.role.StopMove();
                     return ZTResult.Cancel;
                 }
 
                 if (DateTime.Now > expireTime)
                 {
                     G.Instance.DebugWriter("刷图超时");
-                    this.moveState.StopMove();
+                    this.role.StopMove();
                     return ZTResult.Timeout;
                 }
 
-                if (captureScreen)
+                if (needCaptureScreen)
                 {
                     using (bitmap = ScreenCapture.Instance.CaptureScreen())
                     {
@@ -137,7 +131,7 @@
                             image.Dispose();
                         }
                         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));
+                        image = image.GetSubRect(new System.Drawing.Rectangle(map.GameRect.Start.X, map.GameRect.Start.Y, map.GameRect.End.X - map.GameRect.Start.X + 1, map.GameRect.End.Y - map.GameRect.Start.Y + 1));
                         imageIsChange = true;
                     }
                 }
@@ -146,7 +140,7 @@
                 {
                     case KillMonsterStates.Start:
                         //开始
-                        SingleEntryHouseSkill.ReleaseSkill(this.house.Index, this.preHouseIndex, this.moveState);
+                        this.map.EntryHousePrework(this.house.Index, this.preHouseIndex);
                         SetState(KillMonsterStates.IsLastHouse, true);
                         break;
                     case KillMonsterStates.IsLastHouse:
@@ -168,7 +162,7 @@
                         break;
                     case KillMonsterStates.HasRewardWindow:
                         //是否有奖励界面
-                        if (DnfCVHelper.IsJiangli(image, this.GameRect))
+                        if (DnfCVHelper.IsJiangli(image, map.GameRect))
                         {
                             SetState(KillMonsterStates.TurnAroundCard, false);
                         }
@@ -186,7 +180,7 @@
                         break;
                     case KillMonsterStates.IsCompletePage:
                         //是否刷完界面
-                        if (DnfCVHelper.IsCompleteRoom(image, this.GameRect))
+                        if (DnfCVHelper.IsCompleteRoom(image, map.GameRect))
                         {
                             this.isSuccess = true;
                             SetState(KillMonsterStates.Exit, false);
@@ -213,8 +207,9 @@
                         //主角
                         CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv);
 
+                        
                         //定位点
-                        if (!DnfCVHelper.GetLocationPoint(out stateLocationRectangle, hsvImage, this.GameRect))
+                        if (!DnfCVHelper.GetLocationPoint(out locationRectangles, hsvImage, map.GameRect))
                         {
                             //找不到定位点
                             G.Instance.InfoWriter("找不到定位点");
@@ -222,20 +217,20 @@
                             break;
                         }
 
-
-
-
-                        this.stateRolePosition = DnfCVHelper.FindRole(hsvImage, this.GameRect);
-                        if (this.stateRolePosition .Equals( ZTPoint.Empty))
+                        this.stateScreenLocation = new ParametersPoint(locationRectangles[0].Item1.GetCenterPoint(), locationRectangles[0].Item2);
+                        
+                        ZTPoint rolePosition = DnfCVHelper.FindRole(hsvImage, map.GameRect);
+                        if (rolePosition .Equals( ZTPoint.Empty))
                         {
                             SetState(KillMonsterStates.FindRoleMove, false);
                         }
                         else
                         {
-                            if (this.moveState.IsFindRoleMoving)
+                            if (this.role.IsMoveIntent(Utility.Dnf.MoveIntent.FindRoleMove))
                             {
-                                this.moveState.StopMove();
+                                this.role.StopMove();
                             }
+                            role.UpdatePosition(rolePosition);
                             SetState(KillMonsterStates.FindMonster, false);
                         }
                         break;
@@ -245,7 +240,7 @@
                         break;
                     case KillMonsterStates.FindMonster:
                         //找怪                        
-                        this.stateMonsters = LindongCVHelper.FindMonster(hsvImage, this.GameRect);
+                        this.stateMonsters = LindongCVHelper.FindMonster(hsvImage, map.GameRect);
                         
                         if (this.stateMonsters.Length > 0)
                         {
@@ -259,8 +254,13 @@
                         break;
                     case KillMonsterStates.PickupThing:
                         //拾取物品
-                        SetState(KillMonsterStates.FindDoor, false);
+                        SetState(KillMonsterStates.ToNextGatePoint, false);
                         //todo: PickupThing();
+                        break;
+                    case KillMonsterStates.ToNextGatePoint:
+                        //移到进门点
+                        SetState(KillMonsterStates.FindDoor, false);
+                        //todo:ToNextGatePoint
                         break;
                     case KillMonsterStates.FindDoor:
                         //查找门, 是否找到门
@@ -289,7 +289,7 @@
                     case KillMonsterStates.Exit:
                         //结束
                         G.Instance.DebugWriter("退出状态");
-                        this.moveState.StopMove();
+                        this.role.StopMove();
                         if (this.isSuccess)
                         {
                             return ZTResult.Success;
@@ -309,22 +309,17 @@
         /// </summary>
         private void FindRoleMove()
         {
-            this.moveState.FindRoleMove();
-            SetState(KillMonsterStates.FindRole, true);
-
-            //if (this.stateMonsters.Length > 0)
+            //if (this.stateMonsters != null && this.stateMonsters.Length > 0)
             //{
-            //    this.moveState.StopMove();
+            //    this.role.StopMove();
             //    G.Instance.DebugWriter("找不到角色,Send X");
             //    G.Instance.InputControl.PressKey(1000, HIDCode.X);
-            //    SetState(KillMonsterStates.FindMonster, true);
+            //    SetState(KillMonsterStates.FindRole, true);
+
             //    return;
             //}
-            //else
-            //{
-            //    this.moveState.FindRoleMove();
-            //    SetState(KillMonsterStates.IsLastHouse, true);
-            //}
+            this.role.FindRoleMove();
+            SetState(KillMonsterStates.FindRole, true);
         }
 
         /// <summary>
@@ -333,21 +328,21 @@
         private void PickupThing()
         {
             //拾取物品,获取最近一个物品位置并步行过去
-            ZTPoint thingItemPosition = GetNearlyThingItem(image, stateRolePosition);
+            ZTPoint thingItemPosition = GetNearlyThingItem(image, role.Position);
             if (!thingItemPosition .Equals( ZTPoint.Empty))
             {
-                if (this.moveState.IsMoving && !this.moveState.IsPickupMoving)
+                if (this.role.IsMoving && !this.role.IsMoveIntent(Utility.Dnf.MoveIntent.PickupMove))
                 {
-                    this.moveState.StopMove();
+                    this.role.StopMove();
                 }
 
-                this.moveState.PickupMove(this.stateRolePosition, thingItemPosition);
+                this.role.PickupMove(this.role.Position, thingItemPosition);
                 //return new KillMonsterStateResult(STATE_FindMonster, true);
             }
 
-            if (this.moveState.IsPickupMoving)
+            if (this.role.IsMoveIntent(Utility.Dnf.MoveIntent.PickupMove))
             {
-                this.moveState.StopMove();
+                this.role.StopMove();
             }
         }
 
@@ -357,13 +352,13 @@
         private void FindDoor()
         {
             //查找真实的门
-            this.stateDoorPosition = LindongCVHelper.FindDoor(out stateDoorLevelDirect, hsvImage, this.house.DoorDirection, this.GameRect);
+            this.stateDoorPosition = LindongCVHelper.FindDoor(out stateDoorLevelDirect, hsvImage, this.house.DoorDirection, map.GameRect);
             if (!this.stateDoorPosition .Equals(ZTPoint.Empty))
             {
                 //找到门,向门移动  
-                if (this.moveState.IsFindDoorMoving)
+                if (this.role.IsMoveIntent(Utility.Dnf.MoveIntent.FindDoorMove))
                 {
-                    this.moveState.StopMove();
+                    this.role.StopMove();
                 }
                 G.Instance.InfoWriter("已找到门,位置:" + stateDoorPosition.ToString());
                 SetState(KillMonsterStates.EntryDoor, false);
@@ -390,69 +385,69 @@
                 case Direction.Up:
                     //门在上方
                     limitLine = stateDoorPosition.Y + YLevelOffset;
-                    if (stateRolePosition.Y < limitLine)
+                    if (role.Position.Y < limitLine)
                     {
                         //下移
-                        this.moveState.SyncMove(new ZTPoint(0, limitLine - stateRolePosition.Y));
+                        this.role.SyncMove(new ZTPoint(0, limitLine - role.Position.Y));
                     }
 
                     //垂直对齐
-                    diff = stateDoorPosition.X - stateRolePosition.X;
-                    this.moveState.SyncMove(new ZTPoint(diff, 0));
+                    diff = stateDoorPosition.X - role.Position.X;
+                    this.role.SyncMove(new ZTPoint(diff, 0));
 
                     //移动y,进入
-                    this.moveState.SyncMove(new ZTPoint(0, this.GameRect.Start.Y - stateRolePosition.Y));
+                    this.role.SyncMove(new ZTPoint(0, map.GameRect.Start.Y - role.Position.Y));
                     break;
 
                 case Direction.Right:
                     //门在右侧
                     limitLine = stateDoorPosition.X - XLevelOffset;
-                    if (stateRolePosition.X > limitLine)
+                    if (role.Position.X > limitLine)
                     {
                         //如果角色位于门右侧,先向左移
-                        this.moveState.SyncMove(new ZTPoint(limitLine - stateRolePosition.X, 0));
+                        this.role.SyncMove(new ZTPoint(limitLine - role.Position.X, 0));
                     }
 
                     //水平对齐
-                    diff = stateDoorPosition.Y - stateRolePosition.Y;
-                    this.moveState.SyncMove(new ZTPoint(0, diff));
+                    diff = stateDoorPosition.Y - role.Position.Y;
+                    this.role.SyncMove(new ZTPoint(0, diff));
 
                     //移动x,进入
-                    this.moveState.SyncMove(new ZTPoint(this.GameRect.End.X - stateRolePosition.X, 0));
+                    this.role.SyncMove(new ZTPoint(map.GameRect.End.X - role.Position.X, 0));
                     break;
 
                 case Direction.Bottom:
                     //门在下方
                     limitLine = stateDoorPosition.Y - YLevelOffset;
-                    if (stateRolePosition.Y > limitLine)
+                    if (role.Position.Y > limitLine)
                     {
                         //如果角色在门下方,先向上移
-                        this.moveState.SyncMove(new ZTPoint(0, limitLine - stateRolePosition.Y));
+                        this.role.SyncMove(new ZTPoint(0, limitLine - role.Position.Y));
                     }
 
                     //垂直对齐
-                    diff = stateDoorPosition.X - stateRolePosition.X;
-                    this.moveState.SyncMove(new ZTPoint(diff, 0));
+                    diff = stateDoorPosition.X - role.Position.X;
+                    this.role.SyncMove(new ZTPoint(diff, 0));
 
                     //移动y,进入
-                    this.moveState.SyncMove(new ZTPoint(0, this.GameRect.End.Y - stateRolePosition.Y));
+                    this.role.SyncMove(new ZTPoint(0, map.GameRect.End.Y - role.Position.Y));
                     break;
 
                 case Direction.Left:
                     //门在左侧
                     limitLine = stateDoorPosition.X + XLevelOffset;
-                    if (stateRolePosition.X < limitLine)
+                    if (role.Position.X < limitLine)
                     {
                         //如果角色位于门左侧,先向右移
-                        this.moveState.SyncMove(new ZTPoint(limitLine - stateRolePosition.X, 0));
+                        this.role.SyncMove(new ZTPoint(limitLine - role.Position.X, 0));
                     }
 
                     //水平对齐
-                    diff = stateDoorPosition.Y - stateRolePosition.Y;
-                    this.moveState.SyncMove(new ZTPoint(0, diff));
+                    diff = stateDoorPosition.Y - role.Position.Y;
+                    this.role.SyncMove(new ZTPoint(0, diff));
 
                     //移动x,进入
-                    this.moveState.SyncMove(new ZTPoint(this.GameRect.Start.X - stateRolePosition.X, 0));
+                    this.role.SyncMove(new ZTPoint(map.GameRect.Start.X - role.Position.X, 0));
                     break;
             }
             SetState(KillMonsterStates.IsLastHouse, true);
@@ -465,13 +460,13 @@
         private void FindDoorMove()
         {
             Int32 areaID = 0;
-            if (this.outOfBounds.InOutOfBound(this.house.Index, stateRolePosition, out areaID))
+            if (this.outOfBounds.InOutOfBound(this.house.Index, role.Position, out areaID))
             {
                 this.outOfBounds.MoveToCommonBound(areaID);
             }
             else
             {
-                this.moveState.FindDoorMove(stateRolePosition);
+                this.role.FindDoorMove(role.Position);
             }
             SetState(KillMonsterStates.IsLastHouse, true);
         }
@@ -492,7 +487,7 @@
             
             //计算攻击移动距离
             bool needMove = false;
-            attackMoveDistance = AttackRectangle.GetMoveDistance(this.GameRect, stateRolePosition, stateMonsters, attackSkill, out roleDirection, out needMove);
+            attackMoveDistance = AttackRectangle.GetMoveDistance(map.GameRect, role.Position, stateMonsters, attackSkill, out roleDirection, out needMove);
             if (!needMove)
             {
                 G.Instance.DebugWriter(string.Format("不需移动直接发技能,距离:{0}", attackMoveDistance.ToString()));
@@ -517,7 +512,7 @@
             {
                 G.Instance.InputControl.PressKey(100, roleDirection);
             }
-            this.moveState.StopMove();
+            this.role.StopMove();
 
             
 
@@ -547,13 +542,13 @@
         {
             SkillInfo attackSkill = this.house.Skills.SyncPeek();
             //没有移动,可能有障碍物
-            if (stateRolePosition .Equals( this.roleLastPosition))
+            if (role.Position .Equals( this.roleLastPosition))
             {
                 if (FindRoleLastNoMoveStart && (DateTime.Now - FindRoleLastNoMoveTime).TotalMilliseconds > NoMoveMaxMillSecond)
                 {
                     //开始计时 并且 超过最大未移动容忍时间
-                    G.Instance.DebugWriter("find role no mvoe:" + stateRolePosition.ToString());
-                    this.moveState.StopMove();
+                    G.Instance.DebugWriter("find role no mvoe:" + role.Position.ToString());
+                    this.role.StopMove();
                     G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.X);
                     FindRoleLastNoMoveTime = DateTime.Now;
                 }
@@ -567,12 +562,12 @@
             else
             {
                 //移动了 取消计时
-                this.roleLastPosition = stateRolePosition;
+                this.roleLastPosition = role.Position;
                 FindRoleLastNoMoveStart = false;
             }
 
-            G.Instance.DebugWriter("attack move :" + attackMoveDistance.ToString() + ",role:" + stateRolePosition.ToString() + ",monster1:" + stateMonsters[0].ToString() + ",skill:" + attackSkill.Key.ToString());
-            this.moveState.AttackMove(attackMoveDistance);
+            G.Instance.DebugWriter("attack move :" + attackMoveDistance.ToString() + ",role:" + role.Position.ToString() + ",monster1:" + stateMonsters[0].ToString() + ",skill:" + attackSkill.Key.ToString());
+            this.role.AttackMove(attackMoveDistance);
             SetState(KillMonsterStates.FindRole, true);
         }
         #endregion
@@ -584,7 +579,7 @@
         /// <returns></returns>
         public ZTPoint GetNearlyThingItem(Image<Rgb, byte> image, ZTPoint rolePosition)
         {
-            List<ZTPoint> points = DnfCVHelper.GetThingItemPoints(image, this.GameRect);
+            List<ZTPoint> points = DnfCVHelper.GetThingItemPoints(image, map.GameRect);
             if (points.Count <= 0)
             {
                 return ZTPoint.Empty;
@@ -644,14 +639,14 @@
         {
             Thread.Sleep(2000);
             Int32 number = RandomUtils.G(1, 4);
-            ZTPoint willPosition = this.GameRect.Start.Add(CardList[number - 1]);
+            ZTPoint willPosition = map.GameRect.Start.Add(CardList[number - 1]);
             G.Instance.InputControl.MoveToAndClick(RandomUtils.PointRange(willPosition, 10));
 
             //判断黄金版是否可以翻
-            if (DnfCVHelper.HasMowangqiyueCard(this.GameRect))
+            if (DnfCVHelper.HasMowangqiyueCard(map.GameRect))
             {
                 number = RandomUtils.G(5, 8);
-                willPosition = this.GameRect.Start.Add(CardList[number - 1]);
+                willPosition = map.GameRect.Start.Add(CardList[number - 1]);
                 G.Instance.InputControl.MoveToAndClick(RandomUtils.PointRange(willPosition, 10));
             }
 
@@ -665,26 +660,13 @@
         /// <returns></returns>
         private bool HouseIsChange()
         {
-            Int32 houseIndex;
-            if (!LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.miniMapStart))
+            Int32 houseIndex = 0;
+            if (!map.MiniMap.GetCurrentHouseIndexWaitTimeout(out houseIndex, image, map.CancelToken, 30 * 1000))
             {
-                //得不到房间
-                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("找不到默认房间");
-                }
+                throw new Exception("找不到默认房间");
             }
             if (houseIndex != this.house.Index)
             {
-                this.moveState.StopMove();
                 return true;
             }
             return false;
@@ -707,6 +689,7 @@
             FindRoleMove,//让主角移动(原:有怪攻击一下,无怪移动一下)
             FindMonster,//找怪
             PickupThing,//拾取物品
+            ToNextGatePoint,//移到进门点
             FindDoor,//查找门, 是否找到门
             EntryDoor,//向门移动, 进门
             FindDoorMove,//找门移动

--
Gitblit v1.9.3