예제 #1
0
        /// <summary>
        /// Create a Craft Recipes Collection from Binary Stream
        /// </summary>
        /// <param name="craftBinaryFile"></param>
        public CraftListData(Stream craftBinaryFile)
        {
            if (craftBinaryFile == null)
                throw new ArgumentNullException("craftBinaryFile");

            if (!craftBinaryFile.CanRead || !craftBinaryFile.CanSeek)
                throw new IOException("Can't Read or Seek Binary Craft File !");

            // Get File Header and String Content
            craftBinaryFile.Position = 0;
            var m_header = craftBinaryFile.ReadHeader();
            craftBinaryFile.Position += m_header.NameListOffset;
            var m_strings = craftBinaryFile.ReadStrings(m_header.NameListSize, m_header.NumberOfNames);

            // Initialize Realm Data
            var m_professionData = new CraftProfessionData[CraftHeader.RealmCount];
            var m_recipeList = new CraftItem[CraftHeader.RealmCount][];
            var m_categoryList = new CraftCategory[CraftHeader.RealmCount][];

            // For each Realm
            for (int r = 0 ; r < 3 ; r++)
            {
                var realmData = m_header.RealmData[r];

                // retrieve profession
                craftBinaryFile.Position = realmData.ProfessionListOffset;
                m_professionData[r] = craftBinaryFile.ReadProfessions();

                // retrieve recipe
                craftBinaryFile.Position = realmData.RecipeListOffset;
                m_recipeList[r] = craftBinaryFile.ReadRecipes(realmData.NumberOfRecipes);

                // retrieve categories
                craftBinaryFile.Position = realmData.CategoryListOffset;
                m_categoryList[r] = craftBinaryFile.ReadCategories(realmData.NumberOfCategories);
            }

            var recipesResult = new Dictionary<uint, List<CraftDataRecipe>>();

            // For each Realm
            for (uint r = 0 ; r < 3 ; r++)
            {
                string name;

                switch(r)
                {
                    case 0:
                        name = "Albion";
                        break;
                    case 1:
                        name = "Midgard";
                        break;
                    default:
                        name = "Hibernia";
                        break;
                }

                if (!recipesResult.ContainsKey(r))
                    recipesResult.Add(r, new List<CraftDataRecipe>());

                for (uint p = 0 ; p < m_professionData[r].Professions.Length ; p++)
                {
                    var profNameIndex = m_professionData[r].Professions[p].NameIndex;
                    if (profNameIndex == 0)
                        continue;

                    var ProfessionName = m_strings[profNameIndex];

                    foreach (var c in m_professionData[r].Professions[p].Indexes.Where(i => i > 0))
                    {
                        var catNameIndex = m_categoryList[r][c].NameIndex;
                        if (catNameIndex == 0)
                            continue;

                        var CategoryName = m_strings[catNameIndex];

                        for (uint rc = 0 ; rc < m_categoryList[r][c].RecipeIds.Length ; rc++)
                        {
                            var RecipeIndex = m_categoryList[r][c].RecipeIds[rc];
                            if (RecipeIndex == 0)
                                continue;

                            var recipe = m_recipeList[r][RecipeIndex];

                            var RecipeNameIndex = recipe.NameIndex;

                            if (RecipeNameIndex == 0)
                                continue;

                            if (recipe.Materials.All(mat => mat.Count <= 0))
                                continue;

                            //Create Recipe
                            var Recipe = new CraftDataRecipe();
                            Recipe.Name = m_strings[RecipeNameIndex];
                            Recipe.ID = (int)recipe.Id;
                            Recipe.ItemLevel = recipe.Level;
                            Recipe.Profession = ProfessionName;
                            Recipe.Realm = name;
                            Recipe.SkillLevel = recipe.Skill;
                            Recipe.MaterialLevel = recipe.MaterialLevel;
                            Recipe.Ingredients = new List<CraftDataIngredient>();

                            if (recipe.BaseMaterial != 0 && recipe.BaseMaterial < BaseMaterials.Length)
                                Recipe.BaseMaterialName = BaseMaterials[recipe.BaseMaterial];

                            for (uint i = 0 ; i < recipe.Materials.Length ; i++)
                            {
                                var ingredient = recipe.Materials[i];

                                if (ingredient.Count <= 0 || ingredient.NameIndex == 0 || string.IsNullOrEmpty(m_strings[ingredient.NameIndex]))
                                    continue;

                                var Ingredient = new CraftDataIngredient();
                                Ingredient.Name = m_strings[ingredient.NameIndex];
                                Ingredient.Count = ingredient.Count;
                                if (ingredient.BaseMaterial != 0 && ingredient.BaseMaterial < BaseMaterials.Length)
                                    Ingredient.BaseMaterialName = BaseMaterials[ingredient.BaseMaterial];

                                ((List<CraftDataIngredient>)Recipe.Ingredients).Add(Ingredient);
                            }

                            recipesResult[r].Add(Recipe);
                        }
                    }
                }
            }

            var recipesLookup = new Dictionary<string, Dictionary<string, CraftDataRecipe>>();

            // Parsing Results
            foreach(var realmRecipe in recipesResult)
            {
                var eachRealm = realmRecipe.Key;

                foreach(var eachRecipe in realmRecipe.Value)
                {
                    Dictionary<string, CraftDataRecipe> subrealm;
                    if (!recipesLookup.TryGetValue(eachRecipe.Realm, out subrealm))
                    {
                        subrealm = new Dictionary<string, CraftDataRecipe>();
                        recipesLookup.Add(eachRecipe.Realm, subrealm);
                    }

                    // Fix Basic Crafting Base Material Name by copying regular recipes
                    if (eachRecipe.Profession == BasicCraftingName)
                    {
                        eachRecipe.BaseMaterialName = recipesResult[eachRealm].Where(rec => rec.Name == eachRecipe.Name && rec.MaterialLevel == eachRecipe.MaterialLevel).Select(rec => rec.BaseMaterialName).FirstOrDefault();
                    }

                    // Try Matching Sub-Recipe for some Ingredients
                    foreach(var eachIngredient in eachRecipe.Ingredients)
                    {
                        CraftDataRecipe subrec;
                        if (!subrealm.TryGetValue(eachIngredient.FullName, out subrec))
                        {
                            subrec = recipesResult[eachRealm].FirstOrDefault(rec => rec.Realm.Equals(eachRecipe.Realm) && rec.FullName.Equals(eachIngredient.FullName));
                            subrealm.Add(eachIngredient.FullName, subrec);
                        }

                        eachIngredient.SubRecipe = subrec;
                    }
                }
            }

            Recipes = recipesResult.SelectMany(kv => kv.Value).ToArray();
        }
예제 #2
0
        public static CraftItem[] ReadRecipes(this Stream fs, uint count)
        {
            var result = new CraftItem[count];

            for (int r = 0 ; r < count ; r++)
            {
                var current = new CraftItem();

                current.NameIndex = fs.ReadUint();
                current.BaseMaterial = fs.ReadUint();
                current.Id = fs.ReadUint();
                current.Pic = fs.ReadUshort();
                current.Skill = fs.ReadUshort();
                current.MaterialLevel = fs.ReadUshort();
                current.Level = fs.ReadUshort();

                current.Materials = new CraftItem.CraftMaterials[CraftItem.MaterialsCount];

                for (int m = 0 ; m < CraftItem.MaterialsCount ; m++)
                {
                    var mat = new CraftItem.CraftMaterials();
                    mat.NameIndex = fs.ReadUint();
                    mat.Count = fs.ReadUshort();
                    mat.BaseMaterial = fs.ReadUshort();
                    current.Materials[m] = mat;
                }

                result[r] = current;
            }

            return result;
        }