diff --git a/FilterExtension/ConfigNodes/customCategory.cs b/FilterExtension/ConfigNodes/customCategory.cs index 28714149..1d796ad2 100644 --- a/FilterExtension/ConfigNodes/customCategory.cs +++ b/FilterExtension/ConfigNodes/customCategory.cs @@ -7,6 +7,14 @@ namespace FilterExtensions.ConfigNodes { using Utility; + public enum categoryTypeAndBehaviour + { + None, + Engines, + StockAdd, + StockReplace + } + public class customCategory : IEquatable { public string categoryName { get; set; } @@ -14,32 +22,30 @@ public class customCategory : IEquatable public Color colour { get; set; } public string type { get; set; } // procedural categories public string value { get; set; } // mod folder name for mod type categories + public categoryTypeAndBehaviour behaviour { get; set; } public bool all { get; set; } // has an all parts subCategory public string[] subCategories { get; set; } // array of subcategories - public bool stockCategory { get; set; } // editing a stock category or creating a completely new one public List template { get; set; } // Checks to add to every Filter in a category with the template tag private static readonly List categoryNames = new List { "Pods", "Engines", "Fuel Tanks", "Command and Control", "Structural", "Aerodynamics", "Utility", "Science" }; public customCategory(ConfigNode node) { + bool tmp; categoryName = node.GetValue("name"); iconName = node.GetValue("icon"); colour = convertToColor(node.GetValue("colour")); type = node.GetValue("type"); value = node.GetValue("value"); + typeSwitch(); makeTemplate(node); - bool tmp; bool.TryParse(node.GetValue("all"), out tmp); this.all = tmp; - bool.TryParse(node.GetValue("stock"), out tmp); - this.stockCategory = tmp; - ConfigNode subcategoryList = node.GetNode("SUBCATEGORIES", 0); if (subcategoryList != null) { @@ -87,6 +93,11 @@ public void initialise() else { category = PartCategorizer.Instance.filters.Find(c => c.button.categoryName == categoryName); + if (category == null) + { + Core.Log("No Stock category of this name was found: " + categoryName); + return; + } } for (int i = 0; i < subCategories.Length; i++) @@ -118,7 +129,8 @@ public void initialise() try { - sC.initialise(category); + if (Core.checkSubCategoryHasParts(sC)) + sC.initialise(category); } catch (Exception ex) { @@ -137,12 +149,23 @@ private void typeSwitch() { case "engine": generateEngineTypes(); + behaviour = categoryTypeAndBehaviour.Engines; + break; + case "stock": + if (value == "replace") + behaviour = categoryTypeAndBehaviour.StockReplace; + else + behaviour = categoryTypeAndBehaviour.StockAdd; + break; + default: + behaviour = categoryTypeAndBehaviour.None; break; } } private void generateEngineTypes() { + List engines = new List(); foreach (List ls in Core.propellantCombos) { List checks = new List(); @@ -155,15 +178,20 @@ private void generateEngineTypes() checks.Add(new Check("propellant", s)); props += s; } - checks.Add(new Check("propellant", props, true, false)); // exact match to propellant list. Nothing extra, nothing less + if (!Core.Instance.subCategoriesDict.ContainsKey(props)) + { + checks.Add(new Check("propellant", props, true, false)); // exact match to propellant list. Nothing extra, nothing less - customSubCategory sC = new customSubCategory(props, "stock_Engines"); + customSubCategory sC = new customSubCategory(props, "stock_Engines"); - Filter f = new Filter(false); - f.checks = checks; - sC.filters.Add(f); - Core.Instance.subCategoriesDict.Add(sC.subCategoryTitle, sC); + Filter f = new Filter(false); + f.checks = checks; + sC.filters.Add(f); + Core.Instance.subCategoriesDict.Add(props, sC); + } + engines.Add(props); } + subCategories.AddUniqueRange(engines); } private void makeTemplate(ConfigNode node) @@ -236,5 +264,13 @@ public override int GetHashCode() { return categoryName.GetHashCode(); } + + public bool stockCategory + { + get + { + return this.behaviour == categoryTypeAndBehaviour.StockAdd || this.behaviour == categoryTypeAndBehaviour.StockReplace; + } + } } } diff --git a/FilterExtension/ConfigNodes/customSubCategory.cs b/FilterExtension/ConfigNodes/customSubCategory.cs index 1920f0ae..65b02c10 100644 --- a/FilterExtension/ConfigNodes/customSubCategory.cs +++ b/FilterExtension/ConfigNodes/customSubCategory.cs @@ -64,31 +64,6 @@ public bool checkFilters(AvailablePart part) return false; // part passed no filter(s), not compatible with this subcategory } - //public void initialise() - //{ - // PartCategorizer.Icon icon = Core.getIcon(iconName); - // if (icon == null) - // { - // Core.Log(this.subCategoryTitle + " no icon found"); - // icon = PartCategorizer.Instance.fallbackIcon; - // } - - // if (hasFilters) - // { - // PartCategorizer.Category category = PartCategorizer.Instance.filters.FirstOrDefault(f => f.button.categoryName == this.category); - // if (category == null) - // return; - - // PartCategorizer.AddCustomSubcategoryFilter(category, this.subCategoryTitle, icon, p => checkFilters(p)); - // } - // //else if (!string.IsNullOrEmpty(oldTitle) && string.IsNullOrEmpty(subCategoryTitle)) - // // Delete(oldTitle); // if there is an old title and no new title we are deleting - // else if (!string.IsNullOrEmpty(subCategoryTitle)) - // Edit(subCategoryTitle, icon); - // else - // Core.Log("Invalid subCategory definition"); - //} - public void initialise(PartCategorizer.Category cat) { PartCategorizer.Icon icon = Core.getIcon(iconName); @@ -104,8 +79,6 @@ public void initialise(PartCategorizer.Category cat) return; PartCategorizer.AddCustomSubcategoryFilter(cat, this.subCategoryTitle, icon, p => checkFilters(p)); } - //else if (!string.IsNullOrEmpty(subCategoryTitle)) - // Edit(subCategoryTitle, icon); else Core.Log("Invalid subCategory definition"); } diff --git a/FilterExtension/Core.cs b/FilterExtension/Core.cs index 55c117ef..d61782a8 100644 --- a/FilterExtension/Core.cs +++ b/FilterExtension/Core.cs @@ -220,7 +220,8 @@ private void processFilterByManufacturer(List modNames) ConfigNode filterByManufacturer = new ConfigNode("CATEGORY"); filterByManufacturer.AddValue("name", "Filter by Manufacturer"); - filterByManufacturer.AddValue("stock", "true"); + filterByManufacturer.AddValue("type", "stock"); + filterByManufacturer.AddValue("value", "replace"); filterByManufacturer.AddNode(manufacturerSubs); Categories.Add(new customCategory(filterByManufacturer)); } @@ -415,27 +416,18 @@ private void RepairAvailablePartUrl(AvailablePart ap) ap.partUrl = url.url; } - //private void checkForEmptySubCategories() - //{ - // List notEmpty = new List(); - // foreach (customSubCategory sC in subCategories) - // { - // if (!sC.hasFilters) - // notEmpty.Add(sC); - // else - // { - // foreach (AvailablePart p in PartLoader.Instance.parts) - // { - // if (sC.checkFilters(p)) - // { - // notEmpty.Add(sC); - // break; - // } - // } - // } - // } - // subCategories = notEmpty; - //} + public static bool checkSubCategoryHasParts(customSubCategory sC) + { + foreach (AvailablePart p in PartLoader.Instance.parts) + { + if (sC.checkFilters(p)) + { + return true; + } + } + Log(sC.subCategoryTitle + " has no valid parts and was not initialised"); + return false; + } internal static void Log(object o) { diff --git a/FilterExtension/Editor.cs b/FilterExtension/Editor.cs index 0cab9a82..0406bef7 100644 --- a/FilterExtension/Editor.cs +++ b/FilterExtension/Editor.cs @@ -34,7 +34,8 @@ IEnumerator editorInit() customCategory cat = Core.Instance.Categories.FirstOrDefault(c => c.categoryName == C.button.categoryName); if (cat != null && cat.hasSubCategories() && cat.stockCategory) { - C.subcategories.Clear(); + if (cat.behaviour == categoryTypeAndBehaviour.StockReplace) + C.subcategories.Clear(); cat.initialise(); } } diff --git a/FilterExtension/Utility/PartType.cs b/FilterExtension/Utility/PartType.cs index 9b8ad03b..5beea2aa 100644 --- a/FilterExtension/Utility/PartType.cs +++ b/FilterExtension/Utility/PartType.cs @@ -210,14 +210,14 @@ internal static bool checkFolder(AvailablePart part, string[] values) internal static bool checkPath(AvailablePart part, string value) { - string[] values = value.Split(','); + string[] values = value.Replace('\\', '/').Split(','); return checkPath(part, values); } internal static bool checkPath(AvailablePart part, string[] values) { if (Core.partPathDict.ContainsKey(part.name)) - return values.Any(s => Core.partPathDict[part.name].StartsWith(s, StringComparison.InvariantCultureIgnoreCase)); + return values.Any(s => Core.partPathDict[part.name].StartsWith(s.Trim(), StringComparison.InvariantCultureIgnoreCase)); return false; } diff --git a/GameData/000_FilterExtensions/Configs/SubCategories_FilterbyFunction.cfg b/GameData/000_FilterExtensions/Configs/Stock Categories/Categories_FilterbyFunction.cfg similarity index 90% rename from GameData/000_FilterExtensions/Configs/SubCategories_FilterbyFunction.cfg rename to GameData/000_FilterExtensions/Configs/Stock Categories/Categories_FilterbyFunction.cfg index 611a8334..ef8de7b2 100644 --- a/GameData/000_FilterExtensions/Configs/SubCategories_FilterbyFunction.cfg +++ b/GameData/000_FilterExtensions/Configs/Stock Categories/Categories_FilterbyFunction.cfg @@ -1,7 +1,8 @@ CATEGORY { name = Filter by Function - stock = true + type = stock + value = replace SUBCATEGORIES { @@ -13,6 +14,7 @@ CATEGORY list = 5,Aerodynamics list = 6,Utility list = 7,Science + list = 8,SPP } } @@ -127,4 +129,17 @@ SUBCATEGORY value = Science } } +} +SUBCATEGORY +{ + name = SPP + + FILTER + { + CHECK + { + type = path + value = Squad/SPP + } + } } \ No newline at end of file diff --git a/GameData/000_FilterExtensions/Configs/SubCategories_FilterbyResource.cfg b/GameData/000_FilterExtensions/Configs/Stock Categories/Categories_FilterbyResource.cfg similarity index 98% rename from GameData/000_FilterExtensions/Configs/SubCategories_FilterbyResource.cfg rename to GameData/000_FilterExtensions/Configs/Stock Categories/Categories_FilterbyResource.cfg index c44dfc11..b70287ab 100644 --- a/GameData/000_FilterExtensions/Configs/SubCategories_FilterbyResource.cfg +++ b/GameData/000_FilterExtensions/Configs/Stock Categories/Categories_FilterbyResource.cfg @@ -1,7 +1,8 @@ CATEGORY { name = Filter by Resource - stock = true + type = stock + value = replace SUBCATEGORIES { diff --git a/GameData/000_FilterExtensions/FilterExtensions.dll b/GameData/000_FilterExtensions/FilterExtensions.dll index bb6179df..30b98559 100644 Binary files a/GameData/000_FilterExtensions/FilterExtensions.dll and b/GameData/000_FilterExtensions/FilterExtensions.dll differ