Skip to content
This repository has been archived by the owner on Sep 7, 2021. It is now read-only.

Commit

Permalink
v2.0 release
Browse files Browse the repository at this point in the history
  • Loading branch information
Crzyrndm committed Mar 18, 2015
1 parent eafa747 commit 1e3b856
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 92 deletions.
45 changes: 25 additions & 20 deletions FilterExtension/ConfigNodes/customCategory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class customCategory : IEquatable<customCategory>
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 List<string> subCategories { get; set; } // array of subcategories
public List<Check> template { get; set; } // Checks to add to every Filter in a category with the template tag

private static readonly List<string> categoryNames = new List<string> { "Pods", "Engines", "Fuel Tanks", "Command and Control", "Structural", "Aerodynamics", "Utility", "Science" };
Expand All @@ -39,8 +39,6 @@ public customCategory(ConfigNode node)
type = node.GetValue("type");
value = node.GetValue("value");

typeSwitch();

makeTemplate(node);

bool.TryParse(node.GetValue("all"), out tmp);
Expand All @@ -50,19 +48,21 @@ public customCategory(ConfigNode node)
if (subcategoryList != null)
{
string[] stringList = subcategoryList.GetValues();
subCategories = new string[1000];
string[] subs = new string[1000];
for (int i = 0; i < stringList.Length; i++)
{
string[] indexAndValue = stringList[i].Split(',');
if (indexAndValue.Length >= 2)
{
int index;
if (int.TryParse(indexAndValue[0], out index))
subCategories[index] = indexAndValue[1].Trim();
subs[index] = indexAndValue[1].Trim();
}
}
subCategories = subCategories.Distinct().ToArray(); // no duplicates and no gaps in a single line. Yay
subCategories = subs.Distinct().ToList(); // no duplicates and no gaps in a single line. Yay
}

typeSwitch();
}

public void initialise()
Expand All @@ -72,12 +72,11 @@ public void initialise()
Core.Log("Category name is null or empty");
return;
}
if (subCategories == null || subCategories.Length == 0)
if (!hasSubCategories())
{
Core.Log(categoryName + " has no subcategories");
return;
}

PartCategorizer.Category category;
if (!stockCategory)
{
Expand All @@ -100,15 +99,15 @@ public void initialise()
}
}

