diff --git a/CHANGELOG.md b/CHANGELOG.md index b64bff91e..c7d7f81e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ ### Bug Fixes +- The name tag part module is now provided by the shared [KSPCommunityPartModules](https://github.com/KSPModdingLibs/KSPCommunityPartModules) mod, a new **required dependency**, instead of kOS shipping its own copy. kOS and kRPC previously each defined a `KOSNameTag` module, which KSP resolved by load order and could pick the wrong one (#829). Name tags on existing craft and saves are migrated automatically, so `part:TAG` keeps working. - Fixed numeric formatting patters (thanks @sisve) [commit](https://github.com/KSP-KOS/KOS/commit/5780b75ff90e238c441ab71d366391b051e8bd14) - Fixed many documentation issues (thanks @sisve) [commit1](https://github.com/KSP-KOS/KOS/commit/727d345679fe992077fa5604c27b43c34a80fbe7) [commit2](https://github.com/KSP-KOS/KOS/commit/afabb19e860adc67ad63f939a3d624e9344ad7b8) [commit3](https://github.com/KSP-KOS/KOS/commit/110b209ad89225bf447caa079334c434df0e9746) - Fixed `GetSignalDelayToSatellite` for RemoteTech (thanks @KerbalOne) [commit](https://github.com/KSP-KOS/KOS/commit/b76759f24ba43e7cb2d82437c2251caf7d3a582f) diff --git a/Resources/GameData/kOS/kOS-module-manager.cfg b/Resources/GameData/kOS/kOS-module-manager.cfg index 0c79e9bbd..b1c67143e 100644 --- a/Resources/GameData/kOS/kOS-module-manager.cfg +++ b/Resources/GameData/kOS/kOS-module-manager.cfg @@ -1,9 +1,12 @@ // -// ADD the KOSNameTag to all parts in the game. +// ADD the name tag module to all parts in the game. +// +// The ModuleNameTag part module is provided by KSPCommunityPartModules (a +// dependency of kOS); kOS just patches it onto every part. // // THE FOLLOWING EXPLANATION IS FOR ISSUE #2764 // -// The "[!KOSNameTag]" rule below attempted to prevent duplicates +// The "[!ModuleNameTag]" rule below attempted to prevent duplicates // in a part, but it doesn't entirely succeed at that in the // case of KerbalEVA parts if the installation has all the DLCs, // due to a wacky messy way SQUAD implemented the alternate @@ -15,17 +18,17 @@ // cause because they were two *different* parts when it was looking // at them. // -// Therefore there is extra code inside kOS's C# code to additionally -// enforce the "no more than one KOSNameTag" rule, in its OnAwake(). -// You *cannot* force more than one KOSNameTag to exist in a part -// no matter what you do in ModuleManager now, because KOSNameTag +// Therefore there is extra code inside ModuleNameTag's C# code to additionally +// enforce the "no more than one name tag" rule, in its OnAwake(). +// You *cannot* force more than one ModuleNameTag to exist in a part +// no matter what you do in ModuleManager now, because ModuleNameTag // itself refuses to allow it. // -@PART[*]:FOR[kOS]:HAS[!KOSNameTag] +@PART[*]:FOR[kOS]:HAS[!ModuleNameTag] { MODULE { - name = KOSNameTag + name = ModuleNameTag } } @@ -35,13 +38,13 @@ // going with it, it's saved here for reference to look at later should // we change our mind and want to go to this instead: // -// (In a nutshell, this removes the extra KOSNameTag PartModules from +// (In a nutshell, this removes the extra ModuleNameTag PartModules from // those specfic part definitions in the known specific DLC folders // that trigger this exact problem, rather than creating a generic // solution that says "there can be only one, ever"): // // @PART[kerbalEV*]:HAS[~name[*Future],@MODULE[ModuleScienceExperiment]:HAS[#experimentID[ROCScience]]]:AFTER[kOS] // { -// !MODULE[KOSNameTag]{} +// !MODULE[ModuleNameTag]{} // } // diff --git a/src/kOS/Module/KOSNameTag.cs b/src/kOS/Module/KOSNameTag.cs deleted file mode 100644 index 37234074f..000000000 --- a/src/kOS/Module/KOSNameTag.cs +++ /dev/null @@ -1,119 +0,0 @@ -using kOS.Screen; -using kOS.Suffixed; -using kOS.Safe.Utilities; -using UnityEngine; -using System; - -namespace kOS.Module -{ - public class KOSNameTag : PartModule - { - private const string PAWGroup = "kOS"; - - private KOSNameTagWindow typingWindow; - - [KSPField(isPersistant = true, - guiActive = true, - guiActiveEditor = true, - guiName = "name tag", - groupName = PAWGroup, - groupDisplayName = PAWGroup)] - public string nameTag = ""; - - [KSPEvent(guiActive = true, - guiActiveEditor = true, - guiName = "Change Name Tag", - groupName = PAWGroup, - groupDisplayName = PAWGroup)] - public void PopupNameTagChanger() - { - if (typingWindow != null) - typingWindow.Close(); - if (HighLogic.LoadedSceneIsEditor) - { - EditorFacility whichEditor = EditorLogic.fetch.ship.shipFacility; - if (!(Career.CanTagInEditor(whichEditor))) - { - var formattedString = string.Format("The {0} requires an upgrade to assign name tags", whichEditor); - ScreenMessages.PostScreenMessage(formattedString, 6, ScreenMessageStyle.UPPER_CENTER); - return; - } - } - // Make a new instance of typingWindow, replacing the existing one if there was one: - KOSNameTagWindow oldTypingWindow = gameObject.GetComponent(); - if (oldTypingWindow != null) - Destroy(oldTypingWindow); - typingWindow = gameObject.AddComponent(); - typingWindow.Invoke(this, nameTag); - } - - // For issue #2764, this enforces a rule that says regardless of what ModuleManager - // rules end up doing, there shall only ever be one KosNameTag per part: - public override void OnAwake() - { - // If other instances of me exist in this part, remove them. I am replacing them: - for (int i = part.Modules.Count - 1; i >= 0; --i) - { - PartModule pm = part.Modules[i]; - if (pm != this && pm is KOSNameTag) - { - SafeHouse.Logger.Log(string.Format( - "Removing duplicate KOSNameTag PartModule from {0}. KOS cannot deal with more than one tag per part.", part.name)); - part.RemoveModule(pm); - } - } - - // make this module cheaper in update loops - isEnabled = false; - enabled = false; - } - - public void TypingDone(string newValue) - { - nameTag = newValue; - TypingCancel(); - } - - public void TypingCancel() - { - typingWindow.Close(); - Destroy(typingWindow); - typingWindow = null; - } - } - - // setting isEnabled to false prevents the nametag from showing up in the PAW...work around that. - [KSPAddon(KSPAddon.Startup.FlightAndEditor, false)] - class KOSNameTagActivationManager : MonoBehaviour - { - void Awake() - { - GameEvents.onPartActionUICreate.Add(OnPartActionUICreate); - GameEvents.onPartActionUIShown.Add(OnPartActionUIShown); - } - - void OnDestroy() - { - GameEvents.onPartActionUICreate.Remove(OnPartActionUICreate); - GameEvents.onPartActionUIShown.Remove(OnPartActionUIShown); - } - - private void OnPartActionUICreate(Part part) - { - var nameTagModule = part.FindModuleImplementing(); - if (nameTagModule != null) - { - nameTagModule.isEnabled = true; - } - } - - private void OnPartActionUIShown(UIPartActionWindow paw, Part part) - { - var nameTagModule = part.FindModuleImplementing(); - if (nameTagModule != null) - { - nameTagModule.isEnabled = false; - } - } - } -} \ No newline at end of file diff --git a/src/kOS/Module/kOSProcessor.cs b/src/kOS/Module/kOSProcessor.cs index 68d02feb9..63864cffa 100644 --- a/src/kOS/Module/kOSProcessor.cs +++ b/src/kOS/Module/kOSProcessor.cs @@ -1,4 +1,5 @@ using kOS.Binding; +using KSPCommunityPartModules.Modules; using kOS.Callback; using kOS.Execution; using kOS.Communication; @@ -46,13 +47,13 @@ public string Tag { get { - KOSNameTag tag = part.Modules.OfType().FirstOrDefault(); + ModuleNameTag tag = part.Modules.OfType().FirstOrDefault(); return tag == null ? string.Empty : tag.nameTag; } set { - KOSNameTag tag = part.Modules.OfType().FirstOrDefault(); - // Really a null tag shouldn't ever happen. It would mean kOS is installed but KOSNameTag's aren't on all the things. + ModuleNameTag tag = part.Modules.OfType().FirstOrDefault(); + // Really a null tag shouldn't ever happen. It would mean kOS is installed but ModuleNameTag's aren't on all the things. // And that should only happen if someone has a bad ModuleManager config that's screwing with kOS. if (tag != null) tag.nameTag = value; diff --git a/src/kOS/Properties/AssemblyInfo.cs b/src/kOS/Properties/AssemblyInfo.cs index 85b84ccdb..ebcf11c12 100644 --- a/src/kOS/Properties/AssemblyInfo.cs +++ b/src/kOS/Properties/AssemblyInfo.cs @@ -13,4 +13,8 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("324da3fe-391b-421d-93b7-29499dcf9ef3")] -[assembly: KSPAssemblyDependency("kOS.Safe", 0, 0)] \ No newline at end of file +[assembly: KSPAssemblyDependency("kOS.Safe", 0, 0)] + +// The name-tag part module lives in KSPCommunityPartModules, so KSP must load that mod before kOS. +// This is a hard dependency: KSP refuses to load kOS unless it is present. +[assembly: KSPAssemblyDependency("KSPCommunityPartModules", 0, 5)] \ No newline at end of file diff --git a/src/kOS/Screen/KOSNameTagWindow.cs b/src/kOS/Screen/KOSNameTagWindow.cs deleted file mode 100644 index 2a6b462c2..000000000 --- a/src/kOS/Screen/KOSNameTagWindow.cs +++ /dev/null @@ -1,197 +0,0 @@ -using kOS.Utilities; -using UnityEngine; -using kOS.Module; -using System; - -namespace kOS.Screen -{ - public class KOSNameTagWindow : MonoBehaviour - { - private KOSNameTag attachedModule; - private Rect windowRect; - private string tagValue; - // ReSharper disable RedundantDefaultFieldInitializer - private bool wasFocusedOnce = false; // "explicit", not "redundant". - private int numberOfRepaints = 0; // "explicit", not "redundant". - private bool gameEventHooksExist = false; // "explicit", not "redundant". - private int myWindowId; // must be unique for Unity to not mash two nametag windows togehter. - - // ReSharper enable RedundantDefaultFieldInitializer - - public void Invoke(KOSNameTag module, string oldValue) - { - attachedModule = module; - tagValue = oldValue; - myWindowId = GetInstanceID(); // Use the Id of this MonoBehaviour to guarantee unique window ID. - - Vector3 screenPos = GetViewportPosFor(attachedModule.part.transform.position); - - // screenPos is in coords from 0 to 1, 0 to 1, not screen pixel coords. - // Transform it to pixel coords: - float xPixelPoint = screenPos.x * UnityEngine.Screen.width; - float yPixelPoint = (1-screenPos.y) * UnityEngine.Screen.height; - const float WINDOW_WIDTH = 200; - - // windowRect = new Rect(xPixelWindow, yPixelPoint, windowWidth, 130); - windowRect = new Rect(xPixelPoint, yPixelPoint, WINDOW_WIDTH, 130); - - // Please don't delete these. They're not being used, but that's because we haven't - // finished prettying up the interface with the tag line and so the coords aren't - // being made use of yet. But keep this in the code so I can remember how I did the math: - // -------------------------------------------------------------------------------------- - // bool drawOnLeft = (screenPos.x > 0.5f); - // float xPixelWindow = (drawOnLeft ? screenPos.x - 0.3f : screenPos.x + 0.2f) * UnityEngine.Screen.width; - // float tagLineWidth = (drawOnLeft) ? (xPixelPoint - xPixelWindow) : (xPixelWindow - xPixelPoint - windowWidth); - // tagLineRect = new Rect(xPixelPoint, yPixelPoint, tagLineWidth, 3); - // SafeHouse.Logger.Log("tagLineRect = " + tagLineRect ); - - SetEnabled(true); - - if (HighLogic.LoadedSceneIsEditor) - attachedModule.part.SetHighlight(false, false); - - } - - /// - /// Catch the event of the part disappearing, from crashing or - /// from unloading from distance or scene change, and ensure - /// the window closes if it was open when that happens: - /// - /// The callback is called for EVERY part - /// that ever goes away, so we have to check if it's the right one - public void GoAwayEventCallback(Part whichPartWentAway) - { - if (whichPartWentAway != attachedModule.part) - return; - - Close(); - } - - /// - /// If you try to set a Unity.Behaviour.enabled to false when it already IS false, - /// and Unity hasn't fully finished configuring the MonoBehaviour yet, the Property's - /// "set" code throws a null ref error. How lame is that? - /// That's why I wrapped every attempt to set enabled's value with this check, because KSP - /// tries running my hooks in this class before Unity's ready for them. - /// - private void SetEnabled(bool newVal) - { - // ReSharper disable once RedundantCheckBeforeAssignment - if (newVal != enabled) - enabled = newVal; - - if (enabled) - { - if (! gameEventHooksExist) - { - GameEvents.onPartDestroyed.Add(GoAwayEventCallback); - GameEvents.onPartDie.Add(GoAwayEventCallback); - gameEventHooksExist = true; - } - } - else - { - if (gameEventHooksExist) - { - GameEvents.onPartDestroyed.Remove(GoAwayEventCallback); - GameEvents.onPartDie.Remove(GoAwayEventCallback); - gameEventHooksExist = false; - } - } - } - - /// - /// Get the position in screen coordinates that the 3d world coordinates - /// project onto, abstracting the two different ways KSP has to access - /// the camera depending on view mode. - /// Returned coords are in a system where the screen viewport goes from - /// (0,0) to (1,1) and the Z coord is how far from the screen it is - /// (-Z means behind you). - /// - private Vector3 GetViewportPosFor( Vector3 v ) - { - return Utils.GetCurrentCamera().WorldToViewportPoint(v); - } - - public void OnGUI() - { - if (Event.current.type != EventType.Repaint) - ++numberOfRepaints; - - if (! enabled) - return; - if (HighLogic.LoadedSceneIsEditor) - EditorLogic.fetch.Lock(false, false, false, "KOSNameTagLock"); - - GUI.skin = HighLogic.Skin; - GUILayout.Window(myWindowId, windowRect, DrawWindow,"KOS nametag"); - - // Ensure that the first time the window is made, it gets keybaord focus, - // but allow the focus to leave the window after that: - // The reason for the "number of repaints" check is that OnGUI has to run - // through several initial passes before all the components are present, - // and if you call FocusControl on the first few passes, it has no effect. - if (numberOfRepaints >= 2 && ! wasFocusedOnce) - { - GUI.FocusControl("NameTagField"); - wasFocusedOnce = true; - } - } - - public void DrawWindow( int windowID ) - { - if (! enabled) - return; - - Event e = Event.current; - if (e.type == EventType.KeyDown) - { - if (e.keyCode == KeyCode.Return || - e.keyCode == KeyCode.KeypadEnter) - { - e.Use(); - attachedModule.TypingDone(tagValue); - Close(); - } - } - GUILayout.Label(attachedModule.part.name); - GUI.SetNextControlName("NameTagField"); - tagValue = GUILayout.TextField( tagValue, GUILayout.MinWidth(160f)); - - GUILayout.BeginHorizontal(); - if (GUILayout.Button("Cancel")) - { - e.Use(); - Close(); - } - if (GUILayout.Button("Accept")) - { - e.Use(); - attachedModule.TypingDone(tagValue); - Close(); - } - GUILayout.EndHorizontal(); - - // Before going any further, suppress any remaining unprocessed clicks - // so they don't end up causing the editor to detach parts: - if (e.type == EventType.MouseDown || e.type == EventType.MouseUp || e.type == EventType.MouseDrag) - e.Use(); - } - - public void Close() - { - if (HighLogic.LoadedSceneIsEditor) - EditorLogic.fetch.Unlock("KOSNameTagLock"); - - SetEnabled(false); - - if (HighLogic.LoadedSceneIsEditor) - attachedModule.part.SetHighlight(false, false); - } - - public void OnDestroy() - { - SetEnabled(false); - } - } -} \ No newline at end of file diff --git a/src/kOS/Screen/KOSToolbarWindow.cs b/src/kOS/Screen/KOSToolbarWindow.cs index 4e40f4bdc..fff1d9d56 100644 --- a/src/kOS/Screen/KOSToolbarWindow.cs +++ b/src/kOS/Screen/KOSToolbarWindow.cs @@ -1,4 +1,5 @@ using kOS.Module; +using KSPCommunityPartModules.Modules; using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Module; using kOS.Safe.Utilities; @@ -798,7 +799,7 @@ private void DrawPart(Part part) // So for the meantime let's use our own text label and leave it at that. - KOSNameTag partTag = part.Modules.OfType().FirstOrDefault(); + ModuleNameTag partTag = part.Modules.OfType().FirstOrDefault(); string labelText = String.Format("{0}\n({1})", part.partInfo.title.Split(' ')[0], // just the first word of the name, i.e "CX-4181" diff --git a/src/kOS/Screen/TermWindow.cs b/src/kOS/Screen/TermWindow.cs index a84233f2b..38c15812b 100644 --- a/src/kOS/Screen/TermWindow.cs +++ b/src/kOS/Screen/TermWindow.cs @@ -7,6 +7,7 @@ using kOS.Safe.Screen; using kOS.Safe.Encapsulation; using kOS.Module; +using KSPCommunityPartModules.Modules; using kOS.UserIO; using kOS.Safe.UserIO; using KSP.UI.Dialogs; @@ -1162,7 +1163,7 @@ internal void AttachTo(SharedObjects sharedObj) internal string CalcualteTitle() { - KOSNameTag partTag = shared.KSPPart.Modules.OfType().FirstOrDefault(); + ModuleNameTag partTag = shared.KSPPart.Modules.OfType().FirstOrDefault(); return String.Format("{0} CPU: {1} ({2})", shared.Vessel.vesselName, shared.KSPPart.partInfo.title.Split(' ')[0], // just the first word of the name, i.e "CX-4181" diff --git a/src/kOS/Suffixed/Career.cs b/src/kOS/Suffixed/Career.cs index a3fbff89b..c632f3527 100644 --- a/src/kOS/Suffixed/Career.cs +++ b/src/kOS/Suffixed/Career.cs @@ -123,49 +123,6 @@ public static BooleanValue CanDoActions() return CanDoActions(out dummy); } - /// - /// Detect whether we'll allow you to add a NameTag to a part during the editor. - /// You can always add one post-editor during flight, but during editing it will - /// depend on building level.
- /// NOTE: This method does NOT have an associated suffix because it is meant to be called - /// from inside the editor, when a script won't be running. - ///
- /// Pass in whether you are checking from the VAB or SPH. - /// returns a string describing what would need upgrading to change the answer. - /// true if it can. false if it cannot. - public static bool CanTagInEditor(EditorFacility whichEditor, out string reason) - { - float buildingLevel; - switch (whichEditor) - { - case EditorFacility.VAB: - reason = "vehicle assembly building"; - buildingLevel = ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.VehicleAssemblyBuilding); - break; - case EditorFacility.SPH: - reason = "space plane hangar"; - buildingLevel = ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.SpaceplaneHangar); - break; - default: - reason = "unknown editor building"; - return false; // not even sure how you could get here. - } - // We'll attach it to the same point where the game starts unlocking basic action groups: - return GameVariables.Instance.UnlockedActionGroupsStock(buildingLevel, false); - } - - /// - /// Same as CanTagInEditor, but without the 'reason' parameter. (This is a separate method - /// only because you can't default out parameters like 'out string reason' to make them optional.) - /// - /// true if you can. false if you cannot. - public static bool CanTagInEditor(EditorFacility whichEditor) - { - string dummy; - return CanTagInEditor(whichEditor, out dummy); - } - - public override string ToString() { return string.Format("{0} Career", base.ToString()); diff --git a/src/kOS/Suffixed/Part/PartValue.cs b/src/kOS/Suffixed/Part/PartValue.cs index 7d3b6a78b..39aacf750 100644 --- a/src/kOS/Suffixed/Part/PartValue.cs +++ b/src/kOS/Suffixed/Part/PartValue.cs @@ -1,4 +1,5 @@ using kOS.Module; +using KSPCommunityPartModules.Modules; using kOS.Safe.Encapsulation; using kOS.Safe.Encapsulation.Suffixes; using kOS.Safe.Exceptions; @@ -240,14 +241,14 @@ private PartModuleFields GetModuleIndex(ScalarValue moduleIndex) public StringValue GetTagName() // public because I picture this being a useful API method later { - KOSNameTag tagModule = Part.Modules.OfType().FirstOrDefault(); + ModuleNameTag tagModule = Part.Modules.OfType().FirstOrDefault(); return tagModule == null ? string.Empty : tagModule.nameTag; } private void SetTagName(StringValue value) { ThrowIfNotCPUVessel(); - KOSNameTag tagModule = Part.Modules.OfType().FirstOrDefault(); + ModuleNameTag tagModule = Part.Modules.OfType().FirstOrDefault(); if (tagModule != null) tagModule.nameTag = value; } @@ -397,7 +398,7 @@ public ListValue GetPartsTagged(StringValue tagName) { return PartValueFactory.Construct( DynamicFindPartsInBranch( - p => p.Modules.OfType().Any( + p => p.Modules.OfType().Any( tag => String.Equals(tag.nameTag, tagName, StringComparison.CurrentCultureIgnoreCase))), Shared); } @@ -406,7 +407,7 @@ public ListValue GetPartsTaggedPattern(StringValue tagPattern) Regex r = new Regex(tagPattern, RegexOptions.IgnoreCase); return PartValueFactory.Construct( DynamicFindPartsInBranch( - p => p.Modules.OfType().Any( + p => p.Modules.OfType().Any( tag => r.IsMatch(tag.nameTag))), Shared); } @@ -419,7 +420,7 @@ public ListValue GetPartsDubbed(StringValue searchTerm) StaticFindPartsInBranch(this.Part, p => String.Equals(p.partInfo.title, searchTerm, StringComparison.CurrentCultureIgnoreCase), kspParts); StaticFindPartsInBranch(this.Part, - p => p.Modules.OfType().Any(tag => String.Equals(tag.nameTag, searchTerm, StringComparison.CurrentCultureIgnoreCase)), + p => p.Modules.OfType().Any(tag => String.Equals(tag.nameTag, searchTerm, StringComparison.CurrentCultureIgnoreCase)), kspParts); // The "Distinct" operation is there because it's possible for someone to use a tag name that matches the part name. @@ -433,7 +434,7 @@ public ListValue GetPartsDubbedPattern(StringValue searchPattern) List kspParts = new List(); StaticFindPartsInBranch(this.Part, p => r.IsMatch(p.name), kspParts); StaticFindPartsInBranch(this.Part, p => r.IsMatch(p.partInfo.title), kspParts); - StaticFindPartsInBranch(this.Part, p => p.Modules.OfType().Any(tag => r.IsMatch(tag.nameTag)), kspParts); + StaticFindPartsInBranch(this.Part, p => p.Modules.OfType().Any(tag => r.IsMatch(tag.nameTag)), kspParts); // The "Distinct" operation is there because it's possible for someone to use a tag name that matches the part name. return PartValueFactory.Construct(kspParts.Distinct(), Shared); @@ -444,7 +445,7 @@ public ListValue GetPartsDubbedPattern(StringValue searchPattern) /// public ListValue GetAllTaggedParts() { - return PartValueFactory.Construct(DynamicFindPartsInBranch(p => p.Modules.OfType() + return PartValueFactory.Construct(DynamicFindPartsInBranch(p => p.Modules.OfType() .Any(tag => !String.Equals(tag.nameTag, "", StringComparison.CurrentCultureIgnoreCase))), Shared); } diff --git a/src/kOS/UserIO/TelnetWelcomeMenu.cs b/src/kOS/UserIO/TelnetWelcomeMenu.cs index d553ac560..b50e02d0e 100644 --- a/src/kOS/UserIO/TelnetWelcomeMenu.cs +++ b/src/kOS/UserIO/TelnetWelcomeMenu.cs @@ -6,6 +6,7 @@ using kOS.Safe.Utilities; using UnityEngine; using kOS.Module; +using KSPCommunityPartModules.Modules; using kOS.Safe.UserIO; using Math = System.Math; @@ -196,7 +197,7 @@ private void PrintCPUMenu() foreach (kOSProcessor kModule in availableCPUs) { Part thisPart = kModule.part; - KOSNameTag partTag = thisPart.Modules.OfType().FirstOrDefault(); + ModuleNameTag partTag = thisPart.Modules.OfType().FirstOrDefault(); string partLabel = String.Format("{0}({1})", thisPart.partInfo.title.Split(' ')[0], // just the first word of the name, i.e "CX-4181" ((partTag == null) ? "" : partTag.nameTag) diff --git a/src/kOS/kOS.csproj b/src/kOS/kOS.csproj index 3eef2cafe..73541c661 100644 --- a/src/kOS/kOS.csproj +++ b/src/kOS/kOS.csproj @@ -13,6 +13,10 @@ false + + false + KSPCommunityPartModules +