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