diff --git a/FilterExtension/ConfigNodes/Check.cs b/FilterExtension/ConfigNodes/Check.cs index 6e24216c..4d905f5d 100644 --- a/FilterExtension/ConfigNodes/Check.cs +++ b/FilterExtension/ConfigNodes/Check.cs @@ -7,7 +7,7 @@ namespace FilterExtensions.ConfigNodes { using Utility; - public class Check + public class Check : ICloneable { public enum CheckType { @@ -139,13 +139,17 @@ public Check(ConfigNode node) public Check(Check c) { type = c.type; - values = (string[])c.values.Clone(); + if (c.values != null) + values = (string[])c.values.Clone(); invert = c.invert; contains = c.contains; - checks = new List(); - for (int i = 0; i < c.checks.Count; i++) - checks.Add(new Check(c.checks[i])); + if (c.checks != null) + { + checks = new List(c.checks.Count); + for (int i = 0; i < c.checks.Count; ++i) + checks.Add(new Check(c.checks[i])); + } } public Check(string Type, string Value, bool Invert = false, bool Contains = true, Equality Compare = Equality.Equals) @@ -161,26 +165,6 @@ public Check(string Type, string Value, bool Invert = false, bool Contains = tru checks = new List(); } - public ConfigNode toConfigNode() - { - ConfigNode node = new ConfigNode("CHECK"); - node.AddValue("type", type.typeString); - - if (values != null) - node.AddValue("value", string.Join(",", values)); - node.AddValue("invert", invert.ToString()); - - if (type.usesContains) - node.AddValue("contains", contains.ToString()); - if (type.usesEquality) - node.AddValue("equality", equality.ToString()); - - foreach (Check c in this.checks) - node.AddNode(c.toConfigNode()); - - return node; - } - public bool checkPart(AvailablePart part, int depth = 0) { bool result = true; @@ -286,7 +270,32 @@ public static CheckParameters getCheckType(string type) public bool isEmpty() { - return !checks.Any() || values == null || values.Length > 0; + return !checks.Any() && (values == null || values.Length == 0); + } + + public ConfigNode toConfigNode() + { + ConfigNode node = new ConfigNode("CHECK"); + node.AddValue("type", type.typeString); + + if (values != null) + node.AddValue("value", string.Join(",", values)); + node.AddValue("invert", invert.ToString()); + + if (type.usesContains) + node.AddValue("contains", contains.ToString()); + if (type.usesEquality) + node.AddValue("equality", equality.ToString()); + + foreach (Check c in this.checks) + node.AddNode(c.toConfigNode()); + + return node; + } + + public object Clone() + { + return new Check(this); } public bool Equals(Check c2) diff --git a/FilterExtension/ConfigNodes/Filter.cs b/FilterExtension/ConfigNodes/Filter.cs index 8c9c0dfa..86ce947d 100644 --- a/FilterExtension/ConfigNodes/Filter.cs +++ b/FilterExtension/ConfigNodes/Filter.cs @@ -5,7 +5,7 @@ namespace FilterExtensions.ConfigNodes { - public class Filter + public class Filter : ICloneable { public List checks { get; set; } // checks are processed in serial (a && b), inversion gives (!a || !b) logic public bool invert { get; set; } @@ -52,14 +52,14 @@ public ConfigNode toConfigNode() return node; } + public object Clone() + { + return new Filter(this); + } + internal bool checkFilter(AvailablePart part, int depth = 0) { - for (int i = 0; i < checks.Count; i++) - { - if (!checks[i].checkPart(part, depth)) - return invert ? true : false; - } - return invert ? false : true; + return invert ? !checks.All(c => c.checkPart(part, depth)) : checks.All(c => c.checkPart(part, depth)); } /// diff --git a/FilterExtension/ConfigNodes/customCategory.cs b/FilterExtension/ConfigNodes/customCategory.cs index c2b78f3c..ba82ac85 100644 --- a/FilterExtension/ConfigNodes/customCategory.cs +++ b/FilterExtension/ConfigNodes/customCategory.cs @@ -142,7 +142,7 @@ public void initialise() continue; } - List conflictsList; + //List conflictsList; #warning subcategory conflicts are broken and doing stupid things //if (Core.Instance.conflictsDict.TryGetValue(subcategoryItem.subcategoryName, out conflictsList)) //{ @@ -156,7 +156,7 @@ public void initialise() // } //} - customSubCategory sC = new customSubCategory(subcategory.toConfigNode()); + customSubCategory sC = new customSubCategory(subcategory); if (subcategoryItem.applyTemplate) sC.template = templates; diff --git a/FilterExtension/ConfigNodes/customSubCategory.cs b/FilterExtension/ConfigNodes/customSubCategory.cs index 94ca2853..da9d7b8b 100644 --- a/FilterExtension/ConfigNodes/customSubCategory.cs +++ b/FilterExtension/ConfigNodes/customSubCategory.cs @@ -6,7 +6,7 @@ namespace FilterExtensions.ConfigNodes { using KSP.UI.Screens; - public class customSubCategory + public class customSubCategory : ICloneable { public string subCategoryTitle { get; set; } // title of this subcategory public string iconName { get; set; } // default icon to use @@ -39,6 +39,19 @@ public customSubCategory(ConfigNode node) template = new List(); } + public customSubCategory(customSubCategory subCat) + { + subCategoryTitle = subCat.subCategoryTitle; + iconName = subCat.iconName; + filters = new List(subCat.filters.Count); + subCat.filters.ForEach(f => filters.Add(new Filter(f))); + + template = new List(subCat.template.Count); + subCat.template.ForEach(f => template.Add(new Filter(f))); + + unPurchasedOverride = subCat.unPurchasedOverride; + } + public customSubCategory(string name, string icon) { filters = new List(); @@ -77,6 +90,11 @@ public ConfigNode toConfigNode() return node; } + public object Clone() + { + return new customSubCategory(this); + } + /// /// called by subcategory check type, has depth limit protection /// diff --git a/FilterExtension/Core.cs b/FilterExtension/Core.cs index 9b53e63b..37f057d0 100644 --- a/FilterExtension/Core.cs +++ b/FilterExtension/Core.cs @@ -300,8 +300,6 @@ private void generateEngineTypes() f.checks = checks; sC.filters.Add(f); subCategoriesDict.Add(name, sC); - - Log(sC.toConfigNode()); } } } @@ -373,42 +371,6 @@ private bool stringListComparer(List propellants) return false; } - /// - /// refresh the visible subcategories to ensure all changes are visible - /// - public static void setSelectedCategory() - { - try - { - PartCategorizer.Category Filter = PartCategorizer.Instance.filters.FirstOrDefault(f => f.button.activeButton.CurrentState == KSP.UI.UIRadioButton.State.True); - if (Filter != null) - Filter.button.activeButton.SetState(KSP.UI.UIRadioButton.State.False, KSP.UI.UIRadioButton.CallType.APPLICATIONSILENT, null); - - Filter = PartCategorizer.Instance.filters.FirstOrDefault(f => f.button.categoryName == Settings.categoryDefault); - if (Filter != null) - Filter.button.activeButton.SetState(KSP.UI.UIRadioButton.State.True, KSP.UI.UIRadioButton.CallType.APPLICATIONSILENT, null); - else - { - Filter = PartCategorizer.Instance.filters[0]; - if (Filter != null) - { - Filter.button.activeButton.SetState(KSP.UI.UIRadioButton.State.True, KSP.UI.UIRadioButton.CallType.APPLICATIONSILENT, null); - } - } - - // set the subcategory button - //Filter = Filter.subcategories.FirstOrDefault(sC => sC.button.categoryName == instance.subCategoryDefault); - //if (Filter != null && Filter.button.activeButton.State != RUIToggleButtonTyped.ButtonState.TRUE) - // Filter.button.activeButton.SetTrue(Filter.button.activeButton, RUIToggleButtonTyped.ClickType.FORCED); - } - catch (Exception e) - { - Log("Category refresh failed"); - Log(e.InnerException); - Log(e.StackTrace); - } - } - /// /// mark all subcategories that have identical filtering /// diff --git a/FilterExtension/Editor.cs b/FilterExtension/Editor.cs index e00a5a21..1a06c802 100644 --- a/FilterExtension/Editor.cs +++ b/FilterExtension/Editor.cs @@ -110,11 +110,47 @@ IEnumerator editorInit() yield return null; if (Settings.debug) Core.Log("Refreshing parts list"); - Core.setSelectedCategory(); + setSelectedCategory(); ready = true; } + /// + /// refresh the visible subcategories to ensure all changes are visible + /// + public static void setSelectedCategory() + { + //try + //{ + // PartCategorizer.Category Filter = PartCategorizer.Instance.filters.FirstOrDefault(f => f.button.activeButton.CurrentState == KSP.UI.UIRadioButton.State.True); + // if (Filter != null) + // Filter.button.activeButton.SetState(KSP.UI.UIRadioButton.State.False, KSP.UI.UIRadioButton.CallType.APPLICATIONSILENT, null); + + // Filter = PartCategorizer.Instance.filters.FirstOrDefault(f => f.button.categoryName == Settings.categoryDefault); + // if (Filter != null) + // Filter.button.activeButton.SetState(KSP.UI.UIRadioButton.State.True, KSP.UI.UIRadioButton.CallType.APPLICATIONSILENT, null); + // else + // { + // Filter = PartCategorizer.Instance.filters[0]; + // if (Filter != null) + // { + // Filter.button.activeButton.SetState(KSP.UI.UIRadioButton.State.True, KSP.UI.UIRadioButton.CallType.APPLICATIONSILENT, null); + // } + // } + + // // set the subcategory button + // //Filter = Filter.subcategories.FirstOrDefault(sC => sC.button.categoryName == instance.subCategoryDefault); + // //if (Filter != null && Filter.button.activeButton.State != RUIToggleButtonTyped.ButtonState.TRUE) + // // Filter.button.activeButton.SetTrue(Filter.button.activeButton, RUIToggleButtonTyped.ClickType.FORCED); + //} + //catch (Exception e) + //{ + // Core.Log("Category refresh failed"); + // Core.Log(e.InnerException); + // Core.Log(e.StackTrace); + //} + } + /// /// checks all subcats not created by FE for visibility of parts set to "category = none" /// diff --git a/FilterExtension/Utility/PartType.cs b/FilterExtension/Utility/PartType.cs index 1fc06a05..050d8a38 100644 --- a/FilterExtension/Utility/PartType.cs +++ b/FilterExtension/Utility/PartType.cs @@ -460,7 +460,7 @@ public static bool checkCrewCapacity(AvailablePart part, string[] value, ConfigN else // only compare against the first value here { if (value.Length > 1) - Core.Log("Size comparisons against multiple values when not using Equals only use the first value. Value list is: {0}", string.Join(", ", value)); + Core.Log("Crew comparisons against multiple values when not using Equals only use the first value. Value list is: {0}", string.Join(", ", value)); int i; if (int.TryParse(value[0], out i)) diff --git a/GameData/000_FilterExtensions Configs/StockRework/FilterbyFunction.cfg b/GameData/000_FilterExtensions Configs/StockRework/FilterbyFunction.cfg deleted file mode 100644 index f0b225ef..00000000 --- a/GameData/000_FilterExtensions Configs/StockRework/FilterbyFunction.cfg +++ /dev/null @@ -1,16 +0,0 @@ -@CATEGORY[Filter?by?Function] -{ - @SUBCATEGORIES - { - list = 0,Command and Crew - list = 1,Attitude Control - list = 2,Fuel Tanks - list = 3,Engines - list = 4,Structural - list = 5,General Aero - list = 6,Flight - list = 7,Misc - list = 8,Electrical - list = 9,Science - } -} \ No newline at end of file diff --git a/GameData/000_FilterExtensions Configs/StockRework/Subcategories.cfg b/GameData/000_FilterExtensions Configs/StockRework/Subcategories.cfg deleted file mode 100644 index f96d0338..00000000 --- a/GameData/000_FilterExtensions Configs/StockRework/Subcategories.cfg +++ /dev/null @@ -1,130 +0,0 @@ -SUBCATEGORY -{ - name = Command and Crew - icon = stockIcon_pods - FILTER - { - CHECK - { - type = category - value = Pods - } - } - FILTER - { - CHECK - { - type = crew - value = 0 - equality = GreaterThan - } - } -} -SUBCATEGORY -{ - name = Attitude Control - icon = stockIcon_cmdctrl - FILTER - { - CHECK - { - type = category - value = Command and Control - } - } - FILTER - { - CHECK - { - type = subcategory - value = Control Surface - } - } -} -SUBCATEGORY -{ - name = General Aero - icon = Fairing - FILTER - { - CHECK - { - type = category - value = Aerodynamics - } - CHECK - { - type = subcategory - value = Wings, Control Surface - invert = true - } - } - FILTER - { - CHECK - { - type = subcategory - value = Parachutes, Adapter, Cargo Bay - } - } -} -SUBCATEGORY -{ - name = Flight - icon = Wings - FILTER - { - CHECK - { - type = subcategory - value = Wings, Control Surface - } - } - FILTER - { - CHECK - { - type = moduleName - value = ModuleAeroSurface - } - } -} -SUBCATEGORY -{ - name = Misc - icon = stockIcon_utility - FILTER - { - CHECK - { - type = category - value = Utility - } - CHECK - { - type = subcategory - value = Generators, Lights, Power Storage, Solar Panels, Cargo Bay, Parachutes - invert = true - } - CHECK - { - type = crew - value = 0 - invert = true - equality = GreaterThan - } - } -} -SUBCATEGORY -{ - name = Electrical - icon = ElectricCharge - FILTER - { - CHECK - { - type = subcategory - value = Generators, Lights, Power Storage, Solar Panels - } - } -} \ No newline at end of file diff --git a/GameData/000_FilterExtensions/FilterExtensions.dll b/GameData/000_FilterExtensions/FilterExtensions.dll index 3666868f..79651feb 100644 Binary files a/GameData/000_FilterExtensions/FilterExtensions.dll and b/GameData/000_FilterExtensions/FilterExtensions.dll differ diff --git a/GameData/000_FilterExtensions/FilterExtensions.version b/GameData/000_FilterExtensions/FilterExtensions.version index bd5322ff..856ca297 100644 --- a/GameData/000_FilterExtensions/FilterExtensions.version +++ b/GameData/000_FilterExtensions/FilterExtensions.version @@ -1 +1 @@ -{"NAME":"Filter Extensions","URL":"https://github.com/Crzyrndm/FilterExtension/blob/master/GameData/000_FilterExtensions/FilterExtensions.version","DOWNLOAD":"https://github.com/Crzyrndm/FilterExtension/releases","VERSION":{"MAJOR":2,"MINOR":4,"PATCH":1,"BUILD":3},"KSP_VERSION":{"MAJOR":1,"MINOR":0,"PATCH":5}} \ No newline at end of file +{"NAME":"Filter Extensions","URL":"https://github.com/Crzyrndm/FilterExtension/blob/master/GameData/000_FilterExtensions/FilterExtensions.version","DOWNLOAD":"https://github.com/Crzyrndm/FilterExtension/releases","VERSION":{"MAJOR":2,"MINOR":4,"PATCH":2,"BUILD":0},"KSP_VERSION":{"MAJOR":1,"MINOR":1,"PATCH":0}} \ No newline at end of file