private static void UpdateRecipesFromSkills(StreamWriter sw, TechTreeSimData data) { while (data.skillsToEvaluate.Any()) { var skill = data.skillsToEvaluate.Dequeue(); data.curSkills.Add(skill); sw.WriteLine("Adding Skill: " + skill.Name); foreach (var recipe in Recipe.GetRecipesBySkill(skill)) { data.unusableRecipes.Add(recipe); } UpdateRecipes(sw, data); } }
private static void UpdateRecipesFromSkills(InfoBuilder info, TechTreeSimData data) { while (data.SkillsToEvaluate.Any()) { var skill = data.SkillsToEvaluate.Dequeue(); data.CurSkills.Add(skill); info.AppendLineLocStr("Adding Skill: " + skill.Name); foreach (var recipe in RecipeFamily.GetRecipesBySkill(skill)) { data.UnusableRecipes.AddRange(recipe.Recipes); } UpdateRecipes(info, data); } }
private static bool CheckStatus(InfoBuilder info, TechTreeSimData data) { var s = new LocStringBuilder(); if (!data.CraftingTables.Contains(typeof(LaserObject))) { s.AppendLineLocStr("Error: Laser Unobtainable"); } if (data.UnusableRecipes.Any()) { s.AppendLineLocStr("Error: Visible Recipes Uncraftable"); } info.AppendLine(s.ToLocString()); return(s.ToLocString().Length <= 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); }); } }
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); }); } }
private static bool CheckStatus(StreamWriter sw, TechTreeSimData data) { StringBuilder s = new StringBuilder(); if (!data.craftingTables.Contains(typeof(LaserObject))) { s.AppendLine("Error: Laser Unobtainable"); } if (data.unusableRecipes.Any()) { s.AppendLine("Error: Visible Recipes Uncraftable"); } sw.Write(s.ToString()); if (s.Length > 0) { return(false); } else { return(true); } }
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); } } }
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()); }
private static void ReportMissingIngredients(InfoBuilder recipeFamilyInfo, Recipe recipe, TechTreeSimData data) { var missingIngredientsInfo = new InfoBuilder(); foreach (var ingredient in recipe.Ingredients) { if (!data.HasIngredient(ingredient)) { missingIngredientsInfo.AppendLine(ingredient.StackObject.DisplayName); } } recipeFamilyInfo.AddSectionLocStr("- missing ingredients:", missingIngredientsInfo); }
private static void AddNewResources(InfoBuilder info, IEnumerable <Type> itemTypes, TechTreeSimData data) { foreach (var itemType in itemTypes) { data.AddItem(itemType); info.AppendLineLoc($" - New Resource: {Item.Get(itemType).DisplayName}"); } }