private bool ValidateMobSpawnerTemplates(
            RoomTemplate roomTemplate,
            MobSpawnTableSet mobSpawnTableSet)
        {
            bool success = true;

            foreach (MobSpawnerTemplate spawnerTemplate in roomTemplate.MobSpawnerTemplates)
            {
                if (mobSpawnTableSet.GetMobSpawnTableByName(spawnerTemplate.SpawnTableName) == null)
                {
                    _logger.LogError(
                        string.Format("RoomTemplateParser: Template {0} has a monster spawner with invalid spawn table={1}",
                                      roomTemplate.TemplateName,
                                      spawnerTemplate.SpawnTableName));
                    success = false;
                }

                if (!roomTemplate.NavMeshTemplate.ComputeNavRefAtPoint(spawnerTemplate.Position).IsValid)
                {
                    _logger.LogError(
                        string.Format("RoomTemplateParser: Template {0} has a monster spawner off the nav mesh",
                                      roomTemplate.TemplateName));
                    success = false;
                }
            }

            return(success);
        }
Esempio n. 2
0
 public DungeonLayout(
     int gameId,
     WorldTemplate worldTemplate,
     RoomTemplateSet roomTemplateSet,
     MobSpawnTableSet mobSpawnTableSet)
 {
     m_gameId           = gameId;
     m_worldTemplate    = worldTemplate;
     m_roomTemplateSet  = roomTemplateSet;
     m_mobSpawnTableSet = mobSpawnTableSet;
     m_roomGrid         = null;
     m_nextPortalId     = 0;
 }
