public MapLocation this[Location location] { get { if (location == null) return null; if (location.Longitude < 0 || location.Longitude >= longitudeCount || location.Latitude < minLatitude || location.Latitude >= minLatitude + latitudeCount) throw new InvalidOperationException($"Invalid longitude/latitude: ({location.Longitude}, {location.Latitude})"); return locations[location.Longitude, location.Latitude - minLatitude]; } }
public static bool HitTestCoordinate(Location clickLocation, Location location) { var clickPoint = LocationToScreen(clickLocation); if (clickPoint == null) return false; var point = LocationToScreen(location); if (point == null) return false; var dx = point.Value.X - clickPoint.Value.X; var dy = point.Value.Y - clickPoint.Value.Y; var distanceSquared = dx * dx + dy * dy; var distance = Math.Sqrt(distanceSquared); const int allowedDistanceForHit = 3; return distance <= allowedDistanceForHit; }
private void OnChooseDestination(Location location) { //TODO: hit test for terror sites and alien bases var ufos = GameState.Current.Data.VisibleUfos.Where(ufo => Trigonometry.HitTestCoordinate(ufo.Location, location)).ToList(); if (!ufos.Any()) new ConfirmDestination("WAY POINT", () => SelectWaypoint(location)).DoModal(this); else if (ufos.Count == 1) new ConfirmDestination(ufos[0].Name, () => SelectUfo(ufos[0])).DoModal(this); else { var selector = new SelectWorldObject( ufos.Cast<object>().ToList(), ufo => new ConfirmDestination(((Ufo)ufo).Name, () => SelectUfo((Ufo)ufo)).DoModal(this)); selector.DoModal(this); } }
public static Base Create(string name, Location location, RegionType region) { return new Base { Name = name, Number = GameState.Current.Data.NextBaseNumber++, Location = location, Region = region, Facilities = new List<Facility>(), Crafts = new List<Craft>(), Soldiers = new List<Soldier>(), Stores = Stores.Create(), ResearchProjects = new List<ResearchProject>(), ManufactureProjects = new List<ManufactureProject>(), TransferredSoldiers = new List<TransferItem<Soldier>>(), TransferredCrafts = new List<TransferItem<Craft>>(), TransferredStores = new List<TransferItem<StoreItem>>() }; }
public static Location MoveLocation(Location source, Location destination, int distance) { var xr = destination.Longitude < source.Longitude ? destination.Longitude + EighthDegreesCount : destination.Longitude; var xl = destination.Longitude > source.Longitude ? destination.Longitude - EighthDegreesCount : destination.Longitude; var dxr = xr - source.Longitude; var dxl = xl - source.Longitude; var dy = destination.Latitude - source.Latitude; var maxDistanceToRight = Math.Sqrt(dxr * dxr + dy * dy); var maxDistanceToLeft = Math.Sqrt(dxl * dxl + dy * dy); var destinationLongitude = maxDistanceToLeft < maxDistanceToRight ? xl : xr; var dx = maxDistanceToLeft < maxDistanceToRight ? dxl : dxr; var maxDistance = Math.Min(maxDistanceToLeft, maxDistanceToRight); if (distance >= maxDistance) return new Location { Longitude = destination.Longitude, Latitude = destination.Latitude }; double m, b, x; bool vertical; LineEquation(source.Longitude, source.Latitude, destinationLongitude, destination.Latitude, out m, out b, out vertical, out x); if (vertical) return new Location { Longitude = source.Longitude, Latitude = source.Latitude + Math.Sign(dy) * distance }; var c = b - source.Latitude; var longitudes = QuadraticEquationBothSolutions( m * m + 1, 2 * m * c - 2 * source.Longitude, c * c + source.Longitude * source.Longitude - distance * distance); var longitude = dx < 0 ? longitudes.Min() : longitudes.Max(); var latitude = m * longitude + b; return new Location { Longitude = AddEighthDegrees((int)longitude, 0), Latitude = (int)latitude }; }
public static Point? LocationToScreen(Location location) { var rollRadians = GameState.Current.Data.LongitudeOffset * radiansPerEighthDegree; var pitchRadians = GameState.Current.Data.Pitch * radiansPerEighthDegree; var latitude = location.Latitude * radiansPerEighthDegree; var longitude = location.Longitude * radiansPerEighthDegree; var unitZ = Math.Sin(latitude) * Math.Sin(pitchRadians) + Math.Cos(longitude + rollRadians) * Math.Cos(latitude) * Math.Cos(pitchRadians); if (unitZ < 0) return null; var unitX = Math.Sin(longitude + rollRadians) * Math.Cos(latitude); var unitY = Math.Sin(latitude) * Math.Cos(pitchRadians) - Math.Cos(longitude + rollRadians) * Math.Cos(latitude) * Math.Sin(pitchRadians); var x = (int)(unitX * WorldView.Radius) + WorldView.CenterX; var y = (int)(unitY * WorldView.Radius) + WorldView.CenterY; if (x < 0 || x >= WorldView.CenterX * 2 || y < 0 || y >= WorldView.CenterY * 2) return null; return new Point { X = x, Y = y }; }
private void OnChooseLocation(Location location) { var mapLocation = Map.Instance[location]; if (mapLocation.TerrainType != null) new NewBaseLocation(mapLocation).DoModal(this); }
public int CreateWaypoint(Location location) { var number = NextWaypointNumber++; Waypoints.Add(new Waypoint { Location = location, Number = number }); return number; }
public void CenterOn(Location location) { LongitudeOffset = Trigonometry.AddEighthDegrees(-location.Longitude, 0); Pitch = Trigonometry.AddEighthDegrees(location.Latitude, 0); }
private void SelectWaypoint(Location location) { SelectWorldObject(WorldObjectType.Waypoint, GameState.Current.Data.CreateWaypoint(location)); }
private void OnClick(Location location) { var data = GameState.Current.Data; var bases = data.Bases.Where(@base => Trigonometry.HitTestCoordinate(@base.Location, location)); var waypoints = data.Waypoints.Where(waypoint => Trigonometry.HitTestCoordinate(waypoint.Location, location)); var crafts = data.ActiveInterceptors.Where(craft => Trigonometry.HitTestCoordinate(craft.Location, location)); var ufos = data.VisibleUfos.Where(ufo => Trigonometry.HitTestCoordinate(ufo.Location, location)); var worldObjects = bases.Cast<object>() .Concat(waypoints) .Concat(crafts) .Concat(ufos) .ToList(); if (!worldObjects.Any()) return; if (worldObjects.Count > 1) new SelectWorldObject(worldObjects, OnSelectWorldObject).DoModal(this); else OnSelectWorldObject(worldObjects[0]); }