// Get tile public Tile GetTile(int tx, int ty) { Tile tile = new Tile(); char s = ' '; Color4 c = Color4.White; Color4 cbg = Color4.Black; string d = "Empty space."; string dd = "Nothing out of the ordinary."; string type = "none"; bool tileIsStatic = true; // Get tile if (player.tileX == tx && player.tileY == ty) { s = '@'; c = Color4.LimeGreen; d = "Yourself."; dd = player.descDetailed; type = "player"; } else { // If actor is at tile bool actorCheck = false; if (tilesActors[tx, ty] != null) { if (tilesActors[tx, ty].visible) { s = tilesActors[tx, ty].image; c = tilesActors[tx, ty].color; d = tilesActors[tx, ty].desc; dd = tilesActors[tx, ty].descDetailed; type = "actor"; tileIsStatic = false; actorCheck = true; } } // If no actor is at tile bool itemCheck = false; if (!actorCheck) { // If item is at tile if (tilesItems[tx, ty] != null) { if (tilesItems[tx, ty].visible) { s = tilesItems[tx, ty].image; c = tilesItems[tx, ty].color; if (tilesItems[tx, ty].amount > 1) { d = tilesItems[tx, ty].descPlural + " (" + tilesItems[tx, ty].amount + ")"; } else { d = tilesItems[tx, ty].desc; } dd = tilesItems[tx, ty].descDetailed; type = "item"; tileIsStatic = false; itemCheck = true; } } } // If no object is on the tile if (!actorCheck && !itemCheck) { // Floor if (tilesData[tx, ty, mapLevelCurrent].type == TILE_TYPE_FLOOR) { s = '.'; d = "The floor."; dd = "Roughly-hewn stone. Cold and uninviting."; /*if(player.commandCurrent == "look") { c = Color4.Yellow; }*/ type = "floor"; } // Wall if (tilesData[tx, ty, mapLevelCurrent].type == TILE_TYPE_WALL) { s = ' '; cbg = Color4.LightGray; d = "The wall."; dd = "Imposing layers of large bricks."; /*if (player.commandCurrent == "look") { cbg = Color4.Yellow; }*/ type = "wall"; } // Stairs down if (tilesData[tx, ty, mapLevelCurrent].type == TILE_TYPE_STAIRS) { s = '>'; c = Color4.Magenta; d = "Stairs leading down."; dd = "A darkened path downwards."; type = "stairs"; } // Door if (tilesData[tx, ty, mapLevelCurrent].type == TILE_TYPE_DOOR) { if (tilesDoors[tx, ty].open) { s = '`'; d = "An open door."; } else { s = '+'; d = "A closed door."; } type = "door"; c = Color4.Goldenrod; } } } // If tile is not in LOS if (player.tilesInLOS[tx, ty] == 0) { if (type != "stairs") { c = Color4.Gray; } if (cbg != Color4.Black) { cbg = Color4.Gray; } if (!tileIsStatic) { s = '.'; } if (tileExplored[tx, ty] == 0) { s = ' '; cbg = Color4.Black; } } // If tile is currently selected, highlight it if (player.selectTileX == tx && player.selectTileY == ty) { c = Color4.Black; cbg = Color4.Yellow; } tile.image = s; tile.color = c; tile.colorBG = cbg; tile.desc = d; tile.descDetailed = dd; return tile; }
// Generate the floor map public void GenerateFloorMap(int dz) { // Set default for (int dx = 0; dx < mapSizeX; dx++) { for (int dy = 0; dy < mapSizeY; dy++) { tilesData[dx, dy, dz] = new Tile(); tileExplored[dx, dy] = 0; tilesDoors[dx, dy] = new Door(); } } // Create rooms // For each room Random rand = new Random(); int roomsNum = rand.Next(12, 16); Room[] rooms = new Room[roomsNum]; for (int room = 0; room <= roomsNum - 1; room++) { // Position the room so that it doesn't overlap existing rooms int roomX = 0; int roomY = 0; int roomW = 0; int roomH = 0; bool check = false; while (!check) { // Choose a random spot, and choose a random width and height roomX = rand.Next(3, mapSizeX - 5); roomY = rand.Next(3, mapSizeY - 5); roomW = rand.Next(3, 10); roomH = rand.Next(3, 10); check = true; // Larger than map size if (roomX + roomW >= mapSizeX - 1 || roomY + roomH >= mapSizeY - 1) { check = false; } // Compare with other rooms for (int r = 0; r <= room - 1; r++) { // Starts in another room if (roomX > rooms[r].x && roomX <= rooms[r].x + rooms[r].w && roomY > rooms[r].y && roomY <= rooms[r].y + rooms[r].h) { check = false; } // Ends in another room if (roomX + roomW > rooms[r].x && roomX + roomW <= rooms[r].x + rooms[r].w && roomY + roomH > rooms[r].y && roomY + roomH <= rooms[r].y + rooms[r].h) { check = false; } } } rooms[room] = new Room(roomX, roomY, dz, roomW, roomH); // Set the player's starting position if (dz == 0) { if (!playerStartTileSet) { playerStartTileX = roomX + 1; playerStartTileY = roomY + 1; playerStartTileSet = true; player.tileX = playerStartTileX; player.tileY = playerStartTileY; player.tileZ = mapLevelCurrent; player.tileXLast = playerStartTileX; player.tileYLast = playerStartTileY; player.tileZLast = mapLevelCurrent; } } else { // Set start for each floor /*if (!playerFloorStartTileSet[dz]) { playerFloorStartTiles[dz].x = roomX + 1; playerFloorStartTiles[dz].y = roomY + 1; playerFloorStartTileSet[dz] = true; }*/ } // Build floor for (int dx = 0; dx < roomW; dx++) { for (int dy = 0; dy < roomH; dy++) { tilesData[roomX + dx, roomY + dy, dz].type = TILE_TYPE_FLOOR; } } } // Try to connect the rooms for (int room = 0; room <= roomsNum - 1; room++) { if (room != roomsNum - 1) { // Start from the center of the room int mx = rooms[room].x + (int)(rooms[room].w / 2); int my = rooms[room].y + (int)(rooms[room].h / 2); int tx = rooms[room + 1].x + (int)(rooms[room + 1].w / 2); int ty = rooms[room + 1].y + (int)(rooms[room + 1].h / 2); while (mx != tx) { if (mx > tx) { mx--; } if (mx < tx) { mx++; } tilesData[mx, my, dz].type = TILE_TYPE_FLOOR; } while (my != ty) { if (my > ty) { my--; } if (my < ty) { my++; } tilesData[mx, my, dz].type = TILE_TYPE_FLOOR; } } } // Build walls for (int dx = 1; dx < mapSizeX - 1; dx++) { for (int dy = 1; dy < mapSizeY - 1; dy++) { // If floor tile if (tilesData[dx, dy, dz].type == 1) { // Check for empty surrounding space if (tilesData[dx + 1, dy, dz].type == TILE_TYPE_NONE) { tilesData[dx + 1, dy, dz].type = TILE_TYPE_WALL; } if (tilesData[dx + 1, dy - 1, dz].type == TILE_TYPE_NONE) { tilesData[dx + 1, dy - 1, dz].type = TILE_TYPE_WALL; } if (tilesData[dx, dy - 1, dz].type == TILE_TYPE_NONE) { tilesData[dx, dy - 1, dz].type = TILE_TYPE_WALL; } if (tilesData[dx - 1, dy - 1, dz].type == TILE_TYPE_NONE) { tilesData[dx - 1, dy - 1, dz].type = TILE_TYPE_WALL; } if (tilesData[dx - 1, dy, dz].type == TILE_TYPE_NONE) { tilesData[dx - 1, dy, dz].type = TILE_TYPE_WALL; } if (tilesData[dx - 1, dy + 1, dz].type == TILE_TYPE_NONE) { tilesData[dx - 1, dy + 1, dz].type = TILE_TYPE_WALL; } if (tilesData[dx, dy + 1, dz].type == TILE_TYPE_NONE) { tilesData[dx, dy + 1, dz].type = TILE_TYPE_WALL; } if (tilesData[dx + 1, dy + 1, dz].type == TILE_TYPE_NONE) { tilesData[dx + 1, dy + 1, dz].type = TILE_TYPE_WALL; } // Fix partial corner walls if (tilesData[dx + 1, dy, dz].type == TILE_TYPE_WALL && tilesData[dx, dy + 1, dz].type == TILE_TYPE_WALL && tilesData[dx + 1, dy + 1, dz].type == TILE_TYPE_FLOOR) { tilesData[dx, dy, dz].type = TILE_TYPE_WALL; tilesData[dx + 1, dy + 1, dz].type = TILE_TYPE_WALL; } if (tilesData[dx - 1, dy, dz].type == TILE_TYPE_WALL && tilesData[dx, dy - 1, dz].type == TILE_TYPE_WALL && tilesData[dx - 1, dy - 1, dz].type == TILE_TYPE_FLOOR) { tilesData[dx, dy, dz].type = TILE_TYPE_WALL; tilesData[dx - 1, dy - 1, dz].type = TILE_TYPE_WALL; } } } } // Create floor exit int floorExitTX = 0; int floorExitTY = 0; bool floorExitCheck = false; while (!floorExitCheck) { // Choose a random space floorExitTX = rand.Next(3, mapSizeX - 5); floorExitTY = rand.Next(3, mapSizeY - 5); // If space is available if (tilesData[floorExitTX, floorExitTY, dz].type == TILE_TYPE_FLOOR) { // Place exit tilesData[floorExitTX, floorExitTY, dz].type = TILE_TYPE_STAIRS; floorExitStairs = new Stairs(floorExitTX, floorExitTY, dz); floorExitCheck = true; } } floorExitCheck = false; // Build doors for (int dx = 1; dx < mapSizeX - 2; dx++) { for (int dy = 1; dy < mapSizeY - 2; dy++) { // If floor tile if (tilesData[dx, dy, dz].type == TILE_TYPE_FLOOR) { // Check for walls on each side bool check = false; // Vertical if (tilesData[dx + 1, dy, dz].type == TILE_TYPE_WALL && tilesData[dx - 1, dy, dz].type == TILE_TYPE_WALL) { check = true; // Limit the number of doors in one hallway/area for (int d = 0; d <= doorsNum - 1; d++) { int distance = TileDistance(dx, dy, doors[d].tileX, doors[d].tileY); if (distance < 5) { check = false; } } } else { // Horizontal if (tilesData[dx, dy + 1, dz].type == TILE_TYPE_WALL && tilesData[dx, dy - 1, dz].type == TILE_TYPE_WALL) { check = true; // Limit the number of doors in one hallway/area for (int d = 0; d <= doorsNum - 1; d++) { int distance = TileDistance(dx, dy, doors[d].tileX, doors[d].tileY); if (distance < 5) { check = false; } } } } // Create door if (check) { if (doorsNum < 100) { doors[doorsNum] = new Door(dx, dy, dz); tilesData[dx, dy, dz].type = TILE_TYPE_DOOR; tilesDoors[dx, dy] = doors[doorsNum]; doorsNum++; } } } } } // Place items int itemTX = 0; int itemTY = 0; bool itemCheck = false; int floorItemCount = rand.Next(5, 8); for (int c = 1; c <= floorItemCount; c++) { // While placing each item while (!itemCheck) { // Choose a random space itemTX = rand.Next(3, mapSizeX - 5); itemTY = rand.Next(3, mapSizeY - 5); // If space is available if (tilesData[itemTX, itemTY, dz].type == TILE_TYPE_FLOOR) { // Check if an item is on the tile already bool check = true; for (int itm = 0; itm <= itemsNum - 1; itm++) { if (items[itm].tileX == itemTX && items[itm].tileY == itemTY) { check = false; } } // If a place has been found for the item if (check) { int ind = -1; // Choose an item type to spawn by its spawn chance while (!itemCheck) { for (int it = 0; it <= itemTypesNum - 1; it++) { int sc = rand.Next(1, 100); if (sc <= itemTypesSpawnChance[it]) { ind = it; itemCheck = true; break; } } } // Spawn the item SpawnItemAtPosition(ind, itemTX, itemTY, dz); } } } itemCheck = false; } // Place actors int actorTX = 0; int actorTY = 0; bool actorCheck = false; int floorActorCount = rand.Next(4, 6); for (int c = 1; c <= floorActorCount; c++) { // While placing each actor while (!actorCheck) { // Choose a random space actorTX = rand.Next(3, mapSizeX - 5); actorTY = rand.Next(3, mapSizeY - 5); // If space is available if (tilesData[actorTX, actorTY, dz].type == TILE_TYPE_FLOOR) { // Check if an actor or item is on the tile already bool check = true; for (int act = 0; act <= actorsNum - 1; act++) { if (actors[act].tileX == actorTX && actors[act].tileY == actorTY) { check = false; } } for (int i = 0; i <= itemsNum - 1; i++) { if (items[i].tileX == actorTX && items[i].tileY == actorTY) { check = false; } } // If a place has been found for the actor if (check) { int ind = -1; // Choose an actor type to spawn by its spawn chance while (!actorCheck) { for (int at = 0; at <= actorTypesNum - 1; at++) { int sc = rand.Next(1, 100); if (sc <= actorTypesSpawnChance[at]) { ind = at; actorCheck = true; break; } } } // Spawn the actor SpawnActorAtPosition(ind, actorTX, actorTY, dz); } } } actorCheck = false; } }