public static void ListUnobtainableItems(User user)
        {
            HashSet <Type> allBaseItems = new HashSet <Type>();

            foreach (Item item in Item.AllItems)
            {
                if (!ShouldBeCraftable(item))
                {
                    continue;
                }

                TechTreePath path = new TechTreePath();
                GetPathToItemRec(item, true, ref path, 1);
                foreach (Type baseItemType in path.BaseItems.Keys)
                {
                    if (ShouldBeCraftable(Item.Create(baseItemType)))
                    {
                        allBaseItems.Add(baseItemType);
                    }
                }
            }

            foreach (Type unobtainableItem in allBaseItems)
            {
                ChatManager.SendChat(Item.Create(unobtainableItem).ShowName(1), user);
            }

            ChatManager.SendChat(allBaseItems.Count + " total unobtainable items.", user);
        }
        public static void GetPathToItem(User user, string target)
        {
            var item = Item.GetItemByString(user, target);

            if (item == null)
            {
                return;
            }
            TechTreePath path = new TechTreePath();

            GetPathToItemRec(item, true, ref path, 1);
            //probably not the right place to send this, but for now I want to test it
            ChatManager.SendChat(path.Print(), user);
        }
        public static void GetPathToItemRec(Item target, bool includeSkills, ref TechTreePath path, int number = 1)
        {
            var recipes = CraftingComponent.RecipesForItem(target.GetType());

            if (recipes.Any())
            {
                if (path.Items.ContainsKey(target.GetType()))
                {
                    path.Items[target.GetType()] += number;
                }
                else
                {
                    path.Items.Add(target.GetType(), number);
                }
                foreach (RequiresSkillAttribute skill in recipes.First().RequiredSkills)
                {
                    if (skill.Level <= skill.SkillItem.MaxLevel)
                    {
                        GetPathToSkillRec(skill.SkillItem, includeSkills, ref path, skill.Level);
                    }
                }
                foreach (var ingredient in recipes.First().Ingredients)
                {
                    GetPathToItemRec(ingredient.Item, includeSkills, ref path, (int)ingredient.Quantity.GetBaseValue * number);
                }
            }
            else
            {
                if (path.BaseItems.ContainsKey(target.GetType()))
                {
                    path.BaseItems[target.GetType()] += number;
                }
                else
                {
                    path.BaseItems.Add(target.GetType(), number);
                }
            }
        }
 public static void GetPathToSkillRec(Skill target, bool includeItems, ref TechTreePath path, int level = 0)
 {
     if (!path.Skills.ContainsKey(target.GetType()))
     {
         //add skill to path
         path.Skills.Add(target.GetType(), target.Level);
         //if skill had a book and you're including items, path to it
         var rootTree = SkillTree.RootTreeFromSkill(target.GetType());
         if (rootTree != null)
         {
             if (includeItems && SkillTree.SkillToSkillBook.ContainsKey(rootTree.GetType()))
             {
                 GetPathToItemRec(Item.Get(SkillTree.SkillToSkillBook[rootTree.GetType()]), true, ref path);
             }
             //get skill tree root skill
             GetPathToSkillRec(rootTree.StaticSkill, includeItems, ref path, 1);
         }
     }
     else if (path.Skills.ContainsKey(target.GetType()) && path.Skills[target.GetType()] < level)
     {
         path.Skills[target.GetType()] = level;
     }
 }