Example #1
0
        /// <summary>
        /// Checks recipe
        /// </summary>
        private JToken ProcessRecipeType(Recipe recipe)
        {
            JObject result = new JObject();

            _usedSkill = null;
            bool first = true;

            Logger.Assert(recipe.Products.Length > 0, "Products array should be not empty");
            foreach (var craftingElement in recipe.Products)
            {
                string name = craftingElement.Item.Type.Name;
                if (first)
                {
                    first                 = false;
                    result["result"]      = name;
                    result["quantity"]    = EvaluateDynamicValue(craftingElement.Quantity);
                    result["ingredients"] = new JObject();
                    continue;
                }

                result["ingredients"][name] = EvaluateDynamicValue(craftingElement.Quantity);
            }

            foreach (var craftingElement in recipe.Ingredients)
            {
                string name = craftingElement.Item.Type.Name;
                result["ingredients"][name] = EvaluateDynamicValue(craftingElement.Quantity);
            }

            if (_usedSkill != null)
            {
                result["skill"] = _usedSkill;
            }

            foreach (var tableType in CraftingComponent.TablesForRecipe(typeof(Recipe)))
            {
                Logger.Assert(tableType.IsSubclassOf(typeof(WorldObject)), $"{tableType} is not a world object");
                foreach (RequireComponentAttribute attribute in tableType.GetCustomAttributes(typeof(RequireComponentAttribute), true))
                {
                }
            }


            return(result);
        }
Example #2
0
        private static void UpdateRecipes(StreamWriter sw, TechTreeSimData data)
        {
            var numRemoved = 1;

            while (numRemoved != 0)
            {
                numRemoved = 0;
                var toRemove = new List <Recipe>();
                foreach (var recipe in data.unusableRecipes)
                {
                    if (data.craftableItems.Contains(recipe.Products.Select(x => x.Item.Type)))
                    {
                        toRemove.Add(recipe);
                    }
                    else if (data.craftableItems.Contains(recipe.Ingredients.Select(x => x.Item.Type)) &&
                             CraftingComponent.TablesForRecipe(recipe.GetType()).Intersect(data.craftingTables).Any())
                    {
                        foreach (var product in recipe.Products.Select(x => x.Item))
                        {
                            data.craftableItems.AddUnique(product.Type);
                            sw.WriteLine(" - New Craftable Items: " + product);
                            if (product is WorldObjectItem)
                            {
                                data.craftingTables.AddUnique((product as WorldObjectItem).WorldObjectType); //will need to specify power items
                            }
                            if (product is SkillBook)
                            {
                                data.AddSkill(sw, (product as SkillBook).Skill.Type);
                            }
                        }
                        toRemove.Add(recipe);
                        numRemoved++;
                    }
                }
                toRemove.ForEach(x =>
                {
                    data.unusableRecipes.Remove(x);
                    data.curRecipes.Add(x);
                });
            }
        }
Example #3
0
        private static void UpdateRecipes(InfoBuilder info, TechTreeSimData data)
        {
            var numRemoved = 1;

            while (numRemoved != 0)
            {
                numRemoved = 0;
                var toRemove = new List <Recipe>();
                foreach (var recipe in data.UnusableRecipes)
                {
                    if (data.CraftableItems.ContainsAll(recipe.Items.Select(x => x.Item.Type)))
                    {
                        toRemove.Add(recipe);
                    }
                    else if (recipe.Ingredients.All(data.HasIngredient) &&
                             CraftingComponent.TablesForRecipe(recipe.Family.GetType()).Intersect(data.CraftingTables).Any())
                    {
                        foreach (var product in recipe.Items.Select(x => x.Item))
                        {
                            data.AddItem(product.Type);
                            info.AppendLineLocStr(" - New Craftable Items: " + product);
                            if (product is WorldObjectItem)
                            {
                                data.CraftingTables.AddUnique((product as WorldObjectItem).WorldObjectType); //will need to specify power items
                            }
                            if (product is SkillBook)
                            {
                                data.AddSkill((product as SkillBook).Skill.Type);
                            }
                        }
                        toRemove.Add(recipe);
                        numRemoved++;
                    }
                }
                toRemove.ForEach(x =>
                {
                    data.UnusableRecipes.Remove(x);
                    data.CurRecipes.Add(x);
                });
            }
        }
