Exemplo n.º 1
0
        /**
         * Return the smallest distance between the collision boxes
         */
        public double getDistance(Room other)
        {
            double smallest = 0;

            Rectangle[] ocb = other.getCollisionBoxes();
            Rectangle[] cb  = getCollisionBoxes();

            for (int i = 0; i < ocb.Length; i++)
            {
                for (int j = 0; j < cb.Length; j++)
                {
                    double distance = Helpers.Distance(ocb[i], cb[j]);
                    if (distance == 0)
                    {
                        return(0);
                    }
                    smallest = (i == 0 && j == 0) ? distance : Math.Min(distance, smallest);
                }
            }

            return(smallest);
        }
Exemplo n.º 2
0
        /**
         * The plan is: Generate 2*roomsNumber rooms, outshift them and then connect with corridors, removing the ones that intersect a corridor
         * adding locked doors and making sure that the it's possible to reach every room.
         * And I don't fukin' know how to do all of that.
         *
         * Okay, let's start by creating the Dungeon itself. This object will contain all the map data, that is, the map itself as well as
         * any object metadata (for monster spawners, mechanisms, chest contents, and so on.
         *
         * Each object that has metadata will hava a unique ID, as the metadata for said object will be stored separetely, in JSON format.
         * The map itself won't retain the Rooms information, and will be turned into a tileset, or so it will be for DunGen 1.0 file specification.
         *
         * Also, this comments will be very helpful, as I'm most likely going to forget everything I just said, and will come back very
         * often to remember what it is I have to implement next.
         */

        public void generate()
        {
            int gap  = 2;
            int seed = (new Random()).Next();

            rg = new Random(seed);
            int excess = 2;

            print(Heading.Attention, "Starting dungeon generation...");
            print(Heading.Info, "Seed: {0}", new object[] { seed });
            print(Heading.Info, "Generating {0} rooms", new object[] { excess *param.roomsCount });

            rooms = new List <Room>();

            rooms.Add(new BasicRoom(-3, -3, 5, 5));

            //for (int i = 0; i < 10; i++) {
            //    for (int j = 0; j < 10; j++) {
            //        rooms.Add(new BasicRoom(i * 10, j * 10, 10, 10));
            //    }
            //}

            //Application.Run(new DungeonDisplayer(this));

            //return;

            int attemptCount = 0;

            for (int i = 0; i < excess * param.roomsCount;)
            {
                if (generateRoom())
                {
                    i++;
                    attemptCount = 0;
                }
                else
                {
                    attemptCount++;
                    print(Heading.Warning, "Room failed to generate. Attempt #{0}", new object[] { attemptCount });
                }
            }

            //rooms.OrderBy((x) => Helpers.Distance(x.getCenter(), new Point(0, 0)));

            print(Heading.Attention, "Starting outshifting!");
            print(Heading.Info, "{0} set as middle, with center at {1}.", new object[] { rooms[0], rooms[0].getCenter() });
            rooms[0].finalPosition = true;

            bool changed = true;

            while (changed)
            {
                changed = false;
                foreach (var r in rooms)
                {
                    if (r.finalPosition)
                    {
                        continue;
                    }
                    r.shown = true;
                    while (!r.finalPosition)
                    {
                        Point centerR  = r.getCenter();
                        Point centerOR = rooms[0].getCenter();

                        //radialmente!
                        double d = Helpers.Distance(centerR, centerOR);
                        int[]  p;
                        if (d == 0)
                        {
                            p = new int[] { 1, 1 };
                        }
                        else
                        {
                            p = Helpers.IntegerProportion((centerR.x - centerOR.x) / (d), (centerR.y - centerOR.y) / (d), 30);
                        }

                        /*if (p[0] == 0 && p[1] == 0) {
                         *  p = new int[] { rg.Next(10) * (rg.NextDouble() > 0.5 ? 1 : -1), rg.Next(10) * (rg.NextDouble() > 0.5 ? 1 : -1) };
                         * }*/

                        print(Heading.Info, "Increment: {0} {1}", new object[] { p[0], p[1] });
                        r.shift(p[0], p[1]);

                        //Application.Run(new DungeonDisplayer(this));

                        changed = true;

                        bool fix = true;
                        foreach (var or in rooms)
                        {
                            if (r.Equals(or) || !or.finalPosition)
                            {
                                continue;
                            }

                            if (or.getDistance(r) < gap)
                            {
                                fix = false;
                            }
                        }

                        if (fix)
                        {
                            r.finalPosition = true;
                            print(Heading.Info, "{0} is now fixed.", new object[] { r });
                        }
                    }
                    r.shown = false;
                }
            }

            print(Heading.Attention, "Shift finished.");
            print(Heading.Attention, "Deleting {0} random rooms.", new object[] { (excess - 1) * param.roomsCount });

            for (int i = 0; i < (excess - 1) * param.roomsCount; i++)
            {
                Room r = rooms[rg.Next(rooms.Count)];
                rooms.Remove(r);
            }

            print(Heading.Attention, "Done. Displaying.");
            Application.Run(new DungeonDisplayer(this));
        }