Пример #1
0
        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);
        }
Пример #2
0
        /// <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;
        }
Пример #3
0
        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);
        }
Пример #4
0
 void OnCollisionChangedListener.OnCollisionChanged(CollisionChangedEvent collisionEvent)
 {
     if (waypoints.Count > 0) this.MoveToNow(this.waypoints.ElementAt(this.waypoints.Count - 1));
 }
Пример #5
0
        /// <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;
        }
Пример #6
0
 void OnCollisionChangedListener.OnCollisionChanged(CollisionChangedEvent collisionEvent)
 {
     if (collisionEvent.collisionAdded)
     {
         if (collisionEvent.changedRect.Contains(this.GetLocation())) this.Destroy();
     }
 }
Пример #7
0
 void OnCollisionChangedListener.OnCollisionChanged(CollisionChangedEvent collisionEvent)
 {
     if (waypoints.Count() > 0)
     {
         this.MoveToQueue(this.waypoints.ElementAt(this.waypoints.Count() - 1));
     }
 }
Пример #8
0
        /// <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);
            }
        }
Пример #9
0
 /// <summary>
 /// Fires a collision changed event to all listeners.
 /// </summary>
 /// <param name="e">The event</param>
 public void FireCollisionChangedEvent(CollisionChangedEvent e)
 {
     collisionChangedListeners(e);
 }
Пример #10
0
        /*
        /// <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);
        }
Пример #11
0
 /// <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);
 }