Example #4
0
        public static void TechTreeSimulation(User user)
        {
            using (StreamWriter sw = new StreamWriter("TechTreeSimulation.txt"))
            {
                var data = new TechTreeSimData();
                sw.WriteLine("Starting Tech Tree Sim");

                sw.WriteLine("Getting Starting Skills...");
                var introSkills = PlayerDefaults.GetDefaultSkills().ToList();
                introSkills.ForEach(x => data.AddSkill(sw, x));

                sw.WriteLine("Getting Initial Tables...");
                data.craftingTables.Add(typeof(CampsiteObject));

                sw.WriteLine("Getting Recipes with No Skills...");
                var temp = Recipe.AllRecipes.Where(x => !x.RequiredSkills.Any() && x.Ingredients.Any());
                data.unusableRecipes.AddRange(Recipe.AllRecipes.Where(x => !x.RequiredSkills.Any() && x.Ingredients.Any()));

                sw.WriteLine("Getting World Resources...");
                //manually defined for now since theres no easy way of checking for these
                data.craftableItems.AddRange(new List <Type>()
                {
                    typeof(DirtItem),
                    typeof(SandItem),
                    typeof(StoneItem),
                    typeof(IronOreItem),
                    typeof(CopperOreItem),
                    typeof(GoldOreItem),
                    typeof(CoalItem)
                });

                sw.WriteLine("Getting Species Resources...");
                var seedless     = new List <Species>();
                var resourceless = new List <Species>();
                EcoSim.AllSpecies.ForEach(x =>
                {
                    sw.WriteLine("Adding Species: " + x.DisplayName);
                    if (x is PlantSpecies)
                    {
                        if ((x as PlantSpecies).SeedItem.Type != null && (x as PlantSpecies).SeedRange.Max > 0 && (x as PlantSpecies).SeedRange.Min <= (x as PlantSpecies).SeedRange.Max)
                        {
                            var item = (x as PlantSpecies).SeedItem.Type;
                            data.craftableItems.AddUnique(item);
                            sw.WriteLine(" - New Resource: " + item.Name);
                        }
                        else
                        {
                            seedless.Add(x);
                        }
                    }
                    if (x.ResourceItem.Type != null && x.ResourceRange.Max > 0 && x.ResourceRange.Min <= x.ResourceRange.Max)
                    {
                        var item = x.ResourceItem.Type;
                        data.craftableItems.AddUnique(item);
                        sw.WriteLine(" - New Resource: " + item.Name);
                    }
                    else
                    {
                        resourceless.Add(x);
                    }
                });
                sw.WriteLine("\nSimulating...\n");
                UpdateRecipes(sw, data);
                UpdateRecipesFromSkills(sw, data);
                sw.WriteLine("\nTech Tree Sim Complete");
                ChatManager.SendChat(CheckStatus(sw, data) ? "Tech Tree Complete" : "Tech Tree Failed, check the TechTreeSimulation.txt for more information.", user.Player.ID); //get issues with complete

                //PLANT DATA
                sw.WriteLine("\nPlants Missing Seeds");
                sw.WriteLine(String.Join(",", seedless));
                sw.WriteLine("Plants Missing Resources");
                sw.WriteLine(String.Join(",", resourceless));

                //CRAFTABLES
                sw.WriteLine("\nUncraftable Accessed");
                foreach (var recipe in data.unusableRecipes)
                {
                    sw.WriteLine("  " + recipe.DisplayName);
                    recipe.Ingredients.ForEach(x => sw.WriteLine("    I: " + x.Item.DisplayName));
                    recipe.Products.ForEach(x => sw.WriteLine("    P: " + x.Item.DisplayName));

                    if (!data.craftableItems.Contains(recipe.Ingredients.Select(x => x.Item.Type)))
                    {
                        sw.WriteLine("    missing ingredients");
                    }
                    if (!CraftingComponent.TablesForRecipe(recipe.GetType()).Intersect(data.craftingTables).Any())
                    {
                        sw.WriteLine("    missing crafting table");
                    }
                }
                sw.WriteLine("\nUncraftable Unaccessed");
                foreach (var recipe in Recipe.AllRecipes.Except(data.curRecipes))
                {
                    sw.WriteLine("  " + recipe.DisplayName);
                    recipe.Ingredients.ForEach(x => sw.WriteLine("    I: " + x.Item.DisplayName));
                    recipe.Products.ForEach(x => sw.WriteLine("    P: " + x.Item.DisplayName));

                    if (!data.curSkills.Contains(recipe.RequiredSkills.Select(x => x.SkillType)))
                    {
                        sw.WriteLine("    missing skills");
                    }
                    if (!data.craftableItems.Contains(recipe.Ingredients.Select(x => x.Item.Type)))
                    {
                        sw.WriteLine("    missing ingredients");
                    }
                    if (!CraftingComponent.TablesForRecipe(recipe.GetType()).Intersect(data.craftingTables).Any())
                    {
                        sw.WriteLine("    missing crafting table");
                    }
                }

                //ALL UNOBTAINABLE ITEMS
                sw.WriteLine("\nUnobtainable Items");
                foreach (var item in Item.AllItems
                         .Where(x => !(x is Skill) && !(x is ActionbarItem) && !(x is SkillScroll) && !(x.Category == "Hidden"))
                         .Select(x => x.Type)
                         .Except(data.craftableItems))
                {
                    sw.WriteLine("  " + item.Name);
                }
            }
        }
        // Extracting Recipes is complex and requires collection and sorting.

        public static void RecipesDetails()
        {
            // dictionary of recipe properties
            Dictionary <string, string> recipeDetails = new Dictionary <string, string>()
            {
                // Legacy? Maybe OBSOLETE?
                { "dispCraftStn", "'1'" },
                { "checkImage", "'1'" },

                // Info
                { "untranslated", "nil" },
                { "craftStn", "nil" },
                { "skillNeeds", "nil" },
                { "moduleNeeds", "nil" },
                { "baseCraftTime", "nil" },
                { "baseLaborCost", "nil" },
                { "baseXPGain", "nil" },

                // Variants
                { "defaultVariant", "nil" },
                { "defaultVariantUntranslated", "nil" },
                { "numberOfVariants", "nil" },
                { "variants", "nil" },
            };

            Dictionary <string, string> variantDetails = new Dictionary <string, string>()
            {
                { "untranslated", "nil" },
                { "ingredients", "nil" },
                { "products", "nil" }
            };

            // collect all the recipes
            var famalies = RecipeFamily.AllRecipes;

            foreach (RecipeFamily family in famalies)
            {
                string familyName        = Localizer.DoStr(family.RecipeName);
                string familyNameUntrans = family.RecipeName;
                if (!EveryRecipe.ContainsKey(familyName))
                {
                    EveryRecipe.Add(familyName, new Dictionary <string, string>(recipeDetails));

                    EveryRecipe[familyName]["untranslated"] = $"'{familyNameUntrans}'";

                    // Crafting Stations.
                    StringBuilder tables = new StringBuilder();
                    tables.Append("{");
                    foreach (Type type in CraftingComponent.TablesForRecipe(family.GetType()))
                    {
                        WorldObjectItem creatingItem = WorldObjectItem.GetCreatingItemTemplateFromType(type);

                        string table        = creatingItem.DisplayName;
                        string untransTable = creatingItem.DisplayName.NotTranslated;
                        tables.Append($"{{'{table}', '{untransTable}'}}");
                        AddTableRecipeRelation(table, familyName);

                        if (type != CraftingComponent.TablesForRecipe(family.GetType()).Last())
                        {
                            tables.Append(", ");
                        }
                    }
                    tables.Append("}");
                    EveryRecipe[familyName]["craftStn"] = tables.ToString();

                    // Skills required
                    StringBuilder skillNeeds = new StringBuilder();
                    skillNeeds.Append("{");
                    foreach (RequiresSkillAttribute req in family.RequiredSkills)
                    {
                        skillNeeds.Append("{'" + req.SkillItem.DisplayName + "','" + req.Level.ToString() + "','" + req.SkillItem.DisplayName.NotTranslated + "'}");
                        if (req != family.RequiredSkills.Last())
                        {
                            skillNeeds.Append(", ");
                        }
                    }
                    skillNeeds.Append("}");
                    EveryRecipe[familyName]["skillNeeds"] = skillNeeds.ToString();

                    // Modules Required
                    StringBuilder moduleNeeds = new StringBuilder();
                    moduleNeeds.Append("{");
                    foreach (var module in family.RequiredModules)
                    {
                        moduleNeeds.Append("'" + module.ModuleName + "'");
                        if (module != family.RequiredModules.Last())
                        {
                            moduleNeeds.Append(", ");
                        }
                    }
                    moduleNeeds.Append("}");
                    EveryRecipe[familyName]["moduleNeeds"] = moduleNeeds.ToString();

                    // Base craft time.
                    EveryRecipe[familyName]["baseCraftTime"] = (family.CraftMinutes != null) ? "'" + family.CraftMinutes.GetBaseValue.ToString() + "'" : "'0'";

                    // Base labor cost
                    EveryRecipe[familyName]["baseLaborCost"] = "'" + family.Labor.ToString() + "'";

                    // Base XP gain
                    EveryRecipe[familyName]["baseXPGain"] = "'" + family.ExperienceOnCraft.ToString() + "'";

                    // Default Recipe
                    EveryRecipe[familyName]["defaultVariant"]             = "'" + Localizer.DoStr(SplitName(family.DefaultRecipe.Name)) + "'";
                    EveryRecipe[familyName]["defaultVariantUntranslated"] = "'" + SplitName(family.DefaultRecipe.Name) + "'";

                    EveryRecipe[familyName]["numberOfVariants"] = "'" + family.Recipes.Count + "'";

                    SortedDictionary <string, Dictionary <string, string> > variant = new SortedDictionary <string, Dictionary <string, string> >();
                    foreach (Recipe r in family.Recipes)
                    {
                        var recipe = r.DisplayName;
                        if (!variant.ContainsKey(recipe))
                        {
                            variant.Add(recipe, new Dictionary <string, string>(variantDetails));
                            variant[recipe]["untranslated"] = $"'{r.DisplayName.NotTranslated}'";
                            // Ingredients required
                            StringBuilder ingredients = new StringBuilder();
                            ingredients.Append("{");
                            foreach (var e in r.Ingredients)
                            {
                                ingredients.Append("{");
                                LocString element;
                                if (e.IsSpecificItem)
                                {
                                    ingredients.Append("'ITEM', ");
                                    element = e.Item.DisplayName;
                                    AddRecipeIngredientRelation(e.Item.DisplayName, r.DisplayName);
                                }
                                else
                                {
                                    ingredients.Append("'TAG', ");
                                    element = Localizer.DoStr(SplitName(e.Tag.DisplayName));
                                }

                                bool isStatic = false;

                                if (e.Quantity is ConstantValue)
                                {
                                    isStatic = true;
                                }

                                ingredients.Append("'" + element + "', '" + e.Quantity.GetBaseValue + "', '" + isStatic.ToString() + "', '" + element.NotTranslated + "'}");

                                if (e != r.Ingredients.Last())
                                {
                                    ingredients.Append(", ");
                                }
                            }
                            ingredients.Append("}");
                            variant[recipe]["ingredients"] = ingredients.ToString();
                            // Products recieved
                            StringBuilder products = new StringBuilder();
                            products.Append("{");
                            foreach (var e in r.Items)
                            {
                                products.Append("{");
                                products.Append("'" + e.Item.DisplayName + "', '" + e.Quantity.GetBaseValue + "', '" + e.Item.DisplayName.NotTranslated + "'}");

                                if (e != r.Items.Last())
                                {
                                    products.Append(", ");
                                }
                                AddRecipeProductRelation(e.Item.DisplayName, r.DisplayName);
                            }
                            products.Append("}");
                            variant[recipe]["products"] = products.ToString();
                        }
                    }
                    StringBuilder builder = new StringBuilder();
                    builder.AppendLine(" {");
                    string space = space2 + space2 + space3;
                    foreach (string key in variant.Keys)
                    {
                        builder.AppendLine(string.Format("{0}['{1}'] = {{", space, key));
                        foreach (KeyValuePair <string, string> keyValuePair in variant[key])
                        {
                            builder.AppendLine(string.Format("{0}{1}['{2}'] = {3},", space, space2, keyValuePair.Key, keyValuePair.Value));
                        }
                        builder.Append(string.Format("{0}}}", space));

                        //if (key != variant.Keys.Last())
                        builder.AppendLine(",");
                    }
                    builder.Append(space2 + space3 + "}");
                    EveryRecipe[familyName]["variants"] = builder.ToString();
                }
            }

            var lang = LocalizationPlugin.Config.Language;

            // writes to the Eco Server directory.
            if (!Directory.Exists(SaveLocation + $@"{lang}\"))
            {
                Directory.CreateDirectory(SaveLocation + $@"{lang}\");
            }

            // writes to WikiItems.txt to the Eco Server directory.
            string path = SaveLocation + $@"{lang}\" + "Wiki_Module_CraftingRecipes.txt";

            using (StreamWriter streamWriter = new StreamWriter(path, false))
            {
                streamWriter.WriteLine("-- Eco Version : " + EcoVersion.Version);
                streamWriter.WriteLine();
                streamWriter.WriteLine("return {\n    recipes = {");
                foreach (string key in EveryRecipe.Keys)
                {
                    streamWriter.WriteLine(string.Format("{0}['{1}'] = {{", space2, key));
                    foreach (KeyValuePair <string, string> keyValuePair in EveryRecipe[key])
                    {
                        streamWriter.WriteLine(string.Format("{0}{1}['{2}'] = {3},", space2, space3, keyValuePair.Key, keyValuePair.Value));
                    }
                    streamWriter.WriteLine(string.Format("{0}}},", space2));
                }

                // write the recipe ingredients to recipe variant data
                streamWriter.WriteLine("    },\n    ingredients = {");
                foreach (string key1 in RecipeIngedientVariantDic.Keys)
                {
                    streamWriter.Write(string.Format("{0}['{1}'] = {{ ", space2, key1));
                    foreach (string key2 in RecipeIngedientVariantDic[key1].Keys)
                    {
                        if (key2 != RecipeIngedientVariantDic[key1].Keys.Last())
                        {
                            streamWriter.Write(string.Format("'{0}', ", key2));
                        }
                        else
                        {
                            streamWriter.Write(string.Format("'{0}'", key2));
                        }
                    }
                    streamWriter.WriteLine("},");
                }

                // write the recipe products to recipe variant data
                streamWriter.WriteLine("    },\n    products = {");
                foreach (string key1 in RecipeProductVariantDic.Keys)
                {
                    streamWriter.Write(string.Format("{0}['{1}'] = {{ ", space2, key1));
                    foreach (string key2 in RecipeProductVariantDic[key1].Keys)
                    {
                        if (key2 != RecipeProductVariantDic[key1].Keys.Last())
                        {
                            streamWriter.Write(string.Format("'{0}', ", key2));
                        }
                        else
                        {
                            streamWriter.Write(string.Format("'{0}'", key2));
                        }
                    }
                    streamWriter.WriteLine("},");
                }

                // write the table to recipe family data
                streamWriter.WriteLine("    },\n    tables = {");
                foreach (string key1 in tableRecipeFamilyDic.Keys)
                {
                    streamWriter.Write(string.Format("{0}['{1}'] = {{ ", space2, key1));
                    foreach (string key2 in tableRecipeFamilyDic[key1].Keys)
                    {
                        if (key2 != tableRecipeFamilyDic[key1].Keys.Last())
                        {
                            streamWriter.Write(string.Format("'{0}', ", key2));
                        }
                        else
                        {
                            streamWriter.Write(string.Format("'{0}'", key2));
                        }
                    }
                    streamWriter.WriteLine("},");
                }

                /*
                 * // write the group(tag) to recipe data
                 * streamWriter.WriteLine("    },\n    groups = {");
                 * foreach (string key1 in groupRecipeDic.Keys)
                 * {
                 *  streamWriter.Write(string.Format("{0}['{1}'] = {{ ", space2, key1));
                 *  foreach (string key2 in groupRecipeDic[key1].Keys)
                 *      streamWriter.Write(string.Format("'{0}', ", key2));
                 *  streamWriter.WriteLine("},");
                 * }
                 */

                streamWriter.Write("    },\n}");
                streamWriter.Close();
            }
        }
Example #6
0
 public static List <string> GetTablesForRecipe(RecipeFamily recipe)
 {
     return(CraftingComponent.TablesForRecipe(recipe.GetType()).Select(type => GetTableNameFromUILink(WorldObject.UILink(type, false))).ToList());
 }
Example #7
0
        public static void RemoveRecipe(Type targetRecipeType)
        {
            Console.Write("Removing" + string.Concat(targetRecipeType.ToString().Split('.').Last().Select(x => Char.IsUpper(x) ? " " + x : x.ToString())));

            // Get all the existing recipe
            Dictionary <Type, Recipe[]> staticRecipes = (Dictionary <Type, Recipe[]>) typeof(CraftingComponent).GetFields(BindingFlags.Static | BindingFlags.NonPublic).First(x => x.Name.Contains("staticRecipes")).GetValue(Activator.CreateInstance(typeof(CraftingComponent)));

            // Get all the recipe to table dicationary
            Dictionary <Type, List <Type> > recipeToTable = (Dictionary <Type, List <Type> >) typeof(CraftingComponent).GetFields(BindingFlags.Static | BindingFlags.NonPublic).First(x => x.Name.Contains("recipeToTable")).GetValue(Activator.CreateInstance(typeof(CraftingComponent)));

            // Get all item to recipe dictionary
            Dictionary <Type, List <Recipe> > itemToRecipe = (Dictionary <Type, List <Recipe> >) typeof(CraftingComponent).GetFields(BindingFlags.Static | BindingFlags.NonPublic).First(x => x.Name.Contains("itemToRecipe")).GetValue(Activator.CreateInstance(typeof(CraftingComponent)));

            lock (staticRecipes)
            {
                Type targetTable = CraftingComponent.TablesForRecipe(targetRecipeType).First();

                Console.WriteLine(" from" + string.Concat(targetTable.ToString().Split('.').Last().Select(x => Char.IsUpper(x) ? " " + x : x.ToString())));
                Recipe   targetRecipe = null;
                Recipe[] recipes;

                // Get all the recipe inside the table
                if (staticRecipes.TryGetValue(targetTable, out recipes))
                {
                    // Get the recipe
                    targetRecipe = recipes.First(x => x.GetType() == targetRecipeType);

                    // Remove the target recipe from the recipe list
                    recipes = recipes.Where(x => x.GetType() != targetRecipeType).ToArray();
                }
                // Set back the recipe inside the static recipe dictionnary
                staticRecipes[targetTable] = recipes;

                // Remove the recipe from the recipe to table dictionary
                recipeToTable[targetRecipeType].Remove(targetTable);

                // Remove the recipe from the item to recipe dictionary
                targetRecipe?.Products.ForEach(product => itemToRecipe[product.Item.Type].Remove(targetRecipe));

                // Remove the table from the list of table
                // Only if there is no more recipe inside the table
                if (recipes.Length == 0)
                {
                    CraftingComponent.AllTableWorldObjects.Remove(targetTable);
                }

                // After removing the recipe we need to update the skill unlock

                // Get all the skillunlock tooltips
                Dictionary <Type, Dictionary <int, List <LocString> > > skillUnlocksTooltips = (Dictionary <Type, Dictionary <int, List <LocString> > >) typeof(Skill).GetFields(BindingFlags.Static | BindingFlags.NonPublic).First(x => x.Name.Contains("skillUnlocksTooltips")).GetValue(null);

                // Get all the skillbenefit tooltips
                Dictionary <Type, Dictionary <LocString, List <SkillModifiedValue> > > skillBenefitsTooltips = (Dictionary <Type, Dictionary <LocString, List <SkillModifiedValue> > >) typeof(SkillModifiedValueManager).GetFields(BindingFlags.Static | BindingFlags.NonPublic).First(x => x.Name.Contains("skillBenefits")).GetValue(null);

                // Get the skill that unlock the recipe
                Type skillType = RequiresSkillAttribute.Cache.Get(targetRecipeType).FirstOrDefault()?.SkillItem.Type;

                // Get the level that unlock the recipe
                int?recipeUnlockLevel = RequiresSkillAttribute.Cache.Get(targetRecipeType).FirstOrDefault()?.Level;

                // Get the loc string for the recipe
                LocString locStr = new LocString(Text.Indent(targetRecipe.UILink()));

                // If there is a require skill
                if (skillType != null)
                {
                    // Get the list of unlock for the skill for the unlock level
                    List <LocString> unlocks = skillUnlocksTooltips[skillType][recipeUnlockLevel.Value];

                    // Search the correct unlock
                    for (int i = 0; i < unlocks.Count; i++)
                    {
                        if (unlocks[i] == locStr)
                        {
                            // remove the loc string from the list
                            unlocks.RemoveAt(i);
                            break;
                        }
                    }
                    // Set the new unlock list
                    skillUnlocksTooltips[skillType][recipeUnlockLevel.Value] = unlocks;

                    // For testing
                    //List<Type> KeyA = new List<Type>();
                    //List<LocString> KeyB = new List<LocString>();

                    // Search all skill that benefit by the removed recipe
                    foreach (var benefit in skillBenefitsTooltips)
                    {
                        for (int i = 0; i < benefit.Value.Count; i++)
                        {
                            var b = benefit.Value.ElementAt(i);

                            // if the benefit is for a recipe
                            if (b.Key == targetRecipe.UILink())
                            {
                                //KeyA.Add(benefit.Key);
                                //KeyB.Add(b.Key);
                                b.Value.Clear();
                                // Update benefit list
                                benefit.Value[b.Key] = b.Value;
                                continue;
                            }

                            //if not we try to found benefit for an item
                            foreach (var item in targetRecipe.Products)
                            {
                                LocString itemLocString = item.Item.UILink();

                                // if this benefit is benefit for an item on the recipe product
                                if (b.Key == itemLocString)
                                {
                                    //KeyA.Add(benefit.Key);
                                    //KeyB.Add(b.Key);

                                    // clear all the benefit for this recipe
                                    b.Value.Clear();
                                    // Update benefit list
                                    benefit.Value[b.Key] = b.Value;
                                    break;
                                }
                            }
                        }
                    }

                    /*
                     * for (int i = 0; i < KeyA.Count; i++)
                     * {
                     *  Console.WriteLine(KeyA[i]);
                     *  Console.WriteLine(KeyA[i]);
                     *  skillBenefitsTooltips[KeyA[i]][KeyB[i]].ForEach(x => Console.WriteLine(x));
                     * }
                     */
                }
            }
        }
Example #8
0
        public static void RemoveRecipe(Type pTargetRecipeType)
        {
            // Get all the existing recipe
            Dictionary <Type, Recipe[]> staticRecipes = (Dictionary <Type, Recipe[]>) typeof(CraftingComponent).GetFields(BindingFlags.Static | BindingFlags.NonPublic).First(x => x.Name.Contains("staticRecipes")).GetValue(null);

            // Get all the recipe to table dicationary
            Dictionary <Type, List <Type> > recipeToTable = (Dictionary <Type, List <Type> >) typeof(CraftingComponent).GetFields(BindingFlags.Static | BindingFlags.NonPublic).First(x => x.Name.Contains("recipeToTable")).GetValue(null);

            // Get all item to recipe dictionary
            Dictionary <Type, List <Recipe> > itemToRecipe = (Dictionary <Type, List <Recipe> >) typeof(CraftingComponent).GetFields(BindingFlags.Static | BindingFlags.NonPublic).First(x => x.Name.Contains("itemToRecipe")).GetValue(null);

            lock (staticRecipes)
            {
                Type targetTable = CraftingComponent.TablesForRecipe(pTargetRecipeType).First();

                Recipe   targetRecipe = null;
                Recipe[] recipes;

                // Get all the recipe inside the table
                if (staticRecipes.TryGetValue(targetTable, out recipes))
                {
                    // Get the recipe
                    targetRecipe = recipes.First(x => x.GetType() == pTargetRecipeType);

                    // Remove the target recipe from the recipe list
                    recipes = recipes.Where(x => x.GetType() != pTargetRecipeType).ToArray();
                }
                // Set back the recipe inside the static recipe dictionnary
                staticRecipes[targetTable] = recipes;

                // Remove the recipe from the recipe to table dictionary
                recipeToTable[pTargetRecipeType].Remove(targetTable);

                // Remove the recipe from the item to recipe dictionary
                targetRecipe?.Products.ForEach(product => itemToRecipe[product.Item.Type].Remove(targetRecipe));

                // Remove the table from the list of table
                // Only if there is no more recipe inside the table
                if (recipes.Length == 0)
                {
                    CraftingComponent.AllTableWorldObjects.Remove(targetTable);
                }

                // After removing the recipe we need to update the skill unlock

                // Get all the skillunlock tooltips
                Dictionary <Type, Dictionary <int, List <LocString> > > skillUnlocksTooltips = (Dictionary <Type, Dictionary <int, List <LocString> > >) typeof(Skill).GetFields(BindingFlags.Static | BindingFlags.NonPublic).First(x => x.Name.Contains("skillUnlocksTooltips")).GetValue(null);

                // Get the skill that unlock the recipe
                Type skillType = RequiresSkillAttribute.Cache.Get(pTargetRecipeType).FirstOrDefault()?.SkillItem.Type;

                // Get the level that unlock the recipe
                int?recipeUnlockLevel = RequiresSkillAttribute.Cache.Get(pTargetRecipeType).FirstOrDefault()?.Level;

                // If there is a require skill
                if (skillType != null && skillUnlocksTooltips.ContainsKey(skillType))
                {
                    // Get the list of unlock for the skill for the unlock level
                    List <LocString> unlocks = skillUnlocksTooltips[skillType][recipeUnlockLevel.Value];

                    // Search the correct unlock
                    for (int i = 0; i < unlocks.Count; i++)
                    {
                        if (unlocks[i] == new LocString(Text.Indent(targetRecipe.UILink())))
                        {
                            // remove the loc string from the list
                            unlocks.RemoveAt(i);
                            break;
                        }
                    }
                    // Set the new unlock list
                    skillUnlocksTooltips[skillType][recipeUnlockLevel.Value] = unlocks;
                }

                FieldInfo fi = typeof(SkillModifiedValueManager).GetField("skillBenefits", BindingFlags.Static | BindingFlags.NonPublic);
                Dictionary <Type, Dictionary <LocString, List <SkillModifiedValue> > > benefits = (Dictionary <Type, Dictionary <LocString, List <SkillModifiedValue> > >)fi.GetValue(null);

                foreach (var benefitSkillEntry in benefits)
                {
                    foreach (var entry in benefitSkillEntry.Value.ToArray())
                    {
                        if (entry.Key.ToString().Contains("Recipe:" + pTargetRecipeType.FullName))
                        {
                            benefitSkillEntry.Value.Remove(entry.Key);
                        }
                    }
                }
            }

            var allRecipes = Recipe.AllRecipes.ToList();

            allRecipes.RemoveAll(r => r.GetType() == pTargetRecipeType);
            typeof(Recipe).GetProperty("AllRecipes", BindingFlags.Static | BindingFlags.Public).SetValue(null, allRecipes.ToArray());

            RemoveFromDictionary("itemToRecipesWithProduct", pTargetRecipeType);
            RemoveFromDictionary("itemToRecipesWithIngredient", pTargetRecipeType);
            RemoveFromDictionary("skillToRecipes", pTargetRecipeType);

            RemoveFromDictionaryRecipeName(pTargetRecipeType);
        }
Example #9
0
        public static void TechTreeSimulation(User user)
        {
            var info = new InfoBuilder();
            var data = new TechTreeSimData();

            info.AppendLineLocStr("Starting Tech Tree Sim");

            info.AppendLineLocStr("Getting Starting Skills...");
            var introSkills = PlayerDefaults.GetDefaultSkills().ToList();

            introSkills.ForEach(x => data.AddSkill(x));

            info.AppendLineLocStr("Getting Initial Tables...");
            data.CraftingTables.Add(typeof(CampsiteObject));

            info.AppendLineLocStr("Getting Recipes with No Skills...");
            data.UnusableRecipes.AddRange(RecipeFamily.AllRecipes.SelectMany(x => x.Recipes).Where(x => !x.Family.RequiredSkills.Any() && x.Ingredients.Any()));

            info.AppendLineLocStr("Getting World Resources...");
            //manually defined for now since theres no easy way of checking for these
            data.AddItems(new List <Type>
            {
                typeof(DirtItem),
                typeof(SandItem),
                typeof(IronOreItem),
                typeof(CopperOreItem),
                typeof(GoldOreItem),
                typeof(CoalItem),
                typeof(ClayItem)
            });

            // Add all items with "Rock" tag
            data.AddItems(TagManager.TagToTypes[TagManager.Tag("Rock")]);

            info.AppendLineLocStr("Getting Species Resources...");
            var resourceless = new List <Species>();

            EcoSim.AllSpecies.ForEach(x =>
            {
                var speciesInfo = new InfoBuilder();
                AddNewResources(speciesInfo, x.ResourceList.Select(x => x.ResourceType), data);
                if (x is TreeSpecies treeSpecies)
                {
                    AddNewResources(speciesInfo, treeSpecies.TrunkResources.Keys, data);
                    AddNewResources(speciesInfo, treeSpecies.DebrisResources.Keys, data);
                }

                if (speciesInfo.IsEmpty)
                {
                    resourceless.Add(x);
                    speciesInfo.AppendLineLocStr("No resources");
                }

                info.AddSectionLoc($"Adding Species: {x.DisplayName}", speciesInfo);
            });

            info.AppendLine();
            info.AppendLineLocStr("Simulating...");
            info.AppendLine();

            UpdateRecipes(info, data);
            UpdateRecipesFromSkills(info, data);
            info.AppendLine();
            info.AppendLineLocStr("Tech Tree Sim Complete");
            ChatManager.SendChat(CheckStatus(info, data) ? "Tech Tree Complete" : "Tech Tree Failed, check the TechTreeSimulation.txt for more information.", user); //get issues with complete

            //PLANT DATA
            info.AppendLineLocStr("Plants Missing Resources");
            info.AppendLine(Localizer.NotLocalizedStr(string.Join(",", resourceless)));

            //CRAFTABLES
            var uncraftableAccessed = new InfoBuilder();

            foreach (var recipe in data.UnusableRecipes)
            {
                var recipeInfo = new InfoBuilder();
                ReportMissingIngredients(recipeInfo, recipe, data);

                if (!CraftingComponent.TablesForRecipe(recipe.Family.GetType()).Intersect(data.CraftingTables).Any())
                {
                    recipeInfo.AppendLineLocStr("- missing crafting table");
                }
                uncraftableAccessed.AddSection(recipe.DisplayName, recipeInfo);
            }
            info.AppendLine();
            info.AddSectionLocStr("Uncraftable Accessed", uncraftableAccessed);

            var uncraftableUnaccessed = new InfoBuilder();

            foreach (var recipe in RecipeFamily.AllRecipes.SelectMany(x => x.Recipes).Except(data.CurRecipes))
            {
                var recipeInfo        = new InfoBuilder();
                var missingSkillsInfo = new InfoBuilder();
                foreach (var skill in recipe.Family.RequiredSkills)
                {
                    if (!data.CurSkills.Contains(skill.SkillType))
                    {
                        missingSkillsInfo.AppendLine(skill.SkillItem.DisplayName);
                    }
                }
                recipeInfo.AddSectionLocStr("- missing skills:", missingSkillsInfo);

                ReportMissingIngredients(recipeInfo, recipe, data);

                // notify about missing crafting table
                if (!CraftingComponent.TablesForRecipe(recipe.Family.GetType()).Intersect(data.CraftingTables).Any())
                {
                    recipeInfo.AppendLineLocStr("- missing crafting table");
                }

                uncraftableUnaccessed.AddSection(recipe.DisplayName, recipeInfo);
            }
            info.AppendLine();
            info.AddSectionLocStr("Uncraftable Unaccessed", uncraftableUnaccessed);

            //ALL UNOBTAINABLE ITEMS
            info.AppendLine();
            info.AppendLineLocStr("Unobtainable Items");
            foreach (var item in Item.AllItems
                     .Where(x => !(x is Skill) && !(x is ActionbarItem) && !(x is SkillScroll) && !x.Hidden)
                     .Select(x => x.Type)
                     .Except(data.CraftableItems))
            {
                info.AppendLineLocStr("  " + item.Name);
            }

            using var sw = new StreamWriter("TechTreeSimulation.txt");
            sw.Write(info.ToLocString());
        }