private static void singleValidation(DungeonLayout layout, int id) { TestLogger.log("validating layout - id: " + id); if (layout == null) { throw new DungeonLayoutNotAvailableException("DungeonDispatcher returned NULL for layout id: " + id); } if (layout.grid == null) { throw new WrongLayoutDeclarationException("layout.grid is NULL. layout id: " + id); } if (layout.rooms == null) { throw new WrongLayoutDeclarationException("layout.rooms is NULL. layout id: " + id); } if (layout.pathableAreas == null) { throw new WrongLayoutDeclarationException("layout.pathableAreas is NULL. layout id: " + id); } foreach (PseudoRoom room in layout.rooms) { checkRoom(layout, room); } foreach (PathableArea area in layout.pathableAreas) { checkArea(layout, area); } TestLogger.log("validated"); TestLogger.log(""); }
public Dungeon generateDungeon(Random rand, int seed) { //LATER_PATCH: pick dungeon type //scegli layout DungeonLayout layout = DungeonDispatcher.getDungeonLayoutById((rand.Next() % Constants.LAYOUTS_COUNT) + 1); //scegli stanze List <DungeonRoom> rooms = new List <DungeonRoom>(); foreach (PseudoRoom room in layout.rooms) { DungeonRoom pickedRoom = DungeonDispatcher.getDungeonRoomByType(room.sizeX, room.sizeY, rand.Next(), rand); layout.grid.paste(pickedRoom.grid, room.position); rooms.Add(pickedRoom); } //crea percorsi PathLinkingStrategy pathLinker = new ClosestPathLinker(); //LATER_PATCH: decide which srtategy to use pathLinker.linkPaths(layout, rand); layout.grid.normalize(); //inserisci tesori List <Treasure> treasures = new List <Treasure>(); foreach (DungeonRoom room in rooms) { foreach (Treasure treasure in room.treasures) { treasures.Add(TreasureInitializer.initializeTreasure(treasure, rand)); } } List <Coordinates> culDeSacs = layout.grid.getCulDeSacs(); foreach (Coordinates culDeSac in culDeSacs) { } int antiChances = Constants.TREASURE_SPAWN_PERIOD; foreach (Coordinates point in culDeSacs) { if (rand.Next() % antiChances == 0) { layout.grid.put(point, Constants.TREASURE_MARKER); treasures.Add(TreasureInitializer.initializeTreasure(new Treasure(point), rand)); antiChances = Constants.TREASURE_SPAWN_PERIOD + (treasures.Count * Constants.TREASURE_SPAWN_INCREMENTAL); } else { antiChances -= Constants.TREASURE_SPAWN_INCREMENTAL; } } //LATER_PATCH: add traps return(new Dungeon(layout.grid, rooms, treasures, seed /*LATER_PATCH: , traps*/)); }
private bool VerifyMobSpawners( DungeonLayout layout) { bool success = true; for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); RoomTemplate roomTemplate = layout.LayoutRoomTemplateSet.GetTemplateByName(room.static_room_data.room_template_name); // We don't add the mob spawner to the room if we create it // and it doesn't have any mobs left (spawner initially has 0 mobs. // TODO: Add this check back in when we support non-zero min spawn count //if (roomTemplate.MobSpawnerTemplates.Count() != room.mobSpawners.Count) //{ // _logger.WriteLine("DungeonValidator: FAILED: Mob spawner template count != mob spawner count"); // _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); // _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", // room.room_key.x, room.room_key.y, room.room_key.z)); // success = false; // break; //} foreach (MobSpawner spawner in room.mobSpawners) { if (spawner.SpawnTable == null) { _logger.WriteLine("DungeonValidator: FAILED: Mob spawner missing spawn table!"); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } while (spawner.RemainingSpawnCount > 0) { Mob mob = spawner.SpawnRandomMob(); if (mob == null) { _logger.WriteLine("DungeonValidator: FAILED: Mob spawner failed to produce valid mob!"); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } } } return(success); }
public DungeonLayout Generate(int width, int height) { DungeonLayout dungeonLayout = new DungeonLayout(width, height); dungeonLayout = GenerateMainPath(dungeonLayout); return(dungeonLayout); }
public override void linkPaths(DungeonLayout layout, Random rand) { foreach (PathableArea area in layout.pathableAreas) { shufflePaths(layout.grid, area, rand); recursiveMergePaths(layout.grid, area, rand); } }
// Start is called before the first frame update void Start() { layout = new DungeonLayout(10, 4); RoomIdentifier[] identifiers = layout.GetRoomTypes(); foreach (RoomIdentifier i in identifiers) { createRoom(i); } }
//Level Creation Methods //Picks an element for the Level, Creates the map, Creates a Dungeon Layout, and sets the initial game state for that level void CreateDungeonLevel() { currentLevelElement = GetNextElement(); //set the initial element for this dungeon level HUDCanvas.transform.FindChild("CurrentLevel").GetComponent <UnityEngine.UI.Text>().text = "Level " + round; DungeonLayoutGenerator.S.CreateLevelMap(); DungeonLayout DL = DungeonLayoutGenerator.S.levelLayout.GetComponent <DungeonLayout> (); LoadingScreenCanvas.SetActive(false); created = true; }
private bool IsLeftRightAvailable(DungeonLayout roomLayout, RoomInfo previousRoom, int axis) { bool outOfBoundary = (previousRoom.x + axis >= roomLayout.width || previousRoom.x + axis < 0); if (!outOfBoundary) { return(roomLayout.layout[previousRoom.x + axis, previousRoom.y].roomState == RoomInfo.RoomState.Other); } return(false); }
private static void checkRoom(DungeonLayout layout, PseudoRoom room) { for (int x = room.position.x; x < room.sizeX + room.position.x; x++) { for (int y = room.position.y; y < room.sizeY + room.position.y; y++) { if (layout.grid.grid [x, y] != Constants.PSEUDO_ROOM_MARKER) { throw new WrongLayoutDeclarationException("PseudoRoom declaration error. position: " + room.position.x + "," + room.position.y); } } } }
private static void checkArea(DungeonLayout layout, PathableArea area) { for (int x = area.position.x; x < area.sizeX + area.position.x; x++) { for (int y = area.position.y; y < area.sizeY + area.position.y; y++) { if (layout.grid.grid [x, y] != Constants.PATHABLE_MARKER) { throw new WrongLayoutDeclarationException("PathableArea declaration error. position: " + area.position.x + "," + area.position.y); } } } }
private DungeonLayout GenerateMainPath(DungeonLayout dungeonLayout) { //Start from First Row int randX = (Random.Range(0, dungeonLayout.width)); dungeonLayout.layout[randX, dungeonLayout.height - 1] = new RoomInfo(randX, dungeonLayout.height - 1); dungeonLayout.layout[randX, dungeonLayout.height - 1].roomState = RoomInfo.RoomState.StartPoint; RoomInfo lastRoom = dungeonLayout.layout[randX, dungeonLayout.height - 1]; while (true) { MoveDir nextMove = FindNextRoom(dungeonLayout, lastRoom); dungeonLayout.layout[lastRoom.x, lastRoom.y].previousIndex = new Vector2Int(lastRoom.x, lastRoom.y); if (nextMove == MoveDir.End) { dungeonLayout.layout[lastRoom.x, lastRoom.y].roomState = RoomInfo.RoomState.EndPoint; break; } int dirX = lastRoom.x, dirY = lastRoom.y; if (nextMove == MoveDir.Down) { dirY -= 1; } if (nextMove == MoveDir.Left || nextMove == MoveDir.Right) { dirX += ((nextMove == MoveDir.Left) ? -1 : 1); } dungeonLayout.layout[dirX, dirY] = new RoomInfo(dirX, dirY); dungeonLayout.layout[dirX, dirY].roomState = RoomInfo.RoomState.MainPath; dungeonLayout.layout[dirX, dirY].roomStyle = RoomStyle.LeftRightOnly; if (nextMove == MoveDir.Down) { RoomStyle randamType = (RoomStyle)Random.Range(2, 4); dungeonLayout.layout[dirX, dirY].roomStyle = randamType; dungeonLayout.layout[lastRoom.x, lastRoom.y].roomStyle = RoomStyle.Bottom; } lastRoom = dungeonLayout.layout[dirX, dirY]; } return(dungeonLayout); }
public bool BuildWorld( AsyncRPGDataContext db_context, int game_id, out World world, out string result) { bool success = true; WorldTemplate worldTemplate = null; DungeonLayout layout = null; world = null; result = SuccessMessages.GENERAL_SUCCESS; // Get the world generation parameters from the DB worldTemplate = WorldQueries.GetWorldGenerationParameters( db_context, game_id); // Create the initial set of rooms for the world if (success) { layout = new DungeonLayout(game_id, worldTemplate, m_roomTemplateSet, m_mobSpawnTableSet); if (!layout.BuildRoomLayout(out result)) { success = false; } } // Copy the rooms and portals from the layout into the world if (success) { world = new World(this, layout.LayoutWorldTemplate, game_id); world.ApplyLayout(layout); } // TODO: WorldBuilder: Generate the environment objects, etc // Save the cached world into the database if (success) { WorldQueries.InsertWorld(db_context, world); } return success; }
private void RenderRoom(DungeonLayout dungeonLayout) { string renderString = ""; for (int y = dungeonLayout.height - 1; y >= 0; y--) { for (int x = 0; x < dungeonLayout.width; x++) { Debug.Log("x:" + x + ", y:" + y + ", " + dungeonLayout.layout[x, y].roomState.ToString("g") + ", " + dungeonLayout.layout[x, y].roomStyle.ToString("g")); if (x == dungeonLayout.width - 1) { renderString += "\n"; } } } }
public void ApplyLayout( DungeonLayout layout) { // Copy over all the rooms in the layout into the world for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; RoomLayout room = layout.GetRoomByIndex(roomIndex); RoomTemplate roomTemplate= layout.LayoutRoomTemplateSet.GetTemplateByName(room.static_room_data.room_template_name); room.runtime_nav_mesh = new NavMesh(room.room_key, roomTemplate.NavMeshTemplate); m_rooms.Add(room.room_key, room); } }
//function that actually creates the entire level layout private void LoadMapFile(TextAsset file) { try { string[] lines = file.text.Trim().Split('\n'); //split the file into lines for (int i = 0; i < lines.Length; ++i) { lines[i] = CleanLine(lines[i]); } int numRooms = GetNumRooms(lines); //number of rooms to init a DungeonLayout DungeonLayout DL = levelLayout.AddComponent <DungeonLayout>(); DL.Init(numRooms, lines); int height = lines.Length - 1; string line; for (int y = 0; y < height; ++y) { line = lines[y]; int width = line.Length - 1; line = CleanLine(line); if (line != null) { for (int x = 0; x < width; ++x) //for each char in the line { if (line[x] == '1' || line[x] == 'S' || line[x] == 'B') //Add all the room positions to the DL { Vector3 roomPos = MakeRoomPosition(y, x); //row, col if (line[x] == 'S') { DL.startRoomPosition = roomPos; } else if (line[x] == 'B') { DL.bossRoomPosition = roomPos; } } } } } } catch (Exception e) { Console.WriteLine("{0}\n", e.Message); print(e.Message); } }
IEnumerator GenerateNewLevelAsync() { DungeonLayout layout = new DungeonLayout(mainPathLength, sidePathMaxLength); RoomIdentifier[] identifiers = layout.GetRoomIdentifiers(); GameObject newLevelObj = new GameObject("level_" + (curLevel + 1)); newLevelObj.transform.position = Vector3.zero; newLevelObj.transform.parent = transform; newLevelObj.SetActive(false); yield return(null); foreach (RoomIdentifier i in identifiers) { CreateRoom(i, newLevelObj.transform); yield return(null); } nextLevelObj = newLevelObj; }
private MoveDir FindNextRoom(DungeonLayout roomLayout, RoomInfo previousRoom) { //1,2 = Left, 3,4 = Right, 5 = Down int diceValue = Random.Range(1, 6); //Debug.Log(previousRoom.x +", " + previousRoom.y +", " + previousRoom.roomState.ToString("g")); if (diceValue == 1 || diceValue == 2) { if (!IsLeftRightAvailable(roomLayout, previousRoom, -1) && IsLeftRightAvailable(roomLayout, previousRoom, 1)) { return(MoveDir.Right); } else if (!IsLeftRightAvailable(roomLayout, previousRoom, -1) && !IsLeftRightAvailable(roomLayout, previousRoom, 1)) { return(CheckDownValidity(previousRoom)); } return(MoveDir.Left); } if (diceValue == 3 || diceValue == 4) { if (!IsLeftRightAvailable(roomLayout, previousRoom, 1) && IsLeftRightAvailable(roomLayout, previousRoom, -1)) { return(MoveDir.Left); } else if (!IsLeftRightAvailable(roomLayout, previousRoom, 1) && !IsLeftRightAvailable(roomLayout, previousRoom, -1)) { return(CheckDownValidity(previousRoom)); } return(MoveDir.Right); } return(CheckDownValidity(previousRoom)); }
private GameObject GenerateFirstLevel() { curLevel = 0; DungeonLayout layout = new DungeonLayout(mainPathLength, sidePathMaxLength); RoomIdentifier[] identifiers = layout.GetRoomIdentifiers(); GameObject newLevelObj = new GameObject("level_" + (curLevel + 1)); newLevelObj.transform.position = Vector3.zero; newLevelObj.transform.parent = transform; foreach (RoomIdentifier i in identifiers) { CreateRoom(i, newLevelObj.transform); } numEnemiesPerRoom += enemiesIncreasePerLevel; mainPathLength += pathLengthIncreasePerLevel; sidePathMaxLength = mainPathLength / 3; curLevel = 1; StartCoroutine(GenerateNewLevelAsync()); return(newLevelObj); }
private Dictionary <int, Portal> BuildPortalIdMap( DungeonLayout layout) { Dictionary <int, Portal> portalIdToPortalMap = new Dictionary <int, Portal>(); // Generate a mapping from portal id to portal for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); // Add all of the portals to the map foreach (Portal portal in room.portals) { portalIdToPortalMap.Add(portal.portal_id, portal); } } return(portalIdToPortalMap); }
private bool VerifyMobSpawners( DungeonLayout layout) { bool success = true; for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); RoomTemplate roomTemplate= layout.LayoutRoomTemplateSet.GetTemplateByName(room.static_room_data.room_template_name); // We don't add the mob spawner to the room if we create it // and it doesn't have any mobs left (spawner initially has 0 mobs. // TODO: Add this check back in when we support non-zero min spawn count //if (roomTemplate.MobSpawnerTemplates.Count() != room.mobSpawners.Count) //{ // _logger.WriteLine("DungeonValidator: FAILED: Mob spawner template count != mob spawner count"); // _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); // _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", // room.room_key.x, room.room_key.y, room.room_key.z)); // success = false; // break; //} foreach (MobSpawner spawner in room.mobSpawners) { if (spawner.SpawnTable == null) { _logger.WriteLine("DungeonValidator: FAILED: Mob spawner missing spawn table!"); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } while (spawner.RemainingSpawnCount > 0) { Mob mob= spawner.SpawnRandomMob(); if (mob == null) { _logger.WriteLine("DungeonValidator: FAILED: Mob spawner failed to produce valid mob!"); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } } } return success; }
private bool VerifyRoomAccessibility( DungeonLayout layout, Dictionary<int, Portal> portalIdToPortalMap) { UnionFind<RoomKey> roomUnion = new UnionFind<RoomKey>(); RoomKey targetRoomKey = new RoomKey(); bool success = true; // Do a first pass over the rooms to fill out the union and the portal map for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); // Add the room to the union set roomUnion.AddElement(room.room_key); } // Union together all of the rooms connected by portals for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); foreach (Portal portal in room.portals) { Portal targetPortal= portalIdToPortalMap[portal.target_portal_id]; targetRoomKey.game_id= layout.GameID; targetRoomKey.x= targetPortal.room_x; targetRoomKey.y= targetPortal.room_y; targetRoomKey.z= targetPortal.room_z; roomUnion.Union(room.room_key, targetRoomKey); } } // Verify that all rooms share the same connectivity id int sharedConnectivityId = -1; for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); int roomConnectivityId= roomUnion.FindRootIndex(room.room_key); if (sharedConnectivityId != -1) { if (sharedConnectivityId != roomConnectivityId) { _logger.WriteLine("DungeonValidator: FAILED: Found room not connected to other rooms in dungeon!"); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success= false; break; } } else { sharedConnectivityId= roomConnectivityId; } } return success; }
private Dictionary<int, Portal> BuildPortalIdMap( DungeonLayout layout) { Dictionary<int, Portal> portalIdToPortalMap = new Dictionary<int, Portal>(); // Generate a mapping from portal id to portal for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); // Add all of the portals to the map foreach (Portal portal in room.portals) { portalIdToPortalMap.Add(portal.portal_id, portal); } } return portalIdToPortalMap; }
private void DumpLayoutGeometry( string dumpGeometryPath, DungeonLayout layout) { GeometryFileWriter fileWriter = new GeometryFileWriter(); string filename= string.Format("DungeonLayout_Game{0}_Size{1}", layout.GameID, layout.LayoutWorldTemplate.dungeon_size); string header = string.Format("DungeonLayout for GameID:{0} DungeonSize: {1}", layout.GameID, layout.LayoutWorldTemplate.dungeon_size); string result = SuccessMessages.GENERAL_SUCCESS; Vector3d roomSize = new Vector3d(WorldConstants.ROOM_X_SIZE, WorldConstants.ROOM_Y_SIZE, WorldConstants.ROOM_Z_SIZE); for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); AABB3d roomAABB = new AABB3d(room.world_position, room.world_position + roomSize); AABB3d shrunkRoomAABB = roomAABB.ScaleAboutCenter(0.5f); AABB3d centerAABB = roomAABB.ScaleAboutCenter(0.05f); // Add the AABB for this room fileWriter.AppendAABB(shrunkRoomAABB); // Create portal AABBs to all adjacent rooms for (MathConstants.eSignedDirection roomSide = MathConstants.eSignedDirection.first; roomSide < MathConstants.eSignedDirection.count; ++roomSide) { if (room.RoomHasPortalOnSide(roomSide)) { DungeonLayout.RoomIndex neighborRoomIndex = null; switch (roomSide) { case MathConstants.eSignedDirection.positive_x: neighborRoomIndex = roomIndex.Offset(1, 0, 0); break; case MathConstants.eSignedDirection.negative_x: neighborRoomIndex = roomIndex.Offset(-1, 0, 0); break; case MathConstants.eSignedDirection.positive_y: neighborRoomIndex = roomIndex.Offset(0, 1, 0); break; case MathConstants.eSignedDirection.negative_y: neighborRoomIndex = roomIndex.Offset(0, -1, 0); break; case MathConstants.eSignedDirection.positive_z: neighborRoomIndex = roomIndex.Offset(0, 0, 1); break; case MathConstants.eSignedDirection.negative_z: neighborRoomIndex = roomIndex.Offset(0, 0, -1); break; } Room neighborRoom = layout.GetRoomByIndex(neighborRoomIndex); AABB3d neighborRoomAABB = new AABB3d(neighborRoom.world_position, neighborRoom.world_position + roomSize); AABB3d neighborCenterAABB = neighborRoomAABB.ScaleAboutCenter(0.05f); AABB3d portalAABB = centerAABB.EncloseAABB(neighborCenterAABB); fileWriter.AppendAABB(portalAABB); } } // TODO: DumpLayoutGeometry: Color the rooms by teleporter pair } if (!fileWriter.SaveFile(dumpGeometryPath, filename, header, out result)) { _logger.WriteLine("DungeonValidator: WARNING: Failed to save layout geometry file"); _logger.WriteLine(result); } }
public abstract void linkPaths(DungeonLayout layout, Random rand);
public bool ValidateDungeons(Command command) { bool success = true; string result= SuccessMessages.GENERAL_SUCCESS; RoomTemplateSet roomTemplateSet = new RoomTemplateSet(); MobTypeSet mobTypeSet = new MobTypeSet(); MobSpawnTableSet mobSpawnTableSet = new MobSpawnTableSet(); int game_id_min = 0; int game_id_max = 100000; // Int32.MaxValue; This will take ~100 days to finish all 2 billion dungeons string connection_string = ""; string dumpGeometryPath = ""; if (command.HasArgumentWithName("C")) { connection_string = command.GetTypedArgumentByName<CommandArgument_String>("C").ArgumentValue; } else { _logger.WriteLine("DungeonValidator: Missing expected connection string parameter"); success = false; } if (command.HasArgumentWithName("G")) { game_id_min = command.GetTypedArgumentByName<CommandArgument_Int32>("G").ArgumentValue; game_id_max = game_id_min; } else { _logger.WriteLine("DungeonValidator: No game id given, evaluating all possible game ids"); } if (game_id_min == game_id_max && command.HasArgumentWithName("D")) { dumpGeometryPath = command.GetTypedArgumentByName<CommandArgument_String>("D").ArgumentValue; } _logger.WriteLine("Validating layouts for game_ids {0} to {1}", game_id_min, game_id_max); // Get the room templates from the DB if (success && !roomTemplateSet.Initialize(connection_string, out result)) { _logger.WriteLine(string.Format("DungeonValidator: Failed to load the room templates from the DB: {0}", result)); success = false; } // Get the mob type set from the DB if (success && !mobTypeSet.Initialize(connection_string, out result)) { _logger.WriteLine(string.Format("DungeonValidator: Failed to load the mob types from the DB: {0}", result)); success = false; } // Get the mob spawn templates from the DB if (success && !mobSpawnTableSet.Initialize(connection_string, mobTypeSet, out result)) { _logger.WriteLine(string.Format("DungeonValidator: Failed to load the mob spawn tables from the DB: {0}", result)); success = false; } if (success) { DateTime startTime = DateTime.Now; // Test all possible world size configurations for each desired game id WorldTemplate[] worldTemplates = new WorldTemplate[] { new WorldTemplate(GameConstants.eDungeonSize.small, GameConstants.eDungeonDifficulty.normal), new WorldTemplate(GameConstants.eDungeonSize.medium, GameConstants.eDungeonDifficulty.normal), new WorldTemplate(GameConstants.eDungeonSize.large, GameConstants.eDungeonDifficulty.normal), }; for (int game_id = game_id_min; success && game_id <= game_id_max; ++game_id) { foreach (WorldTemplate worldTemplate in worldTemplates) { DungeonLayout layout = new DungeonLayout(game_id, worldTemplate, roomTemplateSet, mobSpawnTableSet); // Create the initial set of rooms for the world if (!layout.BuildRoomLayout(out result)) { _logger.WriteLine( string.Format("DungeonValidator: Failed to generate dungeon layout, game_id:{0}, size:{1}", game_id, worldTemplate.dungeon_size)); _logger.WriteLine(result); success = false; } // Verify that this is a valid dungeon if (success) { Dictionary<int, Portal> portalIdToPortalMap = BuildPortalIdMap(layout); // Verify that all portals are connected correctly success &= VerifyRoomPortals(layout, portalIdToPortalMap); // Verify that every room is accessible to every other room success &= VerifyRoomAccessibility(layout, portalIdToPortalMap); // Verify monster spawners success &= VerifyMobSpawners(layout); } // Dump the generated layout to a .obj file if (dumpGeometryPath.Length > 0) { DumpLayoutGeometry(dumpGeometryPath, layout); } } if (game_id_max > game_id_min) { if ((game_id % 1000) == 0) { TimeSpan elapsed = DateTime.Now.Subtract(startTime); int percent_complete = 100 * (game_id - game_id_min) / (game_id_max - game_id_min); _logger.Write("\r[{0:c}] {1}/{2} {3}%", elapsed, game_id-game_id_min, game_id_max-game_id_min, percent_complete); } } } // Write out a new line after the timing info _logger.WriteLine(); } return success; }
public bool ValidateDungeons(Command command) { bool success = true; string result = SuccessMessages.GENERAL_SUCCESS; RoomTemplateSet roomTemplateSet = new RoomTemplateSet(); MobTypeSet mobTypeSet = new MobTypeSet(); MobSpawnTableSet mobSpawnTableSet = new MobSpawnTableSet(); int game_id_min = 0; int game_id_max = 100000; // Int32.MaxValue; This will take ~100 days to finish all 2 billion dungeons string connection_string = ""; string dumpGeometryPath = ""; if (command.HasArgumentWithName("C")) { connection_string = command.GetTypedArgumentByName <CommandArgument_String>("C").ArgumentValue; } else { _logger.WriteLine("DungeonValidator: Missing expected connection string parameter"); success = false; } if (command.HasArgumentWithName("G")) { game_id_min = command.GetTypedArgumentByName <CommandArgument_Int32>("G").ArgumentValue; game_id_max = game_id_min; } else { _logger.WriteLine("DungeonValidator: No game id given, evaluating all possible game ids"); } if (game_id_min == game_id_max && command.HasArgumentWithName("D")) { dumpGeometryPath = command.GetTypedArgumentByName <CommandArgument_String>("D").ArgumentValue; } _logger.WriteLine("Validating layouts for game_ids {0} to {1}", game_id_min, game_id_max); // Get the room templates from the DB if (success && !roomTemplateSet.Initialize(connection_string, out result)) { _logger.WriteLine(string.Format("DungeonValidator: Failed to load the room templates from the DB: {0}", result)); success = false; } // Get the mob type set from the DB if (success && !mobTypeSet.Initialize(connection_string, out result)) { _logger.WriteLine(string.Format("DungeonValidator: Failed to load the mob types from the DB: {0}", result)); success = false; } // Get the mob spawn templates from the DB if (success && !mobSpawnTableSet.Initialize(connection_string, mobTypeSet, out result)) { _logger.WriteLine(string.Format("DungeonValidator: Failed to load the mob spawn tables from the DB: {0}", result)); success = false; } if (success) { DateTime startTime = DateTime.Now; // Test all possible world size configurations for each desired game id WorldTemplate[] worldTemplates = new WorldTemplate[] { new WorldTemplate(GameConstants.eDungeonSize.small, GameConstants.eDungeonDifficulty.normal), new WorldTemplate(GameConstants.eDungeonSize.medium, GameConstants.eDungeonDifficulty.normal), new WorldTemplate(GameConstants.eDungeonSize.large, GameConstants.eDungeonDifficulty.normal), }; for (int game_id = game_id_min; success && game_id <= game_id_max; ++game_id) { foreach (WorldTemplate worldTemplate in worldTemplates) { DungeonLayout layout = new DungeonLayout(game_id, worldTemplate, roomTemplateSet, mobSpawnTableSet); // Create the initial set of rooms for the world if (!layout.BuildRoomLayout(out result)) { _logger.WriteLine( string.Format("DungeonValidator: Failed to generate dungeon layout, game_id:{0}, size:{1}", game_id, worldTemplate.dungeon_size)); _logger.WriteLine(result); success = false; } // Verify that this is a valid dungeon if (success) { Dictionary <int, Portal> portalIdToPortalMap = BuildPortalIdMap(layout); // Verify that all portals are connected correctly success &= VerifyRoomPortals(layout, portalIdToPortalMap); // Verify that every room is accessible to every other room success &= VerifyRoomAccessibility(layout, portalIdToPortalMap); // Verify monster spawners success &= VerifyMobSpawners(layout); } // Dump the generated layout to a .obj file if (dumpGeometryPath.Length > 0) { DumpLayoutGeometry(dumpGeometryPath, layout); } } if (game_id_max > game_id_min) { if ((game_id % 1000) == 0) { TimeSpan elapsed = DateTime.Now.Subtract(startTime); int percent_complete = 100 * (game_id - game_id_min) / (game_id_max - game_id_min); _logger.Write("\r[{0:c}] {1}/{2} {3}%", elapsed, game_id - game_id_min, game_id_max - game_id_min, percent_complete); } } } // Write out a new line after the timing info _logger.WriteLine(); } return(success); }
private bool VerifyRoomAccessibility( DungeonLayout layout, Dictionary <int, Portal> portalIdToPortalMap) { UnionFind <RoomKey> roomUnion = new UnionFind <RoomKey>(); RoomKey targetRoomKey = new RoomKey(); bool success = true; // Do a first pass over the rooms to fill out the union and the portal map for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); // Add the room to the union set roomUnion.AddElement(room.room_key); } // Union together all of the rooms connected by portals for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); foreach (Portal portal in room.portals) { Portal targetPortal = portalIdToPortalMap[portal.target_portal_id]; targetRoomKey.game_id = layout.GameID; targetRoomKey.x = targetPortal.room_x; targetRoomKey.y = targetPortal.room_y; targetRoomKey.z = targetPortal.room_z; roomUnion.Union(room.room_key, targetRoomKey); } } // Verify that all rooms share the same connectivity id int sharedConnectivityId = -1; for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); int roomConnectivityId = roomUnion.FindRootIndex(room.room_key); if (sharedConnectivityId != -1) { if (sharedConnectivityId != roomConnectivityId) { _logger.WriteLine("DungeonValidator: FAILED: Found room not connected to other rooms in dungeon!"); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } else { sharedConnectivityId = roomConnectivityId; } } return(success); }
private void DumpLayoutGeometry( string dumpGeometryPath, DungeonLayout layout) { GeometryFileWriter fileWriter = new GeometryFileWriter(); string filename = string.Format("DungeonLayout_Game{0}_Size{1}", layout.GameID, layout.LayoutWorldTemplate.dungeon_size); string header = string.Format("DungeonLayout for GameID:{0} DungeonSize: {1}", layout.GameID, layout.LayoutWorldTemplate.dungeon_size); string result = SuccessMessages.GENERAL_SUCCESS; Vector3d roomSize = new Vector3d(WorldConstants.ROOM_X_SIZE, WorldConstants.ROOM_Y_SIZE, WorldConstants.ROOM_Z_SIZE); for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); AABB3d roomAABB = new AABB3d(room.world_position, room.world_position + roomSize); AABB3d shrunkRoomAABB = roomAABB.ScaleAboutCenter(0.5f); AABB3d centerAABB = roomAABB.ScaleAboutCenter(0.05f); // Add the AABB for this room fileWriter.AppendAABB(shrunkRoomAABB); // Create portal AABBs to all adjacent rooms for (MathConstants.eSignedDirection roomSide = MathConstants.eSignedDirection.first; roomSide < MathConstants.eSignedDirection.count; ++roomSide) { if (room.RoomHasPortalOnSide(roomSide)) { DungeonLayout.RoomIndex neighborRoomIndex = null; switch (roomSide) { case MathConstants.eSignedDirection.positive_x: neighborRoomIndex = roomIndex.Offset(1, 0, 0); break; case MathConstants.eSignedDirection.negative_x: neighborRoomIndex = roomIndex.Offset(-1, 0, 0); break; case MathConstants.eSignedDirection.positive_y: neighborRoomIndex = roomIndex.Offset(0, 1, 0); break; case MathConstants.eSignedDirection.negative_y: neighborRoomIndex = roomIndex.Offset(0, -1, 0); break; case MathConstants.eSignedDirection.positive_z: neighborRoomIndex = roomIndex.Offset(0, 0, 1); break; case MathConstants.eSignedDirection.negative_z: neighborRoomIndex = roomIndex.Offset(0, 0, -1); break; } Room neighborRoom = layout.GetRoomByIndex(neighborRoomIndex); AABB3d neighborRoomAABB = new AABB3d(neighborRoom.world_position, neighborRoom.world_position + roomSize); AABB3d neighborCenterAABB = neighborRoomAABB.ScaleAboutCenter(0.05f); AABB3d portalAABB = centerAABB.EncloseAABB(neighborCenterAABB); fileWriter.AppendAABB(portalAABB); } } // TODO: DumpLayoutGeometry: Color the rooms by teleporter pair } if (!fileWriter.SaveFile(dumpGeometryPath, filename, header, out result)) { _logger.WriteLine("DungeonValidator: WARNING: Failed to save layout geometry file"); _logger.WriteLine(result); } }
private bool VerifyRoomPortals( DungeonLayout layout, Dictionary<int, Portal> portalIdToPortalMap) { bool success = true; MathConstants.eSignedDirection[] roomSides = new MathConstants.eSignedDirection[] { MathConstants.eSignedDirection.positive_x, MathConstants.eSignedDirection.negative_x, MathConstants.eSignedDirection.positive_y, MathConstants.eSignedDirection.negative_y, MathConstants.eSignedDirection.positive_z, MathConstants.eSignedDirection.negative_z }; for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); // Verify the the portal bitmask matches the existing portals foreach (MathConstants.eSignedDirection roomSide in roomSides) { if (room.RoomHasPortalOnSide(roomSide)) { if (room.portals.Count(p => p.room_side == roomSide) == 0) { _logger.WriteLine("DungeonValidator: FAILED: Expected portal on room side {0} but found none!", roomSide); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } else { if (room.portals.Count(p => p.room_side == roomSide) != 0) { _logger.WriteLine("DungeonValidator: FAILED: Expected no portal on room side {0} but found one!", roomSide); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } } // Verify that the portals are the right expected type foreach (Portal portal in room.portals) { MathConstants.eSignedDirection roomSide = portal.room_side; switch (portal.portal_type) { case ePortalType.door: if (roomSide != MathConstants.eSignedDirection.positive_x && roomSide != MathConstants.eSignedDirection.negative_x && roomSide != MathConstants.eSignedDirection.positive_y && roomSide != MathConstants.eSignedDirection.negative_y) { _logger.WriteLine( string.Format( "DungeonValidator: FAILED: Door portal id={0} on unexpected side={1}", portal.portal_id, roomSide)); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; } break; case ePortalType.stairs: if (roomSide != MathConstants.eSignedDirection.positive_z && roomSide != MathConstants.eSignedDirection.negative_z) { _logger.WriteLine( string.Format( "DungeonValidator: FAILED: Stairs portal id={0} on unexpected side={1}", portal.portal_id, roomSide)); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; } break; case ePortalType.teleporter: if (roomSide != MathConstants.eSignedDirection.none) { _logger.WriteLine( string.Format( "DungeonValidator: FAILED: Teleporter portal id={0} on unexpected side={1}", portal.portal_id, roomSide)); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; } break; } } // Verify that the portals connect to a valid target portal foreach (Portal portal in room.portals) { if (portalIdToPortalMap.ContainsKey(portal.target_portal_id)) { Portal targetPortal = portalIdToPortalMap[portal.target_portal_id]; if (targetPortal.target_portal_id != portal.portal_id) { _logger.WriteLine("DungeonValidator: FAILED: Target Portal is not connected to a valid portal!"); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } else { _logger.WriteLine("DungeonValidator: FAILED: Portal is not connected to a valid target portal!"); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } } return success; }
private bool VerifyRoomPortals( DungeonLayout layout, Dictionary <int, Portal> portalIdToPortalMap) { bool success = true; MathConstants.eSignedDirection[] roomSides = new MathConstants.eSignedDirection[] { MathConstants.eSignedDirection.positive_x, MathConstants.eSignedDirection.negative_x, MathConstants.eSignedDirection.positive_y, MathConstants.eSignedDirection.negative_y, MathConstants.eSignedDirection.positive_z, MathConstants.eSignedDirection.negative_z }; for (DungeonLayout.RoomIndexIterator iterator = new DungeonLayout.RoomIndexIterator(layout.RoomGrid); iterator.Valid; iterator.Next()) { DungeonLayout.RoomIndex roomIndex = iterator.Current; Room room = layout.GetRoomByIndex(roomIndex); // Verify the the portal bitmask matches the existing portals foreach (MathConstants.eSignedDirection roomSide in roomSides) { if (room.RoomHasPortalOnSide(roomSide)) { if (room.portals.Count(p => p.room_side == roomSide) == 0) { _logger.WriteLine("DungeonValidator: FAILED: Expected portal on room side {0} but found none!", roomSide); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } else { if (room.portals.Count(p => p.room_side == roomSide) != 0) { _logger.WriteLine("DungeonValidator: FAILED: Expected no portal on room side {0} but found one!", roomSide); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } } // Verify that the portals are the right expected type foreach (Portal portal in room.portals) { MathConstants.eSignedDirection roomSide = portal.room_side; switch (portal.portal_type) { case ePortalType.door: if (roomSide != MathConstants.eSignedDirection.positive_x && roomSide != MathConstants.eSignedDirection.negative_x && roomSide != MathConstants.eSignedDirection.positive_y && roomSide != MathConstants.eSignedDirection.negative_y) { _logger.WriteLine( string.Format( "DungeonValidator: FAILED: Door portal id={0} on unexpected side={1}", portal.portal_id, roomSide)); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; } break; case ePortalType.stairs: if (roomSide != MathConstants.eSignedDirection.positive_z && roomSide != MathConstants.eSignedDirection.negative_z) { _logger.WriteLine( string.Format( "DungeonValidator: FAILED: Stairs portal id={0} on unexpected side={1}", portal.portal_id, roomSide)); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; } break; case ePortalType.teleporter: if (roomSide != MathConstants.eSignedDirection.none) { _logger.WriteLine( string.Format( "DungeonValidator: FAILED: Teleporter portal id={0} on unexpected side={1}", portal.portal_id, roomSide)); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; } break; } } // Verify that the portals connect to a valid target portal foreach (Portal portal in room.portals) { if (portalIdToPortalMap.ContainsKey(portal.target_portal_id)) { Portal targetPortal = portalIdToPortalMap[portal.target_portal_id]; if (targetPortal.target_portal_id != portal.portal_id) { _logger.WriteLine("DungeonValidator: FAILED: Target Portal is not connected to a valid portal!"); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } else { _logger.WriteLine("DungeonValidator: FAILED: Portal is not connected to a valid target portal!"); _logger.WriteLine(string.Format(" game_id: {0}", layout.GameID)); _logger.WriteLine(string.Format(" room_key: {0},{1},{2}", room.room_key.x, room.room_key.y, room.room_key.z)); success = false; break; } } } return(success); }