| | |
| | | using RichCreator.Utility.Dnf; |
| | | using RichCreator.Utility.InputControl; |
| | | using RichCreator.Utility.Maps; |
| | | using RichCreator.Utility.Skills; |
| | | using RichCreator.Utility.Structs; |
| | | using RichCreator.Utility.Utilitys; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Threading; |
| | | |
| | | |
| | |
| | | /// </summary> |
| | | public class DnfRole |
| | | { |
| | | |
| | | private SpeedProvider speed;//速度 |
| | | |
| | | private const Int32 PaddingLeft = 140;//左边框内边距 |
| | | private const Int32 PaddingRight = 140;//右边框内边距 |
| | | |
| | | /// <summary> |
| | | /// 角色脚部距色块中央的偏移 |
| | | /// </summary> |
| | | public static readonly ZTPoint RoleFootOffset = new ZTPoint(0, 143); |
| | | |
| | | /// <summary> |
| | | /// 角色身体中间距色块中央的偏移 |
| | | /// </summary> |
| | | public static readonly ZTPoint RoleHalfOffset = new ZTPoint(0, 88); |
| | | |
| | | |
| | | |
| | | public DnfRole(ZTRectangle gameRect) |
| | | { |
| | | this.gameRect = gameRect; |
| | | speed = SpeedProvider.Define; |
| | | |
| | | moveCancelToken = new CancellationTokenSource(); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | private Int32 minCenterLineY; |
| | | private Int32 maxCenterLineY; |
| | | private Int32 centerLineErrorRange = 35;//中间性可允许的误差 |
| | | |
| | | private HouseInfo house; |
| | | private SpeedProvider speed;//速度 |
| | | private HouseInfo house;//所在房间 |
| | | private ZTRectangle gameRect = ZTRectangle.Empty; |
| | | |
| | | |
| | | private MoveIntent movingIntent = MoveIntent.AttackMove;//移动意图 |
| | | private MoveMethod movingMethod = MoveMethod.Vertical;//移动方式,默认垂直移动 |
| | | private ZTSize movingDistance;//移动距离 |
| | | private CancellationTokenSource moveCancelToken;//移动取消令牌 |
| | | |
| | | /// <summary> |
| | | /// 角色色块位置 |
| | | /// </summary> |
| | | public ZTPoint RoleCBPosition { get; private set; } |
| | | |
| | | public ZTPoint Position { get; private set; }//角色位置 |
| | | /// <summary> |
| | | /// 角色脚部位置 |
| | | /// </summary> |
| | | public ZTPoint Position |
| | | { |
| | | get |
| | | { |
| | | return CBToFootPosition(RoleCBPosition); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 身体中间位置 |
| | | /// </summary> |
| | | public ZTPoint HalfPosition |
| | | { |
| | | get |
| | | { |
| | | return CBToHalfPosition(RoleCBPosition); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 按下的键,0:横向,1:纵向 |
| | |
| | | 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; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// <summary> |
| | | /// 更新位置 |
| | | /// </summary> |
| | | /// <param name="position"></param> |
| | | public void UpdatePosition(ZTPoint position) |
| | | /// <param name="roleCBPosition"></param> |
| | | public void UpdatePosition(ZTPoint roleCBPosition) |
| | | { |
| | | this.Position = position; |
| | | this.RoleCBPosition = roleCBPosition; |
| | | } |
| | | |
| | | |
| | |
| | | /// <param name="moveDistance"></param> |
| | | public void AttackMove(ZTSize moveDistance) |
| | | { |
| | | PutKey(moveDistance); |
| | | PutDirectionKey(moveDistance); |
| | | movingIntent = MoveIntent.AttackMove; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 攻击移动至 |
| | | /// </summary> |
| | | /// <param name="skillReleasePoint"></param> |
| | | public void AttackMoveTo(ZTPoint skillReleasePoint,ParametersPoint locationPoint) |
| | | { |
| | | //屏幕坐标转地图坐标 |
| | | ZTPoint start= this.house.ScreenToMapCoordinate(this.Position, locationPoint); |
| | | ZTPoint end = this.house.ScreenToMapCoordinate(DnfRole.HalfToFootPosition(skillReleasePoint), locationPoint); |
| | | List<ZTPoint> paths = this.house.FindPath(start, end); |
| | | MovePaths(start, paths); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 移动到指定地图点 |
| | | /// </summary> |
| | | public void MoveToMapPoint(ZTPoint start,ZTPoint end) |
| | | { |
| | | List<ZTPoint> paths = this.house.FindPath(start, end); |
| | | MovePaths(start, paths); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 移动指定路径 |
| | | /// </summary> |
| | | /// <param name="start"></param> |
| | | /// <param name="paths"></param> |
| | | public void MovePaths(ZTPoint start, List<ZTPoint> paths) |
| | | { |
| | | ZTPoint lastPoint = start; |
| | | if (paths != null && paths.Count > 0) |
| | | { |
| | | for (int i = 0; i < paths.Count; i++) |
| | | { |
| | | ZTPoint distance = paths[i].Sub(lastPoint); |
| | | this.SyncMove(distance); |
| | | lastPoint = paths[i]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | 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 } }; |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | |
| | | findRoleDir++; |
| | | HIDCode[] tempKeys = dir[findRoleDir % 4]; |
| | | Int32 stepms = 0, runms = 0; |
| | | PutKey(out stepms, out runms, tempKeys[0], tempKeys[1], true); |
| | | PutDirectionKey(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 EntryDoorMove() |
| | | { |
| | | if (IsMoving && !IsMoveIntent(MoveIntent.EntryDoor)) |
| | | { |
| | | StopMove(); |
| | | } |
| | | } |
| | | |
| | | public void ToLoopMove() |
| | | { |
| | | if (IsMoving && !IsMoveIntent(MoveIntent.ToLoopPoint)) |
| | | { |
| | | StopMove(); |
| | | } |
| | | } |
| | | |
| | | public void ToNextGateMove() |
| | | { |
| | | if (IsMoving && !IsMoveIntent(MoveIntent.ToNextGatePoint)) |
| | | { |
| | | StopMove(); |
| | | } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// 拾起物品移动 |
| | | /// </summary> |
| | | public void PickupMove(ZTPoint rolePosition, ZTPoint thingItemPosition) |
| | | { |
| | | if (IsMoving && !IsMoveIntent(MoveIntent.PickupMove)) |
| | | { |
| | | StopMove(); |
| | | } |
| | | |
| | | ZTSize moveDistance = new ZTSize(thingItemPosition.X - rolePosition.X, thingItemPosition.Y - rolePosition.Y - 97); |
| | | if (Math.Abs(moveDistance.Width) < 100 && Math.Abs(moveDistance.Height) < 100) |
| | | { |
| | |
| | | } |
| | | |
| | | //G.Instance.DebugWriter("pickup distance:" + moveDistance.ToString()); |
| | | PutKey(moveDistance); |
| | | PutDirectionKey(moveDistance); |
| | | movingIntent = MoveIntent.PickupMove; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 找门移动 |
| | | /// </summary> |
| | | /// <param name="rolePosition"></param> |
| | | 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; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 同步移动指定距离 |
| | |
| | | horizontal = HIDCode.LeftArrow; |
| | | } |
| | | |
| | | PutKey(out stepms, out runms, horizontal, vertical, isRun); |
| | | PutDirectionKey(out stepms, out runms, horizontal, vertical, isRun); |
| | | if (stepms > 0) |
| | | { |
| | | Int32 mdistance = (Int32)(stepms * speed.StepX); |
| | |
| | | xtime = (Int32)(Math.Abs(distance.Width) / speed.RunX); |
| | | } |
| | | |
| | | |
| | | |
| | | Int32 mintime = Math.Min(xtime, ytime); |
| | | if (xtime <= 0) |
| | | { |
| | |
| | | ytime -= mintime; |
| | | if (xtime > 0) |
| | | { |
| | | PutKey(out stepms, out runms, horizontal, HIDCode.NoEvent, isRun); |
| | | PutDirectionKey(out stepms, out runms, horizontal, HIDCode.NoEvent, isRun); |
| | | Thread.Sleep(xtime); |
| | | } |
| | | if (ytime > 0) |
| | | { |
| | | PutKey(out stepms, out runms, HIDCode.NoEvent, vertical, false); |
| | | PutDirectionKey(out stepms, out runms, HIDCode.NoEvent, vertical, false); |
| | | Thread.Sleep(ytime); |
| | | } |
| | | StopMove(); |
| | | //StopMove(); |
| | | |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false); |
| | | pressKeys[0] = HIDCode.NoEvent; |
| | | pressKeys[1] = HIDCode.NoEvent; |
| | | isRun = false; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | { |
| | | if (IsMoving) |
| | | { |
| | | this.moveCancelToken.Cancel(); |
| | | this.moveCancelToken = new CancellationTokenSource(); |
| | | |
| | | //停止 |
| | | G.Instance.InputControl.PutDown(false, false, false, false, false, false, false, false); |
| | | pressKeys[0] = HIDCode.NoEvent; |
| | |
| | | /// <summary> |
| | | /// 释放技能 |
| | | /// </summary> |
| | | /// <param name="key"></param> |
| | | 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; |
| | | SkillInfo skill=SkillInfo.GetSkillInfo(key); |
| | | if (skill != null) |
| | | { |
| | | Int32 subTime = (Int32)(skill.ReleaseWaitTime - dur); |
| | | if (subTime > 0) |
| | | { |
| | | Thread.Sleep(subTime); |
| | | 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;//最大未移动容忍毫秒数 |
| | | |
| | | /// <summary> |
| | | /// 得到循环移动的距离 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | 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); |
| | | } |
| | | } |
| | | |
| | |
| | | /// 按下按键 |
| | | /// </summary> |
| | | /// <param name="distance"></param> |
| | | private void PutKey(ZTSize distance) |
| | | private void PutDirectionKey(ZTSize distance) |
| | | { |
| | | HIDCode horizontal = HIDCode.NoEvent; |
| | | HIDCode vertical = HIDCode.NoEvent; |
| | |
| | | } |
| | | |
| | | Int32 stepms, runms; |
| | | PutKey(out stepms, out runms, horizontal, vertical, isRun); |
| | | PutDirectionKey(out stepms, out runms, horizontal, vertical, isRun); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// <param name="horizontal">横向按键</param> |
| | | /// <param name="vertical">纵向按键</param> |
| | | /// <param name="isRun">是否奔跑</param> |
| | | private void PutKey(out Int32 stepMS, out Int32 runMS, HIDCode horizontal, HIDCode vertical, bool isRun) |
| | | private void PutDirectionKey(out Int32 stepMS, out Int32 runMS, HIDCode horizontal, HIDCode vertical, bool isRun) |
| | | { |
| | | stepMS = 0; |
| | | runMS = 0; |
| | |
| | | /// </summary> |
| | | /// <param name="pressKey"></param> |
| | | /// <returns></returns> |
| | | private bool KeyIsChange(HIDCode[] pressKey) |
| | | private bool IsChangeOfKey(HIDCode[] pressKey) |
| | | { |
| | | if (pressKey == null || pressKey.Length != 2) |
| | | { |
| | |
| | | #endregion |
| | | |
| | | |
| | | |
| | | #region role position convert |
| | | /// <summary> |
| | | /// 色块中央位置转为脚部位置 |
| | | /// </summary> |
| | | /// <param name="cbPosition"></param> |
| | | /// <returns></returns> |
| | | public static ZTPoint CBToFootPosition(ZTPoint cbPosition) |
| | | { |
| | | return cbPosition.Add(RoleFootOffset); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 色块中央位置转为人物中间位置 |
| | | /// </summary> |
| | | /// <param name="cbPosition"></param> |
| | | /// <returns></returns> |
| | | public static ZTPoint CBToHalfPosition(ZTPoint cbPosition) |
| | | { |
| | | return cbPosition.Add(RoleHalfOffset); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 脚部坐标到身份中央坐标转换 |
| | | /// </summary> |
| | | /// <param name="footPosition"></param> |
| | | /// <returns></returns> |
| | | public static ZTPoint FootToHalfPosition(ZTPoint footPosition) |
| | | { |
| | | return footPosition.Sub(RoleFootOffset).Add(RoleHalfOffset); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 身体中央坐标到脚部坐标转换 |
| | | /// </summary> |
| | | /// <param name="halfPosition"></param> |
| | | /// <returns></returns> |
| | | public static ZTPoint HalfToFootPosition(ZTPoint halfPosition) |
| | | { |
| | | return halfPosition.Sub(RoleHalfOffset).Add(RoleFootOffset); |
| | | } |
| | | #endregion |
| | | |
| | | |
| | | } |
| | | } |