private void RefreshCharacterDirection() { var camDir = this.zoneController.CameraDirection; var zeroPoint = new API.Data.Entities.Point(0, 0); var newAngle = CalcUtil.CalculateAngle(CalcUtil.Vector.CreateVector(zeroPoint, camDir), CalcUtil.Vector.CreateVector(zeroPoint, zeroPoint)); this.CameraDirection = newAngle; }
/// <summary> /// Calculates the distance between 2 points, using x, y, and z coordinates /// </summary> /// <param name="ptA">The first point</param> /// <param name="ptB">The second point</param> /// <param name="units">Units of the value to return</param> /// <returns>The distance between ptA and ptB, using x, y, and z coordinates, using the specified units</returns> public static double CalculateDistance(API.Data.Entities.Point ptA, API.Data.Entities.Point ptB, Units units) { switch (units) { case Units.Feet: return(CalcUtil.CalculateDistance(ptA, ptB) / 12.0); case Units.Meters: return(CalcUtil.CalculateDistance(ptA, ptB) / 39.3701); case Units.TimeDistance: return(CalcUtil.CalculateTimeDistance(CalcUtil.CalculateDistance(ptA, ptB))); default: return(0); } }
/// <summary> /// Primary method for refreshing the locations of points in the current zone /// </summary> /// <param name="state"></param> private void RefreshLocations(object state = null) { lock (locationsRefreshTimerLock) { if (this.isStopped) { return; // Immediately return if we are supposed to be stopped } API.Data.Entities.Point playerPos = null; API.Data.Entities.Point cameraDir = null; try { playerPos = this.playerService.PlayerPosition; cameraDir = this.playerService.CameraDirection; } catch (ObjectDisposedException) { // The player service is disposed! return; } if (playerPos != null && cameraDir != null) { var playerMapPosition = CalcUtil.ConvertToMapPosition(playerPos); var cameraDirectionMapPosition = CalcUtil.ConvertToMapPosition(cameraDir); Threading.BeginInvokeOnUI(() => { if (playerMapPosition.X != this.CharacterPosition.X && playerMapPosition.Y != this.CharacterPosition.Y) { this.CharacterPosition = playerMapPosition; } if (cameraDirectionMapPosition.X != this.CameraDirection.X && cameraDirectionMapPosition.Y != this.CameraDirection.Y) { this.CameraDirection = cameraDirectionMapPosition; } }); lock (this.zoneItemsLock) { foreach (var item in this.ZoneItems) { var newDistance = Math.Round(CalcUtil.CalculateDistance(playerMapPosition, item.ItemModel.Location, this.UserData.DistanceUnits)); var newAngle = CalcUtil.CalculateAngle(CalcUtil.Vector.CreateVector(playerMapPosition, item.ItemModel.Location), CalcUtil.Vector.CreateVector(new API.Data.Entities.Point(0, 0), cameraDirectionMapPosition)); if (item.DistanceFromPlayer != newDistance) { Threading.BeginInvokeOnUI(() => item.DistanceFromPlayer = newDistance); } if (item.DirectionFromPlayer != newAngle) { Threading.BeginInvokeOnUI(() => item.DirectionFromPlayer = newAngle); } if (!item.IsUnlocked) { // If the zone item isn't already unlocked, check to see if it should be automatically unlocked // based on the item's distance from the player and based on how long the player has been near the item var ftDistance = Math.Round(CalcUtil.CalculateDistance(playerMapPosition, item.ItemModel.Location, API.Data.Enums.Units.Feet)); switch (item.ItemType) { case API.Data.Enums.ZoneItemType.Waypoint: if (this.UserData.AutoUnlockWaypoints && ftDistance >= 0 && ftDistance < 75) { Threading.InvokeOnUI(() => item.IsUnlocked = true); } break; case API.Data.Enums.ZoneItemType.PointOfInterest: if (this.UserData.AutoUnlockPois && ftDistance >= 0 && ftDistance < 75) { Threading.InvokeOnUI(() => item.IsUnlocked = true); } break; case API.Data.Enums.ZoneItemType.Vista: if (this.UserData.AutoUnlockVistas && ftDistance >= 0 && ftDistance < 8) { if (this.playerInProximityCounters[item.ItemId] > 4) { this.playerInProximityCounters[item.ItemId] = 0; Threading.InvokeOnUI(() => item.IsUnlocked = true); } else { this.playerInProximityCounters[item.ItemId] += 1; } } else { this.playerInProximityCounters[item.ItemId] = 0; } break; case API.Data.Enums.ZoneItemType.HeartQuest: if (this.UserData.AutoUnlockHeartQuests && ftDistance >= 0 && ftDistance < 400) { if (this.playerInProximityCounters[item.ItemId] > 90) { this.playerInProximityCounters[item.ItemId] = 0; Threading.InvokeOnUI(() => item.IsUnlocked = true); } else { this.playerInProximityCounters[item.ItemId] += 1; } } else { this.playerInProximityCounters[item.ItemId] = 0; } break; case API.Data.Enums.ZoneItemType.HeroPoint: if (this.UserData.AutoUnlockSkillChallenges && ftDistance >= 0 && ftDistance < 25) { if (this.playerInProximityCounters[item.ItemId] > 15) { this.playerInProximityCounters[item.ItemId] = 0; Threading.InvokeOnUI(() => item.IsUnlocked = true); } else { this.playerInProximityCounters[item.ItemId] += 1; } } else { this.playerInProximityCounters[item.ItemId] = 0; } break; default: break; } } } } } this.itemLocationsRefreshTimer.Change(this.LocationsRefreshInterval, Timeout.Infinite); } }
/// <summary> /// Calculates the distance between 2 points, using x, y, and z coordinates /// </summary> /// <param name="ptA">The first point</param> /// <param name="ptB">The second point</param> /// <returns>The distance between ptA and ptB, using x, y, and z coordinates</returns> public static double CalculateDistance(API.Data.Entities.Point ptA, API.Data.Entities.Point ptB) { // Note: Removing inclusion of the Z component, since it seems like the resulting distance isn't accurate in the game (might be a problem with the Z axis reported by the game) //return Math.Sqrt(Math.Pow(Math.Abs((ptB.X - ptA.X)), 2) + Math.Pow(Math.Abs((ptB.Y - ptA.Y)), 2) + Math.Pow(Math.Abs((ptB.Z - ptA.Z)), 2)); return(Math.Sqrt(Math.Pow(Math.Abs((ptB.X - ptA.X)), 2) + Math.Pow(Math.Abs((ptB.Y - ptA.Y)), 2))); }
/// <summary> /// Converts a given mumble-link Point to a map position. /// Note: mumble-link is in meters, while map position is in inches /// </summary> /// <param name="mumbleLinkPoint">The mumble link point to convert</param> /// <returns>The point in Map-Coordinates</returns> public static API.Data.Entities.Point ConvertToMapPosition(API.Data.Entities.Point mumbleLinkPoint) { return(new API.Data.Entities.Point(mumbleLinkPoint.X * MapConversionFactor, mumbleLinkPoint.Y * MapConversionFactor, mumbleLinkPoint.Z * MapConversionFactor)); }
public static Vector CreateVector(API.Data.Entities.Point pt1, API.Data.Entities.Point pt2) { return(new Vector(pt2.X - pt1.X, pt2.Y - pt1.Y, pt2.Z - pt1.Z)); }
/// <summary> /// Determines if point B is within the given spherical radius of point A /// </summary> /// <param name="ptA">The static/origin point</param> /// <param name="ptB">Point to test</param> /// <param name="radius">Radius to test with</param> /// <returns>True if point B is within the given spherical radius of point A, else false</returns> public static bool IsInRadius(API.Data.Entities.Point ptA, API.Data.Entities.Point ptB, double radius) { return(Math.Pow((ptB.X - ptA.X), 2) + Math.Pow((ptB.Y - ptA.Y), 2) + Math.Pow((ptB.Z - ptA.Z), 2) <= Math.Pow(radius, 2)); }