using RichCreator.Utility; using RichCreator.Utility.Dnf; using RichCreator.Utility.InputControl; using RichCreator.Utility.Maps; using RichCreator.Utility.Structs; using System; using System.Threading; namespace RichCreator.Dnf { /// /// DNF角色 /// public class DnfRole { private SpeedProvider speed;//速度 private const Int32 PaddingLeft = 140;//左边框内边距 private const Int32 PaddingRight = 140;//右边框内边距 public DnfRole(ZTRectangle gameRect) { this.gameRect = gameRect; speed = SpeedProvider.Define; } private Int32 minCenterLineY; private Int32 maxCenterLineY; private Int32 centerLineErrorRange = 35;//中间性可允许的误差 private HouseInfo house; private ZTRectangle gameRect = ZTRectangle.Empty; private MoveIntent movingIntent = MoveIntent.AttackMove;//移动意图 private MoveMethod movingMethod = MoveMethod.Vertical;//移动方式,默认垂直移动 private ZTSize movingDistance;//移动距离 public ZTPoint Position { get; private set; }//角色位置 /// /// 按下的键,0:横向,1:纵向 /// private HIDCode[] pressKeys = new HIDCode[] { HIDCode.NoEvent, HIDCode.NoEvent };//当前按键 private bool isRun = false;//是否奔跑 /// /// 设置当前房间信息 /// /// public void SetHouse(HouseInfo house) { this.house = house; minCenterLineY = this.gameRect.End.Y + this.house.HouseCenterMoveLine - centerLineErrorRange; maxCenterLineY = this.gameRect.End.Y + this.house.HouseCenterMoveLine + centerLineErrorRange; } /// /// 设置当前角色速度 /// /// public void SetSpeed(Int32 speed) { this.speed = new SpeedProvider(speed); } /// /// 更新位置 /// /// public void UpdatePosition(ZTPoint position) { this.Position = position; } /// /// 是否移动中 /// public bool IsMoving { get { return pressKeys[0] != HIDCode.NoEvent || pressKeys[1] != HIDCode.NoEvent; } } /// /// 是否指定移动行为 /// /// /// public bool IsMoveIntent(MoveIntent intent) { if (IsMoving && movingIntent == intent) { return true; } return false; } /// /// 攻击移动 /// /// public void AttackMove(ZTSize moveDistance) { PutKey(moveDistance); movingIntent = MoveIntent.AttackMove; } private Int32 findRoleDir = 0;//寻找角色行走的方向 private DateTime findRoleMoveTimeout = DateTime.MinValue;//方向移动过期时间 private static HIDCode[][] dir = new HIDCode[][] { new HIDCode[] { HIDCode.LeftArrow ,HIDCode.NoEvent}, new HIDCode[] { HIDCode.NoEvent, HIDCode.UpArrow }, new HIDCode[] { HIDCode.RightArrow, HIDCode.NoEvent }, new HIDCode[] { HIDCode.NoEvent, HIDCode.DownArrow } }; /// /// 查找主角移动 /// /// public void FindRoleMove() { if (IsMoving && !IsMoveIntent(MoveIntent.FindRoleMove)) { StopMove(); } if (DateTime.Now >= findRoleMoveTimeout) { //转换方向 findRoleDir++; HIDCode[] tempKeys = dir[findRoleDir % 4]; Int32 stepms = 0, runms = 0; PutKey(out stepms, out runms, tempKeys[0], tempKeys[1], true); findRoleMoveTimeout = DateTime.Now.AddMilliseconds(speed.RandomMoveMillSecond); } //if (!IsMoving || (IsMoving && KeyIsChange(tempKeys))) //{ // //Int32 stepms = 0, runms = 0; // //PutKey(out stepms, out runms, tempKeys[0], tempKeys[1], true); //} movingIntent = MoveIntent.FindRoleMove; } /// /// 拾起物品移动 /// public void PickupMove(ZTPoint rolePosition, ZTPoint thingItemPosition) { ZTSize moveDistance = new ZTSize(thingItemPosition.X - rolePosition.X, thingItemPosition.Y - rolePosition.Y - 97); if (Math.Abs(moveDistance.Width) < 100 && Math.Abs(moveDistance.Height) < 100) { //距离允许,就近距离移动并X G.Instance.DebugWriter("distance ok"); SyncMove(new ZTPoint(moveDistance.Width,moveDistance.Height)); G.Instance.InputControl.PressKey(RandomUtils.G(400, 500), HIDCode.X); return; } //G.Instance.DebugWriter("pickup distance:" + moveDistance.ToString()); PutKey(moveDistance); movingIntent = MoveIntent.PickupMove; } /// /// 找门移动 /// /// public void FindDoorMove(ZTPoint rolePosition) { ComputeMoveInfo(rolePosition); HIDCode dirKey = HIDCode.NoEvent; switch (movingMethod) { case MoveMethod.ToLeft: dirKey = HIDCode.LeftArrow; break; case MoveMethod.ToRight: dirKey = HIDCode.RightArrow; break; case MoveMethod.Vertical: dirKey = movingDistance.Height > 0 ? HIDCode.DownArrow : HIDCode.UpArrow; break; case MoveMethod.Fixed: SyncMove(new ZTPoint(movingDistance.Width,movingDistance.Height)); StopMove(); return; } PutKey(movingDistance); movingIntent = MoveIntent.FindDoorMove; } /// /// 同步移动指定距离 /// /// public void SyncMove(ZTPoint size) { ZTSize distance = new ZTSize(size.X, size.Y); HIDCode horizontal = HIDCode.NoEvent; HIDCode vertical = HIDCode.NoEvent; bool isRun = false; int runms, stepms; Int32 xsig = Math.Sign(distance.Width); Int32 ysig = Math.Sign(distance.Height); if (Math.Abs(distance.Width) >= speed.RunThresold) { isRun = true; } if (distance.Height > 0) { vertical = HIDCode.DownArrow; } if (distance.Height < 0) { vertical = HIDCode.UpArrow; } if (distance.Width > 0) { horizontal = HIDCode.RightArrow; } if (distance.Width < 0) { horizontal = HIDCode.LeftArrow; } PutKey(out stepms, out runms, horizontal, vertical, isRun); if (stepms > 0) { Int32 mdistance = (Int32)(stepms * speed.StepX); if (runms > 0) { mdistance += (Int32)(runms * speed.RunX); } distance = new ZTSize(distance.Width - xsig * mdistance, distance.Height); } int ytime = (Int32)(Math.Abs(distance.Height) / speed.StepY); Int32 xtime = (Int32)(Math.Abs(distance.Width) / speed.StepX); if (isRun) { xtime = (Int32)(Math.Abs(distance.Width) / speed.RunX); } Int32 mintime = Math.Min(xtime, ytime); if (xtime <= 0) { mintime = ytime; } if (ytime <= 0) { mintime = xtime; } Thread.Sleep(mintime); xtime -= mintime; ytime -= mintime; if (xtime > 0) { PutKey(out stepms, out runms, horizontal, HIDCode.NoEvent, isRun); Thread.Sleep(xtime); } if (ytime > 0) { PutKey(out stepms, out runms, HIDCode.NoEvent, vertical, false); Thread.Sleep(ytime); } StopMove(); } /// /// 停止移动 /// public void StopMove() { if (IsMoving) { //停止 G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false); pressKeys[0] = HIDCode.NoEvent; pressKeys[1] = HIDCode.NoEvent; isRun = false; } } /// /// 休眠 /// /// public void Sleep(Int32 millSecond) { Thread.Sleep(millSecond); } /// /// 释放技能 /// public void ReleaseSkill(HIDCode key) { ReleaseSkill(key, 0); } public void ReleaseSkill(HIDCode key, Int32 skillTimeout) { Int32 dur = RandomUtils.KeyPressDuration; G.Instance.InputControl.PressKey(dur,key); Int32 subTime = skillTimeout - dur; if (subTime > 0) { Thread.Sleep(subTime); } } private ZTPoint roleLastPosition = ZTPoint.Empty; private bool StaticTimerIsStart = false;//静止计时是否开始 private Int32 StaticTimerCounter = 0;//静止计时计数器 private DateTime DetectLastNoMoveTime = DateTime.MaxValue;//最后没移动时间 private const Int32 NoMoveMaxMillSecond = 2000;//最大未移动容忍毫秒数 /// /// 得到循环移动的距离 /// /// private void ComputeMoveInfo(ZTPoint rolePosition) { ZTRectangle limitRect = ZTRectangle.Empty; //达到未移动阀值,可能有障碍物,先攻击,如果攻击后还是无效则上下左右移 if (rolePosition.Equals(this.roleLastPosition)) { if (StaticTimerIsStart) { if ((DateTime.Now - DetectLastNoMoveTime).TotalMilliseconds > NoMoveMaxMillSecond) { G.Instance.DebugWriter($"find door not move,role position:{rolePosition.ToString()}"); this.StopMove(); if (StaticTimerCounter == 0) { //清除障碍物 G.Instance.InputControl.PressKey(RandomUtils.KeyPressDuration, HIDCode.X); } else { //无法清除障碍物,随机移动一下 switch (StaticTimerCounter % 4) { case 0: G.Instance.DebugWriter("random up"); //上 movingDistance = new ZTSize(0, -300); break; case 1: //右 movingDistance = new ZTSize(600, 0); break; case 2: //下 movingDistance = new ZTSize(0, 300); break; case 3: //左 movingDistance = new ZTSize(-600, 0); break; } movingMethod = MoveMethod.Fixed; } StaticTimerCounter++; DetectLastNoMoveTime = DateTime.Now; if (StaticTimerCounter > 1) { return; } } } else if (!StaticTimerIsStart) { //没开始计时 则 开始计时 StaticTimerIsStart = true; DetectLastNoMoveTime = DateTime.Now; } } else { //移动了 取消计时 this.roleLastPosition = rolePosition; StaticTimerIsStart = false; StaticTimerCounter = 0; } if (!IsMoving) { //刚开始移动 movingMethod = MoveMethod.Vertical; } if (movingMethod == MoveMethod.Vertical && rolePosition.Y >= minCenterLineY && rolePosition.Y <= maxCenterLineY) { //不需要上下移动,计算左右 if (this.house.DoorDirection[0] == Direction.Left) { movingMethod = MoveMethod.ToLeft; } else if (this.house.DoorDirection[0] == Direction.Right) { movingMethod = MoveMethod.ToRight; } else { //计算是向左还是右,哪边大往哪边 if (rolePosition.X > (this.gameRect.Start.X + (this.gameRect.End.X - this.gameRect.Start.X) / 2)) { //左边空间大 movingMethod = MoveMethod.ToLeft; } else { movingMethod = MoveMethod.ToRight; } } } if (movingMethod == MoveMethod.ToLeft) { //计算左边界范围 limitRect = new ZTRectangle(gameRect.Start.X, gameRect.Start.Y, gameRect.Start.X + PaddingLeft, gameRect.End.Y); //判断是否到左边界 if (RichCreator.Utilitys.Utils.IsInRect(rolePosition, limitRect)) { //到左边界就向右走 movingMethod = MoveMethod.ToRight; movingDistance = new ZTSize(gameRect.End.X - rolePosition.X, 0); } else { //没到继续向左走 movingMethod = MoveMethod.ToLeft; movingDistance = new ZTSize(limitRect.Start.X - rolePosition.X, 0); } } else if (movingMethod == MoveMethod.ToRight) { //计算右边界范围 limitRect = new ZTRectangle(gameRect.End.X - PaddingRight, gameRect.Start.Y, gameRect.End.X, gameRect.End.Y); //判断是否到右边界 if (Utilitys.Utils.IsInRect(rolePosition, limitRect)) { //到右边界就向左走 G.Instance.InfoWriter($"in limit rect,role position:{rolePosition.ToString()},limit:{limitRect.ToString()}"); movingMethod = MoveMethod.ToLeft; movingDistance = new ZTSize(gameRect.Start.X - rolePosition.X, 0); } else { //没到继续向右走 movingMethod = MoveMethod.ToRight; movingDistance = new ZTSize(gameRect.End.X - rolePosition.X, 0); } } else { //向点移动 Int32 targetY = gameRect.End.Y + this.house.HouseCenterMoveLine; movingDistance = new ZTSize(0, targetY - rolePosition.Y); } } #region 八方向移动 /// /// 按下按键 /// /// private void PutKey(ZTSize distance) { HIDCode horizontal = HIDCode.NoEvent; HIDCode vertical = HIDCode.NoEvent; bool isRun = false; if (distance.Width < 0) { horizontal = HIDCode.LeftArrow; } if (distance.Width > 0) { horizontal = HIDCode.RightArrow; } if (Math.Abs(distance.Width) >= speed.RunThresold) { isRun = true; } if (distance.Height < 0) { vertical = HIDCode.UpArrow; } if (distance.Height > 0) { vertical = HIDCode.DownArrow; } Int32 stepms, runms; PutKey(out stepms, out runms, horizontal, vertical, isRun); } /// /// 行走按键 /// /// 已经步行ms /// 已经奔跑ms /// 横向按键 /// 纵向按键 /// 是否奔跑 private void PutKey(out Int32 stepMS, out Int32 runMS, HIDCode horizontal, HIDCode vertical, bool isRun) { stepMS = 0; runMS = 0; if (horizontal == vertical) { return; } if (horizontal == pressKeys[0] && vertical == pressKeys[1]) { return; } int keyCount = horizontal != HIDCode.NoEvent && vertical != HIDCode.NoEvent ? 2 : 1; Int32 tempwait = 0; if (isRun) { //跑 if (!this.isRun || horizontal != pressKeys[0]) { //如果之前没有跑,或跑的方向不一样,则开始跑 G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal); tempwait = RandomUtils.KeyPressDuration; stepMS += tempwait; Thread.Sleep(tempwait); G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false); Thread.Sleep(RandomUtils.KeyPressDuration); G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal); this.isRun = true; if (keyCount == 2) { tempwait = RandomUtils.KeyPressDuration; runMS += tempwait; Thread.Sleep(tempwait); G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal, vertical); } } else { //奔跑方向不变 int afterKeyCount = pressKeys[0] != HIDCode.NoEvent && pressKeys[1] != HIDCode.NoEvent ? 2 : 1; if (afterKeyCount != keyCount) { //如果跟原来按键数量不一样 if (keyCount == 1) { G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal); } else { G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal, vertical); } } } } else { //走 if (keyCount == 1) { G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal != HIDCode.NoEvent ? horizontal : vertical); } else { G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false, horizontal, vertical); } } pressKeys[0] = horizontal; pressKeys[1] = vertical; } /// /// 按钮是否变化 /// /// /// private bool KeyIsChange(HIDCode[] pressKey) { if (pressKey == null || pressKey.Length != 2) { return true; } if (pressKeys[0] == pressKey[0] && pressKeys[1] == pressKey[1]) { return false; } return true; } #endregion } }