Beispiel #1
0
        public MobSpawnTable(
            Dictionary<int, MobSpawnTable> spawnTables,
            MobTypeSet mob_types,
            MobSpawnTables db_table,
            List<MobSpawnTableEntries> db_entries)
        {
            m_table_id = db_table.MobSpawnTableID;
            m_table_name = db_table.MobSpawnTableName;

            if (db_entries.Count > 0)
            {
                // Compute the total non normalized weight
                float weight_sum = (float)db_entries.Sum(e => e.Weight);

                // Sort the source list by weight and then store in the internal entry array
                m_entries = new MobSpawnTableEntry[db_entries.Count];

                // Copy over the source entries into the table
                // Normalize the weights
                for (int entry_index = 0; entry_index < db_entries.Count; entry_index++)
                {
                    MobSpawnTableEntries db_entry = db_entries[entry_index];
                    MobSpawnTableEntry entry = new MobSpawnTableEntry();

                    entry.cumulative_weight = (float)db_entry.Weight / weight_sum;

                    if (db_entry.ReferenceIsMobType)
                    {
                        entry.mob_type = mob_types.GetMobTypeById(db_entry.ReferenceID);
                        entry.mob_spawn_table = null;
                    }
                    else
                    {
                        entry.mob_type = null;
                        entry.mob_spawn_table = spawnTables[db_entry.ReferenceID];
                    }

                    m_entries[entry_index] = entry;
                }

                // Sort the weights. Largest weight first.
                // We do this so that when we search through the CDF
                // we're more likely to find the random entry we're looking for earlier in the array.
                m_entries.OrderByDescending(e => e.cumulative_weight);

                // Convert the probability density function (PDF) into a cumulative distribution function (CDF)
                float accumulator = 0f;
                for (int entry_index = 0; entry_index < m_entries.Length; entry_index++)
                {
                    MobSpawnTableEntry entry = m_entries[entry_index];
                    float weight = entry.cumulative_weight;

                    entry.cumulative_weight = Math.Min(accumulator + entry.cumulative_weight, 1.0f);
                    accumulator = accumulator + weight;
                }
            }
        }
        public MobSpawnTable(
            Dictionary <int, MobSpawnTable> spawnTables,
            MobTypeSet mob_types,
            MobSpawnTables db_table,
            List <MobSpawnTableEntries> db_entries)
        {
            m_table_id   = db_table.MobSpawnTableID;
            m_table_name = db_table.MobSpawnTableName;

            if (db_entries.Count > 0)
            {
                // Compute the total non normalized weight
                float weight_sum = (float)db_entries.Sum(e => e.Weight);

                // Sort the source list by weight and then store in the internal entry array
                m_entries = new MobSpawnTableEntry[db_entries.Count];

                // Copy over the source entries into the table
                // Normalize the weights
                for (int entry_index = 0; entry_index < db_entries.Count; entry_index++)
                {
                    MobSpawnTableEntries db_entry = db_entries[entry_index];
                    MobSpawnTableEntry   entry    = new MobSpawnTableEntry();

                    entry.cumulative_weight = (float)db_entry.Weight / weight_sum;

                    if (db_entry.ReferenceIsMobType)
                    {
                        entry.mob_type        = mob_types.GetMobTypeById(db_entry.ReferenceID);
                        entry.mob_spawn_table = null;
                    }
                    else
                    {
                        entry.mob_type        = null;
                        entry.mob_spawn_table = spawnTables[db_entry.ReferenceID];
                    }

                    m_entries[entry_index] = entry;
                }

                // Sort the weights. Largest weight first.
                // We do this so that when we search through the CDF
                // we're more likely to find the random entry we're looking for earlier in the array.
                m_entries.OrderByDescending(e => e.cumulative_weight);

                // Convert the probability density function (PDF) into a cumulative distribution function (CDF)
                float accumulator = 0f;
                for (int entry_index = 0; entry_index < m_entries.Length; entry_index++)
                {
                    MobSpawnTableEntry entry = m_entries[entry_index];
                    float weight             = entry.cumulative_weight;

                    entry.cumulative_weight = Math.Min(accumulator + entry.cumulative_weight, 1.0f);
                    accumulator             = accumulator + weight;
                }
            }
        }
        public void Initialize(
            AsyncRPGDataContext db_context,
            MobTypeSet mobTypeSet)
        {
            m_mobSpawnTablesById = MobQueries.LoadMobSpawnTables(db_context, mobTypeSet);

            foreach (MobSpawnTable mobSpawnTable in m_mobSpawnTablesById.Values)
            {
                m_mobSpawnTablesByName.Add(mobSpawnTable.Name, mobSpawnTable);
            }
        }
