/// <summary> /// Gets the point that is furthest away of a collcetion from a unit. /// </summary> /// <param name="unit">The unit.</param> /// <param name="points">The list of points to chose from</param> /// <returns>The point.</returns> private Point GetFarthestPoint(Unit unit, CustomArrayList<Point> points) { Point farthestPoint = new Point(0, 0); double farthestDistance = 0; Point unitLocation = new Point((int)unit.x, (int)unit.y); for (int i = 0; i < points.Count(); i++) { Point p = points.ElementAt(i); double currentDistance = Util.GetHypoteneuseLength(p, unitLocation); if (currentDistance > farthestDistance) { farthestPoint = p; farthestDistance = currentDistance; } } return farthestPoint; }
/// <summary> /// Gets the point that is closest of a collection from a unit. /// </summary> /// <param name="unit">The unit.</param> /// <param name="points">The list of points to chose from</param> /// <returns>The point.</returns> private Point GetClosestPoint(Unit unit, CustomArrayList<Point> points) { Point closestPoint = new Point(0, 0); double closestDistance = Double.MaxValue; Point unitLocation = new Point((int)unit.x, (int)unit.y); for( int i = 0; i < points.Count(); i++){ Point p = points.ElementAt(i); double currentDistance = Util.GetHypoteneuseLength(p, unitLocation); if (currentDistance < closestDistance) { closestPoint = p; closestDistance = currentDistance; } } return closestPoint; }
/// <summary> /// Applies color to the map! /// </summary> /// <param name="location">The location to add color to.</param> /// <param name="radius">The radius to color.</param> public void ApplyColor(Vector2 location, int radius) { Rectangle rect = new Rectangle( (int)(location.X - radius), (int)(location.Y - radius), (int)(radius * 2), (int)(radius * 2)); CustomArrayList<Quad> quadList = new CustomArrayList<Quad>(); double checkInterval = 3.0; quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Left, rect.Top))); // top line for (int i = 0; i < checkInterval; i++) quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Left + (i * (int)(rect.Width / checkInterval)), rect.Top))); quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Right, rect.Top))); // right line for (int i = 0; i < checkInterval; i++) quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Right, rect.Top + (int)(i * (rect.Height / checkInterval))))); quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Left, rect.Bottom))); // bottom line for (int i = 0; i < checkInterval; i++) quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Left + (int)(i * (rect.Width / checkInterval)), rect.Bottom))); quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Right, rect.Bottom))); // left line for (int i = 0; i < checkInterval; i++) quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Left, rect.Top + (int)(i * (rect.Height / checkInterval))))); CustomArrayList<Quad> affectedQuads = new CustomArrayList<Quad>(); for (int i = 0; i < quadList.Count(); i++) { Quad quad = quadList.ElementAt(i); if (quad != null && !affectedQuads.Contains(quad)) affectedQuads.AddLast(quad); } // Update each of the quads. for (int i = 0; i < affectedQuads.Count(); i++) { Quad q = affectedQuads.ElementAt(i); Rectangle updatedRect = Rectangle.Intersect(q.rectangle, rect); updatedRect.X = updatedRect.X - q.rectangle.X; updatedRect.Y = updatedRect.Y - q.rectangle.Y; q.colorTexture.ColorTexture(updatedRect); } // this.tree. }
/* /// <summary> /// Converts a boolean to a texture. /// </summary> /// <param name="device">The device to create the texture on</param> /// <param name="data">The data</param> /// <param name="width">the width</param> /// <param name="inversedScale">An invesed scale. 2 means, 2 times as small. 4 times as small, etc. USE IN MULTIPLES OF 2, OR FAIL.</param> /// <returns></returns> public Texture2D BoolToTexture(GraphicsDevice device, Boolean[] data, int width, int inversedScale) { if (inversedScale == 1) return BoolToTexture(device, data, width); int[] intData = new int[data.Length / ( inversedScale * inversedScale )]; Texture2D texture = new Texture2D(device, width / inversedScale, ( data.Length / width) / inversedScale); int newPixelCount = 0; int skips = 0; for (int i = 0; i < data.Length - 1; i += inversedScale) { bool skipNext = false; if (i % (width * inversedScale) == 0) skipNext = true; if (data[i]) intData[newPixelCount] = (int)Color.Black.PackedValue; else intData[newPixelCount] = 0; newPixelCount++; if (skipNext) { // Console.Out.Write("Skipping @ " + i + ", " + newPixelCount + ", " + skips); i += width * (inversedScale - 1); // Console.Out.WriteLine(" new: " + i); skips++; continue; } } // Console.Out.WriteLine("Finished, copied " + newPixelCount + " pixels, while the array size is " + intData.Length); texture.SetData(intData); return texture; }*/ /// <summary> /// Updates the collisionmap, without updating or adding pathfinding points. /// DO NOT USE THIS METHOD IN-GAME, ONLY IN THE EDITOR. /// </summary> /// <param name="rect">The rectangle</param> /// <param name="add">Whether to add or to remove the rect.</param> public void UpdateCollisionMap(Rectangle rect, Boolean add) { CollisionChangedEvent e = new CollisionChangedEvent(); e.collisionMap = this; e.changedRect = rect; e.collisionAdded = add; CustomArrayList<Quad> quadList = new CustomArrayList<Quad>(); double checkInterval = 3.0; quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Left, rect.Top))); // top line for (int i = 0; i < checkInterval; i++) quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Left + (i * (int)(rect.Width / checkInterval)), rect.Top))); quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Right, rect.Top))); // right line for (int i = 0; i < checkInterval; i++) quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Right, rect.Top + (int)(i * (rect.Height / checkInterval))))); quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Left, rect.Bottom))); // bottom line for (int i = 0; i < checkInterval; i++) quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Left + (int)(i * (rect.Width / checkInterval)), rect.Bottom))); quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Right, rect.Bottom))); // left line for (int i = 0; i < checkInterval; i++) quadList.AddLast(this.tree.GetQuadByPoint(new Point(rect.Left, rect.Top + (int)(i * (rect.Height / checkInterval))))); CustomArrayList<Quad> affectedQuads = new CustomArrayList<Quad>(); for (int i = 0; i < quadList.Count(); i++) { Quad quad = quadList.ElementAt(i); if (quad != null && !affectedQuads.Contains(quad)) affectedQuads.AddLast(quad); } // Update each of the quads. for( int i = 0; i < affectedQuads.Count(); i++ ){ Quad q = affectedQuads.ElementAt(i); Rectangle updatedRect = Rectangle.Intersect(q.rectangle, rect); updatedRect.X = updatedRect.X - q.rectangle.X; updatedRect.Y = updatedRect.Y - q.rectangle.Y; q.collisionTexture.UpdateCollision(updatedRect, add); e.changedQuads.AddLast(new CollisionChangedEvent.QuadPart(q, updatedRect)); } FireCollisionChangedEvent(e); }
/// <summary> /// Places nodes around all the edges /// </summary> public CustomArrayList<Point> GetNodeLocationsAroundEdges() { Boolean previous = CollisionAt(0); CustomArrayList<Point> pointList = new CustomArrayList<Point>(); for (int i = 0; i < dataLength - 1; i++) { Boolean current = CollisionAt(i); if ((int)(i / mapWidth) % VERTICAL_COLLISION_CHECK_SPACING != 0) { continue; } // if (i % mapWidth > mapWidth - 15 || i % mapWidth < 15) { continue; } if (i % mapWidth == 0) { previous = current; } if (current != previous) { if (!current && (i + 10 < dataLength) && !CollisionAt(i + 10)) pointList.AddLast(IndexToPoint(i + 10)); else if ((i - 10 > -1) && !CollisionAt(i - 10)) pointList.AddLast(IndexToPoint(i - 10)); } previous = current; } for (int i = 0; i < mapWidth; i += HORIZONTAL_COLLISION_CHECK_SPACING) { for (int j = 0; j < mapHeight; j++) { int index = i + j * mapWidth; Boolean current = CollisionAt(index); // if (index % mapWidth % HORIZONTAL_COLLISION_CHECK_SPACING != 0) { continue; } if (j == 0) previous = current; // if (index % screenWidth > screenWidth - 15 || index % screenWidth < 15) continue; if (current != previous) { if (!current && (index + (10 * mapWidth) < dataLength) && !CollisionAt(index + (10 * mapWidth))) pointList.AddLast(IndexToPoint(index + (10 * mapWidth))); else if ((index - (10 * mapWidth) > -1) && !CollisionAt(index - (10 * mapWidth))) pointList.AddLast(IndexToPoint(index - (10 * mapWidth))); } previous = current; } } // Remove nodes that are closer than NODE_REMOVE_DISTANCE of each other for (int i = 0; i < pointList.Count(); i++) { Point p1 = pointList.ElementAt(i); for (int j = 0; j < pointList.Count(); j++) { Point p2 = pointList.ElementAt(j); if (p1 != p2 && PathfindingUtil.GetHypoteneuseLength(p1, p2) < NODE_REMOVE_DISTANCE) { pointList.Remove(p1); i--; j--; break; } } } return pointList; }
/// <summary> /// Gets the closest node in line of sight from the given point. /// </summary> /// <param name="p">The point.</param> /// <returns>The node, or null if no node is in range.</returns> public PathfindingNode ClosestNodeInLOS(Point p) { PathfindingNodeManager manager = PathfindingNodeManager.GetInstance(); CustomArrayList<PathfindingNode> inRangeNodes = new CustomArrayList<PathfindingNode>(); for( int i = 0; i < manager.GetNodeCount(); i++) { PathfindingNode node = manager.GetNodeAt(i); if (this.IsCollisionBetween(p, node.GetLocation())) { inRangeNodes.AddLast(node); } } PathfindingNode closestNode = inRangeNodes.ElementAt(0); double closestDistance = Double.MaxValue; for( int i = 0; i < inRangeNodes.Count(); i++ ){ PathfindingNode node = inRangeNodes.ElementAt(i); double newDistance = PathfindingUtil.GetHypoteneuseLength(closestNode.GetLocation(), node.GetLocation()); if (closestDistance > newDistance) { closestDistance = newDistance; closestNode = node; } } return closestNode; }