Esempio n. 3
0
        public static List <MobSpawner> GetMobSpawners(
            AsyncRPGDataContext context,
            MobSpawnTableSet mobSpawnTableSet,
            RoomKey roomKey)
        {
            List <MobSpawner> mobSpawners = new List <MobSpawner>();

            var roomMobSpawnerQuery =
                from s in context.MobSpawners
                where s.GameID == roomKey.game_id && s.RoomX == roomKey.x && s.RoomY == roomKey.y && s.RoomZ == roomKey.z
                select s;

            foreach (MobSpawners dbMobSpawner in roomMobSpawnerQuery)
            {
                MobSpawner mobSpawner = MobSpawner.CreateMobSpawner(dbMobSpawner, mobSpawnTableSet);

                mobSpawners.Add(mobSpawner);
            }

            return(mobSpawners);
        }
        private bool ValidateRoomTemplate(
            string templateName,
            RoomTemplate roomTemplate,
            MobSpawnTableSet mobSpawnTableSet,
            byte[] compressedNavCells,
            byte[] compressedPVS)
        {
            bool success = true;

            // Room has at least one teleporter
            success &= ValidateTeleportersAvailable(roomTemplate);

            // Door portals can only be on the following sides (+x, -x, +y, -y)
            // Stair portals can only be on the following sides (+z, -z)
            // Teleporter portals must have room side of none
            success &= ValidatePortalTypeExpectedRoomSide(roomTemplate);

            // Room doesn't have multiple doors or stairs per side
            success &= ValidateOnlyOneDoorPerSide(roomTemplate);

            // Room has nav mesh
            // All doors, stairs, and teleporters are on the nav mesh
            // All doors, stairs, and teleporters are accessible to each other on the nav mesh
            success &= ValidatePortalAccessibility(roomTemplate);

            // Mob spawner templates are valid
            // All mob spawner templates have spawn table
            // All mob spawner templates are on the nav mesh
            success &= ValidateMobSpawnerTemplates(roomTemplate, mobSpawnTableSet);

            // Energy Tank templates are valid
            // All energy tank templates have positive energy
            // All energy templates are on the nav mesh
            success &= ValidateEnergyTankTemplates(roomTemplate);

            // Compressed navCells/PVS can be decompressed back into the same nav-mesh
            success &= ValidateCompressedNavMeshData(roomTemplate, compressedNavCells, compressedPVS);

            return(success);
        }
        public void ParseRoomTemplates(
            AsyncRPGDataContext db_context,
            string template_path)
        {
            MobTypeSet       mobTypeSet       = new MobTypeSet();
            MobSpawnTableSet mobSpawnTableSet = new MobSpawnTableSet();

            // Clear out any existing room templates
            db_context.ExecuteCommand("DELETE FROM room_templates");

            // Get the mob type set from the DB
            mobTypeSet.Initialize(db_context);

            // Get the mob spawn templates from the DB
            mobSpawnTableSet.Initialize(db_context, mobTypeSet);

            // Read in each XML file and save it into the room templates table
            string[] templateFiles = Directory.GetFiles(template_path, "*.oel");

            if (templateFiles == null || templateFiles.Length == 0)
            {
                throw new Exception("RoomTemplateParser: No room template files (*.oel) found in directory: " + template_path);
            }

            {
                Dictionary <TypedFlags <MathConstants.eSignedDirection>, int> portalLayoutCounts =
                    new Dictionary <TypedFlags <MathConstants.eSignedDirection>, int>();
                bool anyRoomParsingErrors = false;

                foreach (string templateFile in templateFiles)
                {
                    string templateName = Path.GetFileNameWithoutExtension(templateFile);

                    RoomTemplate roomTemplate       = null;
                    byte[]       compressedNavCells = null;
                    byte[]       compressedPVS      = null;

                    // Parse the XML template from the file
                    XmlDocument doc = new XmlDocument();
                    doc.Load(templateFile);

                    // Parse the room template xml into a room template object
                    roomTemplate = new RoomTemplate(templateName, doc);

                    // Keep track of all of the unique portal layouts we encounter
                    if (portalLayoutCounts.ContainsKey(roomTemplate.PortalRoomSideBitmask))
                    {
                        portalLayoutCounts[roomTemplate.PortalRoomSideBitmask] += 1;
                    }
                    else
                    {
                        portalLayoutCounts.Add(roomTemplate.PortalRoomSideBitmask, 1);
                    }

                    // Extract the nav-mesh and visibility data in compressed form to save into the DB
                    roomTemplate.NavMeshTemplate.ToCompressedData(out compressedNavCells, out compressedPVS);

                    // Remove everything from the template XML that we wont care about at runtime
                    RemoveXmlNodeByXPath(doc, "/level/Floor");
                    RemoveXmlNodeByXPath(doc, "/level/Walls");
                    RemoveXmlNodeByXPath(doc, "/level/BackgroundObjects");
                    RemoveXmlNodeByXPath(doc, "/level/ForegroundObjects");
                    RemoveXmlNodeByXPath(doc, "/level/NavMesh");

                    if (ValidateRoomTemplate(
                            templateName,
                            roomTemplate,
                            mobSpawnTableSet,
                            compressedNavCells,
                            compressedPVS))
                    {
                        // Save the XML back into string
                        StringWriter  stringWriter = new StringWriter();
                        XmlTextWriter xmlWriter    = new XmlTextWriter(stringWriter);
                        doc.WriteTo(xmlWriter);

                        RoomTemplates dbRoomTemplate =
                            new RoomTemplates
                        {
                            Name = templateName,
                            XML  = stringWriter.ToString(),
                            CompressedNavMesh    = compressedNavCells,
                            CompressedVisibility = compressedPVS
                        };

                        db_context.RoomTemplates.InsertOnSubmit(dbRoomTemplate);
                        db_context.SubmitChanges();

                        _logger.LogInfo("RoomTemplateParser: Added Room Template:");
                        _logger.LogInfo(templateFile);
                    }
                    else
                    {
                        anyRoomParsingErrors = true;
                    }
                }

                // Verify all possible door-side combinations are represented in the template file set
                if (portalLayoutCounts.Keys.Count < k_expectedRoomLayouts.Length)
                {
                    foreach (TypedFlags <MathConstants.eSignedDirection> expectedLayout in k_expectedRoomLayouts)
                    {
                        if (!portalLayoutCounts.ContainsKey(expectedLayout))
                        {
                            _logger.LogError(
                                string.Format(
                                    "RoomTemplateParser: Missing expected room layout: {0}{1}{2}{3}{4}{5}",
                                    expectedLayout.Test(MathConstants.eSignedDirection.positive_x) ? "X+" : "",
                                    expectedLayout.Test(MathConstants.eSignedDirection.negative_x) ? "X-" : "",
                                    expectedLayout.Test(MathConstants.eSignedDirection.positive_y) ? "Y+" : "",
                                    expectedLayout.Test(MathConstants.eSignedDirection.negative_y) ? "Y-" : "",
                                    expectedLayout.Test(MathConstants.eSignedDirection.positive_z) ? "Z+" : "",
                                    expectedLayout.Test(MathConstants.eSignedDirection.negative_z) ? "Z-" : ""));

                            anyRoomParsingErrors = true;
                        }
                    }
                }

                if (anyRoomParsingErrors)
                {
                    throw new Exception("RoomTemplateParser: Failed to parse all room templates");
                }
            }
        }
        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);
        }
Esempio n. 7
0
 public WorldBuilder()
 {
     m_roomTemplateSet  = new RoomTemplateSet();
     m_mobTypeSet       = new MobTypeSet();
     m_mobSpawnTableSet = new MobSpawnTableSet();
 }