Beispiel #4
0
        public static Mob CreateMob(Mobs dbMob, MobTypeSet mobTypes)
        {
            Mob mob = new Mob();

            mob.m_room_key = new RoomKey(dbMob.GameID, dbMob.RoomX, dbMob.RoomY, dbMob.RoomZ);
            mob.m_mob_id   = dbMob.MobID;
            mob.m_mob_type = mobTypes.GetMobTypeById(dbMob.MobTypeID);
            mob.m_position = new Point3d((float)dbMob.X, (float)dbMob.Y, (float)dbMob.Z);
            mob.m_angle    = (float)dbMob.Angle;
            mob.m_health   = dbMob.Health;
            mob.m_energy   = dbMob.Energy;
            mob.m_ai_data  = ParseJsonAIData(dbMob.AiData);

            if (mob.m_ai_data == null)
            {
                mob.m_ai_data = new MobAIState();
                //Utilities.LogWarning(string.Format("Mob:CreateMob(id={0}) - Unable to parse AI State. Creating new state.", dbMob.MobID));
            }

            return(mob);
        }
        public bool Initialize(
            string connection_string,
            MobTypeSet mobTypeSet,
            out string result)
        {
            bool success =
                MobQueries.LoadMobSpawnTables(
                    connection_string,
                    mobTypeSet,
                    out m_mobSpawnTablesById,
                    out result);

            if (success)
            {
                foreach (MobSpawnTable mobSpawnTable in m_mobSpawnTablesById.Values)
                {
                    m_mobSpawnTablesByName.Add(mobSpawnTable.Name, mobSpawnTable);
                }
            }

            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;
        }
Beispiel #7
0
 public WorldBuilder()
 {
     m_roomTemplateSet = new RoomTemplateSet();
     m_mobTypeSet = new MobTypeSet();
     m_mobSpawnTableSet = new MobSpawnTableSet();
 }
        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");
                }
            }
        }
Beispiel #9
0
        public IEnumerable<Mob> GetMobs(AsyncRPGDataContext db_context, MobTypeSet mobTypeSet)
        {
            if (!m_allMobsCached)
            {
                foreach (Mob mob in MobQueries.GetMobs(db_context, mobTypeSet, m_roomKey))
                {
                    if (!m_mobs.ContainsKey(mob.ID))
                    {
                        m_mobs.Add(mob.ID, mob);
                    }
                }
            }

            return m_mobs.Values;
        }
Beispiel #10
0
        public Mob GetMob(AsyncRPGDataContext db_context, MobTypeSet mobTypeSet, int mobID)
        {
            Mob mob = null;

            if (!m_mobs.TryGetValue(mobID, out mob))
            {
                mob = MobQueries.GetMob(db_context, mobTypeSet, mobID);

                m_mobs.Add(mobID, mob);
            }

            return mob;
        }
