commit 0542e8be07ee5256baf62b222706546b596bec29 Author: cecil Date: Wed Nov 1 04:21:54 2017 -0400 Initial revision, sorts Kerbals in VAB and nowhere else diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..a21c48f --- /dev/null +++ b/.hgignore @@ -0,0 +1,2 @@ +Debug +Release \ No newline at end of file diff --git a/.vs/AlphabeticalKerbals/v14/.suo b/.vs/AlphabeticalKerbals/v14/.suo new file mode 100644 index 0000000..d4b7937 Binary files /dev/null and b/.vs/AlphabeticalKerbals/v14/.suo differ diff --git a/AlphabeticalKerbals.sln b/AlphabeticalKerbals.sln new file mode 100644 index 0000000..2edaf07 --- /dev/null +++ b/AlphabeticalKerbals.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AlphabeticalKerbals", "AlphabeticalKerbals\AlphabeticalKerbals.csproj", "{D01919EF-056F-4311-84AE-E4E686CA033D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D01919EF-056F-4311-84AE-E4E686CA033D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D01919EF-056F-4311-84AE-E4E686CA033D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D01919EF-056F-4311-84AE-E4E686CA033D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D01919EF-056F-4311-84AE-E4E686CA033D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/AlphabeticalKerbals/AlphabeticalKerbals.csproj b/AlphabeticalKerbals/AlphabeticalKerbals.csproj new file mode 100644 index 0000000..9cea05b --- /dev/null +++ b/AlphabeticalKerbals/AlphabeticalKerbals.csproj @@ -0,0 +1,65 @@ + + + + + Debug + AnyCPU + {D01919EF-056F-4311-84AE-E4E686CA033D} + Library + Properties + AlphabeticalKerbals + AlphabeticalKerbals + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\VMShared\KSP_1.3.1\Assembly-CSharp.dll + + + ..\..\..\..\VMShared\KSP_1.3.1\Assembly-CSharp-firstpass.dll + + + + + + + + + ..\..\..\..\VMShared\KSP_1.3.1\UnityEngine.dll + + + ..\..\..\..\VMShared\KSP_1.3.1\UnityEngine.UI.dll + + + + + + + + + + \ No newline at end of file diff --git a/AlphabeticalKerbals/KerbalSorter.cs b/AlphabeticalKerbals/KerbalSorter.cs new file mode 100644 index 0000000..5f8244b --- /dev/null +++ b/AlphabeticalKerbals/KerbalSorter.cs @@ -0,0 +1,193 @@ +using System; +using KSP; +using KSP.UI; +using UnityEngine; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace AlphabeticalKerbals +{ + class KerbalSorter + { + static void print(string s) { MonoBehaviour.print("AlphabeticalKerbals: " + s); } + static public bool Sort_Kerbals() + { + if (CrewAssignmentDialog.Instance == null) + { + print("OnEditorCrewOpened has no CrewAssignmentDialog yet..."); + } + else + { + UIList avail = CrewAssignmentDialog.Instance.scrollListAvail; + + UIList_QSort(avail, 0, avail.Count-1); + + for (int i = 0; i < avail.Count; i++) + { + UIListItem li = avail.GetUilistItemAt(i); + CrewListItem crew = li.GetComponent(); + print("AFTER SORT = " + crew.GetName()); + } + + return true; + + /* + print("AlphabeticalKerbals: OnEditorCrewOpened has CrewAssignmentDialog yay!!!"); + UIList avail = CrewAssignmentDialog.Instance.scrollListAvail; + UIListItem first = avail.GetUilistItemAt(0); + + print("AlphabeticalKerbals: Got first item in UIList"); + + if (first == null) + { + //happens on first load + print("AlphabeticalKerbals: Uhhh.... first is null?"); + } + if (first.gameObject == null) + { + print("AlphabeticalKerbals: Uhhh.... gameObject is null?"); + } + Component[] comps = first.gameObject.GetComponents(); + print("AlphabeticalKerbals: Uhhh.... got components???"); + for (int i = 0; i < comps.Length; ++i) + { + print($"Component {i}: {comps[i].GetType()}"); + } + + CrewListItem firstdata = first.GetComponent(); + print("AlphabeticalKerbals: Got a component for crew list item"); + print("AlphabeticalKerbals: Got crew name: " + firstdata.GetName()); + + print("AlphabeticalKerbals: Got component list"); + foreach (Component comp in firstdata) + { + print("AlphabeticalKerbals: Got a component"); + print("AlphabeticalKerbals: Component name is " + comp.name); + print("AlphabeticalKerbals: Component type is " + comp.GetType().Name); + print("AlphabeticalKerbals: Component string is " + comp.ToString()); + } + */ + + } + + + return false; + } + + /// + /// Return value positive means left > right, return value negative means left < right + /// + /// + /// + /// + static int UIList_Cmp(UIListItem left, UIListItem right) + { + if (left == null) { return 1; } // null values are considered greatest, so they are sorted at the end + if (right == null) { return -1; } // null values are considered greatest, so they are sorted at the end + + CrewListItem ldata = null; + CrewListItem rdata = null; + try { ldata = left.GetComponent(); } catch { return 1; } + try { rdata = right.GetComponent(); } catch { return -1; } + + if (ldata == null) { return 1; } + if (rdata == null) { return -1; } + + return ldata.GetName().CompareTo(rdata.GetName()); + } + + static int UIList_Partition(UIList list, int li, int ri) + { + // Select a random pivot point + int pi = UnityEngine.Random.Range(li+1, ri+1); + UIListItem pivot = list.GetUilistItemAt(pi); + print("Selected pivot is " + pivot.GetComponent().GetName() + " at pos " + pi.ToString()); + + if (pi < ri) + { + // Move the pivot to the very end + list.SwapItems(pivot, list.GetUilistItemAt(ri)); + pi = ri; + } + UIList_DebugPrint(list, li, ri, "Pivot-selection"); + + // Iterate over the list and sort above or below pivot as we go + int i = li; + UIListItem prev = list.GetUilistItemAt(i); + + for (int j = li; j < ri; j++) + { + UIListItem selected = list.GetUilistItemAt(j); + if (UIList_Cmp(selected, pivot) < 1) + { + print("Pivotname is " + pivot.GetComponent().GetName() + " selname is " + selected.GetComponent().GetName()); + UIList_DebugPrint(list, i, j, "Partition-swapping (" + i.ToString() + "," + j.ToString() + "," + UIList_Cmp(selected, pivot) + ")"); + if (i < j) + { + list.SwapItems(prev, selected); + } + UIList_DebugPrint(list, li, ri, "Afterswap i=" + i.ToString()); + i++; + prev = list.GetUilistItemAt(i); + } + } + + + UIListItem pivot_target = list.GetUilistItemAt(i); + if (UIList_Cmp(pivot_target, pivot) >= 0) + { + UIList_DebugPrint(list, li, ri, "Finalswap i=" + i.ToString()); + list.SwapItems(list.GetUilistItemAt(i), pivot); + UIList_DebugPrint(list, li, ri, "Finalswap done i=" + i.ToString()); + return i; + } + else + { + return ri; + } + + } + static void UIList_QSort(UIList list, int li, int ri) + { + + if (list == null || list.Count <= 1) + return; + + if (li < ri) + { + print("Before partition from " + li.ToString() + "-" + ri.ToString()); + UIList_DebugPrint(list, li, ri, "Initial"); + + int pi = UIList_Partition(list, li, ri); + + print ("After partition to pivot " + pi.ToString()); + UIList_DebugPrint(list, li, pi-1, "Left"); + UIList_DebugPrint(list, pi, pi, "Pivot"); + UIList_DebugPrint(list, pi+1, ri, "Right"); + + UIList_QSort(list, li, pi - 1); + UIList_QSort(list, pi + 1, ri); + } + + + } + + + static void UIList_DebugPrint(UIList list, int li, int ri, string msg) + { + string outmsg = msg + " -- "; + + for (int i = li; i < ri+1; i++) + { + UIListItem curitem = list.GetUilistItemAt(i); + CrewListItem crew = curitem.GetComponent(); + outmsg = outmsg + crew.GetName().Split(' ')[0] + "[" + i.ToString() + "], "; + } + + print(outmsg); + } + + + } +} diff --git a/AlphabeticalKerbals/Properties/AssemblyInfo.cs b/AlphabeticalKerbals/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..321111a --- /dev/null +++ b/AlphabeticalKerbals/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AlphabeticalKerbals")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("AlphabeticalKerbals")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("d01919ef-056f-4311-84ae-e4e686ca033d")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/AlphabeticalKerbals/SceneHooks.cs b/AlphabeticalKerbals/SceneHooks.cs new file mode 100644 index 0000000..d8f74c5 --- /dev/null +++ b/AlphabeticalKerbals/SceneHooks.cs @@ -0,0 +1,125 @@ +using System; +using KSP; +using KSP.UI; +using KSP.UI.Screens; +using UnityEngine; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace AlphabeticalKerbals +{ + + [KSPAddon(KSPAddon.Startup.EditorAny, false)] + public class AlphabetVAB : MonoBehaviour + { + public bool HasBeenSorted; + public EditorScreen CurrentEditorScreen; + private int sortAttempts; + + /// + /// Module initialization + /// + public void Start() + { + print("AlphabeticalKerbals: AlphabetVAB started!"); + } + + /// + /// Module startup + /// + public void Awake() + { + print("AlphabeticalKerbals: Registering VAB events"); + GameEvents.onEditorLoad.Add(OnShipLoaded); + GameEvents.onEditorScreenChange.Add(OnEditorScreenChange); + } + + + /// + /// Module shutdown + /// + public void OnDestroy() + { + print("AlphabeticalKerbals: Unregistering VAB events"); + GameEvents.onEditorLoad.Remove(OnShipLoaded); + GameEvents.onEditorScreenChange.Remove(OnEditorScreenChange); + } + + /// + /// Here when a ship is loaded in the editor. + /// + /// + /// + private void OnShipLoaded(ShipConstruct construct, CraftBrowserDialog.LoadType loadType) + { + try + { + CurrentEditorScreen = EditorScreen.Parts; + HasBeenSorted = false; + sortAttempts = 0; + } + catch (Exception e) + { + print("AlphabeticalKerbals: There was an error in OnShipLoaded"); + } + } + + /// + /// Here when Editor Panel is changed + /// + /// + private void OnEditorScreenChange(EditorScreen screen) + { + try + { + CurrentEditorScreen = screen; + HasBeenSorted = false; + sortAttempts = 0; + + if (screen == EditorScreen.Crew) + { + OnEditorCrewOpened(); + } + } + catch (Exception e) + { + print("AlphabeticalKerbals: There was an error in OnEditorScreenChange"); + } + } + + /// + /// Here when Editor Crew Panel is opened + /// + /// + /// + private void OnEditorCrewOpened() + { + try + { + if (KerbalSorter.Sort_Kerbals()) + { + print("AlphabeticalKerbals: CrewPanel Sorting successful!"); + HasBeenSorted = true; + } + } + catch (Exception e) + { + print("AlphabeticalKerbals: There was an error in OnEditorCrewOpened"); + } + } + + } + + + + [KSPAddon(KSPAddon.Startup.SpaceCentre, false)] + public class AlphabetSC : MonoBehaviour + { + public void Start() + { + print("AlphabeticalKerbals: AlphabetSC started!"); + } + + } +}