public RDungeon(int dungeonIndex) { DungeonIndex = dungeonIndex; DungeonName = ""; Floors = new List<RDungeonFloor>(); options = new GeneratorOptions(); }
public RDungeonFloor() { Traps = new List<int>(); Weather = new List<Enums.Weather>(); Npc = new MapNpcPreset[Constants.MAX_MAP_NPCS]; for (int i = 0; i < Npc.Length; i++) { Npc[i] = new MapNpcPreset(); } Items = new int[16]; options = new GeneratorOptions(); }
public RDungeonFloor() { GroundTile = new Tile(new DataManager.Maps.Tile()); HallTile = new Tile(new DataManager.Maps.Tile()); WaterTile = new Tile(new DataManager.Maps.Tile()); WallTile = new Tile(new DataManager.Maps.Tile()); SpecialTiles = new List<RDungeonTrap>(); Weather = new List<Enums.Weather>(); Npcs = new List<MapNpcPreset>(); Items = new List<RDungeonItem>(); options = new GeneratorOptions(); }
public static RDungeonMap GenerateFloor(Client client, int dungeonIndex, int floorNum, GeneratorOptions options) { RDungeon dungeon = RDungeonManager.RDungeons[dungeonIndex]; RDungeonFloor floor = dungeon.Floors[floorNum]; //decide on a chamber RDungeonChamberReq req = null; int chamber = -1; if (options.Chambers.Count > 0) { chamber = Math.Rand(0, options.Chambers.Count); req = (RDungeonChamberReq)Scripting.ScriptManager.InvokeFunction("GetChamberReq", options.Chambers[chamber].ChamberNum, options.Chambers[chamber].String1, options.Chambers[chamber].String2, options.Chambers[chamber].String3); } // Generate the ASCII map DungeonArrayFloor arrayFloor = new DungeonArrayFloor(options, req); //int[,] arrayMap = ASCIIFloorGen.GenASCIIMap(options); //ASCIIFloorGen.TextureDungeon(arrayMap); System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); // Prepare the base map DataManager.Maps.RDungeonMap rDungeonMap = new DataManager.Maps.RDungeonMap(MapManager.GenerateMapID(RDungeonMap.ID_PREFIX)); rDungeonMap.MaxX = arrayFloor.MapArray.GetUpperBound(0); rDungeonMap.MaxY = arrayFloor.MapArray.GetUpperBound(1); rDungeonMap.Tile = new DataManager.Maps.Tile[rDungeonMap.MaxX + 1, rDungeonMap.MaxY + 1]; rDungeonMap.RDungeonIndex = dungeonIndex; rDungeonMap.RDungeonFloor = floorNum; RDungeonMap map = new RDungeonMap(rDungeonMap); for (int x = 0; x <= rDungeonMap.Tile.GetUpperBound(0); x++) { for (int y = 0; y <= rDungeonMap.Tile.GetUpperBound(1); y++) { AmbiguateTile(map.Tile[x,y]); } } map.Name = GenerateName(dungeonIndex, floorNum); map.Revision = 0; map.OriginalDarkness = floor.Darkness; map.HungerEnabled = true; map.RecruitEnabled = dungeon.Recruitment; map.ExpEnabled = dungeon.Exp; map.TimeLimit = dungeon.WindTimer; map.DungeonIndex = dungeon.DungeonIndex; map.MinNpcs = floor.NpcMin; map.MaxNpcs = floor.NpcMax; map.NpcSpawnTime = floor.NpcSpawnTime; if (Globals.ServerWeather != Enums.Weather.Ambiguous) { map.Weather = Globals.ServerWeather; } else if (floor.Weather.Count > 0) { map.Weather = floor.Weather[Server.Math.Rand(0, floor.Weather.Count)]; } map.Music = floor.Music; //texture chamber if (arrayFloor.Chamber.X != -1 && arrayFloor.Chamber.Y != -1) { Scripting.ScriptManager.InvokeSub("CreateChamber", map, arrayFloor, options.Chambers[chamber].ChamberNum, options.Chambers[chamber].String1, options.Chambers[chamber].String2, options.Chambers[chamber].String3); } DungeonArrayFloor.TextureDungeon(arrayFloor.MapArray); for (int x = 0; x <= rDungeonMap.Tile.GetUpperBound(0); x++) { for (int y = 0; y <= rDungeonMap.Tile.GetUpperBound(1); y++) { map.Tile[x, y].RDungeonMapValue = arrayFloor.MapArray[x, y]; } } TextureDungeonMap(map); //block borders for (int y = 0; y <= map.MaxY; y++) { map.Tile[0, y].Type = Enums.TileType.Blocked; map.Tile[map.MaxX, y].Type = Enums.TileType.Blocked; } for (int x = 0; x <= map.MaxX; x++) { map.Tile[x, 0].Type = Enums.TileType.Blocked; map.Tile[x, map.MaxY].Type = Enums.TileType.Blocked; } watch.Stop(); foreach (MapNpcPreset npc in floor.Npcs) { MapNpcPreset newNpc = new MapNpcPreset(); newNpc.NpcNum = npc.NpcNum; newNpc.MinLevel = npc.MinLevel; newNpc.MaxLevel = npc.MaxLevel; newNpc.SpawnX = npc.SpawnX; newNpc.SpawnY = npc.SpawnY; newNpc.AppearanceRate = npc.AppearanceRate; newNpc.StartStatus = npc.StartStatus; newNpc.StartStatusCounter = npc.StartStatusCounter; newNpc.StartStatusChance = npc.StartStatusChance; map.Npc.Add(newNpc); } map.SpawnItems(); int n = Server.Math.Rand(options.ItemMin, options.ItemMax + 1); if (floor.Items.Count == 0) { n = 0; } else if (n > Constants.MAX_MAP_ITEMS) { n = Constants.MAX_MAP_ITEMS; } int slot = 0; int itemX = -1, itemY = -1; for (int i = 0; i < n; i++) { for (int j = 0; j < 100; j++) { bool spawned = false; if (Server.Math.Rand(0, 100) < floor.Items[slot].AppearanceRate) { arrayFloor.GenItem(floor.Items[slot].OnGround, floor.Items[slot].OnWater, floor.Items[slot].OnWall, ref itemX, ref itemY); if (itemX > -1) { map.SpawnItem(floor.Items[slot].ItemNum, Server.Math.Rand(floor.Items[slot].MinAmount, floor.Items[slot].MaxAmount + 1), (Server.Math.Rand(0, 100) < floor.Items[slot].StickyRate), floor.Items[slot].Hidden, floor.Items[slot].Tag, itemX, itemY, null); spawned = true; } } slot++; if (slot >= floor.Items.Count) slot = 0; if (spawned) break; } } //map.SpawnNpcs(); map.NpcSpawnWait = new TickCount(Core.GetTickCount().Tick); return map; }
public static char[,] GenASCIIMap(GeneratorOptions options) { int[,] room = new int[16, 5]; //array of all rooms,[closed/open/hall, startx, starty, endx, endy] int[] vhall = new int[12]; //vertical halls int[] hhall = new int[12]; //horizontal halls int start; //marks spawn point int end = 0; //marks stairs int i, j, a = -1, b; //counter variables char[,] mapArray = new char[50, 50]; // stores map grid int x, y; // used for navigating map array bool isDone; // bool used for various purposes // Part of Options class now //int trapFreq = 66; // adjust to number between 0 and 100 to see changes //int trapMin = 5; // adjust to number between 0 and 255 to see changes //int trapMax = 30; // adjust to number between 0 and 255 to see changes //initialize map array to empty for (y = 0; y < 50; y++) { for (x = 0; x < 50; x++) { mapArray[y, x] = ' '; } } //initialize all rooms+halls to closed by default for (i = 0; i < 16; i++) { room[i, 0] = CLOSED; } for (i = 0; i < 12; i++) { vhall[i] = CLOSED; hhall[i] = CLOSED; } // path generation algorithm start = random.Next(0, 16); // randomly determine start room x = start; i = 0; j = random.Next(0, 6) + 5; // magic numbers, determine what the dungeon looks like b = -1; do { if (random.Next(0, (2 + i)) == 0) { room[x, 0] = OPEN; i++; x = start; b = -1; } else { bool working = true; do { y = random.Next(0, 4); if (y != b) {//makes sure there is no backtracking switch (y) { case 0: a = getRoomUp(x); b = 1; break; case 1: a = getRoomDown(x); b = 0; break; case 2: a = getRoomLeft(x); b = 3; break; case 3: a = getRoomRight(x); b = 2; break; } if (a > -1) { openHallBetween(x, a, hhall, vhall); x = a; working = false; } } else { b = -1; } } while (working); if (random.Next(0, 2) == 0) { room[x, 0] = OPEN; } else { room[x, 0] = HALL; } } } while (i < j); room[start, 0] = OPEN; //Determine key rooms isDone = false; do { //determine ending room randomly x = random.Next(0, 16); if (room[x, 0] == OPEN) { end = x; //Console.WriteLine(x); isDone = true; } } while (!isDone); isDone = false; do { //determine starting room randomly x = random.Next(0, 16); if (room[x, 0] == OPEN) { start = x; isDone = true; } } while (!isDone); // begin part 2, creating ASCII map //create rooms //Console.WriteLine("ROOMS:"); for (i = 0; i < 16; i++) { if (room[i, 0] != CLOSED) { createRoom(i, room, options); } } //Console.WriteLine("DRAW:"); for (i = 0; i < 16; i++) { if (room[i, 0] != CLOSED) { drawRoom(i, mapArray, room); } } //Console.WriteLine("HALLS:"); for (i = 0; i < 16; i++) { if (room[i, 0] != CLOSED) { Console.WriteLine(i + ": X=" + room[i, 1] + "-" + room[i, 3] + " Y=" + room[i, 2] + "-" + room[i, 4]); } } // create halls for (i = 0; i < 12; i++) { if (vhall[i] == OPEN) { createVHall(i, mapArray, room, options); } if (hhall[i] == OPEN) { createHHall(i, mapArray, room, options); } } //Console.WriteLine("SE:"); addSEpos(start, START, mapArray, room); addSEpos(end, END, mapArray, room); //Console.WriteLine("WATER:"); //add water for (y = 1; y < 49; y++) { for (x = 1; x < 49; x++) { if (mapArray[y, x] != ' ') { } else if (options.WaterFrequency < 1) { } else if (options.WaterFrequency > 99) { mapArray[y, x] = '~'; } else if (random.Next(0, 100) + 1 <= options.WaterFrequency) { // dotchi ~nyo? Water or Wall? mapArray[y, x] = '~'; } else { } } } if (options.Craters > 0) { for (i = 0; i < options.Craters; i++) { int centerX = random.Next(1, 50); int centerY = random.Next(1, 50); int craterLength = random.Next(options.CraterMinLength, options.CraterMaxLength); int startX; int startY; if (craterLength % 2 == 1) { startX = centerX - craterLength / 2; startY = centerY - craterLength / 2; } else { startX = centerX + 1 - craterLength / 2; startY = centerY + 1 - craterLength / 2; } for (y = startY; y < startY + craterLength; y++) { for (x = startX; x < startX + craterLength; x++) { if (x < 1 || x > 47 || y < 1 || y > 47) { } else if (mapArray[y, x] == '~' || mapArray[y, x] == ',' || mapArray[y, x] == '.' || mapArray[y, x] == 'S' || mapArray[y, x] == 'E') { } else { if (System.Math.Abs(x - centerX) + System.Math.Abs(y - centerY) <= craterLength / 2) {//makes a crater in a "diamond" shape mapArray[y, x] = '~'; } else if (options.CraterFuzzy == true && System.Math.Abs(x - centerX) + System.Math.Abs(y - centerY) <= craterLength * 0.75) {//makes a "fuzzy" edge to the diamond crater if (random.Next(0, 100) > 49) { mapArray[y, x] = '~'; } } } } } } } //Console.WriteLine("TRAPS:"); // add traps int finalTraps = random.Next(options.TrapMin, options.TrapMax + 1); if (finalTraps > 0) { for (i = 0; i < finalTraps; i++) { // add traps for (j = 0; j < 200; j++) { a = random.Next(0, 16); x = random.Next(room[a, 1], room[a, 3] + 1); y = random.Next(room[a, 2], room[a, 4] + 1); if (mapArray[y, x] == '.') { mapArray[y, x] = 'Q'; break; } } } } //if (options.TrapFrequency > 0 && options.TrapMax > 0) { // for (i = options.TrapMin; i < options.TrapMax; i++) { // if (random.Next(0, 100) + 1 >= options.TrapFrequency) { // then generate a trap // a = random.Next(0, 16); // convertRoomToXY(a, ref x, ref y); // x = x + 1 + (random.Next(0, 6)); // y = y + 1 + (random.Next(0, 5)); // if (mapArray[y, x] == '.') { // mapArray[y, x] = 'Q'; // } // } // } //} //Console.WriteLine("ITEMS:"); // generate items (up to 16) ~moved to its own method //for (i = 0; i < 16; i++) { //bool success = false; // for (int k = 0; k < 200; k++) { // do until you succeed // a = random.Next(0, 16); //convertRoomToXY(a, ref x, ref y); // x = random.Next(room[a,1], room[a,3]+1); // y = random.Next(room[a,2], room[a,4]+1); // if (mapArray[y, x] == '.' /* mapArray[y, x] != 'S' && mapArray[y, x] != 'E' && // mapArray[y, x] != ' '*/) { // mapArray[y, x] = (char)(96 + i); //ascii for lowercase letters // break; // } // } //} return mapArray; }
static void createVHall(int hall, char[,] mapArray, int[,] room, GeneratorOptions options) { //Console.Write("V"+hall+":"); int startRoom = hall; int endRoom = hall + 4; int n = room[endRoom, 2] - room[startRoom, 4]; if (n < 1) { if (room[startRoom, 1] > room[endRoom, 3] || room[startRoom, 3] < room[endRoom, 1]) { n++; } else { //Console.WriteLine(";"); return; } } n--; int x, y, m,/* n,*/ h, r = 0, var; y = room[startRoom, 4]; m = random.Next(options.HallTurnMin, options.HallTurnMax + 1); if (m > ((n - 1) / 2)) m = (n - 1) / 2; x = random.Next(room[startRoom, 1], room[startRoom, 3] + 1); if (m <= 0 && (x > room[endRoom, 3] || x < room[endRoom, 1])) { m = 1; } //Console.Write("("+room[startRoom,1]+"."+room[startRoom,3]+")"); for (int i = 0; i <= m; i++) { if (i == m) { var = random.Next(room[endRoom, 1], room[endRoom, 3] + 1) - x; } else { var = random.Next(options.HallVarMin, options.HallVarMax + 1); if (random.Next(0, 2) == 0) { var = -var; } } if (i != 0) { if ((x + var) < 1) var = 1 - x; if ((x + var) > 48) var = 48 - x; addHorizHall(x, y, var, mapArray); x += var; }// else { //mapArray[y,x] = ','; //} if (n >= 0) { h = (r + n) / (m + 1); r = (r + n) % (m + 1); } else { h = -(r - n) / (m + 1); r = (r - n) % (m + 1); } //Console.Write("("+n+","+r+")"); addVertHall(x, y, h, mapArray); y += h; } mapArray[y + 1, x] = ','; //int x, y, h, j; // variables for position //h = hall % 4; //j = hall / 4; //x = 3 + Convert.ToInt32(13.5 * h); //y = 7 + 12 * j; //addVertHall(x, y, mapArray); //Console.WriteLine(";"); }
static void createRoom(int roomNum, int[,] room, GeneratorOptions options) { if (room[roomNum, 1] > 0) { return; } int x = 0, y = 0, u, v, w, l; // variables used for position convertRoomToXY(roomNum, ref x, ref y); //Determine room length/width if (room[roomNum, 0] == HALL) { w = 0; l = 0; } else { w = random.Next(options.RoomWidthMin, options.RoomWidthMax + 1); l = random.Next(options.RoomLengthMin, options.RoomLengthMax + 1); if (w < 1) w = 1; if (l < 1) l = 1; if (w > 47) w = 47; if (l > 47) l = 47; } //move X and Y to a random starting point that still would include the original x/y; exceptional case for l/w under or equal to 6 if (w <= 6) { x -= (random.Next(0, (13 - w)) + w - 7); } else { x -= random.Next(0, w + 1); } if (l <= 6) { y -= (random.Next(0, (13 - l)) + l - 7); } else { y -= random.Next(0, l + 1); } if (x < 1) x = 1; if ((x + w) > 48) x = (48 - w); if (y < 1) y = 1; if ((y + l) > 48) y = (48 - l); // once we have our room coords, render it on the map u = x + w; v = y + l; // fill in the walls first, then plot the inside //mapArray[y, x] = '5'; //x++; //for (; x < u; x++) mapArray[y, x] = 'T'; //mapArray[y, x] = '6'; //y++; //for (; y < v; y++) mapArray[y, x] = 'R'; //mapArray[v, u] = '7'; //x = u - 7; //y = v - 6; //u--; //for (; u > x; u--) mapArray[v, u] = 'B'; //mapArray[v, u] = '8'; //v--; //for (; v > y; v--) mapArray[v, u] = 'L'; //u = x + 6; //v = y + 5; // now render inside as ground tiles //count all rooms whose centers have been touched by this room as this room //Console.Write("#" + roomNum + "," + x + "," + y + "," + u + "," + v); //if (l <=6 || w <= 6) { // room[roomNum,1] = x; // room[roomNum,2] = y; // room[roomNum,3] = u; // room[roomNum,4] = v; //} else { for (int i = 0; i < 16; i++) { if (i == roomNum || ((6 + i % 4 * 12) >= x && (6 + i % 4 * 12) <= u && (6 + i / 4 * 12) >= y && (6 + i / 4 * 12) <= v)) { room[i, 1] = x; room[i, 2] = y; room[i, 3] = u; room[i, 4] = v; //Console.Write(" =" + i); } } //} //Console.WriteLine(";"); // done }
static void createHHall(int hall, char[,] mapArray, int[,] room, GeneratorOptions options) { //Console.Write("H"+hall+":"); int startRoom = hall + hall / 3; int endRoom = hall + hall / 3 + 1; int n = room[endRoom, 1] - room[startRoom, 3]; if (n < 1) { if (room[startRoom, 2] > room[endRoom, 4] || room[startRoom, 4] < room[endRoom, 2]) { n++; } else { //Console.WriteLine(";"); return; } } n--; int x, y, m,/* n,*/ h, r = 0, var; x = room[startRoom, 3]; m = random.Next(options.HallTurnMin, options.HallTurnMax + 1); if (m > ((n - 1) / 2)) m = (n - 1) / 2; y = random.Next(room[startRoom, 2], room[startRoom, 4] + 1); if (m <= 0 && (y > room[endRoom, 4] || y < room[endRoom, 2])) { m = 1; } //Console.Write("("+room[startRoom,2]+"."+room[startRoom,4]+")"); for (int i = 0; i <= m; i++) { if (i == m) { var = random.Next(room[endRoom, 2], room[endRoom, 4] + 1) - y; } else { var = random.Next(options.HallVarMin, options.HallVarMax + 1); if (random.Next(0, 2) == 0) { var = -var; } } if (i != 0) { if ((y + var) < 1) var = 1 - y; if ((y + var) > 48) var = 48 - y; addVertHall(x, y, var, mapArray); y += var; }// else { //mapArray[y,x] = ','; //} if (n >= 0) { h = (r + n) / (m + 1); r = (r + n) % (m + 1); } else { h = -(r - n) / (m + 1); r = (r - n) % (m + 1); } //Console.Write("("+n+","+r+")"); addHorizHall(x, y, h, mapArray); x += h; } mapArray[y, x + 1] = ','; //int x, y, h, j; //h = hall % 3; //j = hall / 3; //x = 8 + 13 * h; //y = 3 + 12 * j; //addHorizHall(x, y, 6, mapArray); //Console.WriteLine(";"); }
void DrawWater(GeneratorOptions options) { for (int y = 1; y < 49; y++) { for (int x = 1; x < 49; x++) { if (MapArray[x, y] != UBLOCK) { } else if (options.WaterFrequency < 1) { } else if (options.WaterFrequency > 99) { MapArray[x, y] = UWATER; } else if (random.Next(0, 100) + 1 <= options.WaterFrequency) { // dotchi ~nyo? Water or Wall? MapArray[x, y] = UWATER; } else { } } } }
public DungeonArrayFloor(GeneratorOptions options, RDungeonChamberReq req) { Rooms = new DungeonArrayRoom[4, 4]; //array of all rooms VHalls = new DungeonArrayHall[4, 3]; //vertical halls HHalls = new DungeonArrayHall[3, 4]; //horizontal halls Start = new DungeonPoint(-1, -1); //marks spawn point End = new DungeonPoint(-1, -1); //marks stairs Chamber = new DungeonPoint(-1, -1); //marks chamber int i, j, a = -1, b; //counter variables MapArray = new int[50, 50]; // stores map grid int x, y; // used for navigating map array bool isDone; // bool used for various purposes // Part of Options class now //int trapFreq = 66; // adjust to number between 0 and 100 to see changes //int trapMin = 5; // adjust to number between 0 and 255 to see changes //int trapMax = 30; // adjust to number between 0 and 255 to see changes //initialize map array to empty for (y = 0; y < 50; y++) { for (x = 0; x < 50; x++) { MapArray[x, y] = UBLOCK; } } //initialize all rooms+halls to closed by default for (x = 0; x <= Rooms.GetUpperBound(0); x++) { for (y = 0; y <= Rooms.GetUpperBound(1); y++) { Rooms[x, y] = new DungeonArrayRoom(); } } for (x = 0; x <= VHalls.GetUpperBound(0); x++) { for (y = 0; y <= VHalls.GetUpperBound(1); y++) { VHalls[x, y] = new DungeonArrayHall(); } } for (x = 0; x <= HHalls.GetUpperBound(0); x++) { for (y = 0; y <= HHalls.GetUpperBound(1); y++) { HHalls[x, y] = new DungeonArrayHall(); } } // path generation algorithm Start = new DungeonPoint(random.Next(0, Rooms.GetUpperBound(0) + 1), random.Next(0, Rooms.GetUpperBound(1) + 1)); // randomly determine start room DungeonPoint wanderer = Start; //start = random.Next(0, 16); // randomly determine start room //x = start; i = 0; j = random.Next(0, 6) + 5; // magic numbers, determine what the dungeon looks like (in general, paths) b = -1; // direction of movement do { if (random.Next(0, (2 + i)) == 0) {//will end the current path and start a new one from the start if (random.Next(0, 2) == 0) {//determine if the room should be open or a hall Rooms[wanderer.X, wanderer.Y].Opened = OPEN; } else { Rooms[wanderer.X, wanderer.Y].Opened = HALL; } i++; wanderer = Start; b = -1; } else { bool working = true; do { DungeonPoint sample = wanderer; y = random.Next(0, 4); if (y != b) {//makes sure there is no backtracking switch (y) { case 0: sample.Y--; b = 1; break; case 1: sample.Y++; b = 0; break; case 2: sample.X--; b = 3; break; case 3: sample.X++; b = 2; break; } if (sample.X >= 0 && sample.X <= Rooms.GetUpperBound(0) && sample.Y >= 0 && sample.Y <= Rooms.GetUpperBound(1)) {// a is the room to be checked after making a move between rooms openHallBetween(wanderer, sample); wanderer = sample; working = false; } } else { b = -1; } } while (working); if (random.Next(0, 2) == 0) {//determine if the room should be open or a hall Rooms[wanderer.X, wanderer.Y].Opened = OPEN; } else { Rooms[wanderer.X, wanderer.Y].Opened = HALL; } } } while (i < j); Rooms[Start.X, Start.Y].Opened = OPEN; //Determine key rooms if (req == null || req.End != Enums.Acceptance.Always) { isDone = false; do { //determine ending room randomly x = random.Next(0, Rooms.GetUpperBound(0) + 1); y = random.Next(0, Rooms.GetUpperBound(1) + 1); if (Rooms[x, y].Opened == OPEN) { End = new DungeonPoint(x, y); //Console.WriteLine(x); isDone = true; } } while (!isDone); } Start = new DungeonPoint(-1, -1); if (req == null || req.Start != Enums.Acceptance.Always) { isDone = false; do { //determine starting room randomly x = random.Next(0, Rooms.GetUpperBound(0) + 1); y = random.Next(0, Rooms.GetUpperBound(1) + 1); if (Rooms[x, y].Opened == OPEN) { Start = new DungeonPoint(x, y); //Console.WriteLine(x); isDone = true; } } while (!isDone); } if (req != null) { isDone = false; for (int n = 0; n < 100; n++) { //determine chamber room randomly x = random.Next(0, Rooms.GetUpperBound(0) + 1); y = random.Next(0, Rooms.GetUpperBound(1) + 1); bool approved = true; //if the chamber cannot be on a start, and it picked the start if (req.Start == Enums.Acceptance.Never && Start.X == x && Start.Y == y) { approved = false; } //if the chamber cannot be on an end, and it picked the end if (req.End == Enums.Acceptance.Never && End.X == x && End.Y == y) { approved = false; } //if the chamber demands a certain setup, and it doesn't meet the setup if (req.TopAcceptance == Enums.Acceptance.Always) { if (y == 0 || !VHalls[x, y - 1].Open) approved = false; } else if (req.TopAcceptance == Enums.Acceptance.Never) { if (y > 0 && VHalls[x, y - 1].Open) approved = false; } if (req.BottomAcceptance == Enums.Acceptance.Always) { if (y == Rooms.GetUpperBound(1) || !VHalls[x, y].Open) approved = false; } else if (req.BottomAcceptance == Enums.Acceptance.Never) { if (y < Rooms.GetUpperBound(1) && VHalls[x, y].Open) approved = false; } if (req.LeftAcceptance == Enums.Acceptance.Always) { if (x == 0 || !HHalls[x - 1, y].Open) approved = false; } else if (req.LeftAcceptance == Enums.Acceptance.Never) { if (x > 0 && HHalls[x - 1, y].Open) approved = false; } if (req.RightAcceptance == Enums.Acceptance.Always) { if (x == Rooms.GetUpperBound(0) || !HHalls[x, y].Open) approved = false; } else if (req.RightAcceptance == Enums.Acceptance.Never) { if (x < Rooms.GetUpperBound(0) && HHalls[x, y].Open) approved = false; } if (Rooms[x, y].Opened == OPEN && approved) { //set chamber to the point Chamber = new DungeonPoint(x, y); //if start or end is on this point, set to this location if (End.X == -1 && End.Y == -1) { End = new DungeonPoint(x, y); } if (Start.X == -1 && Start.Y == -1) { Start = new DungeonPoint(x, y); } //Console.WriteLine(x); isDone = true; break; } } if (!isDone) { //chamber could not be placed; reroll start and end if they were set to -1 assuming that chamber was going to take care of it if (End.X == -1 && End.Y == -1) { isDone = false; do { //determine ending room randomly x = random.Next(0, Rooms.GetUpperBound(0) + 1); y = random.Next(0, Rooms.GetUpperBound(1) + 1); if (Rooms[x, y].Opened == OPEN) { End = new DungeonPoint(x, y); //Console.WriteLine(x); isDone = true; } } while (!isDone); } if (Start.X == -1 && Start.Y == -1) { isDone = false; do { //determine starting room randomly x = random.Next(0, Rooms.GetUpperBound(0) + 1); y = random.Next(0, Rooms.GetUpperBound(1) + 1); if (Rooms[x, y].Opened == OPEN) { Start = new DungeonPoint(x, y); //Console.WriteLine(x); isDone = true; } } while (!isDone); } } } // begin part 2, creating ASCII map //create rooms //Console.WriteLine("ROOMS:"); //Console.WriteLine(Chamber.X + "," + Chamber.Y); for (i = 0; i <= Rooms.GetUpperBound(0); i++) { for (j = 0; j <= Rooms.GetUpperBound(1); j++) { if (Rooms[i, j].Opened != CLOSED && (Chamber.X != i || Chamber.Y != j)) { createRoom(i, j, options, req); } } } //Console.WriteLine(Chamber.X + "," + Chamber.Y); //create chamber if (Chamber.X > -1 && Chamber.Y > -1) { createChamber(options, req); } //Console.WriteLine("DRAW:"); for (i = 0; i <= Rooms.GetUpperBound(0); i++) { for (j = 0; j <= Rooms.GetUpperBound(1); j++) { if (Rooms[i, j].Opened != CLOSED) { drawRoom(i, j); } } } for (i = 0; i <= Rooms.GetUpperBound(0); i++) { for (j = 0; j <= Rooms.GetUpperBound(1); j++) { if (Rooms[i, j].Opened != CLOSED) { padSingleRoom(i, j); } } } //Console.WriteLine("HALLS:"); for (i = 0; i <= VHalls.GetUpperBound(0); i++) { for (j = 0; j <= VHalls.GetUpperBound(1); j++) { if (VHalls[i, j].Open) { createVHall(i, j, options, req); } } } for (i = 0; i <= HHalls.GetUpperBound(0); i++) { for (j = 0; j <= HHalls.GetUpperBound(1); j++) { if (HHalls[i, j].Open) { createHHall(i, j, options, req); } } } for (i = 0; i <= VHalls.GetUpperBound(0); i++) { for (j = 0; j <= VHalls.GetUpperBound(1); j++) { if (VHalls[i, j].Open) { DrawHalls(VHalls[i, j]); } } } for (i = 0; i <= HHalls.GetUpperBound(0); i++) { for (j = 0; j <= HHalls.GetUpperBound(1); j++) { if (HHalls[i, j].Open) { DrawHalls(HHalls[i, j]); } } } // create halls //for (i = 0; i < 12; i++) { // if (VHalls[i] == OPEN) { // createVHall(i, options); // } // if (HHalls[i] == OPEN) { // createHHall(i, options); // } //} //Console.WriteLine("SE:"); if (Start.X != Chamber.X || Start.Y != Chamber.Y) { addSEpos(Start, START, req); } if (End.X != Chamber.X || End.Y != Chamber.Y) { addSEpos(End, END, req); } //Console.WriteLine("WATER:"); //add water DrawWater(options); DrawCraters(options); //Console.WriteLine("TRAPS:"); // add traps int finalTraps = random.Next(options.TrapMin, options.TrapMax + 1); if (finalTraps > 0) { for (i = 0; i < finalTraps; i++) { // add traps for (j = 0; j < 200; j++) { a = random.Next(0, Rooms.GetUpperBound(0) + 1); b = random.Next(0, Rooms.GetUpperBound(1) + 1); x = random.Next(Rooms[a, b].StartX, Rooms[a, b].EndX + 1); y = random.Next(Rooms[a, b].StartY, Rooms[a, b].EndY + 1); if (Rooms[a, b].Opened == OPEN && MapArray[x, y] == GROUND) { MapArray[x, y] = TRAPTILE; break; } } } } //if (options.TrapFrequency > 0 && options.TrapMax > 0) { // for (i = options.TrapMin; i < options.TrapMax; i++) { // if (random.Next(0, 100) + 1 >= options.TrapFrequency) { // then generate a trap // a = random.Next(0, 16); // convertRoomToXY(a, ref x, ref y); // x = x + 1 + (random.Next(0, 6)); // y = y + 1 + (random.Next(0, 5)); // if (mapArray[y, x] == '.') { // mapArray[y, x] = 'Q'; // } // } // } //} //Console.WriteLine("ITEMS:"); // generate items (up to 16) ~moved to its own method //for (i = 0; i < 16; i++) { //bool success = false; // for (int k = 0; k < 200; k++) { // do until you succeed // a = random.Next(0, 16); //convertRoomToXY(a, ref x, ref y); // x = random.Next(room[a,1], room[a,3]+1); // y = random.Next(room[a,2], room[a,4]+1); // if (mapArray[y, x] == '.' /* mapArray[y, x] != 'S' && mapArray[y, x] != 'E' && // mapArray[y, x] != ' '*/) { // mapArray[y, x] = (char)(96 + i); //ascii for lowercase letters // break; // } // } //} //return MapArray; }
void DrawCraters(GeneratorOptions options) { if (options.Craters > 0) { for (int i = 0; i < options.Craters; i++) { int centerX = random.Next(1, 50); int centerY = random.Next(1, 50); int craterLength = random.Next(options.CraterMinLength, options.CraterMaxLength); int startX; int startY; if (craterLength % 2 == 1) { startX = centerX - craterLength / 2; startY = centerY - craterLength / 2; } else { startX = centerX + 1 - craterLength / 2; startY = centerY + 1 - craterLength / 2; } for (int y = startY; y < startY + craterLength; y++) { for (int x = startX; x < startX + craterLength; x++) { if (x < 1 || x > 47 || y < 1 || y > 47) { } else if (MapArray[x, y] != UBLOCK) { } else { if (System.Math.Abs(x - centerX) + System.Math.Abs(y - centerY) <= craterLength / 2) {//makes a crater in a "diamond" shape MapArray[x, y] = UWATER; } else if (options.CraterFuzzy == true && System.Math.Abs(x - centerX) + System.Math.Abs(y - centerY) <= craterLength * 0.75) {//makes a "fuzzy" edge to the diamond crater if (random.Next(0, 100) > 49) { MapArray[x, y] = UWATER; } } } } } } } }
void createVHall(int hallX, int hallY, GeneratorOptions options, RDungeonChamberReq req) { //Console.Write("V"+hall+":"); DungeonArrayRoom startRoom = Rooms[hallX, hallY]; DungeonArrayRoom endRoom = Rooms[hallX, hallY + 1]; int n = endRoom.StartY - startRoom.EndY; //distance between rooms if (n < 1) { if (startRoom.StartX > endRoom.EndX || startRoom.EndX < endRoom.StartX) { n++; } else { //Console.WriteLine(";"); return; } } n--; int x, y, m,/* n,*/ h, r = 0, var; y = startRoom.EndY; m = random.Next(options.HallTurnMin, options.HallTurnMax + 1); // the number of horizontal pieces in the hall if (m > ((n - 1) / 2)) m = (n - 1) / 2; //reduces the number of hall turns to something the length of the hall can accept x = random.Next(startRoom.StartX, startRoom.EndX + 1); //picks a X coordinate to start at if (Chamber.X == hallX && Chamber.Y == hallY && req != null && req.BottomPassage > -1) { x = startRoom.StartX + req.BottomPassage; } VHalls[hallX, hallY].TurnPoints.Add(new DungeonPoint(x, y)); if (m <= 0 && (x > endRoom.EndX || x < endRoom.StartX || (Chamber.X == hallX && Chamber.Y == hallY + 1 && req != null && req.TopPassage > -1 && x != endRoom.StartX + req.TopPassage))) {//checks if at least one turn is needed to make rooms meet m = 1; } //Console.Write("("+room[startRoom,1]+"."+room[startRoom,3]+")"); for (int i = 0; i <= m; i++) { if (i == m) { var = random.Next(endRoom.StartX, endRoom.EndX + 1) - x; if (Chamber.X == hallX && Chamber.Y == hallY + 1 && req != null && req.TopPassage > -1) { var = endRoom.StartX + req.TopPassage - x; } } else { var = random.Next(options.HallVarMin, options.HallVarMax + 1); if (random.Next(0, 2) == 0) { var = -var; } } if (i != 0) { if ((x + var) < 1) var = 1 - x; if ((x + var) > 48) var = 48 - x; //addHorizHall(x, y, var, mapArray); x += var; VHalls[hallX, hallY].TurnPoints.Add(new DungeonPoint(x, y)); }// else { //mapArray[y,x] = ','; //} if (n >= 0) { h = (r + n) / (m + 1); r = (r + n) % (m + 1); } else { h = -(r - n) / (m + 1); r = (r - n) % (m + 1); } //Console.Write("("+n+","+r+")"); //addVertHall(x, y, h, mapArray); y += h; VHalls[hallX, hallY].TurnPoints.Add(new DungeonPoint(x, y)); } VHalls[hallX, hallY].TurnPoints[VHalls[hallX, hallY].TurnPoints.Count - 1] = new DungeonPoint(x, y + 1); //mapArray[y + 1, x] = ','; //int x, y, h, j; // variables for position //h = hall % 4; //j = hall / 4; //x = 3 + Convert.ToInt32(13.5 * h); //y = 7 + 12 * j; //addVertHall(x, y, mapArray); //Console.WriteLine(";"); }
void createRoom(int roomX, int roomY, GeneratorOptions options, RDungeonChamberReq req) { if (Rooms[roomX, roomY].StartX > -1) { return; } int x = 0, y = 0, u, v, w, l; // variables used for position convertRoomToXY(roomX, roomY, ref x, ref y); //Determine room length/width if (Rooms[roomX, roomY].Opened == HALL) { w = 0; l = 0; } else { w = random.Next(options.RoomWidthMin, options.RoomWidthMax + 1) - 1; l = random.Next(options.RoomLengthMin, options.RoomLengthMax + 1) - 1; if (w < 1) w = 1; if (l < 1) l = 1; if (w > 47) w = 47; if (l > 47) l = 47; } //move X and Y to a random starting point that still would include the original x/y; exceptional case for l/w under or equal to 6 if (w <= 6) { x -= (random.Next(0, (13 - w)) + w - 7); } else { x -= random.Next(0, w + 1); } if (l <= 6) { y -= (random.Next(0, (13 - l)) + l - 7); } else { y -= random.Next(0, l + 1); } if (x < 1) x = 1; if ((x + w) > 48) x = (48 - w); if (y < 1) y = 1; if ((y + l) > 48) y = (48 - l); // once we have our room coords, render it on the map u = x + w; v = y + l; for (int i = 0; i <= Rooms.GetUpperBound(0); i++) { for (int j = 0; j <= Rooms.GetUpperBound(1); j++) { if ((roomX == i && roomY == j) ||//if the room is this room ((6 + i * 12) >= x && (6 + i * 12) <= u && (6 + j * 12) >= y && (6 + j * 12) <= v)) {//if the room's anchor point was eclipsed in this room Rooms[i, j].StartX = x; Rooms[i, j].StartY = y; Rooms[i, j].EndX = u; Rooms[i, j].EndY = v; } } } // done }
void createHHall(int hallX, int hallY, GeneratorOptions options, RDungeonChamberReq req) { //Console.Write("H"+hall+":"); DungeonArrayRoom startRoom = Rooms[hallX, hallY]; DungeonArrayRoom endRoom = Rooms[hallX + 1, hallY]; int n = endRoom.StartX - startRoom.EndX; //distance between rooms if (n < 1) { if (startRoom.StartY > endRoom.EndY || startRoom.EndY < endRoom.StartY) { n++; } else { //Console.WriteLine(";"); return; } } n--; int x, y, m,/* n,*/ h, r = 0, var; x = startRoom.EndX; m = random.Next(options.HallTurnMin, options.HallTurnMax + 1); // the number of vertical pieces in the hall if (m > ((n - 1) / 2)) m = (n - 1) / 2; //reduces the number of hall turns to something the length of the hall can accept y = random.Next(startRoom.StartY, startRoom.EndY + 1); //picks a Y coordinate to start at if (Chamber.X == hallX && Chamber.Y == hallY && req != null && req.RightPassage > -1) { y = startRoom.StartY + req.RightPassage; } HHalls[hallX, hallY].TurnPoints.Add(new DungeonPoint(x, y)); if (m <= 0 && (y > endRoom.EndY || y < endRoom.StartY || (Chamber.X == hallX + 1 && Chamber.Y == hallY && req != null && req.LeftPassage > -1 && y != endRoom.StartY + req.LeftPassage))) {//checks if at least one turn is needed to make rooms meet m = 1; } //Console.Write("("+room[startRoom,2]+"."+room[startRoom,4]+")"); for (int i = 0; i <= m; i++) { if (i == m) { var = random.Next(endRoom.StartY, endRoom.EndY + 1) - y; if (Chamber.X == hallX + 1 && Chamber.Y == hallY && req != null && req.LeftPassage > -1) { var = endRoom.StartY + req.LeftPassage - y; } } else { var = random.Next(options.HallVarMin, options.HallVarMax + 1); if (random.Next(0, 2) == 0) { var = -var; } } if (i != 0) { if ((y + var) < 1) var = 1 - y; if ((y + var) > 48) var = 48 - y; //addVertHall(x, y, var, mapArray); y += var; HHalls[hallX, hallY].TurnPoints.Add(new DungeonPoint(x, y)); }// else { //mapArray[y,x] = ','; //} if (n >= 0) { h = (r + n) / (m + 1); r = (r + n) % (m + 1); } else { h = -(r - n) / (m + 1); r = (r - n) % (m + 1); } //Console.Write("("+n+","+r+")"); //addHorizHall(x, y, h, mapArray); x += h; HHalls[hallX, hallY].TurnPoints.Add(new DungeonPoint(x, y)); } HHalls[hallX, hallY].TurnPoints[HHalls[hallX, hallY].TurnPoints.Count - 1] = new DungeonPoint(x + 1, y); //mapArray[y, x + 1] = ','; //int x, y, h, j; //h = hall % 3; //j = hall / 3; //x = 8 + 13 * h; //y = 3 + 12 * j; //addHorizHall(x, y, 6, mapArray); //Console.WriteLine(";"); }
void createChamber(GeneratorOptions options, RDungeonChamberReq req) { int x = 0, y = 0, u = 0, v = 0, w, l; // variables used for position convertRoomToXY(Chamber.X, Chamber.Y, ref x, ref y); int roomX = Chamber.X; int roomY = Chamber.Y; bool eclipse = true; int iterations = 100; if (req.MinX == req.MaxX && req.MinY == req.MaxY) { iterations = 1; } for (int k = 0; k < iterations && eclipse == true; k++) { //Determine room length/width //chamber cannot be a hall w = random.Next(req.MinX, req.MaxX + 1) - 1; l = random.Next(req.MinY, req.MaxY + 1) - 1; if (w < 1) w = 1; if (l < 1) l = 1; if (w > 47) w = 47; if (l > 47) l = 47; //move X and Y to a random starting point that still would include the original x/y; exceptional case for l/w under or equal to 6 if (w <= 6) { x -= (random.Next(0, (13 - w)) + w - 7); } else { x -= random.Next(0, w + 1); } if (l <= 6) { y -= (random.Next(0, (13 - l)) + l - 7); } else { y -= random.Next(0, l + 1); } if (x < 1) x = 1; if ((x + w) > 48) x = (48 - w); if (y < 1) y = 1; if ((y + l) > 48) y = (48 - l); // once we have our room coords, render it on the map u = x + w; v = y + l; eclipse = false; if (req.Start == Enums.Acceptance.Never || req.End == Enums.Acceptance.Never) {//if we're dealing with a chamber with no tolerance to entrances/exits for (int i = 0; i <= Rooms.GetUpperBound(0); i++) { for (int j = 0; j <= Rooms.GetUpperBound(1); j++) { if (Chamber.X != i || Chamber.Y != j) {//if the room not is this room if (doesBigRoomEclipseSmallRoom(x, y, u, v, Rooms[i, j].StartX, Rooms[i, j].StartY, Rooms[i, j].EndX, Rooms[i, j].EndY)) { if (req.Start == Enums.Acceptance.Never && Start.X == i && Start.Y == j) { eclipse = true; } if (req.End == Enums.Acceptance.Never && End.X == i && End.Y == j) { eclipse = true; } } } } } } } if (eclipse) { //the chamber has eclipsed a start/end room; it can't stay Chamber = new DungeonPoint(-1, -1); //reroll everything w = random.Next(options.RoomWidthMin, options.RoomWidthMax + 1) - 1; l = random.Next(options.RoomLengthMin, options.RoomLengthMax + 1) - 1; if (w < 1) w = 1; if (l < 1) l = 1; if (w > 47) w = 47; if (l > 47) l = 47; //move X and Y to a random starting point that still would include the original x/y; exceptional case for l/w under or equal to 6 if (w <= 6) { x -= (random.Next(0, (13 - w)) + w - 7); } else { x -= random.Next(0, w + 1); } if (l <= 6) { y -= (random.Next(0, (13 - l)) + l - 7); } else { y -= random.Next(0, l + 1); } if (x < 1) x = 1; if ((x + w) > 48) x = (48 - w); if (y < 1) y = 1; if ((y + l) > 48) y = (48 - l); // once we have our room coords, render it on the map u = x + w; v = y + l; } for (int i = 0; i <= Rooms.GetUpperBound(0); i++) { for (int j = 0; j <= Rooms.GetUpperBound(1); j++) { if ((roomX == i && roomY == j) ||//if the room is this room doesBigRoomEclipseSmallRoom(x, y, u, v, Rooms[i, j].StartX, Rooms[i, j].StartY, Rooms[i, j].EndX, Rooms[i, j].EndY)) { Rooms[i, j].StartX = x; Rooms[i, j].StartY = y; Rooms[i, j].EndX = u; Rooms[i, j].EndY = v; } } } // done }