| | |
| | | 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.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; |
| | | using RichCreator.Utility.Structs; |
| | | using Emgu.CV; |
| | | using Emgu.CV.Structure; |
| | | using RichCreator.Maps; |
| | | using RichCreator.Maps.Lindong; |
| | | using RichCreator.StateMachines; |
| | | using RichCreator.Utility.Utilitys; |
| | | 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 |
| | | { |
| | | /// <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 |
| | | public class KillMonsterStateMachine : StateMachineBase |
| | | { |
| | | private const Int32 NoMoveMaxMillSecond = 2000;//最大未移动容忍毫秒数 |
| | | private StateAction[] states;//状态动作列表 |
| | | private MapHouse house;//当前房间 |
| | | private ZTPoint miniMapStart;//小地图区域 |
| | | private ZTRectangle gameRect;//游戏区域 |
| | | private Int32 preHouseIndex = 0;//上一房间编号 |
| | | private MoveState moveState;//移动状态 |
| | | private OutOfBounds outOfBounds;//是否在禁区 |
| | | private bool exitResult;//退出结果 |
| | | |
| | | private MapInfo map;//地图 |
| | | private HouseInfo house;//当前房间 |
| | | private DnfRole role;//当前角色控制 |
| | | private bool isSuccess;//退出结果 |
| | | |
| | | private ZTPoint roleLastPosition=ZTPoint.Empty;//角色最后位置 |
| | | private Int32 runningStep = RunningStep.None;//是否恢复的状态 |
| | | |
| | | |
| | | private KillMonsterStates currentState = KillMonsterStates.Start;//当前状态 |
| | | private bool needCaptureScreen = false;//是否截图屏幕 |
| | | private ZTPoint[] stateMonsters;//怪 |
| | | |
| | | private Image<Rgb, byte> image = null;//原图 |
| | | private Image<Hsv, byte> hsvImage = null;//色彩hsv |
| | | |
| | | private ZTPoint state_DoorPosition;//门坐标 |
| | | private Direction state_DoorDirect = Direction.None;//门朝向 |
| | | private ParametersPoint stateScreenLocation = new ParametersPoint();//屏幕定位点 |
| | | |
| | | private ZTPoint skillReleasePoint = ZTPoint.Empty; |
| | | private HIDCode roleDirection = HIDCode.NoEvent; |
| | | private bool tryEntryDoor = false;//是否尝试进门 |
| | | |
| | | |
| | | #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 ZTPoint[] stateMonsters; |
| | | |
| | | |
| | | #endregion |
| | | |
| | | |
| | | public KillMonsterStateMachine(MapHouse house, ZTPoint miniMapStart, ZTRectangle gameRect,Int32 preHouseIndex,Int32 runningStep) |
| | | public KillMonsterStateMachine(MapInfo map,HouseInfo house, DnfRole role) |
| | | { |
| | | this.runningStep = runningStep; |
| | | this.house = house; |
| | | this.miniMapStart = miniMapStart; |
| | | this.gameRect = gameRect; |
| | | this.preHouseIndex = preHouseIndex; |
| | | moveState = new MoveState(this.gameRect, this.house); |
| | | outOfBounds = new OutOfBounds(this.gameRect,moveState); |
| | | if (house.HousePathInfo.LoopPoint.Equals(ZTPoint.Empty)) |
| | | { |
| | | throw new ArgumentOutOfRangeException("寻路中不存在循环点"); |
| | | } |
| | | |
| | | InitStates(); |
| | | this.map = map; |
| | | this.house = house; |
| | | this.role = role; |
| | | |
| | | |
| | | hsvImage = new Image<Hsv, byte>(map.GameRect.End.X - map.GameRect.Start.X + 1, map.GameRect.End.Y - map.GameRect.Start.Y + 1); |
| | | } |
| | | |
| | | private void SetState(KillMonsterStates current, bool capture) |
| | | { |
| | | currentState = current; |
| | | needCaptureScreen = capture; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 状态机开始 |
| | | /// </summary> |
| | |
| | | /// <param name="cancellationToken"></param> |
| | | /// <param name="timeoutMillSecond"></param> |
| | | /// <returns></returns> |
| | | public Int32 Start(CancellationToken cancellationToken, Int32 timeoutMillSecond) |
| | | public ZTResult Work(Int32 timeoutMillSecond,Int32 fromHouseIndex,Int32 runningStep) |
| | | { |
| | | bool imageIsChange = false;//图像是否改变 |
| | | DateTime expireTime = DateTime.Now.AddMilliseconds(timeoutMillSecond); |
| | | KillMonsterStateResult result = new KillMonsterStateResult(STATE_Start, false); |
| | | if (this.runningStep > RunningStep.None) |
| | | { |
| | | result = new KillMonsterStateResult(STATE_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) |
| | | if (map.CancelToken.IsCancellationRequested) |
| | | { |
| | | G.Instance.DebugWriter("取消刷图"); |
| | | this.moveState.StopMove(); |
| | | return JobResult.Cancel; |
| | | this.role.StopMove("cancel"); |
| | | return ZTResult.Cancel; |
| | | } |
| | | |
| | | if (DateTime.Now > expireTime) |
| | | { |
| | | G.Instance.DebugWriter("刷图超时"); |
| | | this.moveState.StopMove(); |
| | | return JobResult.Timeout; |
| | | } |
| | | if (result.NextState == STATE_Exit) |
| | | { |
| | | G.Instance.DebugWriter("退出状态"); |
| | | this.moveState.StopMove(); |
| | | if (this.exitResult) |
| | | { |
| | | return JobResult.Success; |
| | | } |
| | | return JobResult.Failed; |
| | | |
| | | this.role.StopMove("timeout"); |
| | | return ZTResult.Timeout; |
| | | } |
| | | |
| | | bool refreshScreen = result.RefreshScreen; |
| | | if (refreshScreen) |
| | | if (needCaptureScreen) |
| | | { |
| | | using (bitmap = ScreenCapture.Instance.CaptureScreen()) |
| | | using (System.Drawing.Bitmap 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)) |
| | | image.Dispose(); |
| | | } |
| | | image = new Image<Rgb, byte>(bitmap); |
| | | 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; |
| | | } |
| | | } |
| | | |
| | | switch (currentState) |
| | | { |
| | | case KillMonsterStates.Start: |
| | | //开始 |
| | | if (this.house.FromHouseIndex == fromHouseIndex) |
| | | { |
| | | this.map.EntryHousePrework(this.house.Index, fromHouseIndex); |
| | | } |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | break; |
| | | case KillMonsterStates.IsLastHouse: |
| | | //是否最后一个房间 |
| | | if (!imageIsChange) |
| | | { |
| | | //图片没变,不用判断 |
| | | SetState(KillMonsterStates.FindRole, false); |
| | | break; |
| | | } |
| | | if (this.house.IsEnd) |
| | | { |
| | | SetState(KillMonsterStates.HasRewardWindow, false); |
| | | } |
| | | else |
| | | { |
| | | SetState(KillMonsterStates.IsOtherHouse, false); |
| | | } |
| | | break; |
| | | case KillMonsterStates.HasRewardWindow: |
| | | //是否有奖励界面 |
| | | if (DnfCVHelper.IsJiangli(image, map.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, map.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: |
| | | //主角 |
| | | //定位点 |
| | | if (this.house.WithoutNumber.Count <= 0) |
| | | { |
| | | this.stateScreenLocation = DnfCVHelper.GetLocationPoint(image, map.GameRect); |
| | | } |
| | | else |
| | | { |
| | | this.stateScreenLocation = DnfCVHelper.GetLocationPoint(image, map.GameRect,this.house.WithoutNumber); |
| | | } |
| | | |
| | | if (this.stateScreenLocation.Equals(ParametersPoint.Empty)) |
| | | { |
| | | //找不到定位点 |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | break; |
| | | } |
| | | |
| | | CvInvoke.CvtColor(image, hsvImage, Emgu.CV.CvEnum.ColorConversion.Rgb2Hsv); |
| | | |
| | | ZTPoint roleCBPosition = DnfCVHelper.FindRole(hsvImage, map.GameRect); |
| | | if (roleCBPosition.Equals(ZTPoint.Empty)) |
| | | { |
| | | //未找到角色 |
| | | if (!this.role.IsMoving) |
| | | { |
| | | return JobResult.Failed; |
| | | SetState(KillMonsterStates.FindRoleMove, false); |
| | | } |
| | | else |
| | | { |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | } |
| | | } |
| | | if (houseIndex != this.house.Index) |
| | | else |
| | | { |
| | | this.moveState.StopMove(); |
| | | return JobResult.Success; |
| | | if (this.role.IsMoveIntent(MoveIntent.FindRoleMove)) |
| | | { |
| | | this.role.StopMove("update cb position"); |
| | | } |
| | | role.UpdatePosition(roleCBPosition); |
| | | SetState(KillMonsterStates.FindMonster, false); |
| | | } |
| | | } |
| | | break; |
| | | case KillMonsterStates.FindRoleMove: |
| | | 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)); |
| | | SetState(KillMonsterStates.CalcAttackPoint, false); |
| | | } |
| | | else |
| | | { |
| | | if (this.role.IsMoveIntent(MoveIntent.AttackMove)) |
| | | { |
| | | this.role.StopMove("find monster to pickup thing"); |
| | | } |
| | | SetState(KillMonsterStates.PickupThing, false); |
| | | } |
| | | break; |
| | | case KillMonsterStates.PickupThing: |
| | | //拾取物品 |
| | | PickupThing(); |
| | | break; |
| | | case KillMonsterStates.FindDoor: |
| | | //查找门 |
| | | if (this.house.IsEnd) |
| | | { |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | break; |
| | | } |
| | | FindDoor(); |
| | | break; |
| | | case KillMonsterStates.EntryDoor: |
| | | //向门移动, 进门 |
| | | EntryDoor(); |
| | | break; |
| | | case KillMonsterStates.ToLoop: |
| | | //巡逻 |
| | | ToLoop(); |
| | | break; |
| | | case KillMonsterStates.CalcAttackPoint: |
| | | //判断使用何技能,计算攻击移动距离, 是否需要移动 |
| | | CalcAttackDistance(); |
| | | break; |
| | | case KillMonsterStates.ReleaseSkill: |
| | | //调整朝向, 释放技能, |
| | | ReleaseSkill(); |
| | | break; |
| | | case KillMonsterStates.AttackMove: |
| | | //攻击移动 |
| | | AttackMove(); |
| | | break; |
| | | case KillMonsterStates.Exit: |
| | | //结束 |
| | | this.role.StopMove("exit"); |
| | | 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},capture screen:{needCaptureScreen}"); |
| | | } |
| | | } |
| | | |
| | | #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; |
| | | } |
| | | |
| | | |
| | | 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) |
| | | //{ |
| | | // 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); |
| | | |
| | | //} |
| | | #endregion |
| | | //怪 |
| | | this.stateMonsters = LindongCVHelper.FindMonster(hsvImage,this.gameRect); |
| | | //主角 |
| | | this.stateRolePosition = DnfCVHelper.FindRole(hsvImage, this.gameRect); |
| | | //定位点 |
| | | DnfCVHelper.GetLocationPoint(out stateLocationRectangle, hsvImage, this.gameRect); |
| | | |
| | | if (this.stateMonsters.Length > 0) |
| | | if (this.role.IsMoving) |
| | | { |
| | | G.Instance.DebugWriter(string.Format("已找到{0}个怪", this.stateMonsters.Length)); |
| | | //未找到主角 |
| | | if (stateRolePosition == ZTPoint.Empty) |
| | | if (this.role.IsMoveIntent(MoveIntent.FindRoleMove)) |
| | | { |
| | | this.moveState.StopMove(); |
| | | G.Instance.DebugWriter("找不到角色,Send X"); |
| | | G.Instance.InputControl.PressKey(1000, HIDCode.X); |
| | | return new KillMonsterStateResult(STATE_FindMonster, true); |
| | | //进行中,则返回 |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | return; |
| | | } |
| | | else |
| | | { |
| | | //不是则停止 |
| | | this.role.StopMove("find role other"); |
| | | } |
| | | } |
| | | this.role.FindRoleMove(); |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | } |
| | | |
| | | |
| | | DateTime pickupTime = DateTime.MinValue; |
| | | /// <summary> |
| | | /// 拾取物品 |
| | | /// </summary> |
| | | private void PickupThing() |
| | | { |
| | | //拾取物品中,返回 |
| | | if (this.role.IsMoveIntent(MoveIntent.PickupMove)) |
| | | { |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | return; |
| | | } |
| | | |
| | | 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"); |
| | | } |
| | | |
| | | return new KillMonsterStateResult(STATE_PrepareReleaseSkill, false); |
| | | //第一次发现有物品后,等一秒再去拾取,防物品刚出来时的去错误的位置拾取 |
| | | 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 |
| | | { |
| | | //未查找到主角 |
| | | |
| | | |
| | | 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.FindDoor, false); |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | private DateTime FindRoleLastNoMoveTime = DateTime.MaxValue;//最后没移动时间 |
| | | private bool FindRoleLastNoMoveStart = false;//没移动是否开始计时 |
| | | /// <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 FindDoor() |
| | | { |
| | | if (this.moveState.IsMoving&&!this.moveState.IsAttackMoving) |
| | | //查找真实的门 |
| | | Dictionary<ZTPoint,Direction> doors=ShikongzhimenCVHelper.FindDoor(hsvImage, this.house.DoorDirection, map.GameRect); |
| | | this.state_DoorDirect = Direction.None; |
| | | this.state_DoorPosition = ZTPoint.Empty; |
| | | if (doors.Count > 0) |
| | | { |
| | | this.moveState.StopMove(); |
| | | } |
| | | SkillInfo skill = this.house.Skills.SyncPeek(); |
| | | |
| | | foreach (var door in doors) |
| | | { |
| | | //门地图坐标 |
| | | ZTPoint mapDoorPoint = this.house.ScreenToMapCoordinate(door.Key, this.stateScreenLocation); |
| | | |
| | | //要进入门的允许区域 |
| | | ZTPoint nextGatePoint = this.house.GetNextGatePoint(door.Value); |
| | | ZTRectangle doorRect = new ZTRectangle(nextGatePoint.X - 70, nextGatePoint.Y - 70, nextGatePoint.X + 70, nextGatePoint.Y + 70); |
| | | |
| | | if (GeoHelper.IsInRect(mapDoorPoint, doorRect)) |
| | | { |
| | | this.state_DoorDirect = door.Value; |
| | | this.state_DoorPosition = door.Key; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!this.state_DoorPosition.Equals(ZTPoint.Empty)) |
| | | { |
| | | //找到门,向门移动 |
| | | SetState(KillMonsterStates.EntryDoor, false); |
| | | } |
| | | else |
| | | { |
| | | //未找到门,巡逻 |
| | | SetState(KillMonsterStates.ToLoop, false); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 向门移动, 进门 |
| | | /// </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.Sub(DnfRole.RoleHalfOffset), doorRect)) |
| | | { |
| | | //离门太近,先向外走,再向门走 |
| | | |
| | | Int32 limitLine = 0; |
| | | Int32 diff = 0; |
| | | //传过来人物坐标和门的坐标,根据门的朝向计算人物走向 |
| | | switch (state_DoorDirect) |
| | | { |
| | | case Direction.Up: |
| | | //门在上方 |
| | | limitLine = state_DoorPosition.Y + offsetY; |
| | | //下移 |
| | | this.role.SyncMove(new ZTPoint(0, limitLine - role.Position.Y)); |
| | | //垂直对齐 |
| | | diff = state_DoorPosition.X - role.Position.X; |
| | | this.role.SyncMove(new ZTPoint(diff, 0)); |
| | | //移动y,进入 |
| | | this.role.SyncMove(new ZTPoint(0, map.GameRect.Start.Y - role.Position.Y)); |
| | | break; |
| | | |
| | | case Direction.Right: |
| | | //门在右侧 |
| | | limitLine = state_DoorPosition.X - offsetX; |
| | | //如果角色位于门右侧,先向左移 |
| | | this.role.SyncMove(new ZTPoint(limitLine - role.Position.X, 0)); |
| | | //水平对齐 |
| | | diff = state_DoorPosition.Y - role.Position.Y; |
| | | this.role.SyncMove(new ZTPoint(0, diff)); |
| | | //移动x,进入 |
| | | this.role.SyncMove(new ZTPoint(map.GameRect.End.X - role.Position.X, 0)); |
| | | break; |
| | | |
| | | case Direction.Bottom: |
| | | //门在下方 |
| | | limitLine = state_DoorPosition.Y - offsetY; |
| | | //如果角色在门下方,先向上移 |
| | | this.role.SyncMove(new ZTPoint(0, limitLine - role.Position.Y)); |
| | | //垂直对齐 |
| | | diff = state_DoorPosition.X - role.Position.X; |
| | | this.role.SyncMove(new ZTPoint(diff, 0)); |
| | | |
| | | //移动y,进入 |
| | | this.role.SyncMove(new ZTPoint(0, map.GameRect.End.Y - role.Position.Y)); |
| | | break; |
| | | |
| | | case Direction.Left: |
| | | //门在左侧 |
| | | limitLine = state_DoorPosition.X + offsetX; |
| | | //如果角色位于门左侧,先向右移 |
| | | this.role.SyncMove(new ZTPoint(limitLine - role.Position.X, 0)); |
| | | //水平对齐 |
| | | diff = state_DoorPosition.Y - role.Position.Y; |
| | | this.role.SyncMove(new ZTPoint(0, diff)); |
| | | |
| | | //移动x,进入 |
| | | this.role.SyncMove(new ZTPoint(map.GameRect.Start.X - role.Position.X, 0)); |
| | | break; |
| | | } |
| | | tryEntryDoor = false; |
| | | } |
| | | else |
| | | { |
| | | this.role.EntryDoorMove(this.state_DoorPosition, this.stateScreenLocation, this.state_DoorDirect); |
| | | tryEntryDoor = true; |
| | | } |
| | | |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | return; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 判断使用何技能,计算攻击移动距离, 是否需要移动 |
| | | /// </summary> |
| | | private void CalcAttackDistance() |
| | | { |
| | | 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); |
| | | skillReleasePoint = AttackRectangle.GetAttackPoint(map.GameRect, role.HalfPosition, stateMonsters, attackSkill, out roleDirection, out needMove); |
| | | if (!needMove) |
| | | { |
| | | this.roleLastPosition = ZTPoint.Empty; |
| | | //不需要移动 |
| | | if (dir != HIDCode.NoEvent) |
| | | if (this.role.IsMoving) |
| | | { |
| | | G.Instance.InputControl.PressKey(100, dir); |
| | | this.role.StopMove("calc attack"); |
| | | } |
| | | this.moveState.StopMove(); |
| | | G.Instance.DebugWriter(string.Format("不需移动直接发技能,距离:{0}", moveDistance.ToString())); |
| | | return new KillMonsterStateResult(STATE_ReleaseSkill, false); |
| | | } |
| | | |
| | | //没有移动,可能有障碍物 |
| | | if (stateRolePosition == this.roleLastPosition) |
| | | { |
| | | if (FindRoleLastNoMoveStart && (DateTime.Now - FindRoleLastNoMoveTime).TotalMilliseconds > NoMoveMaxMillSecond) |
| | | { |
| | | //开始计时 并且 超过最大未移动容忍时间 |
| | | G.Instance.DebugWriter("find role no mvoe:" + stateRolePosition.ToString()); |
| | | this.moveState.StopMove(); |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.X); |
| | | FindRoleLastNoMoveTime = DateTime.Now; |
| | | } |
| | | else if (!FindRoleLastNoMoveStart) |
| | | { |
| | | //没开始计时 则 开始计时 |
| | | FindRoleLastNoMoveStart = true; |
| | | FindRoleLastNoMoveTime = DateTime.Now; |
| | | } |
| | | G.Instance.DebugWriter(string.Format("不需移动直接发技能,距离:{0}", skillReleasePoint.ToString())); |
| | | SetState(KillMonsterStates.ReleaseSkill, false); |
| | | } |
| | | else |
| | | { |
| | | //移动了 取消计时 |
| | | this.roleLastPosition = stateRolePosition; |
| | | FindRoleLastNoMoveStart = false; |
| | | SetState(KillMonsterStates.AttackMove, 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) |
| | | 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.AttackMove(skillReleasePoint, this.stateScreenLocation); |
| | | SetState(KillMonsterStates.FindRole, true); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 调整朝向, 释放技能 |
| | | /// </summary> |
| | | private void ReleaseSkill() |
| | | { |
| | | SkillInfo skill = this.house.Skills.SyncDeQueue(); |
| | | StateProvider.Instance.AttackKey = skill.Key; |
| | | if (roleDirection != HIDCode.NoEvent) |
| | | { |
| | | G.Instance.InputControl.PressKey(100, roleDirection); |
| | | } |
| | | if (skill.Key == HIDCode.X) |
| | | { |
| | | for (int i = 0; i < 5; i++) |
| | |
| | | else |
| | | { |
| | | G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, skill.Key); |
| | | Thread.Sleep((Int32)skill.ReleaseTime); |
| | | Thread.Sleep((Int32)skill.ReleaseWaitTime); |
| | | } |
| | | |
| | | G.Instance.DebugWriter(string.Format("发完技能,技能按键:{0},技能名称:{1}", skill.Key, skill.SkillName)); |
| | | return new KillMonsterStateResult(STATE_FindMonster, true); |
| | | |
| | | G.Instance.DebugWriter(string.Format("发完技能,技能按键:{0},技能名称:{1}", skill.Key, skill.SkillName)); |
| | | SetState(KillMonsterStates.IsLastHouse, 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 |
| | | /// <summary> |
| | | /// 巡逻 |
| | | /// </summary> |
| | | private void ToLoop() |
| | | { |
| | | //巡逻 |
| | | if (this.role.IsMoving) |
| | | { |
| | | //未找到门,循环移动 |
| | | Int32 areaID = 0; |
| | | if (this.outOfBounds.InOutOfBound(this.house.Index, stateRolePosition, out areaID)) |
| | | if (this.role.IsMoveIntent(MoveIntent.ToLoop)) |
| | | { |
| | | this.outOfBounds.MoveToCommonBound(areaID); |
| | | //进行中,则返回 |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | return; |
| | | } |
| | | else |
| | | { |
| | | this.moveState.FindDoorMove(stateRolePosition); |
| | | //不是则停止 |
| | | this.role.StopMove("to loop other"); |
| | | } |
| | | } |
| | | |
| | | 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); |
| | | this.role.LoopMove(this.stateScreenLocation); |
| | | SetState(KillMonsterStates.IsLastHouse, true); |
| | | } |
| | | #endregion |
| | | |
| | |
| | | /// </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, this.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) |
| | |
| | | |
| | | 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> |
| | | private static readonly ZTPoint[] CardList = new ZTPoint[] { |
| | | new ZTPoint(364,231), |
| | | new ZTPoint(561,231), |
| | | new ZTPoint(744,231), |
| | | new ZTPoint(924,231), |
| | | new ZTPoint(164,195), |
| | | new ZTPoint(315,195), |
| | | new ZTPoint(474,195), |
| | | new ZTPoint(635,195), |
| | | |
| | | |
| | | new ZTPoint(364,570), |
| | | new ZTPoint(561,570), |
| | | new ZTPoint(744,570), |
| | | new ZTPoint(924,570), |
| | | new ZTPoint(164,480), |
| | | new ZTPoint(315,480), |
| | | new ZTPoint(474,480), |
| | | new ZTPoint(635,480), |
| | | |
| | | }; |
| | | |
| | | /// <summary> |
| | | /// 翻牌 |
| | | /// 1-4 |
| | |
| | | { |
| | | 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 = map.GameRect.Start.Add(CardList[number - 1]); |
| | | G.Instance.InputControl.MoveToAndClick(RandomUtils.PointRange(willPosition, 10)); |
| | | |
| | | //判断黄金版是否可以翻 |
| | | if (DnfCVHelper.HasMowangqiyueCard(this.gameRect)) |
| | | if (DnfCVHelper.HasGoldCard(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)); |
| | | } |
| | | |
| | | } |
| | | #endregion |
| | | |
| | | /// <summary> |
| | | /// 是否改变房间 |
| | | /// </summary> |
| | | /// <param name="cancellationToken"></param> |
| | | /// <returns></returns> |
| | | private bool HouseIsChange() |
| | | { |
| | | Int32 houseIndex = 0; |
| | | if (!map.MiniMap.GetCurrentHouseIndexWaitTimeout(out houseIndex, image, map.CancelToken, 30 * 1000)) |
| | | { |
| | | throw new Exception("找不到默认房间"); |
| | | } |
| | | if (houseIndex != this.house.Index) |
| | | { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 杀怪状态 |
| | | /// </summary> |
| | | public enum KillMonsterStates : Int32 |
| | | { |
| | | Start,//开始状态 |
| | | Exit,//完成状态 |
| | | IsLastHouse,//是否最后一个房间 |
| | | HasRewardWindow,//是否有奖励界面 |
| | | TurnAroundCard,//翻牌 |
| | | IsCompletePage,//是否刷完界面 |
| | | IsOtherHouse,//是否进入其它房间 |
| | | FindRole,//找主角 |
| | | FindRoleMove,//让主角移动(原:有怪攻击一下,无怪移动一下) |
| | | FindMonster,//找怪 |
| | | PickupThing,//拾取物品 |
| | | FindDoor,//查找门, 是否找到门 |
| | | EntryDoor,//向门移动, 进门 |
| | | ToLoop,//巡逻 |
| | | |
| | | |
| | | |
| | | CalcAttackPoint,//判断使用何技能,计算攻击移动距离, 是否需要移动 |
| | | ReleaseSkill,//调整朝向, 释放技能, |
| | | AttackMove,//攻击移动 |
| | | } |
| | | } |
| | | } |