public static WoWPoint FindSafeLocation(double distanceFromTarget, double distanceFromOthers) { WoWPoint myLocation = Me.Location; WoWPoint destinationLocation; List <WoWPoint> mobLocations = new List <WoWPoint>(); mobLocations = AllMobsAroundUs; double bestSafetyMargin = distanceFromTarget; //mobLocations.Add(Me.CurrentTarget.Location); // Rotate 10 degrees each itteration for (float degrees = 0f; degrees < 360f; degrees += 10f) { // Search 5 yards further away each itteration for (float distanceFromMob = 0f; distanceFromMob <= 35f; distanceFromMob += 5f) { destinationLocation = myLocation.RayCast((float)(degrees * Math.PI / 180f), distanceFromMob); double mobDistance = destinationLocation.Distance2D(NearestMobLoc(destinationLocation, mobLocations)); // Mob(s) too close to our current base-safe location, not a suitable location if (mobDistance <= bestSafetyMargin) { continue; } // Found a mob-free location, lets do further testing. // * Check if we can generate a path // * Check if we have LOS // Can we generate a path to this location? if (Navigator.GeneratePath(Me.Location, destinationLocation).Length <= 0) { Utils.Log("Mob-free location failed path generation check"); continue; } // Is the destination in line of sight? if (!GameWorld.IsInLineOfSight(Me.Location, destinationLocation)) { Utils.Log("Mob-free location failed line of sight check"); continue; } // We pass all checks. This is a good location // Make it so 'Number 1', "Engage" return(destinationLocation); } } return(null); }
private void button2_Click(object sender, EventArgs e) { var point = new WoWPoint((float)numericUpDown1.Value, (float)numericUpDown2.Value, (float)numericUpDown3.Value); Logging.Write("Точка: {0}", point); var rayCast = point.RayCast(StyxWoW.Me.Rotation, 20); Logging.Write("Точка RayCast: {0}", rayCast); if (!Navigator.CanNavigateFully(StyxWoW.Me.Location, rayCast)) { Logging.Write("Неудается найти путь от {0} до {1}", StyxWoW.Me.Location, rayCast); return; } Logging.Write("Путь найден. Устанавливаю значение для метода передвижения."); ImpMovePlugin.PointTo = rayCast; ImpMovePlugin.NeedMove = true; }
WoWPoint TryGetHieght(WoWPoint point) { float PIx2 = (float)Math.PI * 2f; int step = 20; for (int d = 5; d <= 50; d += 5) { for (int i = 0; i < 20; i++) { WoWPoint newPoint = point.RayCast((i * PIx2) / step, d); try { newPoint.Z = Navigator.FindHeights(newPoint.X, newPoint.Y).Max(); return(newPoint); } catch { } } } return(point); }
float?GetFaceWaterDirection() { WoWPoint playerLoc = _me.Location; var sonar = new List <int>(TraceStep); var tracelines = new WorldLine[TraceStep * 3]; bool[] tracelineRetVals; for (int i = 0; i < TraceStep; i++) { // scans 10,15 and 20 yards from player for water at every 18 degress for (int n = 0; n < 3; n++) { WoWPoint p = (playerLoc.RayCast((i * PIx2) / TraceStep, 10 + (n * 5))); WoWPoint highPoint = p; highPoint.Z += 5; WoWPoint lowPoint = p; lowPoint.Z -= 55; tracelines[(i * 3) + n].Start = highPoint; tracelines[(i * 3) + n].End = lowPoint; } } GameWorld.MassTraceLine(tracelines, GameWorld.CGWorldFrameHitFlags.HitTestLiquid | GameWorld.CGWorldFrameHitFlags.HitTestLiquid2, out tracelineRetVals); for (int i = 0; i < TraceStep; i++) { int scan = 0; for (int n = 0; n < 3; n++) { if (tracelineRetVals[(i * 3) + n]) { scan++; } } sonar.Add(scan); } int widest = 0; for (int i = 0; i < TraceStep; i++) { if (sonar[i] > widest) { widest = sonar[i]; } } bool counting = false; int startIndex = 0, bigestStartIndex = 0, startLen = 0, endLen = 0, bigestStretch = 0; // if we found water find the largest area and face towards the center of it. if (widest > 0) { for (int i = 0; i < TraceStep; i++) { if (sonar[i] == widest && !counting) { startIndex = i; if (i == 0) { startLen = 1; } counting = true; } if (sonar[i] != widest && counting) { if ((i) - startIndex > bigestStretch) { bigestStretch = (i) - startIndex; bigestStartIndex = startIndex; } if (startIndex == 0) { startLen = i; } counting = false; } if (sonar[i] == widest && counting && i == 19) { endLen = i - startIndex; } } int index; if (startLen + endLen > bigestStretch) { if (startLen >= endLen) { index = startLen > endLen ? startLen - endLen : endLen - startLen; } else { index = (TraceStep - 1) - (endLen - startLen); } } else { index = bigestStartIndex + (bigestStretch / 2); } float direction = (index * PIx2) / 20; return(direction); } return(null); }
/// <summary> /// locates safe point away from enemies /// </summary> /// <param name="ptOrigin">start point for search</param> /// <param name="minSafeDist">min distance to be safe</param> /// <returns></returns> public WoWPoint FindLocationOriginal(WoWPoint ptOrigin) { WoWPoint destinationLocation = new WoWPoint(); List<WoWPoint> mobLocations = new List<WoWPoint>(); int arcIncrement = 360 / RaysToCheck; mobLocations = AllEnemyMobLocations; double minSafeDistSqr = MinSafeDistance * MinSafeDistance; double degreesFacing = (Me.RenderFacing * 180f) / Math.PI; // Logger.WriteDebug( Color.Cyan, "Facing {0:F0}d {1:F2}r Searching for {2:F1} yard mob free area", degreesFacing, Me.RenderFacing, MinSafeDistance); for (int arcIndex = 0; arcIndex < RaysToCheck ; arcIndex++) { float degreesFrom = 180; if ((arcIndex & 1) == 0) degreesFrom += (arcIndex >> 1) * arcIncrement; else degreesFrom -= (arcIndex >> 1) * arcIncrement; for (float distFromOrigin = MinScanDistance; distFromOrigin <= MaxScanDistance ; distFromOrigin += IncrementScanDistance ) { float heading = (float)(degreesFrom * Math.PI / 180f); heading -= Me.RenderFacing; destinationLocation = ptOrigin.RayCast((float)(degreesFrom * Math.PI / 180f), distFromOrigin); double mobDistSqr = destinationLocation.Distance2DSqr(NearestMobLoc(destinationLocation, mobLocations)); if (mobDistSqr <= minSafeDistSqr) continue; //if (Navigator.CanNavigateFully(Me.Location, destinationLocation)) if (Navigator.GeneratePath(Me.Location, destinationLocation).Length <= 0) { // Logger.WriteDebug( Color.Cyan, "Mob-free location failed path check for degrees={0:F1} dist={1:F1}", degreesFrom, distFromOrigin); continue; } if (!Styx.WoWInternals.World.GameWorld.IsInLineOfSight(Me.Location, destinationLocation)) { // Logger.WriteDebug( Color.Cyan, "Mob-free location failed line of sight check for degrees={0:F1} dist={1:F1}", degreesFrom, distFromOrigin); continue; } if (MobToRunFrom != null) { if (!Styx.WoWInternals.World.GameWorld.IsInLineOfSpellSight(destinationLocation, MobToRunFrom.Location)) { // Logger.WriteDebug( Color.Cyan, "Mob-free location failed line of sight check for degrees={0:F1} dist={1:F1}", degreesFrom, distFromOrigin); continue; } } Logger.WriteDebug(Color.Cyan, "Found mob-free location ({0:F1} yd radius) at degrees={1:F1} dist={2:F1}", MinSafeDistance, degreesFrom, distFromOrigin); return destinationLocation; } } Logger.WriteDebug(Color.Cyan, "No mob-free location ({0:F1} yd radius) found within {1:F1} yds", MinSafeDistance, MaxScanDistance ); return WoWPoint.Empty; }
public WoWPoint FindLocation(WoWPoint ptOrigin) { DateTime startFind = DateTime.Now; int countPointsChecked = 0; int countFailToPointNav = 0; int countFailRange = 0; int countFailSafe = 0; int countFailToPointLoS = 0; int countFailToMobLoS = 0; double furthestNearMobDistSqr = 0f; WoWPoint ptFurthest = WoWPoint.Empty; bool reallyCheckRangeToLineOfSightMob = CheckRangeToLineOfSightMob && Me.GotTarget; WoWPoint ptAdjOrigin = ptOrigin; ptAdjOrigin.Z += 1f; WoWPoint ptDestination = new WoWPoint(); List<WoWPoint> mobLocations = new List<WoWPoint>(); float arcIncrement = ((float)Math.PI * 2) / RaysToCheck; mobLocations = AllEnemyMobLocationsToCheck; double minSafeDistSqr = MinSafeDistance * MinSafeDistance; float baseDestinationFacing = MobToRunFrom == null ? Me.RenderFacing + (float)Math.PI : Styx.Helpers.WoWMathHelper.CalculateNeededFacing(MobToRunFrom.Location, Me.Location); // Logger.WriteDebug( Color.Cyan, "SafeArea: search near {0:F0}d @ {1:F1} yds for mob free area", RadiansToDegrees(baseDestinationFacing), MinSafeDistance); for (int arcIndex = 0; arcIndex < RaysToCheck; arcIndex++) { // rather than tracing around the circle, toggle between clockwise and counter clockwise for each test // .. so we favor a position furthest away from mob float checkFacing = baseDestinationFacing; if ((arcIndex & 1) == 0) checkFacing += arcIncrement * (arcIndex >> 1); else checkFacing -= arcIncrement * ((arcIndex >> 1) + 1); for (float distFromOrigin = MinScanDistance; distFromOrigin <= MaxScanDistance; distFromOrigin += IncrementScanDistance) { countPointsChecked++; ptDestination = ptOrigin.RayCast(checkFacing, distFromOrigin); if (!Navigator.CanNavigateFully(Me.Location, ptDestination)) { // Logger.WriteDebug( Color.Cyan, "Safe Location failed navigation check for degrees={0:F1} dist={1:F1}", RadiansToDegrees(checkFacing), distFromOrigin); countFailToPointNav++; continue; } WoWPoint ptNearest = NearestMobLoc(ptDestination, mobLocations); if (ptNearest == WoWPoint.Empty) { if (furthestNearMobDistSqr < minSafeDistSqr) { furthestNearMobDistSqr = minSafeDistSqr; ptFurthest = ptDestination; // set best available if others fail } } else { double mobDistSqr = ptDestination.Distance2DSqr(ptNearest); if (furthestNearMobDistSqr < mobDistSqr) { furthestNearMobDistSqr = mobDistSqr; ptFurthest = ptDestination; // set best available if others fail } if (mobDistSqr <= minSafeDistSqr) { countFailSafe++; continue; } } if (reallyCheckRangeToLineOfSightMob && RangeToLineOfSightMob < ptDestination.Distance(LineOfSightMob.Location) - LineOfSightMob.MeleeDistance()) { countFailRange++; continue; } if (CheckLineOfSightToSafeLocation) { WoWPoint ptAdjDest = ptDestination; ptAdjDest.Z += 1f; if (!Styx.WoWInternals.World.GameWorld.IsInLineOfSight(ptAdjOrigin, ptAdjDest)) { // Logger.WriteDebug( Color.Cyan, "Mob-free location failed line of sight check for degrees={0:F1} dist={1:F1}", degreesFrom, distFromOrigin); countFailToPointLoS++; continue; } } if (CheckSpellLineOfSightToMob && LineOfSightMob != null) { if (!Styx.WoWInternals.World.GameWorld.IsInLineOfSpellSight(ptDestination, LineOfSightMob.Location)) { if (!Styx.WoWInternals.World.GameWorld.IsInLineOfSight(ptDestination, LineOfSightMob.Location)) { // Logger.WriteDebug( Color.Cyan, "Mob-free location failed line of sight check for degrees={0:F1} dist={1:F1}", degreesFrom, distFromOrigin); countFailToMobLoS++; continue; } } } Logger.WriteDebug(Color.Cyan, "SafeArea: Found mob-free location ({0:F1} yd radius) at degrees={1:F1} dist={2:F1} on point check# {3}", MinSafeDistance, WoWMathHelper.RadiansToDegrees(checkFacing), distFromOrigin, countPointsChecked); Logger.WriteDebug(Color.Cyan, "SafeArea: processing took {0:F0} ms", (DateTime.Now - startFind).TotalMilliseconds); return ptDestination; } } Logger.WriteDebug(Color.Cyan, "SafeArea: No mob-free location ({0:F1} yd radius) found within {1:F1} yds ({2} checked, {3} nav, {4} not safe, {5} range, {6} pt los, {7} mob los)", MinSafeDistance, MaxScanDistance, countPointsChecked, countFailToPointNav, countFailSafe, countFailRange, countFailToPointLoS, countFailToMobLoS); if (ChooseSafestAvailable && ptFurthest != WoWPoint.Empty) { Logger.WriteDebug(Color.Cyan, "SafeArea: choosing best available spot in {0:F1} yd radius where closest mob is {1:F1} yds", MinSafeDistance, Math.Sqrt(furthestNearMobDistSqr)); Logger.WriteDebug(Color.Cyan, "SafeArea: processing took {0:F0} ms", (DateTime.Now - startFind).TotalMilliseconds); return ChooseSafestAvailable ? ptFurthest : WoWPoint.Empty; } Logger.WriteDebug(Color.Cyan, "SafeArea: processing took {0:F0} ms", (DateTime.Now - startFind).TotalMilliseconds); return WoWPoint.Empty; }
public WoWPoint FindLocation(WoWPoint ptOrigin) { DateTime startFind = DateTime.UtcNow; int countPointsChecked = 0; int countFailDiff = 0; int countFailTrace = 0; int countFailToPointNav = 0; int countFailRange = 0; int countFailSafe = 0; int countFailToPointLoS = 0; int countFailToMobLoS = 0; TimeSpan spanTrace = TimeSpan.Zero; TimeSpan spanNav = TimeSpan.Zero; double furthestNearMobDistSqr = 0f; WoWPoint ptFurthest = WoWPoint.Empty; float facingFurthest = 0f; bool reallyCheckRangeToLineOfSightMob = CheckRangeToLineOfSightMob && Me.GotTarget(); WoWPoint ptAdjOrigin = ptOrigin; // ptAdjOrigin.Z += 1f; // comment out origin adjustment since using GetTraceLinePos() WoWPoint ptDestination = new WoWPoint(); List<WoWPoint> mobLocations = new List<WoWPoint>(); float arcIncrement = ((float)Math.PI * 2) / RaysToCheck; mobLocations = AllEnemyMobLocationsToCheck; double minSafeDistSqr = MinSafeDistance * MinSafeDistance; #if OLD_WAY float baseDestinationFacing = MobToRunFrom == null ? Me.RenderFacing + (float)Math.PI : Styx.Helpers.WoWMathHelper.CalculateNeededFacing(MobToRunFrom.Location, Me.Location); #else float baseDestinationFacing; if (PreferredDirection == Disengage.Direction.None && MobToRunFrom != null) baseDestinationFacing = Styx.Helpers.WoWMathHelper.CalculateNeededFacing(MobToRunFrom.Location, Me.Location); else if (PreferredDirection == Disengage.Direction.Frontwards) baseDestinationFacing = Me.RenderFacing; else // if (PreferredDirection == Disengage.Direction.Backwards) baseDestinationFacing = Me.RenderFacing + (float)Math.PI; #endif Logger.WriteDebug( Color.Cyan, "SafeArea: facing {0:F0} degrees, looking for safespot towards {1:F0} degrees", WoWMathHelper.RadiansToDegrees(Me.RenderFacing), WoWMathHelper.RadiansToDegrees(baseDestinationFacing) ); for (int arcIndex = 0; arcIndex < RaysToCheck; arcIndex++) { // rather than tracing around the circle, toggle between clockwise and counter clockwise for each test // .. so we favor a position furthest away from mob float checkFacing = baseDestinationFacing; if ((arcIndex & 1) == 0) checkFacing += arcIncrement * (arcIndex >> 1); else checkFacing -= arcIncrement * ((arcIndex >> 1) + 1); checkFacing = WoWMathHelper.NormalizeRadian(checkFacing); for (float distFromOrigin = MinScanDistance; distFromOrigin <= MaxScanDistance; distFromOrigin += IncrementScanDistance) { countPointsChecked++; ptDestination = ptOrigin.RayCast(checkFacing, distFromOrigin); Logger.WriteDebug("SafeArea: checking {0:F1} degrees at {1:F1} yds", WoWMathHelper.RadiansToDegrees(checkFacing), distFromOrigin); DateTime start = DateTime.UtcNow; bool failTrace = Movement.MeshTraceline(Me.Location, ptDestination); spanTrace += DateTime.UtcNow - start; bool failNav; if (DirectPathOnly) { failNav = failTrace; spanNav = spanTrace; } else { start = DateTime.UtcNow; failNav = !Navigator.CanNavigateFully(Me.Location, ptDestination); spanNav += DateTime.UtcNow - start; } if (failTrace) countFailTrace++; if (failTrace != failNav) countFailDiff++; if (failNav) { // Logger.WriteDebug( Color.Cyan, "Safe Location failed navigation check for degrees={0:F1} dist={1:F1}", RadiansToDegrees(checkFacing), distFromOrigin); countFailToPointNav++; continue; } WoWPoint ptNearest = NearestMobLoc(ptDestination, mobLocations); if (ptNearest == WoWPoint.Empty) { if (furthestNearMobDistSqr < minSafeDistSqr) { furthestNearMobDistSqr = minSafeDistSqr; ptFurthest = ptDestination; // set best available if others fail facingFurthest = checkFacing; } } else { double mobDistSqr = ptDestination.Distance2DSqr(ptNearest); if (furthestNearMobDistSqr < mobDistSqr) { furthestNearMobDistSqr = mobDistSqr; ptFurthest = ptDestination; // set best available if others fail facingFurthest = checkFacing; } if (mobDistSqr <= minSafeDistSqr) { countFailSafe++; continue; } } if (reallyCheckRangeToLineOfSightMob && RangeToLineOfSightMob < ptDestination.Distance(LineOfSightMob.Location) - LineOfSightMob.MeleeDistance()) { countFailRange++; continue; } if (CheckLineOfSightToSafeLocation) { WoWPoint ptAdjDest = ptDestination; ptAdjDest.Z += 1f; if (!Styx.WoWInternals.World.GameWorld.IsInLineOfSight(ptAdjOrigin, ptAdjDest)) { // Logger.WriteDebug( Color.Cyan, "Mob-free location failed line of sight check for degrees={0:F1} dist={1:F1}", degreesFrom, distFromOrigin); countFailToPointLoS++; continue; } } if (CheckSpellLineOfSightToMob && LineOfSightMob != null) { if (!Styx.WoWInternals.World.GameWorld.IsInLineOfSpellSight(ptDestination, LineOfSightMob.GetTraceLinePos())) { if (!Styx.WoWInternals.World.GameWorld.IsInLineOfSight(ptDestination, LineOfSightMob.GetTraceLinePos())) { // Logger.WriteDebug( Color.Cyan, "Mob-free location failed line of sight check for degrees={0:F1} dist={1:F1}", degreesFrom, distFromOrigin); countFailToMobLoS++; continue; } } } Logger.WriteDebug(Color.Cyan, "SafeArea: Found mob-free location ({0:F1} yd radius) at degrees={1:F1} dist={2:F1} on point check# {3} at {4}, {5}, {6}", MinSafeDistance, WoWMathHelper.RadiansToDegrees(checkFacing), distFromOrigin, countPointsChecked, ptDestination.X, ptDestination.Y, ptDestination.Z); Logger.WriteDebug(Color.Cyan, "SafeArea: processing took {0:F0} ms", (DateTime.UtcNow - startFind).TotalMilliseconds); Logger.WriteDebug(Color.Cyan, "SafeArea: meshtrace took {0:F0} ms / fullynav took {1:F0} ms", spanTrace.TotalMilliseconds, spanNav.TotalMilliseconds); Logger.WriteDebug(Color.Cyan, "SafeArea: stats for ({0:F1} yd radius) found within {1:F1} yds ({2} checked, {3} nav, {4} not safe, {5} range, {6} pt los, {7} mob los, {8} mesh trace)", MinSafeDistance, MaxScanDistance, countPointsChecked, countFailToPointNav, countFailSafe, countFailRange, countFailToPointLoS, countFailToMobLoS, countFailTrace); return ptDestination; } } Logger.WriteDebug(Color.Cyan, "SafeArea: No mob-free location ({0:F1} yd radius) found within {1:F1} yds ({2} checked, {3} nav, {4} not safe, {5} range, {6} pt los, {7} mob los, {8} mesh trace)", MinSafeDistance, MaxScanDistance, countPointsChecked, countFailToPointNav, countFailSafe, countFailRange, countFailToPointLoS, countFailToMobLoS, countFailTrace); if (ChooseSafestAvailable && ptFurthest != WoWPoint.Empty) { Logger.WriteDebug(Color.Cyan, "SafeArea: choosing best available spot in {0:F1} yd radius where closest mob is {1:F1} yds", MinSafeDistance, Math.Sqrt(furthestNearMobDistSqr)); Logger.WriteDebug(Color.Cyan, "SafeArea: processing took {0:F0} ms", (DateTime.UtcNow - startFind).TotalMilliseconds); Logger.WriteDebug(Color.Cyan, "SafeArea: meshtrace took {0:F0} ms / fullynav took {1:F0} ms", spanTrace.TotalMilliseconds, spanNav.TotalMilliseconds); return ChooseSafestAvailable ? ptFurthest : WoWPoint.Empty; } Logger.WriteDebug(Color.Cyan, "SafeArea: processing took {0:F0} ms", (DateTime.UtcNow - startFind).TotalMilliseconds); Logger.WriteDebug(Color.Cyan, "SafeArea: meshtrace took {0:F0} ms / fullynav took {1:F0} ms", spanTrace.TotalMilliseconds, spanNav.TotalMilliseconds); return WoWPoint.Empty; }
public static WoWPoint getSaveLocation(WoWPoint Location, int minDist, int maxDist, int traceStep) { Logging.WriteNavigator("{0} - Navigation: Looking for save Location around {1}.", TimeNow, Location); float _PIx2 = 3.14159f * 2f; for (int i = 0, x = minDist; i < traceStep && x < maxDist; i++) { WoWPoint p = Location.RayCast((i * _PIx2) / traceStep, x); p.Z = getGroundZ(p); WoWPoint pLoS = p; pLoS.Z = p.Z + 0.5f; if (p.Z != float.MinValue && StyxWoW.Me.Location.Distance(p) > 1) { if (getHighestSurroundingSlope(p) < 1.2f && GameWorld.IsInLineOfSight(pLoS, Location) /*&& Navigator.CanNavigateFully(StyxWoW.Me.Location, Location)*/) { Logging.WriteNavigator("{0} - Navigation: Moving to {1}. Distance: {2}", TimeNow, p, Location.Distance(p)); return p; } } if (i == (traceStep - 1)) { i = 0; x++; } } Logging.Write(System.Drawing.Color.Red, "{0} - No valid points returned by RayCast...", TimeNow); return WoWPoint.Empty; }
/// <summary> /// Credits to funkescott. /// </summary> /// <returns>Highest slope of surrounding terrain, returns 100 if the slope can't be determined</returns> public static float getHighestSurroundingSlope(WoWPoint p) { Logging.WriteNavigator("{0} - Navigation: Sloapcheck on Point: {1}", TimeNow, p); float _PIx2 = 3.14159f * 2f; float highestSlope = -100; float slope = 0; int traceStep = 15; float range = 0.5f; WoWPoint p2; for (int i = 0; i < traceStep; i++) { p2 = p.RayCast((i * _PIx2) / traceStep, range); p2.Z = getGroundZ(p2); slope = Math.Abs(getSlope(p, p2)); if (slope > highestSlope) { highestSlope = (float)slope; } } Logging.WriteNavigator("{0} - Navigation: Highslope {1}", TimeNow, highestSlope); return Math.Abs(highestSlope); }
WoWPoint TryGetHeight(WoWPoint point, Height ht) { float PIx2 = (float)Math.PI * 2f; int step = 20; for (int d = 5; d <= 50; d += 5) { for (int i = 0; i < 20; i++) { WoWPoint newPoint = point.RayCast((i * PIx2) / step, d); try { newPoint.Z = ht == Height.High ? Navigator.FindHeights(newPoint.X, newPoint.Y).Max() : Navigator.FindHeights(newPoint.X, newPoint.Y).Min(); return newPoint; } catch { } } } return point; }