/** * 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)); }