for (int i = 0; i < subCategories.Length; i++)
for (int i = 0; i < subCategories.Count; i++)
{
if (!string.IsNullOrEmpty(subCategories[i]) && Core.Instance.subCategoriesDict.ContainsKey(subCategories[i]))
{
if (Core.Instance.conflictsDict.ContainsKey(subCategories[i]))
{
List<string> conflicts = Core.Instance.conflictsDict[subCategories[i]].Intersect(subCategories).ToList();

if (conflicts.Any(c => Array.IndexOf(subCategories, c) < i))
if (conflicts.Any(c => subCategories.IndexOf(c) < i))
{
string conflictList = "";
foreach (string s in conflicts)
Expand Down Expand Up @@ -166,30 +165,36 @@ private void typeSwitch()
private void generateEngineTypes()
{
List<string> engines = new List<string>();
foreach (List<string> ls in Core.propellantCombos)
foreach (List<string> ls in Core.Instance.propellantCombos)
{
List<Check> checks = new List<Check>();
string props = "";
foreach (string s in ls)
{
if (props != "")
props += ",";

checks.Add(new Check("propellant", s));
props += s;
}
if (!Core.Instance.subCategoriesDict.ContainsKey(props))
{
checks.Add(new Check("propellant", props, true, false)); // exact match to propellant list. Nothing extra, nothing less
checks.Add(new Check("propellant", 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");
string name = props.Replace(',', '/');
string icon = props;
if (Core.Instance.proceduralNames.ContainsKey(name))
name = Core.Instance.proceduralNames[name];
if (Core.Instance.proceduralIcons.ContainsKey(name))
icon = Core.Instance.proceduralIcons[name];

if (!Core.Instance.subCategoriesDict.ContainsKey(name))
{
customSubCategory sC = new customSubCategory(name, icon);

Filter f = new Filter(false);
f.checks = checks;
sC.filters.Add(f);
Core.Instance.subCategoriesDict.Add(props, sC);
Core.Instance.subCategoriesDict.Add(name, sC);
}
engines.Add(props);
engines.Add(name);
}
subCategories.AddUniqueRange(engines);
}
Expand Down Expand Up @@ -236,7 +241,7 @@ public static Color convertToColor(string hex_ARGB)

public bool hasSubCategories()
{
return (this.subCategories != null && this.subCategories.Length > 0);
return (this.subCategories != null && this.subCategories.Any());
}

public override bool Equals(object obj)
Expand Down
142 changes: 90 additions & 52 deletions FilterExtension/Core.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,24 @@ public class Core : MonoBehaviour
private static Core instance;

// storing categories loaded at Main Menu for creation when entering SPH/VAB
internal List<customCategory> Categories = new List<customCategory>();
public List<customCategory> Categories = new List<customCategory>();
// storing all subCategory definitions for categories to reference
internal Dictionary<string, customSubCategory> subCategoriesDict = new Dictionary<string, customSubCategory>();
public Dictionary<string, customSubCategory> subCategoriesDict = new Dictionary<string, customSubCategory>();
// all subcategories with duplicated filters
public Dictionary<string, List<string>> conflictsDict = new Dictionary<string, List<string>>();

// renaming procedural stuff
public Dictionary<string, string> proceduralNames = new Dictionary<string, string>();
// icons for procedural stuff
public Dictionary<string, string> proceduralIcons = new Dictionary<string, string>();
// url for each part by internal name
public static Dictionary<string, string> partPathDict = new Dictionary<string, string>();
public Dictionary<string, string> partPathDict = new Dictionary<string, string>();
// entry for each unique combination of propellants
public static List<List<string>> propellantCombos = new List<List<string>>();
public List<List<string>> propellantCombos = new List<List<string>>();
// entry for each unique resource
public static List<string> resources = new List<string>();
public List<string> resources = new List<string>();

// Dictionary of icons created on entering the main menu
public static Dictionary<string, PartCategorizer.Icon> iconDict = new Dictionary<string, PartCategorizer.Icon>();
public Dictionary<string, PartCategorizer.Icon> iconDict = new Dictionary<string, PartCategorizer.Icon>();

// Config has options to disable the FbM replacement, and the default Category/SC and sort method
public KSP.IO.PluginConfiguration config;
Expand All @@ -46,43 +49,61 @@ public class Core : MonoBehaviour
void Awake()
{
instance = this;
Log("Version 2.0 alpha2");

DontDestroyOnLoad(this);
Log("Version 2.0");
config = KSP.IO.PluginConfiguration.CreateForType<Core>();
config.load();

// get the names and icons for the procedural categories
foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("PROCNAMES"))
{
string[] names = node.GetValues("name");
foreach (string s in names)
{
if (s.Split().Length >= 2)
{
string nameToReplace = s.Split(',')[0].Trim();
string newName = s.Split(',')[1].Trim();
if (!proceduralNames.ContainsKey(nameToReplace))
proceduralNames.Add(nameToReplace, newName);
}
}
}

foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("PROCICONS"))
{
string[] icons = node.GetValues("icon");
foreach (string s in icons)
{
if (s.Split().Length >= 2)
{
string categoryName = s.Split(',')[0].Trim();
string icon = s.Split(',')[1].Trim();
if (!proceduralIcons.ContainsKey(categoryName))
proceduralIcons.Add(categoryName, icon);
}
}
}

// generate the associations between parts and folders, create all the mod categories, get all propellant combinations,
getPartData();

// mod categories key: title, value: folder
// used for adding the folder check to subCategories
Dictionary<string, string> folderToCategoryDict = new Dictionary<string, string>();
// load all category configs
foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("CATEGORY"))
{
customCategory C = new customCategory(node);
if (Categories.Find(n => n.categoryName == C.categoryName) == null)
if (Categories.Find(n => n.categoryName == C.categoryName) == null && C.subCategories != null)
{
Categories.Add(C);
if (C.type == "mod" && C.value != null)
{
if (!folderToCategoryDict.ContainsKey(C.categoryName))
folderToCategoryDict.Add(C.categoryName, C.value.Trim());
}
}
}

//load all subCategory configs
foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("SUBCATEGORY"))
{
customSubCategory sC = new customSubCategory(node);
if (sC.hasFilters)
{
foreach (Filter f in sC.filters)
{
if (folderToCategoryDict.ContainsKey(sC.subCategoryTitle))
f.checks.Add(new Check("folder", folderToCategoryDict[sC.subCategoryTitle]));
}
if (sC.subCategoryTitle != null)
{
if (!subCategoriesDict.ContainsKey(sC.subCategoryTitle)) // if nothing else has the same title
Expand All @@ -93,40 +114,48 @@ void Awake()
}
}

foreach (string s in resources)
customCategory Cat = Categories.Find(C => C.categoryName == "Filter by Resource");
if (Cat != null)
{
// add spaces before each capital letter
string name = System.Text.RegularExpressions.Regex.Replace(s, @"\B([A-Z])", " $1");
if (name != null && !subCategoriesDict.ContainsKey(name))
foreach (string s in resources)
{
customSubCategory sC = new customSubCategory(name, "");
Check c = new Check("resource", s);
Filter f = new Filter(false);
f.checks.Add(c);
sC.filters.Add(f);
subCategoriesDict.Add(name, sC);
// add spaces before each capital letter
string name = System.Text.RegularExpressions.Regex.Replace(s, @"\B([A-Z])", " $1");
string icon = "";
if (proceduralNames.ContainsKey(name))
name = proceduralNames[name];
if (proceduralIcons.ContainsKey(name))
icon = proceduralIcons[name];
if (name != null && !subCategoriesDict.ContainsKey(name))
{
customSubCategory sC = new customSubCategory(name, icon);
Check c = new Check("resource", s);
Filter f = new Filter(false);
f.checks.Add(c);
sC.filters.Add(f);
subCategoriesDict.Add(name, sC);
}
Cat.subCategories.AddUnique(name);
}
}

foreach (customCategory C in Categories)
{// generating the "all parts in ..." subcategories
if (!C.all)
continue;

List<Filter> filterList = new List<Filter>();
foreach (string s in C.subCategories)
if (C.subCategories != null)
{
if (s != null && subCategoriesDict.ContainsKey(s))
filterList.AddUniqueRange(subCategoriesDict[s].filters);
foreach (string s in C.subCategories)
{
if (s != null && subCategoriesDict.ContainsKey(s))
filterList.AddUniqueRange(subCategoriesDict[s].filters);
}
}

customSubCategory newSub = new customSubCategory("All parts in " + C.categoryName, C.iconName);
newSub.filters = filterList;
subCategoriesDict.Add(newSub.subCategoryTitle, newSub);

List<string> subCategories = new List<string>() { newSub.subCategoryTitle };
subCategories.AddUniqueRange(C.subCategories);
C.subCategories = subCategories.ToArray();
C.subCategories.Insert(0, newSub.subCategoryTitle);
}
loadIcons();
checkAndMarkConflicts();
Expand Down Expand Up @@ -199,11 +228,20 @@ private void processFilterByManufacturer(List<string> modNames)
{
customCategory fbm = Categories.FirstOrDefault(C => C.categoryName == "Filter by Manufacturer");
// define the mod subcategories
List<string> subCatNames = new List<string>();
for (int i = 0; i < modNames.Count; i++)
{
string name = modNames[i];
string icon = modNames[i];
if (proceduralNames.ContainsKey(name))
name = proceduralNames[name];
if (proceduralIcons.ContainsKey(name))
icon = proceduralIcons[name];

Check ch = new Check("folder", modNames[i]);
Filter f = new Filter(false);
customSubCategory sC = new customSubCategory(modNames[i], modNames[i]);
customSubCategory sC = new customSubCategory(name, icon);
subCatNames.Add(name);

f.checks.Add(ch);
sC.filters.Add(f);
Expand All @@ -215,8 +253,8 @@ private void processFilterByManufacturer(List<string> modNames)
if (fbm == null)
{
ConfigNode manufacturerSubs = new ConfigNode("SUBCATEGORIES");
for (int i = 0; i < modNames.Count; i++)
manufacturerSubs.AddValue("list", i.ToString() + "," + modNames[i]);
for (int i = 0; i < subCatNames.Count; i++)
manufacturerSubs.AddValue("list", i.ToString() + "," + subCatNames[i]);

ConfigNode filterByManufacturer = new ConfigNode("CATEGORY");
filterByManufacturer.AddValue("name", "Filter by Manufacturer");
Expand Down Expand Up @@ -376,10 +414,10 @@ private static void loadIcons()
selectedTex = t.texture;

string name = t.name.Split(new char[] { '/', '\\' }).Last();
if (iconDict.ContainsKey(name))
if (Instance.iconDict.ContainsKey(name))
{
int i = 1;
while (iconDict.ContainsKey(name + i.ToString()) && i < 1000)
while (Instance.iconDict.ContainsKey(name + i.ToString()) && i < 1000)
i++;
if (i != 1000)
name = name + i.ToString();
Expand All @@ -389,17 +427,17 @@ private static void loadIcons()
PartCategorizer.Icon icon = new PartCategorizer.Icon(name, t.texture, selectedTex, false);

// shouldn't be neccesary to check, but just in case...
if (!iconDict.ContainsKey(icon.name))
iconDict.Add(icon.name, icon);
if (!Instance.iconDict.ContainsKey(icon.name))
Instance.iconDict.Add(icon.name, icon);
}
}

public static PartCategorizer.Icon getIcon(string name)
{
if (string.IsNullOrEmpty(name))
return null;
if (iconDict.ContainsKey(name))
return iconDict[name];
if (Instance.iconDict.ContainsKey(name))
return Instance.iconDict[name];
if (PartCategorizer.Instance.iconDictionary.ContainsKey(name))
return PartCategorizer.Instance.iconDictionary[name];
return null;
Expand Down
4 changes: 3 additions & 1 deletion FilterExtension/Editor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ IEnumerator editorInit()
foreach (PartCategorizer.Category C in PartCategorizer.Instance.filters)
{
customCategory cat = Core.Instance.Categories.FirstOrDefault(c => c.categoryName == C.button.categoryName);
if (cat != null && cat.hasSubCategories() && cat.stockCategory)
if (cat == null)
continue;
if (cat.hasSubCategories() && cat.stockCategory)
{
if (cat.behaviour == categoryTypeAndBehaviour.StockReplace)
C.subcategories.Clear();
Expand Down
Loading

0 comments on commit 1e3b856

Please sign in to comment.