public void Reverse() { CollisionChangedEvent e = new CollisionChangedEvent(); e.collisionMap = collision; e.collisionAdded = false; e.changedRect = this.rect; foreach (CollisionChangedEvent.QuadPart part in e.changedQuads) { part.quad.collisionTexture.UpdateCollision(part.rectangle, false); } CustomArrayList<Node> processedNodes = new CustomArrayList<Node>(); foreach (Node node in createdNodes) { CustomArrayList<PathfindingNode> connectedNodes = node.GetConnectedNodes(); for( int i = 0; i < connectedNodes.Count(); i++ ){ Node connectedNode = (Node)connectedNodes.ElementAt(i); if (!processedNodes.Contains(connectedNode)) { SmartPathfindingNodeProcessor.GetInstance().Push(connectedNode); processedNodes.AddLast(connectedNode); } } node.Destroy(); } for( int i = 0; i < this.removedNodes.Count(); i++ ){ Point p = this.removedNodes.ElementAt(i); // Console.Out.WriteLine("Restoring node " + p); new Node(collision, p.X, p.Y); } collision.FireCollisionChangedEvent(e); }
/// <summary> /// Updates the collisionmap, adding the rectangle to the collisionmap, and performing new connections, as for placing nodes /// </summary> /// <param name="rect"></param> public BuildingMesh PlaceBuilding(Rectangle rect) { CollisionChangedEvent e = new CollisionChangedEvent(); e.collisionMap = this; e.changedRect = rect; e.collisionAdded = true; long ticks = DateTime.UtcNow.Ticks; this.UpdateCollisionMap(rect, true); Console.Out.WriteLine("Data put time: " + (DateTime.UtcNow.Ticks - ticks) / 10000 + "ms"); ticks = DateTime.UtcNow.Ticks; Node[] newNodes = new Node[4]; RTSCollisionMap map = Game1.GetInstance().map.collisionMap; newNodes[0] = new Node(map, rect.Left - 1, rect.Top - 1, false); newNodes[1] = new Node(map, rect.Right + 1, rect.Top - 1, false); newNodes[2] = new Node(map, rect.Left - 1, rect.Bottom + 1, false); newNodes[3] = new Node(map, rect.Right + 1, rect.Bottom + 1, false); Console.Out.WriteLine("Node create time: " + (DateTime.UtcNow.Ticks - ticks) / 10000 + "ms"); ticks = DateTime.UtcNow.Ticks; BuildingMesh mesh = new BuildingMesh(this); mesh.rect = rect; mesh.createdNodes = newNodes; PathfindingNodeManager manager = PathfindingNodeManager.GetInstance(); for (int i = 0; i < manager.GetNodeCount(); i++) { Node node = (Node)manager.GetNodeAt(i); if (rect.Contains(node.GetLocation())) mesh.removedNodes.AddLast(node.GetLocation()); } Console.Out.WriteLine("Mesh create time: " + (DateTime.UtcNow.Ticks - ticks) / 10000 + "ms"); /* ticks = DateTime.UtcNow.Ticks; CustomArrayList<Node> processedNodes = new CustomArrayList<Node>(); int nodesAdded = 0; foreach (Node newNode in newNodes) { } Console.Out.WriteLine("Node connection time: " + (DateTime.UtcNow.Ticks - ticks) / 10000 + "ms, adding " + nodesAdded + " nodes"); */ ticks = DateTime.UtcNow.Ticks; FireCollisionChangedEvent(e); Console.Out.WriteLine("Event time: " + (DateTime.UtcNow.Ticks - ticks)); return mesh; }
public void Reverse() { CollisionChangedEvent e = new CollisionChangedEvent(); e.collision = collision; e.collisionAdded = false; e.changedRect = this.rect; e.oldData = (Boolean[])collision.data.Clone(); Boolean color = false; for (int i = rect.Left; i < rect.Right; i++) { for (int j = rect.Top; j < rect.Bottom; j++) { collision.data[collision.PointToIndex(i, j)] = color; } } collision.texture = collision.BoolToTexture(Game1.GetInstance().GraphicsDevice, collision.data, collision.mapWidth, collision.collisionMapTextureScale); e.newData = collision.data; LinkedList<Node> processedNodes = new LinkedList<Node>(); foreach (Node node in createdNodes) { foreach (Node connectedNode in node.GetConnectedNodes()) { if (!processedNodes.Contains(connectedNode)) { SmartPathfindingNodeProcessor.GetInstance().Push(connectedNode); processedNodes.AddLast(connectedNode); } } node.Destroy(); } foreach (Point p in removedNodes) { // Console.Out.WriteLine("Restoring node " + p); new Node(collision, p.X, p.Y); } collision.FireCollisionChangedEvent(e); }
void OnCollisionChangedListener.OnCollisionChanged(CollisionChangedEvent collisionEvent) { if (waypoints.Count > 0) this.MoveToNow(this.waypoints.ElementAt(this.waypoints.Count - 1)); }
/// <summary> /// Updates the collisionmap, adding the rectangle to the collisionmap, and performing new connections, as for placing nodes /// </summary> /// <param name="rect"></param> public BuildingMesh PlaceBuilding(Rectangle rect) { CollisionChangedEvent e = new CollisionChangedEvent(); e.collision = this; e.changedRect = rect; e.collisionAdded = true; long ticks = DateTime.UtcNow.Ticks; e.oldData = (Boolean[])data.Clone(); Console.Out.WriteLine("Clone time: " + (DateTime.UtcNow.Ticks - ticks) / 10000 + "ms"); ticks = DateTime.UtcNow.Ticks; Boolean color = true; // Update collisionmap data for (int i = rect.Left; i < rect.Right; i++) { for (int j = rect.Top; j < rect.Bottom; j++) { data[PointToIndex(i, j)] = color; } } // Update collisionmap texture this.texture = BoolToTexture(Game1.GetInstance().graphics.GraphicsDevice, this.data, mapWidth, collisionMapTextureScale); e.newData = data; Console.Out.WriteLine("Data put time: " + (DateTime.UtcNow.Ticks - ticks) / 10000 + "ms"); ticks = DateTime.UtcNow.Ticks; Node[] newNodes = new Node[4]; RTSCollisionMap map = Game1.GetInstance().collision; newNodes[0] = new Node(map, rect.Left - 1, rect.Top - 1, true); newNodes[1] = new Node(map, rect.Right + 1, rect.Top - 1, true); newNodes[2] = new Node(map, rect.Left - 1, rect.Bottom + 1, true); newNodes[3] = new Node(map, rect.Right + 1, rect.Bottom + 1, true); Console.Out.WriteLine("Node create time: " + (DateTime.UtcNow.Ticks - ticks) / 10000 + "ms"); ticks = DateTime.UtcNow.Ticks; BuildingMesh mesh = new BuildingMesh(this); mesh.rect = rect; mesh.createdNodes = newNodes; LinkedList<PathfindingNode> nodes = PathfindingNodeManager.GetInstance().nodeList; foreach (PathfindingNode node in nodes) { if (rect.Contains(node.GetLocation())) mesh.removedNodes.AddLast(node.GetLocation()); } Console.Out.WriteLine("Mesh create time: " + (DateTime.UtcNow.Ticks - ticks) / 10000 + "ms"); ticks = DateTime.UtcNow.Ticks; LinkedList<Node> processedNodes = new LinkedList<Node>(); int nodesAdded = 0; foreach (Node newNode in newNodes) { foreach (Node connectedNode in newNode.GetConnectedNodes()) { // Let's not process things twice, as it's quite a heavy computation if (!processedNodes.Contains(connectedNode)) { // Remove its current nodes connectedNode.RemoveAllConnections(); // Scedule it for reprocessing SmartPathfindingNodeProcessor.GetInstance().Push(connectedNode); processedNodes.AddLast(connectedNode); nodesAdded++; } } } Console.Out.WriteLine("Node connection time: " + (DateTime.UtcNow.Ticks - ticks) / 10000 + "ms, adding " + nodesAdded + " nodes"); ticks = DateTime.UtcNow.Ticks; FireCollisionChangedEvent(e); Console.Out.WriteLine("Event time: " + (DateTime.UtcNow.Ticks - ticks)); return mesh; }
void OnCollisionChangedListener.OnCollisionChanged(CollisionChangedEvent collisionEvent) { if (collisionEvent.collisionAdded) { if (collisionEvent.changedRect.Contains(this.GetLocation())) this.Destroy(); } }
void OnCollisionChangedListener.OnCollisionChanged(CollisionChangedEvent collisionEvent) { if (waypoints.Count() > 0) { this.MoveToQueue(this.waypoints.ElementAt(this.waypoints.Count() - 1)); } }
/// <summary> /// Updates the collisionmap, without updating or adding pathfinding points. /// DO NOT USE THIS METHOD IN-GAME, ONLY IN THE EDITOR. /// </summary> /// <param name="device">The graphics device to create the new texture on</param> /// <param name="rect">The rectangle</param> /// <param name="add">Whether to add or to remove the rect.</param> public void UpdateCollisionMap(GraphicsDevice device, Rectangle rect, Boolean add) { CollisionChangedEvent e = new CollisionChangedEvent(); e.collision = this; e.changedRect = rect; e.collisionAdded = add; e.oldData = (Boolean[])data.Clone(); int pixelsChanged = 0; // Update collisionmap data for (int i = rect.Left; i < rect.Right; i++) { for (int j = rect.Top; j < rect.Bottom; j++) { if (data[PointToIndex(i, j)] != add) { data[PointToIndex(i, j)] = add; pixelsChanged++; } } } if (pixelsChanged > 0) { // Update collisionmap texture this.texture = BoolToTexture(device, this.data, mapWidth, collisionMapTextureScale); e.newData = data; FireCollisionChangedEvent(e); } }
/// <summary> /// Fires a collision changed event to all listeners. /// </summary> /// <param name="e">The event</param> public void FireCollisionChangedEvent(CollisionChangedEvent e) { collisionChangedListeners(e); }
/* /// <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> /// Fires a collision changed event to all listeners. /// </summary> /// <param name="e">The event</param> public void FireCollisionChangedEvent(CollisionChangedEvent e) { if (collisionChangedListeners != null) collisionChangedListeners(e); }