using RichCreator.Utility; using RichCreator.Utility.Captures; using RichCreator.Utility.CV; using RichCreator.Utility.InputControl; using RichCreator.Utility.Structs; using RichCreator.Utility.Utilitys; using Emgu.CV; using Emgu.CV.Structure; using RichCreator.Jobs; using RichCreator.Jobs.StateMachines; using System; using System.Collections.Generic; using System.Threading; namespace RichCreator.Maps { /// /// 凛冬地图 /// public class LindongMap : MapInfo { /// /// 地图的所有房间 /// NextIndex=-1,完成 /// NextIndex=-2,出错 /// internal static MapHouse[] Houses = new MapHouse[] { new MapHouse (){ Index=0 ,NextIndex=1 , OpenStatusDetectIndex=1 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Right } }, new MapHouse (){ Index=1 ,NextIndex=5 , OpenStatusDetectIndex=5 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Bottom } }, new MapHouse (){ Index=2 ,NextIndex=1 , OpenStatusDetectIndex=1 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, new MapHouse (){ Index=3 ,NextIndex=2 , OpenStatusDetectIndex=2 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, new MapHouse (){ Index=4 ,NextIndex=8 , OpenStatusDetectIndex=8 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Bottom } }, new MapHouse (){ Index=5 ,NextIndex=4 , OpenStatusDetectIndex=4 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, new MapHouse (){ Index=6 ,NextIndex=5 , OpenStatusDetectIndex=5 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, new MapHouse (){ Index=7 ,NextIndex=6 , OpenStatusDetectIndex=6 , HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, new MapHouse (){ Index=8 ,NextIndex=12 ,OpenStatusDetectIndex=12, HouseCenterMoveLine=-148,IsEnd=false,DoorDirection=new[]{Direction.Right,Direction.Bottom } }, new MapHouse (){ Index=9 ,NextIndex=10, OpenStatusDetectIndex=10, HouseCenterMoveLine=-300,IsEnd=false,DoorDirection=new[]{Direction.Right,Direction.Bottom } }, new MapHouse (){ Index=10,NextIndex=14, OpenStatusDetectIndex=14, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Bottom } }, new MapHouse (){ Index=11,NextIndex=10, OpenStatusDetectIndex=10, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Left } }, new MapHouse (){ Index=12,NextIndex=13, OpenStatusDetectIndex=12, HouseCenterMoveLine=-220,IsEnd=false,DoorDirection=new[]{Direction.Right } }, new MapHouse (){ Index=13,NextIndex=14, OpenStatusDetectIndex=14, HouseCenterMoveLine=-320,IsEnd=false,DoorDirection=new[]{Direction.Right } }, new MapHouse (){ Index=14,NextIndex=15, OpenStatusDetectIndex=-1, HouseCenterMoveLine=-320,IsEnd=false,DoorDirection=new[]{Direction.Right } }, new MapHouse (){ Index=15,NextIndex=-1, OpenStatusDetectIndex=-1, HouseCenterMoveLine=-250,IsEnd=true, DoorDirection=new[]{Direction.Right } }, new MapHouse (){ Index=16,NextIndex=12, OpenStatusDetectIndex=12, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } }, new MapHouse (){ Index=17,NextIndex=13, OpenStatusDetectIndex=13, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } }, new MapHouse (){ Index=18,NextIndex=14, OpenStatusDetectIndex=14, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } }, new MapHouse (){ Index=19,NextIndex=15, OpenStatusDetectIndex=15, HouseCenterMoveLine=-250,IsEnd=false,DoorDirection=new[]{Direction.Up } } }; static LindongMap() { //1 SkillQueue queue = new SkillQueue(); //queue.EnQueue(false, HIDCode.G); //queue.EnQueue(false, HIDCode.E); queue.EnQueue(false, HIDCode.A); queue.EnQueue(false, HIDCode.D); queue.EnQueue(false, HIDCode.X); Houses[2].Skills = queue; //2 queue = new SkillQueue(); //queue.EnQueue(false, HIDCode.W); //queue.EnQueue(false, HIDCode.E); queue.EnQueue(false, HIDCode.A); queue.EnQueue(false, HIDCode.D); queue.EnQueue(false, HIDCode.X); Houses[1].Skills = queue; //3 queue = new SkillQueue(); //queue.EnQueue(false, HIDCode.Q); //queue.EnQueue(false, HIDCode.T); //queue.EnQueue(false, HIDCode.E); queue.EnQueue(false, HIDCode.A); queue.EnQueue(false, HIDCode.D); queue.EnQueue(false, HIDCode.X); Houses[5].Skills = queue; //4 queue = new SkillQueue(); //queue.EnQueue(false, HIDCode.E); queue.EnQueue(false, HIDCode.A); queue.EnQueue(false, HIDCode.D); queue.EnQueue(false, HIDCode.X); Houses[4].Skills = queue; //5 queue = new SkillQueue(); //queue.EnQueue(false, HIDCode.W); //queue.EnQueue(false, HIDCode.E); queue.EnQueue(false, HIDCode.A); queue.EnQueue(false, HIDCode.D); queue.EnQueue(false, HIDCode.X); Houses[8].Skills = queue; //6 queue = new SkillQueue(); //queue.EnQueue(false, HIDCode.R); //queue.EnQueue(false, HIDCode.T); //queue.EnQueue(false, HIDCode.E); queue.EnQueue(false, HIDCode.A); queue.EnQueue(false, HIDCode.D); queue.EnQueue(false, HIDCode.X); Houses[9].Skills = queue; //7 queue = new SkillQueue(); //queue.EnQueue(false, HIDCode.Q); //queue.EnQueue(false, HIDCode.E); queue.EnQueue(false, HIDCode.A); queue.EnQueue(false, HIDCode.D); queue.EnQueue(false, HIDCode.X); Houses[10].Skills = queue; queue = new SkillQueue(); //queue.EnQueue(false, HIDCode.R); //queue.EnQueue(false, HIDCode.T); //queue.EnQueue(false, HIDCode.E); queue.EnQueue(false, HIDCode.A); queue.EnQueue(false, HIDCode.D); queue.EnQueue(false, HIDCode.X); Houses[12].Skills = queue; queue = new SkillQueue(); //queue.EnQueue(false, HIDCode.Q); //queue.EnQueue(false, HIDCode.E); queue.EnQueue(false, HIDCode.A); queue.EnQueue(false, HIDCode.D); queue.EnQueue(false, HIDCode.X); Houses[13].Skills = queue; //8 queue = new SkillQueue(); //queue.EnQueue(false, HIDCode.W); //queue.EnQueue(false, HIDCode.E); queue.EnQueue(false, HIDCode.A); queue.EnQueue(false, HIDCode.D); queue.EnQueue(false, HIDCode.X); Houses[14].Skills = queue; //9 queue = new SkillQueue(); //queue.EnQueue(false, HIDCode.H); //queue.EnQueue(false, HIDCode.Y); //queue.EnQueue(false, HIDCode.T); //queue.EnQueue(false, HIDCode.R); //queue.EnQueue(false, HIDCode.F); //queue.EnQueue(false, HIDCode.E); queue.EnQueue(false, HIDCode.A); queue.EnQueue(false, HIDCode.D); queue.EnQueue(false, HIDCode.X); Houses[15].Skills = queue; //10 queue = new SkillQueue(); //queue.EnQueue(false, HIDCode.W); //queue.EnQueue(false, HIDCode.E); queue.EnQueue(false, HIDCode.A); queue.EnQueue(false, HIDCode.D); queue.EnQueue(false, HIDCode.X); Houses[18].Skills = queue; } /// /// 游戏区域 /// public ZTRectangle GameRect { get; set; } /// /// 小地图区域 /// public ZTPoint MinimapPoint = ZTPoint.Empty; //小地图距游戏区域的偏移 private ZTPoint minimapPointOffset = new ZTPoint(1201, 47); public CancellationToken cancellationToken { get; set; } private Int32 runningStep = RunningStep.None; public override ZTResult Start(ZTRectangle gameRect, CancellationToken cancelToken,Int32 runningStep) { this.runningStep = runningStep; this.GameRect = gameRect; this.cancellationToken = cancelToken; this.MinimapPoint = gameRect.Start.Add(minimapPointOffset); WindowUtils.SetDnfToTop(); if (runningStep < RunningStep.War) { if (!MoveToSunan()) { return ZTResult.Failed; } if (!MoveToShikongzhimen()) { return ZTResult.Failed; } if (!MoveToChoiceTaskPage()) { return ZTResult.Failed; } if (!IntoTaskRoom()) { return ZTResult.Failed; } G.Instance.InfoWriter("成功进入副本"); } while (true) { //重复刷,直到疲劳值不够了 if (this.cancellationToken.IsCancellationRequested) { return ZTResult.Cancel; } DateTime startHouse = DateTime.Now; ZTResult killResult = KillMonster(); if (killResult==ZTResult.Success) { //捡东西 G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.V); Thread.Sleep(1000); for (int i = 0; i < 5; i++) { G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.X); Thread.Sleep(RandomUtils.KeyPressDuration * 3); } //卖装备并关闭商店 SaleEquipment( this.cancellationToken); Int32 houseTotalSecond = (Int32)(DateTime.Now - startHouse).TotalSeconds; //查询疲劳值 G.Instance.InfoWriter("单次刷图成功,用时:"+(houseTotalSecond/60)+"分"+(houseTotalSecond%60)+"秒"); Int32 pilaozhi =DnfCVHelper.GetPiLaoZhi(this.GameRect); G.Instance.InfoWriter("疲劳值:" + pilaozhi); if (pilaozhi <= 0) { ExitToTown(); return ZTResult.Success; } ReplayGame(); continue; } else { return killResult; } } } /// /// esc退到城镇 /// private void ExitToTown() { G.Instance.DebugWriter("返回城镇"); ZTPoint point = new ZTPoint(this.GameRect.End.X - 124, this.GameRect.Start.Y + 146); G.Instance.InputControl.MoveToAndClick(point); Thread.Sleep(5000); } /// /// 点击再次挑战 /// private void ReplayGame() { G.Instance.DebugWriter("重新挑战"); ZTPoint point = new ZTPoint(this.GameRect.End.X - 132, this.GameRect.Start.Y + 90); G.Instance.InputControl.MoveToAndClick(point); } /// /// 刷房间 /// /// private ZTResult KillMonster() { bool ret = false; //查找顶端凛冬文字 bool findResult = FuncUtils.TimeoutCancelableWrap(2 * 60 * 1000, cancellationToken, () => { using (Image image = ScreenCapture.Instance.CaptureScreenReturnImage()) { return LindongCVHelper.ExistLingdongText(image, this.GameRect); } }, 10); if (!findResult) { G.Instance.InfoWriter("未找到进入凛冬的文字"); return ZTResult.Failed; } G.Instance.InfoWriter("进入凛冬"); Int32 preHouseIndex = -1; Int32 houseIndex = -1; //技能加成 G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.Space); //循环刷房间 while (true) { preHouseIndex = houseIndex; //看房间号 ret=FuncUtils.TimeoutCancelableWrap(3 * 1000, this.cancellationToken, () => { Image image = ScreenCapture.Instance.CaptureScreenReturnImage(); return LindongCVHelper.GetCurrentHouseIndex(out houseIndex, image, this.MinimapPoint); }, 1); if (!ret) { G.Instance.InfoWriter("未找到人物所在房间"); return ZTResult.Failed; } G.Instance.InfoWriter("进入房间->" + houseIndex.ToString()); DateTime roomStartTime = DateTime.Now; KillMonsterStateMachine kmsm = new KillMonsterStateMachine(Houses[houseIndex], this.MinimapPoint, this.GameRect, preHouseIndex,this.runningStep); ZTResult smresult = kmsm.Work(cancellationToken, 5 * 60 * 1000); Int32 roomTotalSecond = (Int32)(DateTime.Now - roomStartTime).TotalSeconds; G.Instance.InfoWriter("房间刷完,用时:" + (roomTotalSecond / 60) + "分" + (roomTotalSecond % 60) + "秒"); runningStep = RunningStep.None; if (smresult == ZTResult.Success) { if (houseIndex == 15) { //所有房间刷完 return ZTResult.Success; } //刷其它房间 continue; } else { return smresult; } } } /// /// 步行到素喃 /// /// private bool MoveToSunan() { bool result = FuncUtils.NoChangeRetryCallWrap( () => { CloseAllAlertWindow(this.cancellationToken, this.GameRect); //向下走出赛丽亚的房间 ,走向素喃 G.Instance.InputControl.PressKey(2000, HIDCode.DownArrow); }, () => { G.Instance.InfoWriter("检测是否进入素喃"); result = FuncUtils.TimeoutCancelableWrap(10000, this.cancellationToken, () => { return LindongCVHelper.IsInSunan(this.GameRect); }); if (!result) { G.Instance.InfoWriter("进入素喃失败"); return false; } G.Instance.InfoWriter("进入素喃成功"); return true; }, () => { return DnfCVHelper.IsInSaiLiYaHouse(this.GameRect); }); return result; } /// /// 步行至时空之门 /// /// private bool MoveToShikongzhimen() { bool result=FuncUtils.NoChangeRetryCallWrap(() => { //打开地图 ZTPoint mapButtonPosition = new ZTPoint(this.GameRect.End.X - 14, this.GameRect.Start.Y + 16); G.Instance.InputControl.MoveToAndClick(mapButtonPosition); Thread.Sleep(1000); //点到副本之前的地图 ZTPoint mapPrePosition = new ZTPoint(this.GameRect.Start.X + 382, this.GameRect.Start.Y + 252); G.Instance.InputControl.MoveToAndClick(mapPrePosition); //关闭地图框 CloseAllAlertWindow(this.cancellationToken, this.GameRect); }, () => { //检测是否进入时空之门 return FuncUtils.TimeoutCancelableWrap(15000, this.cancellationToken, () => { CloseAllAlertWindow(this.cancellationToken, this.GameRect); return LindongCVHelper.IsInShikongzhimen(this.GameRect); }); }, () => { //检测是否还在素喃 return FuncUtils.TimeoutCancelableWrap(3000, this.cancellationToken, () => { CloseAllAlertWindow(this.cancellationToken, this.GameRect); return LindongCVHelper.IsInSunan(this.GameRect); }); }); Thread.Sleep(5000); return result; } /// /// 步行到任务选择和正式开打页面 /// /// private bool MoveToChoiceTaskPage() { bool result = false; //右走进选择副本界面 G.Instance.InputControl.PressKey(1500, HIDCode.LeftArrow); G.Instance.InfoWriter("检测是否打开选择副本界面"); result = FuncUtils.TimeoutCancelableWrap(10000, this.cancellationToken, () => { Image image = ScreenCapture.Instance.CaptureScreenReturnImage(); return LindongCVHelper.IsInChoiceTaskPage(image, this.GameRect); }); if (!result) { G.Instance.InfoWriter("进入打开选择副本界面失败"); return false; } G.Instance.InfoWriter("打开选择副本界面成功"); return true; } /// /// 进入指定房间 /// /// private bool IntoTaskRoom() { bool result = false; //选择凛冬 G.Instance.InfoWriter("开始选择凛冬"); Int32 nandu = 0; if (!SelectLindong(out nandu)) { G.Instance.InfoWriter("选择凛冬失败"); return false; } G.Instance.InfoWriter("选择凛冬成功,难度:"+nandu); if (nandu != 4) { G.Instance.InfoWriter("开始选择难度"); result=SelectNandu(nandu); if (!result) { G.Instance.InfoWriter("选择难度失败"); return false; } G.Instance.InfoWriter("选择难度成功"); } //开始 G.Instance.InputControl.PressKey(80, HIDCode.Space); return true; } /// /// 关闭所有弹出窗 /// /// /// /// private void CloseAllAlertWindow(CancellationToken cancelToken, ZTRectangle gameRect) { while (!cancelToken.IsCancellationRequested) { //G.Instance.InputControl.MoveTo(gameRect.Start.X,gameRect.Start.Y, false, false, false); //Thread.Sleep(10); //截图 Image image = ScreenCapture.Instance.CaptureScreenReturnImage(); ZTRectangle closeButtonRect = ZTRectangle.Empty; if (!DnfCVHelper.GetAlertWindow(out closeButtonRect, image, gameRect)) { return; } G.Instance.InputControl.MoveToAndClick(closeButtonRect.GetCenterPoint()); Thread.Sleep(500); } } /// /// 选择凛冬 /// /// private bool SelectLindong(out Int32 nandu) { Image image = ScreenCapture.Instance.CaptureScreenReturnImage(); if (LindongCVHelper.GetChoiceLingdongNandu(out nandu, image, this.GameRect)) { return true; } G.Instance.InputControl.MoveToAndClick(new ZTPoint(this.GameRect.Start.X + 508, this.GameRect.Start.Y + 552)); Thread.Sleep(5000); image = ScreenCapture.Instance.CaptureScreenReturnImage(); if (LindongCVHelper.GetChoiceLingdongNandu(out nandu, image, this.GameRect)) { return true; } return false; } /// /// 选择难度 /// /// /// /// private bool SelectNandu(Int32 nandu) { Int32 count = 4 - nandu; for (int i = 0; i < Math.Abs(count); i++) { if (count < 0) { G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.LeftArrow); } else { G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.RightArrow); } Thread.Sleep(400); } Image image = ScreenCapture.Instance.CaptureScreenReturnImage(); if (!LindongCVHelper.GetChoiceLingdongNandu(out nandu, image, this.GameRect)) { return false; } if (nandu == 4) { return true; } return false; } /// /// 出售装备 /// /// private bool SaleEquipment(CancellationToken cancelToken) { //卖装备并关闭商店 ZTRectangle closeButtonRect = ZTRectangle.Empty; ZTRectangle saleButtonRect = ZTRectangle.Empty; if (!DnfCVHelper.HasSaleButton(out saleButtonRect, out closeButtonRect, this.GameRect)) { return false; } //卖装备 G.Instance.InfoWriter("出售装备"); G.Instance.InputControl.MoveToAndClick(saleButtonRect.GetCenterPoint()); //得到装备文字位置 ZTRectangle equipmentTextRect = ZTRectangle.Empty; bool result = FuncUtils.TimeoutCancelableWrap(5000, cancelToken, () => { Int32 status = 0; if (DnfCVHelper.GetEquipmentSelectStatus(out equipmentTextRect, out status, this.GameRect)) { if (status == 1) { return true; } G.Instance.InputControl.MoveToAndClick(equipmentTextRect.GetCenterPoint()); } return false; }); if (!result) { //todo:remove G.Instance.InfoWriter("装备文字未取到"); return false; } //开始点,每格步进30 ZTPoint startPoint = new ZTPoint( equipmentTextRect.End.X-30,equipmentTextRect.End.Y+9); List points = DnfCVHelper.GetEquipmentIndexs(startPoint); for (int i = 0; i < points.Count; i++) { Int32 index = points[i]; int row = index / 8; int col = index % 8; int x = col * 30+15; int y = row * 30+15; //点窗格 G.Instance.InputControl.MoveToAndClick(new ZTPoint(startPoint.X+x,startPoint.Y+y)); Thread.Sleep(500); //点确定 G.Instance.InputControl.Move(0, 0, true, false, false); Thread.Sleep(RandomUtils.MouseClickDuration); G.Instance.InputControl.Move(0, 0, false, false, false); Thread.Sleep(RandomUtils.MouseClickDuration); } G.Instance.DebugWriter("equipment:" +ZTImage.Utils.ConcatString(points.ToArray(),",")); Thread.Sleep(RandomUtils.KeyPressDuration); G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.Escape); return true; } } }