using Emgu.CV; using Emgu.CV.Structure; using RichCreator.Dnf; using RichCreator.Jobs.StateMachines; using RichCreator.Utility; using RichCreator.Utility.Captures; using RichCreator.Utility.CV; using RichCreator.Utility.InputControl; using RichCreator.Utility.Maps; using RichCreator.Utility.Structs; using RichCreator.Utility.Utilitys; using System; using System.Collections.Generic; using System.Threading; namespace RichCreator.Maps.Kalete { /// /// 卡勒特地图 /// public class KaleteMap : MapInfo { public KaleteMap(ZTRectangle gameRect, CancellationToken cancelToken) : base(MapType.Lingdong, gameRect, cancelToken) { this.MiniMap = new KaleteMiniMap(gameRect); this.Role = new DnfRole(gameRect); } /// /// 地图的所有房间 /// NextIndex=-1,完成 /// NextIndex=-2,出错 /// private static readonly HouseInfo[] Houses = new HouseInfo[] { new HouseInfo (0 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Right } }, new HouseInfo (1 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Bottom } }, new HouseInfo (2 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Left } }, new HouseInfo (3 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Bottom } }, new HouseInfo (4 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Bottom } }, new HouseInfo (5 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Left } }, new HouseInfo (6 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Right } }, new HouseInfo (7 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Right } }, new HouseInfo (8 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-148,DoorDirection=new[]{Direction.Bottom } }, new HouseInfo (9 ,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-300,DoorDirection=new[]{Direction.Left} }, new HouseInfo (10,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Bottom } }, new HouseInfo (11,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Right } }, new HouseInfo (12,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-220,DoorDirection=new[]{Direction.Bottom } }, new HouseInfo (13,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-320,DoorDirection=new[]{Direction.Left } }, new HouseInfo (14,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-320,DoorDirection=new[]{Direction.Right } }, new HouseInfo (15,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Right } }, new HouseInfo (16,MapType.Lingdong,true ,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Up } }, new HouseInfo (17,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Left } }, new HouseInfo (18,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Up } }, new HouseInfo (19,MapType.Lingdong,false,new HIDCode[] { HIDCode.A,HIDCode.D,HIDCode.X}){ HouseCenterMoveLine=-250,DoorDirection=new[]{Direction.Up } } }; /// /// 角色 /// public DnfRole Role { get; set; } private Int32 runningStep = RunningStep.None; /// /// 开始 /// /// /// /// /// public override ZTResult Start(Int32 runningStep) { this.runningStep = runningStep; WindowUtils.SetDnfToTop(); if (runningStep < RunningStep.War) { if (!MoveToSunan()) { return ZTResult.Failed; } if (!MoveToShikongzhimen()) { return ZTResult.Failed; } if (!MoveToChoiceTaskPage()) { return ZTResult.Failed; } if (!IntoHouse()) { return ZTResult.Failed; } G.Instance.InfoWriter("成功进入副本"); } while (true) { //重复刷,直到疲劳值不够了 if (this.CancelToken.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(); 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; } } } /// /// 是否进入打怪地图 /// /// public override bool IsEntryMap() { //查找顶端卡勒特之初文字 bool findResult = FuncUtils.TimeoutCancelableWrap(2 * 60 * 1000, CancelToken, () => { using (Image image = ScreenCapture.Instance.CaptureScreenReturnImage()) { return KaleteCVHelper.ExistKaleteText(image, this.GameRect); } }, 10); return findResult; } /// /// 进入房间后的预先工作 /// /// /// public override void EntryHousePrework(int houseIndex, int preHouseIndex) { //移动和发招 switch (houseIndex) { case 0: this.Role.SyncMove(new ZTPoint(550, 0)); this.Role.ReleaseSkill(HIDCode.R, 1000); this.Role.ReleaseSkill(HIDCode.E, 1000); break; case 1: this.Role.SyncMove(new ZTPoint(300, 0)); this.Role.ReleaseSkill(HIDCode.Q, 1300); this.Role.ReleaseSkill(HIDCode.W, 1000); break; case 6: this.Role.SyncMove(new ZTPoint(448, 94)); this.Role.ReleaseSkill(HIDCode.G, 0); break; case 7: this.Role.SyncMove(new ZTPoint(530, 0)); this.Role.ReleaseSkill(HIDCode.R, 0); break; case 8: this.Role.SyncMove(new ZTPoint(453, 0)); this.Role.ReleaseSkill(HIDCode.H, 0); break; case 13: this.Role.SyncMove(new ZTPoint(-100, 203)); this.Role.ReleaseSkill(HIDCode.Q, 1300); this.Role.ReleaseSkill(HIDCode.E, 0); break; case 12: this.Role.SyncMove(new ZTPoint(-851, 120)); this.Role.ReleaseSkill(HIDCode.T, 0); break; case 17: this.Role.SyncMove(new ZTPoint(-306, 130)); this.Role.ReleaseSkill(HIDCode.Q, 1300); this.Role.ReleaseSkill(HIDCode.F, 0);//用w代替 break; case 16: this.Role.SyncMove(new ZTPoint(-385, 0)); this.Role.ReleaseSkill(HIDCode.Y, 0); break; } } /// /// esc退到城镇 /// private void ExitToTown() { G.Instance.DebugWriter("返回城镇"); Utility.Structs.ZTPoint point = new Utility.Structs.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("重新挑战"); Utility.Structs.ZTPoint point = new Utility.Structs.ZTPoint(this.GameRect.End.X - 132, this.GameRect.Start.Y + 90); G.Instance.InputControl.MoveToAndClick(point); } /// /// 刷房间 /// /// private ZTResult KillMonster() { bool ret = false; if (!IsEntryMap()) { 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 = this.MiniMap.GetCurrentHouseIndexWaitTimeout(out houseIndex, null, this.CancelToken, 3 * 1000); if (!ret) { G.Instance.InfoWriter("未找到人物所在房间"); return ZTResult.Failed; } G.Instance.InfoWriter("进入房间->" + houseIndex.ToString()); HouseInfo houseInfo = Houses[houseIndex]; this.Role.SetHouse(houseInfo); DateTime startTime = DateTime.Now; KillMonsterStateMachine kmsm = new KillMonsterStateMachine(this, houseInfo,this.Role, preHouseIndex, this.runningStep); ZTResult smresult = kmsm.Work(5 * 60 * 1000); Int32 roomTotalSecond = (Int32)(DateTime.Now - startTime).TotalSeconds; G.Instance.InfoWriter("房间刷完,用时:" + (roomTotalSecond / 60) + "分" + (roomTotalSecond % 60) + "秒"); runningStep = RunningStep.None; if (smresult == ZTResult.Success) { if (houseInfo.IsEnd) { //所有房间刷完 return ZTResult.Success; } //刷其它房间 continue; } else { return smresult; } } } /// /// 步行到素喃 /// /// private bool MoveToSunan() { bool result = FuncUtils.NoChangeRetryCallWrap( () => { WindowUtils.SetDnfToTop(); CloseAllAlertWindow(this.CancelToken, this.GameRect); //向下走出赛丽亚的房间 ,走向素喃 G.Instance.InputControl.PressKey(2000, HIDCode.DownArrow); }, () => { G.Instance.InfoWriter("检测是否进入素喃"); result = FuncUtils.TimeoutCancelableWrap(10000, this.CancelToken, () => { 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.CancelToken, this.GameRect); }, () => { //检测是否进入时空之门 return FuncUtils.TimeoutCancelableWrap(15000, this.CancelToken, () => { CloseAllAlertWindow(this.CancelToken, this.GameRect); return LindongCVHelper.IsInShikongzhimen(this.GameRect); }); }, () => { //检测是否还在素喃 return FuncUtils.TimeoutCancelableWrap(3000, this.CancelToken, () => { CloseAllAlertWindow(this.CancelToken, 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.CancelToken, () => { 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 IntoHouse() { bool result = false; //选择凛冬 G.Instance.InfoWriter("开始选择卡勒特之初"); Int32 nandu = 0; if (!SelectKalete(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 SelectKalete(out Int32 nandu) { Image image = ScreenCapture.Instance.CaptureScreenReturnImage(); if (KaleteCVHelper.GetChoiceKaleteNandu(out nandu, image, this.GameRect)) { return true; } G.Instance.InputControl.MoveToAndClick(new ZTPoint(this.GameRect.Start.X + 819, this.GameRect.Start.Y + 181)); Thread.Sleep(5000); image = ScreenCapture.Instance.CaptureScreenReturnImage(); if (KaleteCVHelper.GetChoiceKaleteNandu(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 (!KaleteCVHelper.GetChoiceKaleteNandu(out nandu, image, this.GameRect)) { return false; } if (nandu == 4) { return true; } return false; } /// /// 出售装备 /// /// private bool SaleEquipment() { //卖装备并关闭商店 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, this.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) { G.Instance.InfoWriter("装备文字未取到"); return false; } //开始点,每格步进30 ZTPoint startPoint = new Utility.Structs.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 Utility.Structs.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; } } }