/// <summary> /// Load from XML: initializing constructor from an XML node. /// </summary> /// <param name="node">A node is a "Waypoint" node Nova save file (xml document). /// </param> public Waypoint(XmlNode node) { XmlNode mainNode = node.FirstChild; while (mainNode != null) { try { switch (mainNode.Name.ToLower()) { case "destination": Destination = mainNode.FirstChild.Value; break; case "warpfactor": WarpFactor = int.Parse(mainNode.FirstChild.Value, System.Globalization.CultureInfo.InvariantCulture); break; case "position": Position = new NovaPoint(mainNode); break; default: LoadTask(mainNode.Name.ToString(), mainNode); break; } } catch (Exception e) { Report.FatalError(e.Message + "\n Details: \n" + e.ToString()); } mainNode = mainNode.NextSibling; } }
/// <summary> /// Move a position some distance nearer to another point. /// </summary> /// <remarks> /// FIXME (priority 6) - rounding can cause no movement to occur. /// Fix added, requires testing - Dan 4 Apr 10. /// </remarks> /// <param name="from">The stating <see cref="NovaPoint"/>.</param> /// <param name="to">The destination <see cref="NovaPoint"/>.</param> /// <param name="distance">The actual distance to move.</param> /// <returns>If the distance between from and to is less than 'distance' then returns 'to. /// Otherwise a point 'distance' away from 'from' in the direction of 'to'.</returns> public static NovaPoint MoveTo(NovaPoint from, NovaPoint to, double distance) { NovaPoint result = new NovaPoint(from); double my = to.Y - from.Y; double mx = to.X - from.X; double theta = Math.Atan2(my, mx); double dx = distance * Math.Cos(theta); double dy = distance * Math.Sin(theta); result.X += (int)(dx + 0.5); result.Y += (int)(dy + 0.5); // Check for no movement due to rounding and correct. if (result.X == from.X && result.Y == from.Y && distance > 0.5) { if (my > mx) { result.Y += (int)(distance + 0.5); } else { result.X += (int)(distance + 0.5); } } return(result); }
internal void CenterMapOnPoint(NovaPoint pointToCentre) { // We want to put the logical point given in the center of the map as much as possible NovaPoint centerDisplay = new NovaPoint(MapPanel.Width / 2, MapPanel.Height / 2); ScrollToDisplayLocation(centerDisplay, pointToCentre); }
/// <summary> /// Check if the fleet hits the minefiled. /// </summary> /// <remarks> /// The probability of hitting a mine is 0.3% per light year traveled for each /// warp over the safe speed. /// TODO (priority 3) - reference required. /// /// Example: A fleet traveling at Warp 9 has a 1.5% chance per light year /// traveled in a turn. Traveling 10 light years through the Minefield that /// turn, the fleet has a 10.5% chance of triggering a mine. /// </remarks> /// <param name="fleet">The moving fleet.</param> /// <param name="minefield">The minefield being traversed.</param> /// <returns>true if the minefield is hit.</returns> private bool CheckForHit(Fleet fleet, Minefield minefield) { // Calculate how long we are going to be in the Minefield. This is the // lesser of the distance to the next waypoint and the radius of the // field. NovaPoint currentPosition = fleet.Position; Waypoint targetWaypoint = fleet.Waypoints[0]; NovaPoint targetPosition = targetWaypoint.Position; double travelDistance = PointUtilities.Distance(currentPosition, targetPosition); if (minefield.Radius > (int)travelDistance) { travelDistance = minefield.Radius; } double speeding = fleet.Speed - minefield.SafeSpeed; double probability = (0.03 * travelDistance * speeding) * 100; double dice = random.Next(0, 100); if (dice < probability) { return(true); } return(false); }
/// <Summary> /// Provides a list of objects within a certain distance from a position, /// ordered by distance. /// /// Copied from StarMap.cs (should probably make this a utility) /// </Summary> /// <param name="position">Starting Point for the search.</param> /// <returns>A list of Fleet and Star objects.</returns> private List <Mappable> FindNearObjects(NovaPoint position) { List <Mappable> nearObjects = new List <Mappable>(); foreach (FleetIntel report in clientData.EmpireState.FleetReports.Values) { if (!report.IsStarbase) { if (PointUtilities.IsNear(report.Position, position)) { nearObjects.Add(report); } } } foreach (StarIntel report in clientData.EmpireState.StarReports.Values) { if (PointUtilities.IsNear(report.Position, position)) { nearObjects.Add(report); } } // nearObjects.Sort(ItemSorter); return(nearObjects); }
/// <summary> /// Calculate the fuel required for this fleet to reach a given destination. /// </summary> /// <param name="warpFactor">The warp speed to travel at.</param> /// <param name="race">The race operating the fleet.</param> /// <param name="dest">The destination as a <see cref="NovaPoint"/>.</param> /// <returns>The estimated fuel consumption.</returns> /// <remarks> /// FIXME (priority 4) - probably has rounding errors. /// FIXME (priority 3) - should this account for final year slow down?. /// </remarks> public int GetFuelRequired(int warpFactor, Race race, NovaPoint dest) { double fuelConsumption = FuelConsumption(warpFactor, race); double time = PointUtilities.DistanceSquare(this.Position, dest) / (warpFactor * warpFactor * warpFactor * warpFactor); return((int)(time * fuelConsumption)); }
/// <Summary> /// Add an indication of a starbase (circle) or orbiting fleets (smaller /// circle) or both. /// </Summary> /// <param name="Star">The Star being drawn.</param> private void DrawOrbitingFleets(Graphics g, StarIntel report) { NovaPoint position = LogicalToDevice(report.Position); if (report == null) { return; } if (report.Starbase != null) { g.FillEllipse( Brushes.Yellow, position.X + 6, position.Y - 6, 4, 4); } if (report.HasFleetsInOrbit) { int size = 12; g.DrawEllipse( Pens.White, position.X - (size / 2), position.Y - (size / 2), size, size); } }
/// <summary> /// Fleet construction for unit testing and stack creation during a battle. /// </summary> /// <param name="name">The fleet name.</param> /// <param name="id">The fleet id.</param> /// <param name="position">The fleet position.</param> public Fleet(string name, ushort owner, uint id, NovaPoint position) { Name = name; Owner = owner; Id = id; Position = position; }
/// <summary> /// Find the square of the distance between two points. /// <para> /// This is much faster than finding the actual distance (as it avoids a square root calculation) and just as useful when making distance comparisons. /// </para> /// </summary> /// <param name="start">A point.</param> /// <param name="end">Another point.</param> /// <returns>The distance between start and end, squared.</returns> public static double DistanceSquare(NovaPoint start, NovaPoint end) { double xo = start.X - end.X; double yo = start.Y - end.Y; return((xo * xo) + (yo * yo)); }
private void Zoom(double delta, NovaPoint preserveDisplayLocation) { if (System.Object.ReferenceEquals(preserveDisplayLocation, null)) { preserveDisplayLocation = new NovaPoint(MapPanel.Width / 2, MapPanel.Height / 2); } NovaPoint preserveLogicalLocation = DeviceToLogical(preserveDisplayLocation); zoomFactor *= delta; this.zoomFactor = Math.Max(MinZoom, this.zoomFactor); this.zoomFactor = Math.Min(MaxZoom, this.zoomFactor); this.zoomOut.Enabled = zoomFactor > MinZoom; this.zoomIn.Enabled = zoomFactor < MaxZoom; this.extent.X = (int)(this.logical.X * this.zoomFactor) + (extraSpace.X * 2); this.extent.Y = (int)(this.logical.Y * this.zoomFactor) + (extraSpace.X * 2); // In the case where the Map Panel is bigger than what we want to display (i.e. extent) // then we add an offset to center the displayed map inside the panel // If extent is bigger then it's handled by the scroll offsets displayOffset.X = Math.Max((MapPanel.Width - extent.X) / 2, 0); displayOffset.Y = Math.Max((MapPanel.Height - extent.Y) / 2, 0); this.verticalScrollBar.Maximum = Math.Max(0, extent.Y - MapPanel.Height); this.horizontalScrollBar.Maximum = Math.Max(0, (extent.X - MapPanel.Width)); // Try and scroll map back to location ScrollToDisplayLocation(preserveDisplayLocation, preserveLogicalLocation); this.RefreshStarMap(this, EventArgs.Empty); }
/// <summary> /// Calculate the distance between two points. /// </summary> /// <remarks> /// If comparing distances consider using DistanceSquare - it is much faster. /// </remarks> /// <param name="start">A point.</param> /// <param name="end">Another point.</param> /// <returns>Distance between the start and end points.</returns> /// TODO (priority 3) - Find calls to this function that could use DistanceSquare instead (for speed). public static double Distance(NovaPoint start, NovaPoint end) { double xo = start.X - end.X; double yo = start.Y - end.Y; double distance = Math.Sqrt((xo * xo) + (yo * yo)); return(distance); }
/// <summary> /// Handle zooming via the mousewheel. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void StarMap_MouseWheel(object sender, MouseEventArgs e) { double zoomChange = 1 + (Math.Sign(e.Delta) * 0.15); // This event fires on the StarMap control so we have to remove the mappanel offset to // get the real mouse location NovaPoint preserveLocation = new NovaPoint(e.X - MapPanel.Left, e.Y - MapPanel.Top); Zoom(zoomChange, preserveLocation); }
private NovaPoint LogicalToExtent(NovaPoint p) { NovaPoint result = new NovaPoint(); result.X = (int)(p.X * zoomFactor) + extraSpace.X; result.Y = (int)(p.Y * zoomFactor) + extraSpace.Y; return(result); }
/// <Summary> /// Convert device coordinates to logical coordinates. /// </Summary> /// <param name="p">The Point to convert.</param> /// <returns>The converted Point.</returns> private NovaPoint DeviceToLogical(NovaPoint p) { NovaPoint result = new NovaPoint(); result.X = (int)((p.X - displayOffset.X + scrollOffset.X - extraSpace.X) / zoomFactor); result.Y = (int)((p.Y - displayOffset.Y + scrollOffset.Y - extraSpace.Y) / zoomFactor); return(result); }
/// <Summary> /// Convert logical coordinates to device coordintes. /// </Summary> /// <param name="p">The Point to convert.</param> /// <returns>A converted Point.</returns> private NovaPoint LogicalToDevice(NovaPoint p) { NovaPoint result = LogicalToExtent(p); result.X += displayOffset.X - scrollOffset.X; result.Y += displayOffset.Y - scrollOffset.Y; return(result); }
/// <summary> /// Return a random position within a Rectangle. A border (which may be zero) is /// applied to the area where point positions will not be allocated. This /// ensures that returned points are never too close to the edge of the /// rectangle. /// </summary> /// <param name="box">A <see cref="Rectangle"/> which will contain the point.</param> /// <param name="boxBorder">The minimum distance between the point and the edge of the box.</param> /// <returns>A <see cref="Point"/> within the box.</returns> public static NovaPoint GetPositionInBox(Rectangle box, int boxBorder) { int boxSize = box.Width; NovaPoint position = new NovaPoint(box.X, box.Y); position.X += Random.Next(boxBorder, boxSize - boxBorder); position.Y += Random.Next(boxBorder, boxSize - boxBorder); return(position); }
/// <summary> /// Copy (initializing) constructor. /// </summary> /// <param name="existing"></param> public Mappable(Mappable existing) : base(existing) { if (existing == null) { return; } // Use a new object, no just a reference to the copy's NovaPoint Position = new NovaPoint(existing.Position); }
/// <Summary> /// Draw a filled circle using logical coordinates. /// </Summary> /// <param name="brush"></param> /// <param name="where"></param> /// <param name="logicalRadius"></param> private void DrawCircle(Graphics g, Brush brush, NovaPoint where, int logicalRadius) { if (logicalRadius == 0) { return; } NovaPoint position = LogicalToDevice(where); FillCircle(g, brush, (Point)position, (int)(logicalRadius * zoomFactor)); }
/// <summary> /// Resets all values to default. /// </summary> public void Clear() { Year = Global.Unset; Name = string.Empty; Position = new NovaPoint(); Owner = Global.Nobody; Type = ItemType.FleetIntel; Bearing = Global.Unset; Speed = Global.Unset; Composition = new Dictionary <long, ShipToken>(); }
public void TestIsNearDoesNotChangeParams() { NovaPoint a = new NovaPoint(1, 2); NovaPoint b = new NovaPoint(3, 4); bool testNear = PointUtilities.IsNear(a, b); Assert.IsTrue(a.X == 1); Assert.IsTrue(a.Y == 2); Assert.IsTrue(b.X == 3); Assert.IsTrue(b.Y == 4); }
private void ScrollToDisplayLocation(NovaPoint oldDisplay, NovaPoint pointToCentre) { NovaPoint newCenterDisplay = LogicalToExtent(pointToCentre); Debug.WriteLine(String.Format("Center Disp {0} NewCenterDisp {1}", oldDisplay, newCenterDisplay)); scrollOffset.X = Math.Min(horizontalScrollBar.Maximum, Math.Max(0, newCenterDisplay.X - oldDisplay.X)); scrollOffset.Y = Math.Min(verticalScrollBar.Maximum, Math.Max(0, newCenterDisplay.Y - oldDisplay.Y)); horizontalScrollBar.Value = scrollOffset.X; verticalScrollBar.Value = scrollOffset.Y; }
private void SendFleet(NovaPoint position, Fleet fleet, IWaypointTask task) { Waypoint w = new Waypoint(); w.Position = position; w.Destination = position.ToString(); w.Task = task; WaypointCommand command = new WaypointCommand(CommandMode.Add, w, fleet.Key); command.ApplyToState(clientState.EmpireState); clientState.Commands.Push(command); }
public Star GetStarAtPosition(NovaPoint position) { if (starPositionDictionary == null) { starPositionDictionary = new Dictionary <string, Star>(); foreach (Star star in AllStars.Values) { starPositionDictionary.Add(star.Position.ToHashString(), star); } } return(starPositionDictionary[position.ToHashString()]); }
/// <summary> /// Determine if two positions are within a 40x40 box. /// </summary> /// <param name="position1">The first position.</param> /// <param name="position2">The second position.</param> /// <returns>true if position 2 is within a 40x40 box around position 1.</returns> public static bool IsNear(NovaPoint position1, NovaPoint position2) { NovaPoint topCorner = new NovaPoint(position1); topCorner.Offset(-20, -20); Rectangle scanArea = new Rectangle(topCorner.X, topCorner.Y, 40, 40); if (InBox(position2, scanArea)) { return(true); } return(false); }
/// <summary> /// Load: initializing constructor from an XmlNode representing the object (from a save file). /// </summary> /// <param name="node">An XmlNode representing the Mappable object.</param> public Mappable(XmlNode node) : base(node) { if (node == null) { Report.FatalError("Mappable.cs: Mappable(XmlNode node) - node is null - no Mappable found."); return; } // Search for the first Mappable node in this Xml representation. XmlNode mapNode = null; while (node != null) { if ((mapNode = node.SelectSingleNode("Mappable")) != null) { break; } node = node.FirstChild; } if (mapNode == null) { Report.FatalError("Mappable.cs: Mappable(XmlNode node) - could not find Mappable node, input file may be corrupt."); return; } XmlNode mainNode = mapNode.FirstChild; while (mainNode != null) { try { switch (mainNode.Name.ToLower()) { case "point": Position = new NovaPoint(mainNode); break; } } catch (Exception e) { Report.Error(e.Message + " \n Details: \n " + e.ToString()); } mainNode = mainNode.NextSibling; } }
/// <summary> /// Resets all values to default. /// </summary> public void Clear() { Year = Global.Unset; Name = string.Empty; Position = new NovaPoint(); Owner = Global.Nobody; Type = ItemType.StarIntel; MineralConcentration = new Resources(); Gravity = Global.Unset; Radiation = Global.Unset; Temperature = Global.Unset; Colonists = Global.Unset; HasFleetsInOrbit = false; Starbase = null; }
/// <summary> /// Determine if a point is within a bounding box. /// </summary> /// <param name="p">The <see cref="NovaPoint"/> in question.</param> /// <param name="box">The <see cref="Rectangle"/> defining the space to check.</param> /// <returns>True if point p is in the box.</returns> public static bool InBox(NovaPoint p, Rectangle box) { NovaPoint upperLeft = new NovaPoint(box.Location); NovaPoint bottomRight = new NovaPoint(box.Location); bottomRight.Offset(box.Width, box.Height); if (((p.X > upperLeft.X) && (p.X < bottomRight.X)) && ((p.Y > upperLeft.Y) && (p.Y < bottomRight.Y))) { return(true); } return(false); }
/// <Summary> /// Populate context menu after right clicking the diamond button /// </Summary> /// <param name="sender">The source of the event.</param> /// <param name="e">A <see cref="EventArgs"/> that contains the event data.</param> private void ShowWaypointContext(object sender, EventArgs e) { NovaPoint position = new NovaPoint(); int index = wayPoints.SelectedIndices[0]; Waypoint waypoint = new Waypoint(selectedFleet.Waypoints[index]); position = waypoint.Position; List <Mappable> nearObjects = FindNearObjects(position); if (nearObjects.Count == 0) { return; } contextMenuWaypointTargets.Items.Clear(); bool needSep = false; bool doneSep = false; foreach (Item sortableItem in nearObjects) { ToolStripItem menuItem = contextMenuWaypointTargets.Items.Add(sortableItem.Name); if (sortableItem.Type == ItemType.StarIntel) { // Put stars at the top o' da list contextMenuWaypointTargets.Items.Insert(0, menuItem); contextMenuWaypointTargets.Items.Insert(1, new ToolStripSeparator()); } menuItem.Tag = sortableItem; if (sortableItem.Type == ItemType.StarIntel) { menuItem.Image = Properties.Resources.planeticon; needSep = true; } else if (sortableItem.Type == ItemType.FleetIntel) { menuItem.Image = Properties.Resources.fleet; if (needSep && !doneSep) { contextMenuWaypointTargets.Items.Insert(1, new ToolStripSeparator()); doneSep = true; } } } }
/// <summary> /// Determine if two circles overlap. /// </summary> /// <remarks> /// For two circles (position x,y and radius r) x1,y1,r1 and x2,y2,r2, if: /// (x2-x1)^2+(y2-y1)^2 <!--<--> (r2+r1)^2 /// Then the circles overlap. /// </remarks> /// <param name="p1">Centre of the first circle.</param> /// <param name="p2">Centre of the second circle.</param> /// <param name="r1">Radius of the first circle.</param> /// <param name="r2">Radius of the second circle.</param> /// <returns></returns> public static bool CirclesOverlap(NovaPoint p1, NovaPoint p2, double r1, double r2) { double x1 = p1.X; double x2 = p2.X; double y1 = p1.Y; double y2 = p2.Y; double f1 = Math.Pow(x2 - x1, 2); double f2 = Math.Pow(y2 - y1, 2); double f3 = Math.Pow(r2 + r1, 2); if ((f1 + f2) < f3) { return(true); } return(false); }
public void Generate_Dont_ScrapFleets() { // ToDo: Fleet-Generation and other things to seperate class/es and/or methods Fleet fleet = new Fleet(2); fleet.Owner = 1; NovaPoint point = new NovaPoint(0, 0); fleet.Position = point; ShipDesign shipDesign = new ShipDesign(2); shipDesign.Blueprint = new Component(); Hull hull = new Hull(); hull.Modules = new List <HullModule>(); hull.Modules.Add(new HullModule()); shipDesign.Blueprint.Properties.Add("Hull", hull); ShipToken shipToken = new ShipToken(shipDesign, 1); fleet.Composition.Add(shipToken.Key, shipToken); fleets.Add(fleet); Waypoint waypoint = new Waypoint(); NovaPoint waypointpoint = new NovaPoint(1, 1); waypoint.Position = waypointpoint; IWaypointTask task = new NoTask(); waypoint.Task = task; waypoint.Destination = "Star1"; fleet.Waypoints.Add(waypoint); empireData.AddOrUpdateFleet(fleet); // empireData.OwnedFleets.Add(fleet); // ToDo: this should not be allowed I think Console.WriteLine("2 Fleets: " + fleets.Count()); Assert.IsNotEmpty(serverData.IterateAllFleets().ToList()); Console.WriteLine("all Fleets count: " + serverData.IterateAllFleets().ToList().Count()); SimpleTurnGenerator turnGenerator = new SimpleTurnGenerator(serverData); turnGenerator.Generate(); // Assert.AreEqual(fleets.First().Composition.Count(), 1); Assert.IsNotEmpty(serverData.IterateAllFleets().ToList()); }