Beispiel #11
0
        public static Mob CreateMob(Mobs dbMob, MobTypeSet mobTypes)
        {
            Mob mob = new Mob();

            mob.m_room_key = new RoomKey(dbMob.GameID, dbMob.RoomX, dbMob.RoomY, dbMob.RoomZ);
            mob.m_mob_id = dbMob.MobID;
            mob.m_mob_type= mobTypes.GetMobTypeById(dbMob.MobTypeID);
            mob.m_position = new Point3d((float)dbMob.X, (float)dbMob.Y, (float)dbMob.Z);
            mob.m_angle = (float)dbMob.Angle;
            mob.m_health = dbMob.Health;
            mob.m_energy = dbMob.Energy;
            mob.m_ai_data = ParseJsonAIData(dbMob.AiData);

            if (mob.m_ai_data == null)
            {
                mob.m_ai_data = new MobAIState();
                //Utilities.LogWarning(string.Format("Mob:CreateMob(id={0}) - Unable to parse AI State. Creating new state.", dbMob.MobID));
            }

            return mob;
        }
        public void ParseMobSpawnTables(
            AsyncRPGDataContext db_context,
            string mob_spawn_tables_file_path)
        {
            MobTypeSet mobTypeSet = new MobTypeSet();

            // Load the mob spawn types from the DB
            mobTypeSet.Initialize(db_context);

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

            // Read in the given JSON file and save it into the mob spawn table db table
            string jsonString = "";
            JSONMobSpawnTableSet jsonMobSpawnTableSet = null;

            // Read the spawn table file into a string
            using (StreamReader streamReader = new StreamReader(mob_spawn_tables_file_path))
            {
                jsonString = streamReader.ReadToEnd();

                if (jsonString.Length == 0)
                {
                    throw new Exception("MobSpawnTableParser: Mob spawn table file empty:" + mob_spawn_tables_file_path);
                }
            }

            // Parse the JSON into an object
            jsonMobSpawnTableSet = JsonMapper.ToObject<JSONMobSpawnTableSet>(jsonString);

            // Parse and verify each spawn table given
            {
                Dictionary<string, JSONMobSpawnTable> validMobSpawnTables = new Dictionary<string, JSONMobSpawnTable>();
                Dictionary<string, int> spawnTableNameToId = new Dictionary<string, int>();

                foreach (JSONMobSpawnTable jsonMobSpawnTable in jsonMobSpawnTableSet.mob_spawn_table_set)
                {
                    if (ValidateMobSpawnTable(jsonMobSpawnTable, validMobSpawnTables))
                    {
                        bool validTable = true;

                        // Verify each entry references either a valid spawn table or mob type
                        // and has a valid weight
                        foreach (JSONMobSpawnTableEntry jsonSpawnTableEntry in jsonMobSpawnTable.entries)
                        {
                            if (!ValidateMobSpawnTableEntry(
                                    jsonSpawnTableEntry,
                                    mobTypeSet,
                                    validMobSpawnTables))
                            {
                                validTable = false;
                            }
                        }

                        // If all the table entries look good, add the spawn table to the DB
                        if (validTable)
                        {
                            // Insert the spawn table first
                            MobSpawnTables dbMobSpawnTable = new MobSpawnTables
                            {
                                MobSpawnTableName = jsonMobSpawnTable.mob_spawn_table_name,
                            };

                            db_context.MobSpawnTables.InsertOnSubmit(dbMobSpawnTable);
                            db_context.SubmitChanges();

                            // Then insert all the entries associated with the table
                            foreach (JSONMobSpawnTableEntry jsonEntry in jsonMobSpawnTable.entries)
                            {
                                MobSpawnTableEntries dbMobSpawnTableEntry = null;

                                if (jsonEntry.mob_spawn_table_name.Length > 0)
                                {
                                    dbMobSpawnTableEntry = new MobSpawnTableEntries
                                    {
                                        MobSpawnTableID = dbMobSpawnTable.MobSpawnTableID,
                                        ReferenceID = spawnTableNameToId[jsonEntry.mob_spawn_table_name],
                                        ReferenceIsMobType = false,
                                        Weight = jsonEntry.weight
                                    };
                                }
                                else
                                {
                                    dbMobSpawnTableEntry = new MobSpawnTableEntries
                                    {
                                        MobSpawnTableID = dbMobSpawnTable.MobSpawnTableID,
                                        ReferenceID = mobTypeSet.GetMobTypeByName(jsonEntry.mob_type_name).ID,
                                        ReferenceIsMobType = true,
                                        Weight = jsonEntry.weight
                                    };
                                }

                                db_context.MobSpawnTableEntries.InsertOnSubmit(dbMobSpawnTableEntry);
                                db_context.SubmitChanges();
                            }

                            _logger.LogInfo("MobSpawnTableParser: Added Mob Spawn Table:");
                            _logger.LogInfo(jsonMobSpawnTable.mob_spawn_table_name);

                            // Keep track of each valid table added and what it's DB id is
                            validMobSpawnTables.Add(
                                jsonMobSpawnTable.mob_spawn_table_name,
                                jsonMobSpawnTable);
                            spawnTableNameToId.Add(
                                jsonMobSpawnTable.mob_spawn_table_name,
                                dbMobSpawnTable.MobSpawnTableID);
                        }
                        else
                        {
                            throw new Exception("MobSpawnTableParser: Problem(s) validating mob spawn table entries: " + jsonMobSpawnTable.mob_spawn_table_name);
                        }
                    }
                    else
                    {
                        throw new Exception("MobSpawnTableParser: Problem(s) validating mob spawn table: " + jsonMobSpawnTable.mob_spawn_table_name);
                    }
                }
            }
        }
        private bool ValidateMobSpawnTableEntry(
            JSONMobSpawnTableEntry jsonSpawnTableEntry, 
            MobTypeSet mobTypeSet,
            Dictionary<string, JSONMobSpawnTable> validMobSpawnTables)
        {
            bool valid= true;

            if (jsonSpawnTableEntry.mob_spawn_table_name.Length > 0)
            {
                if (!validMobSpawnTables.ContainsKey(jsonSpawnTableEntry.mob_spawn_table_name))
                {
                    _logger.LogError("MobSpawnTableParser: Invalid mob spawn table reference:");
                    _logger.LogError(jsonSpawnTableEntry.mob_spawn_table_name);
                    valid = false;
                }
            }
            else if (jsonSpawnTableEntry.mob_type_name.Length > 0)
            {
                if (!mobTypeSet.HasMobTypeWithName(jsonSpawnTableEntry.mob_type_name))
                {
                    _logger.LogError("MobSpawnTableParser: Invalid mob type reference:");
                    _logger.LogError(jsonSpawnTableEntry.mob_type_name);
                    valid = false;
                }
            }
            else
            {
                _logger.LogError("MobSpawnTableParser: No spawn table or mob type references:");
                valid = false;
            }

            if (jsonSpawnTableEntry.weight <= 0)
            {
                _logger.LogError("MobSpawnTableParser: Non-positive weight given");
                valid = false;
            }

            return valid;
        }
Beispiel #14
0
        public void Initialize(
            AsyncRPGDataContext db_context,
            MobTypeSet mobTypeSet)
        {
            m_mobSpawnTablesById = MobQueries.LoadMobSpawnTables(db_context, mobTypeSet);

            foreach (MobSpawnTable mobSpawnTable in m_mobSpawnTablesById.Values)
            {
                m_mobSpawnTablesByName.Add(mobSpawnTable.Name, mobSpawnTable);
            }
        }
Beispiel #15
0
        public bool Initialize(
            string connection_string,
            MobTypeSet mobTypeSet, 
            out string result)
        {
            bool success =
                MobQueries.LoadMobSpawnTables(
                    connection_string,
                    mobTypeSet,
                    out m_mobSpawnTablesById,
                    out result);

            if (success)
            {
                foreach (MobSpawnTable mobSpawnTable in m_mobSpawnTablesById.Values)
                {
                    m_mobSpawnTablesByName.Add(mobSpawnTable.Name, mobSpawnTable);
                }
            }

            return success;
        }