From 2aeab450471cb80b59002da7da80faf251a0c4f4 Mon Sep 17 00:00:00 2001
From: asmrobot <asmrobot@hotmail.com>
Date: Mon, 25 Nov 2019 15:02:53 +0000
Subject: [PATCH] sigle computer
---
src/RichCreator/StateMachines/KillMonsterStateMachine.cs | 269 +++++++++++++++++++++++++++++++----------------------
1 files changed, 155 insertions(+), 114 deletions(-)
diff --git a/src/RichCreator/StateMachines/KillMonsterStateMachine.cs b/src/RichCreator/StateMachines/KillMonsterStateMachine.cs
index 49ddf2c..2b6cee4 100644
--- a/src/RichCreator/StateMachines/KillMonsterStateMachine.cs
+++ b/src/RichCreator/StateMachines/KillMonsterStateMachine.cs
@@ -2,10 +2,12 @@
using Emgu.CV.Structure;
using RichCreator.Dnf;
using RichCreator.Maps.Kalete;
+using RichCreator.Models;
using RichCreator.StateMachines;
using RichCreator.Utility;
using RichCreator.Utility.Captures;
using RichCreator.Utility.CV;
+using RichCreator.Utility.Dnf;
using RichCreator.Utility.InputControl;
using RichCreator.Utility.Maps;
using RichCreator.Utility.Skills;
@@ -51,6 +53,11 @@
public KillMonsterStateMachine(MapInfo map,HouseInfo house, DnfRole role)
{
+ if (house.HousePathInfo.LoopPoint.Equals(ZTPoint.Empty))
+ {
+ throw new ArgumentOutOfRangeException("寻路中不存在循环点");
+ }
+
this.map = map;
this.house = house;
this.role = role;
@@ -72,10 +79,9 @@
/// <param name="cancellationToken"></param>
/// <param name="timeoutMillSecond"></param>
/// <returns></returns>
- public ZTResult Work(Int32 timeoutMillSecond,Int32 preHouseIndex,Int32 runningStep)
+ public ZTResult Work(Int32 timeoutMillSecond,Int32 fromHouseIndex,Int32 runningStep)
{
bool imageIsChange = false;//图像是否改变
- Int32 nextGate = 0;
DateTime expireTime = DateTime.Now.AddMilliseconds(timeoutMillSecond);
while (true)
@@ -83,14 +89,14 @@
if (map.CancelToken.IsCancellationRequested)
{
G.Instance.DebugWriter("取消刷图");
- this.role.StopMove();
+ this.role.StopMove("cancel");
return ZTResult.Cancel;
}
if (DateTime.Now > expireTime)
{
G.Instance.DebugWriter("刷图超时");
- this.role.StopMove();
+ this.role.StopMove("timeout");
return ZTResult.Timeout;
}
@@ -112,7 +118,10 @@
{
case KillMonsterStates.Start:
//开始
- this.map.EntryHousePrework(this.house.Index, preHouseIndex);
+ if (this.house.FromHouseIndex == fromHouseIndex)
+ {
+ this.map.EntryHousePrework(this.house.Index, fromHouseIndex);
+ }
SetState(KillMonsterStates.IsLastHouse, true);
break;
case KillMonsterStates.IsLastHouse:
@@ -136,7 +145,6 @@
//是否有奖励界面
if (DnfCVHelper.IsJiangli(image, map.GameRect))
{
- G.Instance.InfoWriter("has jiangli");
SetState(KillMonsterStates.TurnAroundCard, false);
}
else
@@ -178,7 +186,6 @@
break;
case KillMonsterStates.FindRole:
//主角
-
//定位点
if (this.house.WithoutNumber.Count <= 0)
{
@@ -201,26 +208,32 @@
ZTPoint roleCBPosition = DnfCVHelper.FindRole(hsvImage, map.GameRect);
if (roleCBPosition.Equals(ZTPoint.Empty))
{
- SetState(KillMonsterStates.FindRoleMove, false);
+ //未找到角色
+ if (!this.role.IsMoving)
+ {
+ SetState(KillMonsterStates.FindRoleMove, false);
+ }
+ else
+ {
+ SetState(KillMonsterStates.IsLastHouse, true);
+ }
}
else
{
- if (this.role.IsMoveIntent(Utility.Dnf.MoveIntent.FindRoleMove))
+ if (this.role.IsMoveIntent(MoveIntent.FindRoleMove))
{
- this.role.StopMove();
+ this.role.StopMove("update cb position");
}
role.UpdatePosition(roleCBPosition);
SetState(KillMonsterStates.FindMonster, false);
}
break;
case KillMonsterStates.FindRoleMove:
- //todo:让主角移动(原:有怪攻击一下,无怪移动一下)
FindRoleMove();
break;
case KillMonsterStates.FindMonster:
- //找怪
+ //找怪
this.stateMonsters = DnfCVHelper.FindMonster(hsvImage, map.GameRect);
-
if (this.stateMonsters.Length > 0)
{
G.Instance.DebugWriter(string.Format("找到{0}个怪", this.stateMonsters.Length));
@@ -228,13 +241,16 @@
}
else
{
+ if (this.role.IsMoveIntent(MoveIntent.AttackMove))
+ {
+ this.role.StopMove("find monster to pickup thing");
+ }
SetState(KillMonsterStates.PickupThing, false);
}
break;
case KillMonsterStates.PickupThing:
//拾取物品
- //todo: PickupThing();
- SetState(KillMonsterStates.FindDoor, false);
+ PickupThing();
break;
case KillMonsterStates.FindDoor:
//查找门
@@ -249,39 +265,9 @@
//向门移动, 进门
EntryDoor();
break;
- case KillMonsterStates.InNextGatePoint:
- //是否在进门点
- ParametersPoint nextGatePoint = ParametersPoint.Empty;
- ZTPoint rmhp=this.house.ScreenToMapCoordinate(this.role.HalfPosition, this.stateScreenLocation);
- if (this.house.IsInNextGatePoint(out nextGatePoint,rmhp))
- {
- SetState(KillMonsterStates.ToLoopPoint, false);
- }
- else
- {
- //不在进门点
- SetState(KillMonsterStates.ToNextGatePoint, false);
- }
- break;
- case KillMonsterStates.ToNextGatePoint:
- //移到进门点
- ZTPoint rmp = this.house.ScreenToMapCoordinate(this.role.Position, this.stateScreenLocation);
- ZTPoint ngp = DnfRole.HalfToFootPosition(this.house.HousePathInfo.NextGates[nextGate].Point);
- this.role.MoveToMapPoint(rmp, ngp);
- nextGate++;
- nextGate = nextGate % this.house.HousePathInfo.NextGates.Count;
- SetState(KillMonsterStates.IsLastHouse, true);
- break;
- case KillMonsterStates.ToLoopPoint:
- //移动到循环点
- if (!this.house.HousePathInfo.LoopPoint.Equals(ZTPoint.Empty))
- {
- //开始移动
- ZTPoint roleMapPoint = this.house.ScreenToMapCoordinate(this.role.Position, this.stateScreenLocation);
- this.role.MoveToMapPoint(roleMapPoint, this.house.HousePathInfo.LoopPoint);
-
- }
- SetState(KillMonsterStates.IsLastHouse, true);
+ case KillMonsterStates.ToLoop:
+ //巡逻
+ ToLoop();
break;
case KillMonsterStates.CalcAttackPoint:
//判断使用何技能,计算攻击移动距离, 是否需要移动
@@ -292,13 +278,12 @@
ReleaseSkill();
break;
case KillMonsterStates.AttackMove:
- //todo:攻击移动
+ //攻击移动
AttackMove();
break;
case KillMonsterStates.Exit:
//结束
- G.Instance.DebugWriter("退出!~");
- this.role.StopMove();
+ this.role.StopMove("exit");
if (this.isSuccess)
{
return ZTResult.Success;
@@ -306,7 +291,7 @@
return ZTResult.Failed;
}
- G.Instance.DebugWriter("next state:" + currentState.ToString());
+ G.Instance.DebugWriter($"next state:{currentState},capture screen:{needCaptureScreen}");
}
}
@@ -316,32 +301,69 @@
/// </summary>
private void FindRoleMove()
{
+ if (this.role.IsMoving)
+ {
+ if (this.role.IsMoveIntent(MoveIntent.FindRoleMove))
+ {
+ //进行中,则返回
+ SetState(KillMonsterStates.IsLastHouse, true);
+ return;
+ }
+ else
+ {
+ //不是则停止
+ this.role.StopMove("find role other");
+ }
+ }
this.role.FindRoleMove();
- SetState(KillMonsterStates.FindRole, true);
+ SetState(KillMonsterStates.IsLastHouse, true);
}
+
+ DateTime pickupTime = DateTime.MinValue;
/// <summary>
/// 拾取物品
/// </summary>
private void PickupThing()
{
- ////拾取物品,获取最近一个物品位置并步行过去
- //ZTPoint thingItemPosition = GetNearlyThingItem(image, role.Position);
- //if (!thingItemPosition .Equals( ZTPoint.Empty))
- //{
- // if (this.role.IsMoving && !this.role.IsMoveIntent(Utility.Dnf.MoveIntent.PickupMove))
- // {
- // this.role.StopMove();
- // }
+ //拾取物品中,返回
+ if (this.role.IsMoveIntent(MoveIntent.PickupMove))
+ {
+ SetState(KillMonsterStates.IsLastHouse, true);
+ return;
+ }
- // this.role.PickupMove(this.role.Position, thingItemPosition);
- // //return new KillMonsterStateResult(STATE_FindMonster, true);
- //}
+ ZTPoint screenThingPosition = GetNearlyThingItem(hsvImage, role.Position);
+ //是否有物品
+ if (!screenThingPosition.Equals(ZTPoint.Empty))
+ {
+ //有其它移动,则停止
+ if (this.role.IsMoving&&!this.role.IsMoveIntent(MoveIntent.PickupMove))
+ {
+ this.role.StopMove("pickup moveing");
+ }
- //if (this.role.IsMoveIntent(Utility.Dnf.MoveIntent.PickupMove))
- //{
- // this.role.StopMove();
- //}
+ //第一次发现有物品后,等一秒再去拾取,防物品刚出来时的去错误的位置拾取
+ if (pickupTime == DateTime.MinValue)
+ {
+ pickupTime = DateTime.Now.AddSeconds(1);
+ }
+
+ if (pickupTime > DateTime.Now)
+ {
+ SetState(KillMonsterStates.IsLastHouse, true);
+ return;
+ }
+ ////todo:remove
+ //hsvImage.Save(DateTime.Now.ToString("HH_mm_ss_fff")+"_" + Guid.NewGuid().ToString()+".png");
+
+ this.role.PickupMove(screenThingPosition,this.stateScreenLocation);
+ SetState(KillMonsterStates.IsLastHouse, true);
+ }
+ else
+ {
+ SetState(KillMonsterStates.FindDoor, false);
+ }
}
/// <summary>
@@ -363,20 +385,15 @@
//要进入门的允许区域
ZTPoint nextGatePoint = this.house.GetNextGatePoint(door.Value);
ZTRectangle doorRect = new ZTRectangle(nextGatePoint.X - 70, nextGatePoint.Y - 70, nextGatePoint.X + 70, nextGatePoint.Y + 70);
-
- G.Instance.InfoWriter("has door:" + mapDoorPoint.ToString()+",rect:"+doorRect.ToString());
-
+
if (GeoHelper.IsInRect(mapDoorPoint, doorRect))
{
- G.Instance.InfoWriter("in door");
this.state_DoorDirect = door.Value;
this.state_DoorPosition = door.Key;
break;
}
}
}
-
-
if (!this.state_DoorPosition.Equals(ZTPoint.Empty))
{
@@ -385,8 +402,8 @@
}
else
{
- //未找到门,是否存进门点
- SetState(KillMonsterStates.InNextGatePoint, false);
+ //未找到门,巡逻
+ SetState(KillMonsterStates.ToLoop, false);
}
}
@@ -395,12 +412,19 @@
/// </summary>
private void EntryDoor()
{
+ //已经开始进门
+ if (this.role.IsMoving)
+ {
+ this.role.StopMove("entry door other moving");
+ }
+
const Int32 offsetX = 200;
const Int32 offsetY = 100;
ZTRectangle doorRect = new ZTRectangle(this.state_DoorPosition.X - offsetX, this.state_DoorPosition.Y - offsetY, this.state_DoorPosition.X + offsetX, this.state_DoorPosition.Y + offsetY);
- if (tryEntryDoor && GeoHelper.IsInRect(this.role.RoleCBPosition, doorRect))
+ if (tryEntryDoor && GeoHelper.IsInRect(this.role.RoleCBPosition.Sub(DnfRole.RoleHalfOffset), doorRect))
{
//离门太近,先向外走,再向门走
+
Int32 limitLine = 0;
Int32 diff = 0;
//传过来人物坐标和门的坐标,根据门的朝向计算人物走向
@@ -460,32 +484,7 @@
}
else
{
- //先到进门点
- ZTPoint roleMapPoint = this.house.ScreenToMapCoordinate(this.role.Position, this.stateScreenLocation);
- ZTPoint nextGatePoint = this.house.GetNextGatePoint(this.state_DoorDirect);
- List<ZTPoint> paths = this.house.FindPath(roleMapPoint, DnfRole.HalfToFootPosition(nextGatePoint));
-
- //再到门后50像素
- ZTPoint dp = this.house.ScreenToMapCoordinate(this.state_DoorPosition, this.stateScreenLocation);
- ZTPoint doorPoint = DnfRole.HalfToFootPosition(dp);
- switch (this.state_DoorDirect)
- {
- case Direction.Up:
- doorPoint = doorPoint.Add(0, -50);
- break;
- case Direction.Right:
- doorPoint = doorPoint.Add(50, 0);
- break;
- case Direction.Bottom:
- doorPoint = doorPoint.Add(0, 50);
- break;
- case Direction.Left:
- doorPoint = doorPoint.Add(-50, 0);
- break;
- }
- paths.Add(doorPoint);
- this.role.MovePaths(roleMapPoint, paths);
-
+ this.role.EntryDoorMove(this.state_DoorPosition, this.stateScreenLocation, this.state_DoorDirect);
tryEntryDoor = true;
}
@@ -505,6 +504,10 @@
skillReleasePoint = AttackRectangle.GetAttackPoint(map.GameRect, role.HalfPosition, stateMonsters, attackSkill, out roleDirection, out needMove);
if (!needMove)
{
+ if (this.role.IsMoving)
+ {
+ this.role.StopMove("calc attack");
+ }
G.Instance.DebugWriter(string.Format("不需移动直接发技能,距离:{0}", skillReleasePoint.ToString()));
SetState(KillMonsterStates.ReleaseSkill, false);
}
@@ -519,8 +522,24 @@
/// </summary>
private void AttackMove()
{
+ if (this.role.IsMoving)
+ {
+ if (this.role.IsMoveIntent(MoveIntent.AttackMove))
+ {
+ //todo:添加如果是攻击移动中,如果怪物偏差太大则重新计算
+ //进行中,则返回
+ SetState(KillMonsterStates.IsLastHouse, true);
+ return;
+ }
+ else
+ {
+ //不是则停止
+ this.role.StopMove("attack move other");
+ }
+ }
+
G.Instance.DebugWriter("attack move :" + skillReleasePoint.ToString() + ",role:" + role.Position.ToString() + ",monster1:" + stateMonsters[0].ToString() + ",skill:" + this.house.Skills.SyncPeek().Key.ToString());
- this.role.AttackMoveTo(skillReleasePoint,this.stateScreenLocation);
+ this.role.AttackMove(skillReleasePoint, this.stateScreenLocation);
SetState(KillMonsterStates.FindRole, true);
}
@@ -529,9 +548,8 @@
/// </summary>
private void ReleaseSkill()
{
- this.role.StopMove();
-
SkillInfo skill = this.house.Skills.SyncDeQueue();
+ StateProvider.Instance.AttackKey = skill.Key;
if (roleDirection != HIDCode.NoEvent)
{
G.Instance.InputControl.PressKey(100, roleDirection);
@@ -553,6 +571,31 @@
G.Instance.DebugWriter(string.Format("发完技能,技能按键:{0},技能名称:{1}", skill.Key, skill.SkillName));
SetState(KillMonsterStates.IsLastHouse, true);
}
+
+ /// <summary>
+ /// 巡逻
+ /// </summary>
+ private void ToLoop()
+ {
+ //巡逻
+ if (this.role.IsMoving)
+ {
+ if (this.role.IsMoveIntent(MoveIntent.ToLoop))
+ {
+ //进行中,则返回
+ SetState(KillMonsterStates.IsLastHouse, true);
+ return;
+ }
+ else
+ {
+ //不是则停止
+ this.role.StopMove("to loop other");
+ }
+ }
+
+ this.role.LoopMove(this.stateScreenLocation);
+ SetState(KillMonsterStates.IsLastHouse, true);
+ }
#endregion
/// <summary>
@@ -560,22 +603,22 @@
/// </summary>
/// <param name="image"></param>
/// <returns></returns>
- public ZTPoint GetNearlyThingItem(Image<Rgb, byte> image, ZTPoint rolePosition)
+ public ZTPoint GetNearlyThingItem(Image<Hsv, byte> image, ZTPoint rolePosition)
{
- List<ZTPoint> points = DnfCVHelper.GetThingItemPoints(image, map.GameRect);
- if (points.Count <= 0)
+ ZTPoint[] points = DnfCVHelper.FindThings(image, map.GameRect);
+ if (points.Length <= 0)
{
return ZTPoint.Empty;
}
- if (points.Count == 1)
+ if (points.Length == 1)
{
return points[0];
}
double distance = 0;
ZTPoint result = ZTPoint.Empty;
- for (int i = 0; i < points.Count; i++)
+ for (int i = 0; i < points.Length; i++)
{
double temp = ZTImage.Utils.GetDistance(rolePosition.X, rolePosition.Y, points[i].X, points[i].Y);
if (i == 0)
@@ -672,9 +715,7 @@
PickupThing,//拾取物品
FindDoor,//查找门, 是否找到门
EntryDoor,//向门移动, 进门
- InNextGatePoint,//是否在进门点
- ToNextGatePoint,//移至进门点
- ToLoopPoint,//移至巡逻点
+ ToLoop,//巡逻
--
Gitblit v1.9.3