From 0428b116719d746bba6bb8b1f275b773157e8f4f Mon Sep 17 00:00:00 2001 From: "schlosrat@gmail.com" Date: Sat, 15 Apr 2023 18:31:35 -0400 Subject: [PATCH 01/26] Updated to align with the SW 1.1.1 template. This necessitated changes in the csproj as well as the swinfo files, removal of AssemblyInfo.cs, and relocation of both the icon and swinfo file. In it's current form the post-event build (defined in csproj) will copy the file to the (hard coded) location for my KSP2 game folder. This is the only place a hard coded folder directory appears now. Added game input blocking when the user clicks in a text field. --- LazyOrbit/LazyOrbit.cs | 82 +++- LazyOrbit/LazyOrbit.csproj | 116 ++--- LazyOrbit/Properties/AssemblyInfo.cs | 36 -- .../BepInEx/plugins/LazyOrbit/swinfo.json | 13 - .../assets/images/icon.png | Bin lazy_orbit/swinfo.json | 22 + license.txt | 427 ++++++++++++++++++ 7 files changed, 554 insertions(+), 142 deletions(-) delete mode 100644 LazyOrbit/Properties/AssemblyInfo.cs delete mode 100644 LazyOrbitBuild/BepInEx/plugins/LazyOrbit/swinfo.json rename {LazyOrbitBuild/BepInEx/plugins/LazyOrbit => lazy_orbit}/assets/images/icon.png (100%) create mode 100644 lazy_orbit/swinfo.json create mode 100644 license.txt diff --git a/LazyOrbit/LazyOrbit.cs b/LazyOrbit/LazyOrbit.cs index 78e6e07..37f9253 100644 --- a/LazyOrbit/LazyOrbit.cs +++ b/LazyOrbit/LazyOrbit.cs @@ -23,14 +23,17 @@ namespace LazyOrbit { - [BepInDependency(SpaceWarpPlugin.ModGuid,SpaceWarpPlugin.ModVer)] - [BepInPlugin(ModGuid, ModName, ModVer)] + [BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)] + [BepInDependency(SpaceWarpPlugin.ModGuid, SpaceWarpPlugin.ModVer)] public class LazyOrbit : BaseSpaceWarpPlugin { - public const string ModGuid = "com.github.halbann.lazyorbit"; - public const string ModName = "Lazy Orbit"; + // public const string ModGuid = "com.github.halbann.lazyorbit"; + // public const string ModName = "Lazy Orbit"; public const string ModVer = MyPluginInfo.PLUGIN_VERSION; - + // These are useful in case some other mod wants to add a dependency to this one + public const string ModGuid = MyPluginInfo.PLUGIN_GUID; + public const string ModName = MyPluginInfo.PLUGIN_NAME; + // public const string ModVer = MyPluginInfo.PLUGIN_VERSION; #region Fields // Main. @@ -52,11 +55,16 @@ public class LazyOrbit : BaseSpaceWarpPlugin private Rect windowRect; private int windowWidth = 500; private int windowHeight = 700; - private static GUIStyle boxStyle, errorStyle, warnStyle, peStyle, apStyle; + private static GUIStyle boxStyle, errorStyle, warnStyle, peStyle, apStyle, labelStyle; private static Vector2 scrollPositionBodies; private static Vector2 scrollPositionVessels; private static Color labelColor; private static GameState[] validScenes = new[] { GameState.FlightView, GameState.Map3DView }; + private int spacingAfterEntry = -5; + + // Control click through to the game + private bool gameInputState = true; + public List inputFields = new List(); private static bool ValidScene => validScenes.Contains(GameManager.Instance.Game.GlobalGameState.GetState()); @@ -134,6 +142,8 @@ public override void OnInitialized() interfaceMode = GetDefaultMode(); + Logger.LogInfo($"Lazy Orbit: SpaceWarpMetadata.ModID = {SpaceWarpMetadata.ModID}"); + Appbar.RegisterAppButton( "Lazy Orbit", "BTN-LazyOrbitButton", @@ -154,6 +164,11 @@ void Update() void OnGUI() { + //GUIenabled = false; + //var gameState = Game?.GlobalGameState?.GetState(); + //if (gameState == GameState.Map3DView) GUIenabled = true; + //if (gameState == GameState.FlightView) GUIenabled = true; + if (drawUI && ValidScene) { if (!guiLoaded) @@ -168,6 +183,39 @@ void OnGUI() "// LAZY ORBIT", GUILayout.Height(0), GUILayout.Width(350)); + + if (gameInputState && inputFields.Contains(GUI.GetNameOfFocusedControl())) + { + // Logger.LogDebug($"OnGUI: Disabling Game Input: Focused Item '{GUI.GetNameOfFocusedControl()}'"); + gameInputState = false; + GameManager.Instance.Game.Input.Disable(); + } + else if (!gameInputState && !inputFields.Contains(GUI.GetNameOfFocusedControl())) + { + // Logger.LogDebug($"OnGUI: Enabling Game Input: FYI, Focused Item '{GUI.GetNameOfFocusedControl()}'"); + gameInputState = true; + GameManager.Instance.Game.Input.Enable(); + } + //if (selectingBody) + //{ + // // Do something here to disable mouse wheel control of zoom in and out. + // // Intent: allow player to scroll in the scroll view without causing the game to zoom in and out + // GameManager.Instance._game.MouseManager.enabled = false; + //} + //else + //{ + // // Do something here to re-enable mouse wheel control of zoom in and out. + // GameManager.Instance._game.MouseManager.enabled = true; + //} + } + else + { + if (!gameInputState) + { + // Logger.LogDebug($"OnGUI: Enabling Game Input due to GUI disabled: FYI, Focused Item '{GUI.GetNameOfFocusedControl()}'"); + gameInputState = true; + GameManager.Instance.Game.Input.Enable(); + } } } @@ -187,6 +235,7 @@ private void GetStyles() return; boxStyle = GUI.skin.GetStyle("Box"); + labelStyle = new GUIStyle(GUI.skin.GetStyle("Label")); errorStyle = new GUIStyle(GUI.skin.GetStyle("Label")); warnStyle = new GUIStyle(GUI.skin.GetStyle("Label")); apStyle = new GUIStyle(GUI.skin.GetStyle("Label")); @@ -209,7 +258,11 @@ private void FillWindow(int windowID) } if (GUI.Button(new Rect(windowRect.width - 18, 2, 16, 16), "x")) + { + Logger.LogDebug("FillWindow: Restoring Game Input on window close."); + GameManager.Instance.Game.Input.Enable(); ToggleButton(false); + } GUILayout.BeginVertical(); @@ -232,6 +285,18 @@ private void FillWindow(int windowID) break; } + // Indication to User that its safe to type, or why vessel controls aren't working + GUILayout.BeginHorizontal(); + string inputStateString = gameInputState ? "Enabled" : "Disabled"; + GUILayout.Label("Game Input: ", labelStyle); + if (gameInputState) + GUILayout.Label(inputStateString, labelStyle); + else + GUILayout.Label(inputStateString, warnStyle); + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + GUILayout.Space(spacingAfterEntry); + GUILayout.EndVertical(); GUI.DragWindow(new Rect(0, 0, 10000, 500)); } @@ -374,11 +439,16 @@ void BodySelectionGUI() void TextField(string label, ref string field, ref float number, ref bool success) { + // Setup the list of input field names (most are the same as the entry string text displayed in the GUI window) + if (!inputFields.Contains(label)) + inputFields.Add(label); + GUILayout.BeginHorizontal(); GUILayout.Label(label, GUILayout.Width(windowWidth / 2)); bool parsed = float.TryParse(field, out number); if (!parsed) GUI.color = Color.red; + GUI.SetNextControlName(label); field = GUILayout.TextField(field); GUI.color = Color.white; diff --git a/LazyOrbit/LazyOrbit.csproj b/LazyOrbit/LazyOrbit.csproj index fc1f860..b462a5c 100644 --- a/LazyOrbit/LazyOrbit.csproj +++ b/LazyOrbit/LazyOrbit.csproj @@ -1,95 +1,37 @@  - - + - Debug - AnyCPU - {C0BDE81C-46FF-40A1-B3A1-07E40830115C} - Library - Properties - LazyOrbit - LazyOrbit - v4.8 - 512 - true + netstandard2.0 + true + latest + true + com.github.halbann.lazy_orbit + Lazy Orbit + A GUI for teleporting to orbit, keybind is ALT+H. 0.4.0 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 + + https://nuget.spacewarp.org/v3/index.json + + LazyOrbit + lazy_orbit - G:\Games\Steam Library\steamapps\common\Kerbal Space Program 2\KSP2_x64_Data\Managed\Assembly-CSharp.dll - False - - - G:\Games\Steam Library\steamapps\common\Kerbal Space Program 2\BepInEx\core\BepInEx.dll - False - - - G:\Games\Steam Library\steamapps\common\Kerbal Space Program 2\KSP2_x64_Data\Managed\Newtonsoft.Json.dll - False - - - False - G:\Games\Steam Library\steamapps\common\Kerbal Space Program 2\BepInEx\plugins\SpaceWarp\SpaceWarp.dll - False - - - - - - - - - - - G:\Games\Steam Library\steamapps\common\Kerbal Space Program 2\KSP2_x64_Data\Managed\UnityEngine.dll - False - - - G:\Games\Steam Library\steamapps\common\Kerbal Space Program 2\KSP2_x64_Data\Managed\UnityEngine.CoreModule.dll - False - - - G:\Games\Steam Library\steamapps\common\Kerbal Space Program 2\KSP2_x64_Data\Managed\UnityEngine.IMGUIModule.dll - False - - - G:\Games\Steam Library\steamapps\common\Kerbal Space Program 2\KSP2_x64_Data\Managed\UnityEngine.InputLegacyModule.dll - False + ..\external_dlls\Assembly-CSharp.dll + true + false - - - - - - - -"$(ProjectDir)pdb2mdb\pdb2mdb.exe" "$(TargetPath)" - -SET KSP2=G:\Games\Steam Library\steamapps\common\Kerbal Space Program 2 - -copy /Y "$(TargetDir)$(ProjectName).dll" "%25KSP2%25\BepInEx\plugins\LazyOrbit\$(ProjectName).dll" -copy /Y "$(TargetDir)$(Targetname).pdb" "%25KSP2%25\BepInEx\plugins\LazyOrbit\" -copy /Y "$(TargetDir)$(Targetname).dll.mdb" "%25KSP2%25\BepInEx\plugins\LazyOrbit\" - -copy /Y "$(TargetDir)$(ProjectName).dll" "$(SolutionDir)\LazyOrbitBuild\BepInEx\plugins\LazyOrbit\$(ProjectName).dll" -copy /Y "$(SolutionDir)\README.md" "$(SolutionDir)\LazyOrbitBuild\BepInEx\plugins\LazyOrbit\readme.txt" - - \ No newline at end of file + + + + + + + + + + + + + diff --git a/LazyOrbit/Properties/AssemblyInfo.cs b/LazyOrbit/Properties/AssemblyInfo.cs deleted file mode 100644 index 6775fd9..0000000 --- a/LazyOrbit/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -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("LazyOrbit")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("LazyOrbit")] -[assembly: AssemblyCopyright("Copyright © 2023")] -[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("c0bde81c-46ff-40a1-b3a1-07e40830115c")] - -// 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/LazyOrbitBuild/BepInEx/plugins/LazyOrbit/swinfo.json b/LazyOrbitBuild/BepInEx/plugins/LazyOrbit/swinfo.json deleted file mode 100644 index 04db382..0000000 --- a/LazyOrbitBuild/BepInEx/plugins/LazyOrbit/swinfo.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "mod_id": "LazyOrbit", - "name": "Lazy Orbit", - "author": "Halban, XYZ3211", - "description": "A GUI for teleporting to orbit, keybind is ALT+H.", - "source": "https://github.com/Halbann/LazyOrbit", - "version": "v0.4.0", - "dependencies": [], - "ksp2_version": { - "min": "0", - "max": "1" - } -} \ No newline at end of file diff --git a/LazyOrbitBuild/BepInEx/plugins/LazyOrbit/assets/images/icon.png b/lazy_orbit/assets/images/icon.png similarity index 100% rename from LazyOrbitBuild/BepInEx/plugins/LazyOrbit/assets/images/icon.png rename to lazy_orbit/assets/images/icon.png diff --git a/lazy_orbit/swinfo.json b/lazy_orbit/swinfo.json new file mode 100644 index 0000000..469e29c --- /dev/null +++ b/lazy_orbit/swinfo.json @@ -0,0 +1,22 @@ +{ + "mod_id": "lazy_orbit", + "name": "Lazy Orbit", + "author": "Halban, XYZ3211, schlosrat", + "description": "A GUI for teleporting to orbit, keybind is ALT+H.", + "source": "https://github.com/Halbann/LazyOrbit", + "version": "v0.4.0", + "version_check": "", + "dependencies": [ + { + "id": "SpaceWarp", + "version": { + "min": "1.0.1", + "max": "*" + } + } + ], + "ksp2_version": { + "min": "0.1.1", + "max": "*" + } +} \ No newline at end of file diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..2c66ec6 --- /dev/null +++ b/license.txt @@ -0,0 +1,427 @@ +Attribution-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-ShareAlike 4.0 International Public +License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-ShareAlike 4.0 International Public License ("Public +License"). To the extent this Public License may be interpreted as a +contract, You are granted the Licensed Rights in consideration of Your +acceptance of these terms and conditions, and the Licensor grants You +such rights in consideration of benefits the Licensor receives from +making the Licensed Material available under these terms and +conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + l. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + m. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + including for purposes of Section 3(b); and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. \ No newline at end of file From 4f3c4b0753418a6c176a6367f58f37c531487355 Mon Sep 17 00:00:00 2001 From: "schlosrat@gmail.com" Date: Sat, 15 Apr 2023 18:33:28 -0400 Subject: [PATCH 02/26] Updated for v 0.5.0 --- LazyOrbit/LazyOrbit.csproj | 2 +- lazy_orbit/swinfo.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LazyOrbit/LazyOrbit.csproj b/LazyOrbit/LazyOrbit.csproj index b462a5c..43c42a0 100644 --- a/LazyOrbit/LazyOrbit.csproj +++ b/LazyOrbit/LazyOrbit.csproj @@ -8,7 +8,7 @@ com.github.halbann.lazy_orbit Lazy Orbit A GUI for teleporting to orbit, keybind is ALT+H. - 0.4.0 + 0.5.0 https://nuget.spacewarp.org/v3/index.json diff --git a/lazy_orbit/swinfo.json b/lazy_orbit/swinfo.json index 469e29c..33aa93c 100644 --- a/lazy_orbit/swinfo.json +++ b/lazy_orbit/swinfo.json @@ -4,7 +4,7 @@ "author": "Halban, XYZ3211, schlosrat", "description": "A GUI for teleporting to orbit, keybind is ALT+H.", "source": "https://github.com/Halbann/LazyOrbit", - "version": "v0.4.0", + "version": "v0.5.0", "version_check": "", "dependencies": [ { From 7d77e6ced2fc9b307168dc8a37da735633802883 Mon Sep 17 00:00:00 2001 From: "schlosrat@gmail.com" Date: Sat, 15 Apr 2023 18:38:03 -0400 Subject: [PATCH 03/26] Removed deprecated LazyOrbitBuild folder. Releases now go intot he Release folder and Debug builds go into the Debug folder. The zip file should be attached to the GitHub release and not held in the repo itself like code is. --- .../BepInEx/plugins/LazyOrbit/license.txt | 427 ------------------ LazyOrbitBuild/LazyOrbit-v0.4.0.zip | Bin 16026 -> 0 bytes 2 files changed, 427 deletions(-) delete mode 100644 LazyOrbitBuild/BepInEx/plugins/LazyOrbit/license.txt delete mode 100644 LazyOrbitBuild/LazyOrbit-v0.4.0.zip diff --git a/LazyOrbitBuild/BepInEx/plugins/LazyOrbit/license.txt b/LazyOrbitBuild/BepInEx/plugins/LazyOrbit/license.txt deleted file mode 100644 index 2c66ec6..0000000 --- a/LazyOrbitBuild/BepInEx/plugins/LazyOrbit/license.txt +++ /dev/null @@ -1,427 +0,0 @@ -Attribution-ShareAlike 4.0 International - -======================================================================= - -Creative Commons Corporation ("Creative Commons") is not a law firm and -does not provide legal services or legal advice. Distribution of -Creative Commons public licenses does not create a lawyer-client or -other relationship. Creative Commons makes its licenses and related -information available on an "as-is" basis. Creative Commons gives no -warranties regarding its licenses, any material licensed under their -terms and conditions, or any related information. Creative Commons -disclaims all liability for damages resulting from their use to the -fullest extent possible. - -Using Creative Commons Public Licenses - -Creative Commons public licenses provide a standard set of terms and -conditions that creators and other rights holders may use to share -original works of authorship and other material subject to copyright -and certain other rights specified in the public license below. The -following considerations are for informational purposes only, are not -exhaustive, and do not form part of our licenses. - - Considerations for licensors: Our public licenses are - intended for use by those authorized to give the public - permission to use material in ways otherwise restricted by - copyright and certain other rights. Our licenses are - irrevocable. Licensors should read and understand the terms - and conditions of the license they choose before applying it. - Licensors should also secure all rights necessary before - applying our licenses so that the public can reuse the - material as expected. Licensors should clearly mark any - material not subject to the license. This includes other CC- - licensed material, or material used under an exception or - limitation to copyright. More considerations for licensors: - wiki.creativecommons.org/Considerations_for_licensors - - Considerations for the public: By using one of our public - licenses, a licensor grants the public permission to use the - licensed material under specified terms and conditions. If - the licensor's permission is not necessary for any reason--for - example, because of any applicable exception or limitation to - copyright--then that use is not regulated by the license. Our - licenses grant only permissions under copyright and certain - other rights that a licensor has authority to grant. Use of - the licensed material may still be restricted for other - reasons, including because others have copyright or other - rights in the material. A licensor may make special requests, - such as asking that all changes be marked or described. - Although not required by our licenses, you are encouraged to - respect those requests where reasonable. More considerations - for the public: - wiki.creativecommons.org/Considerations_for_licensees - -======================================================================= - -Creative Commons Attribution-ShareAlike 4.0 International Public -License - -By exercising the Licensed Rights (defined below), You accept and agree -to be bound by the terms and conditions of this Creative Commons -Attribution-ShareAlike 4.0 International Public License ("Public -License"). To the extent this Public License may be interpreted as a -contract, You are granted the Licensed Rights in consideration of Your -acceptance of these terms and conditions, and the Licensor grants You -such rights in consideration of benefits the Licensor receives from -making the Licensed Material available under these terms and -conditions. - - -Section 1 -- Definitions. - - a. Adapted Material means material subject to Copyright and Similar - Rights that is derived from or based upon the Licensed Material - and in which the Licensed Material is translated, altered, - arranged, transformed, or otherwise modified in a manner requiring - permission under the Copyright and Similar Rights held by the - Licensor. For purposes of this Public License, where the Licensed - Material is a musical work, performance, or sound recording, - Adapted Material is always produced where the Licensed Material is - synched in timed relation with a moving image. - - b. Adapter's License means the license You apply to Your Copyright - and Similar Rights in Your contributions to Adapted Material in - accordance with the terms and conditions of this Public License. - - c. BY-SA Compatible License means a license listed at - creativecommons.org/compatiblelicenses, approved by Creative - Commons as essentially the equivalent of this Public License. - - d. Copyright and Similar Rights means copyright and/or similar rights - closely related to copyright including, without limitation, - performance, broadcast, sound recording, and Sui Generis Database - Rights, without regard to how the rights are labeled or - categorized. For purposes of this Public License, the rights - specified in Section 2(b)(1)-(2) are not Copyright and Similar - Rights. - - e. Effective Technological Measures means those measures that, in the - absence of proper authority, may not be circumvented under laws - fulfilling obligations under Article 11 of the WIPO Copyright - Treaty adopted on December 20, 1996, and/or similar international - agreements. - - f. Exceptions and Limitations means fair use, fair dealing, and/or - any other exception or limitation to Copyright and Similar Rights - that applies to Your use of the Licensed Material. - - g. License Elements means the license attributes listed in the name - of a Creative Commons Public License. The License Elements of this - Public License are Attribution and ShareAlike. - - h. Licensed Material means the artistic or literary work, database, - or other material to which the Licensor applied this Public - License. - - i. Licensed Rights means the rights granted to You subject to the - terms and conditions of this Public License, which are limited to - all Copyright and Similar Rights that apply to Your use of the - Licensed Material and that the Licensor has authority to license. - - j. Licensor means the individual(s) or entity(ies) granting rights - under this Public License. - - k. Share means to provide material to the public by any means or - process that requires permission under the Licensed Rights, such - as reproduction, public display, public performance, distribution, - dissemination, communication, or importation, and to make material - available to the public including in ways that members of the - public may access the material from a place and at a time - individually chosen by them. - - l. Sui Generis Database Rights means rights other than copyright - resulting from Directive 96/9/EC of the European Parliament and of - the Council of 11 March 1996 on the legal protection of databases, - as amended and/or succeeded, as well as other essentially - equivalent rights anywhere in the world. - - m. You means the individual or entity exercising the Licensed Rights - under this Public License. Your has a corresponding meaning. - - -Section 2 -- Scope. - - a. License grant. - - 1. Subject to the terms and conditions of this Public License, - the Licensor hereby grants You a worldwide, royalty-free, - non-sublicensable, non-exclusive, irrevocable license to - exercise the Licensed Rights in the Licensed Material to: - - a. reproduce and Share the Licensed Material, in whole or - in part; and - - b. produce, reproduce, and Share Adapted Material. - - 2. Exceptions and Limitations. For the avoidance of doubt, where - Exceptions and Limitations apply to Your use, this Public - License does not apply, and You do not need to comply with - its terms and conditions. - - 3. Term. The term of this Public License is specified in Section - 6(a). - - 4. Media and formats; technical modifications allowed. The - Licensor authorizes You to exercise the Licensed Rights in - all media and formats whether now known or hereafter created, - and to make technical modifications necessary to do so. The - Licensor waives and/or agrees not to assert any right or - authority to forbid You from making technical modifications - necessary to exercise the Licensed Rights, including - technical modifications necessary to circumvent Effective - Technological Measures. For purposes of this Public License, - simply making modifications authorized by this Section 2(a) - (4) never produces Adapted Material. - - 5. Downstream recipients. - - a. Offer from the Licensor -- Licensed Material. Every - recipient of the Licensed Material automatically - receives an offer from the Licensor to exercise the - Licensed Rights under the terms and conditions of this - Public License. - - b. Additional offer from the Licensor -- Adapted Material. - Every recipient of Adapted Material from You - automatically receives an offer from the Licensor to - exercise the Licensed Rights in the Adapted Material - under the conditions of the Adapter's License You apply. - - c. No downstream restrictions. You may not offer or impose - any additional or different terms or conditions on, or - apply any Effective Technological Measures to, the - Licensed Material if doing so restricts exercise of the - Licensed Rights by any recipient of the Licensed - Material. - - 6. No endorsement. Nothing in this Public License constitutes or - may be construed as permission to assert or imply that You - are, or that Your use of the Licensed Material is, connected - with, or sponsored, endorsed, or granted official status by, - the Licensor or others designated to receive attribution as - provided in Section 3(a)(1)(A)(i). - - b. Other rights. - - 1. Moral rights, such as the right of integrity, are not - licensed under this Public License, nor are publicity, - privacy, and/or other similar personality rights; however, to - the extent possible, the Licensor waives and/or agrees not to - assert any such rights held by the Licensor to the limited - extent necessary to allow You to exercise the Licensed - Rights, but not otherwise. - - 2. Patent and trademark rights are not licensed under this - Public License. - - 3. To the extent possible, the Licensor waives any right to - collect royalties from You for the exercise of the Licensed - Rights, whether directly or through a collecting society - under any voluntary or waivable statutory or compulsory - licensing scheme. In all other cases the Licensor expressly - reserves any right to collect such royalties. - - -Section 3 -- License Conditions. - -Your exercise of the Licensed Rights is expressly made subject to the -following conditions. - - a. Attribution. - - 1. If You Share the Licensed Material (including in modified - form), You must: - - a. retain the following if it is supplied by the Licensor - with the Licensed Material: - - i. identification of the creator(s) of the Licensed - Material and any others designated to receive - attribution, in any reasonable manner requested by - the Licensor (including by pseudonym if - designated); - - ii. a copyright notice; - - iii. a notice that refers to this Public License; - - iv. a notice that refers to the disclaimer of - warranties; - - v. a URI or hyperlink to the Licensed Material to the - extent reasonably practicable; - - b. indicate if You modified the Licensed Material and - retain an indication of any previous modifications; and - - c. indicate the Licensed Material is licensed under this - Public License, and include the text of, or the URI or - hyperlink to, this Public License. - - 2. You may satisfy the conditions in Section 3(a)(1) in any - reasonable manner based on the medium, means, and context in - which You Share the Licensed Material. For example, it may be - reasonable to satisfy the conditions by providing a URI or - hyperlink to a resource that includes the required - information. - - 3. If requested by the Licensor, You must remove any of the - information required by Section 3(a)(1)(A) to the extent - reasonably practicable. - - b. ShareAlike. - - In addition to the conditions in Section 3(a), if You Share - Adapted Material You produce, the following conditions also apply. - - 1. The Adapter's License You apply must be a Creative Commons - license with the same License Elements, this version or - later, or a BY-SA Compatible License. - - 2. You must include the text of, or the URI or hyperlink to, the - Adapter's License You apply. You may satisfy this condition - in any reasonable manner based on the medium, means, and - context in which You Share Adapted Material. - - 3. You may not offer or impose any additional or different terms - or conditions on, or apply any Effective Technological - Measures to, Adapted Material that restrict exercise of the - rights granted under the Adapter's License You apply. - - -Section 4 -- Sui Generis Database Rights. - -Where the Licensed Rights include Sui Generis Database Rights that -apply to Your use of the Licensed Material: - - a. for the avoidance of doubt, Section 2(a)(1) grants You the right - to extract, reuse, reproduce, and Share all or a substantial - portion of the contents of the database; - - b. if You include all or a substantial portion of the database - contents in a database in which You have Sui Generis Database - Rights, then the database in which You have Sui Generis Database - Rights (but not its individual contents) is Adapted Material, - including for purposes of Section 3(b); and - - c. You must comply with the conditions in Section 3(a) if You Share - all or a substantial portion of the contents of the database. - -For the avoidance of doubt, this Section 4 supplements and does not -replace Your obligations under this Public License where the Licensed -Rights include other Copyright and Similar Rights. - - -Section 5 -- Disclaimer of Warranties and Limitation of Liability. - - a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE - EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS - AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF - ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, - IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, - WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, - ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT - KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT - ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. - - b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE - TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, - NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, - INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, - COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR - USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR - DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR - IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. - - c. The disclaimer of warranties and limitation of liability provided - above shall be interpreted in a manner that, to the extent - possible, most closely approximates an absolute disclaimer and - waiver of all liability. - - -Section 6 -- Term and Termination. - - a. This Public License applies for the term of the Copyright and - Similar Rights licensed here. However, if You fail to comply with - this Public License, then Your rights under this Public License - terminate automatically. - - b. Where Your right to use the Licensed Material has terminated under - Section 6(a), it reinstates: - - 1. automatically as of the date the violation is cured, provided - it is cured within 30 days of Your discovery of the - violation; or - - 2. upon express reinstatement by the Licensor. - - For the avoidance of doubt, this Section 6(b) does not affect any - right the Licensor may have to seek remedies for Your violations - of this Public License. - - c. For the avoidance of doubt, the Licensor may also offer the - Licensed Material under separate terms or conditions or stop - distributing the Licensed Material at any time; however, doing so - will not terminate this Public License. - - d. Sections 1, 5, 6, 7, and 8 survive termination of this Public - License. - - -Section 7 -- Other Terms and Conditions. - - a. The Licensor shall not be bound by any additional or different - terms or conditions communicated by You unless expressly agreed. - - b. Any arrangements, understandings, or agreements regarding the - Licensed Material not stated herein are separate from and - independent of the terms and conditions of this Public License. - - -Section 8 -- Interpretation. - - a. For the avoidance of doubt, this Public License does not, and - shall not be interpreted to, reduce, limit, restrict, or impose - conditions on any use of the Licensed Material that could lawfully - be made without permission under this Public License. - - b. To the extent possible, if any provision of this Public License is - deemed unenforceable, it shall be automatically reformed to the - minimum extent necessary to make it enforceable. If the provision - cannot be reformed, it shall be severed from this Public License - without affecting the enforceability of the remaining terms and - conditions. - - c. No term or condition of this Public License will be waived and no - failure to comply consented to unless expressly agreed to by the - Licensor. - - d. Nothing in this Public License constitutes or may be interpreted - as a limitation upon, or waiver of, any privileges and immunities - that apply to the Licensor or You, including from the legal - processes of any jurisdiction or authority. - - -======================================================================= - -Creative Commons is not a party to its public -licenses. Notwithstanding, Creative Commons may elect to apply one of -its public licenses to material it publishes and in those instances -will be considered the “Licensor.” The text of the Creative Commons -public licenses is dedicated to the public domain under the CC0 Public -Domain Dedication. Except for the limited purpose of indicating that -material is shared under a Creative Commons public license or as -otherwise permitted by the Creative Commons policies published at -creativecommons.org/policies, Creative Commons does not authorize the -use of the trademark "Creative Commons" or any other trademark or logo -of Creative Commons without its prior written consent including, -without limitation, in connection with any unauthorized modifications -to any of its public licenses or any other arrangements, -understandings, or agreements concerning use of licensed material. For -the avoidance of doubt, this paragraph does not form part of the -public licenses. - -Creative Commons may be contacted at creativecommons.org. \ No newline at end of file diff --git a/LazyOrbitBuild/LazyOrbit-v0.4.0.zip b/LazyOrbitBuild/LazyOrbit-v0.4.0.zip deleted file mode 100644 index 705c9bbbfa0e897b8783976823bd39fce01a84f9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16026 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 NPN2U>4cA|9{}15OET#Ye From a8090b45db260e9bd9d43dfd08014605c9097358 Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Sat, 15 Apr 2023 19:14:45 -0400 Subject: [PATCH 04/26] Update README.md Added screenshots to show the GUI in action. Described the features, improved the details for the installation instructions, and added myself as a contributor. --- README.md | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 8b97fa0..027e7af 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,36 @@ -# LazyOrbit v0.4.0 +# LazyOrbit -Lazy Orbit is a simple mod that allows you to set a vessel's orbit, land it on a surface, or teleport it to another vessel. Open the GUI by clicking the button in the APP.BAR (or press ALT+H), select a body and an altitude, and press Set Orbit. Great for testing and modding, don't use it for anything nefarious! +![Lazy Orbit - Simple Mode](https://i.imgur.com/8INfw3O.png) +Lazy Orbit is a simple mod that allows you to set a vessel's orbit, land it on a surface, or teleport it to another vessel. Open the GUI by clicking the button in the APP.BAR (or press ALT+H), select a body and an altitude, and press Set Orbit. Great for testing and modding, don't use it for anything nefarious! -# Installation +## Installation +1. Download and extract SpaceWarp into your game folder. If you've installed the game via Steam, then this is probably here: *C:\Program Files (x86)\Steam\steamapps\common\Kerbal Space Program 2*. If you complete this step correctly you'll have a **BepInEx** subfolder in that directory along with the following files (in addition to what was there before): **changelog.txt, doorstop_config.ini, winhttp.dll** +1. Download and extract this mod into the game folder. The mod's ZIP file contains a single BepInEx folder. You can drag that right onto your KSP2 folder to install the mod. If done correctly, you should have the following folder structure within your KSP2 game folder: *KSP2GameFolder*/**BepInEx/plugins/lazy_orbit**. -Open the game folder by right-clicking on the game in your Steam library, selecting "Manage," and then clicking "Browse local files." +## Compatibility +* Tested with Kerbal Space Program 2 v0.1.2.0.22258 & SpaceWarp 1.1.3 +* Requires SpaceWarp 1.0.1 -Install the BepInEx mod loader: -https://spacedock.info/mod/3255/BepInEx%20for%20KSP%202 +## Features +* **Simple Mode**: Set the **Altitude** you want, pick the **Body** you'd like to be in orbit about, and press the **Set Orbit** button! What could possibly be simpler? +* **Advanced Mode**: Pic the **Body** you want to be in orbit about, then configure specific parameters you want to get the exact orbit you need. Set your **Semi-Major Axis** and see what you'll get for *Ap* and *Pe*. Set your **Inclination**, **Eccentricity**, **Longitude of Ascending Node**, and **Argument of Periapsis**. With these configured, press the **Set Orbit** button and before you know it you'll be in the exact orbit you want! +* **Landing Mode**: Here you can set the **Lattitude**, **Longitude**, and **Height** above ground level for the point you'd like to have your craft dropped at on the **Body** you've selected. Be sure to have landing legs and/or parachutes ready, or this might be a bumpy ride! +* **Rendezvous Mode**: Set the **Distance** (in meters) you'd like to be from a **Target** you can pick from the drop down menu, then just press the **Rendezvous** button and you'll be there in a flash! -Install the Space Warp plugin. You need both BepInEx AND Space Warp: -https://spacedock.info/mod/3257/Space%20Warp +In all modes, if you click inside a text entry field that will automaticaly disable game input from the keyboard and mouse. This allows you to type you need to without inadvertently increasing time warp or muting the game or music. Your current Game Input state is displayed on the bottom of the GUI, and will be bright Yellow when game input is disabled. Game input from your keyboard and mouse are automatically restored when you click anywhere outside a text input field, or if you shoudl close the mod. In the image below note that Game Input is shown as Disabled. -Download Lazy Orbit, open the zip file, and drag the included `BepInEx` folder into the game folder. +![Lazy Orbit - Advanced Mode](https://i.imgur.com/GuGAHds.png) +All the text input fields in this mods GUI are designed for entering numbers. If you should accidentally type sonthing that can't be converted to a number (e.g., include non numeric characters or to many decimal points, etc.) the mod will alert you by setting that field to red as shown above. # Contributors - [Halban](https://github.com/Halbann) - [XYZ3211](https://github.com/XYZ3211) - +- [Schlosrat](https://github.com/schlosrat) # License Lazy Orbit is distributed under the CC BY-SA 4.0 license. Read about the license here before redistributing: -https://creativecommons.org/licenses/by-sa/4.0/ \ No newline at end of file +https://creativecommons.org/licenses/by-sa/4.0/ From 252c99237c5abcdbc9a074c86642fba9dda09d33 Mon Sep 17 00:00:00 2001 From: "schlosrat@gmail.com" Date: Thu, 20 Apr 2023 19:00:29 -0400 Subject: [PATCH 05/26] Fixed version check --- lazy_orbit/swinfo.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lazy_orbit/swinfo.json b/lazy_orbit/swinfo.json index 33aa93c..fb38ed6 100644 --- a/lazy_orbit/swinfo.json +++ b/lazy_orbit/swinfo.json @@ -5,10 +5,10 @@ "description": "A GUI for teleporting to orbit, keybind is ALT+H.", "source": "https://github.com/Halbann/LazyOrbit", "version": "v0.5.0", - "version_check": "", + "version_check": "https://raw.githubusercontent.com/schlosrat/LazyOrbit/master/lazy_orbit/swinfo.json", "dependencies": [ { - "id": "SpaceWarp", + "id": "SpaceWarp", "version": { "min": "1.0.1", "max": "*" From 14538ffaf6c41b368042880647368b129dd40067 Mon Sep 17 00:00:00 2001 From: "schlosrat@gmail.com" Date: Thu, 20 Apr 2023 19:01:06 -0400 Subject: [PATCH 06/26] Fixed post build event to also copy the swinfo.json file to the games plugin folder for this mod --- LazyOrbit/LazyOrbit.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LazyOrbit/LazyOrbit.csproj b/LazyOrbit/LazyOrbit.csproj index 43c42a0..0d52d6e 100644 --- a/LazyOrbit/LazyOrbit.csproj +++ b/LazyOrbit/LazyOrbit.csproj @@ -32,6 +32,6 @@ - + From c621f5b621ca3a476220989f257a9c36af81c7b2 Mon Sep 17 00:00:00 2001 From: "schlosrat@gmail.com" Date: Fri, 21 Apr 2023 18:14:08 -0400 Subject: [PATCH 07/26] Capitalized Schlosrat --- lazy_orbit/swinfo.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lazy_orbit/swinfo.json b/lazy_orbit/swinfo.json index fb38ed6..01d92b3 100644 --- a/lazy_orbit/swinfo.json +++ b/lazy_orbit/swinfo.json @@ -1,7 +1,7 @@ { "mod_id": "lazy_orbit", "name": "Lazy Orbit", - "author": "Halban, XYZ3211, schlosrat", + "author": "Halban, XYZ3211, Schlosrat", "description": "A GUI for teleporting to orbit, keybind is ALT+H.", "source": "https://github.com/Halbann/LazyOrbit", "version": "v0.5.0", From 650c6ef8147653f6e256bf4a012a16050ccf6f38 Mon Sep 17 00:00:00 2001 From: "schlosrat@gmail.com" Date: Sun, 23 Apr 2023 15:07:52 -0400 Subject: [PATCH 08/26] Fixed stupid json --- lazy_orbit/swinfo.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lazy_orbit/swinfo.json b/lazy_orbit/swinfo.json index 01d92b3..2c5e316 100644 --- a/lazy_orbit/swinfo.json +++ b/lazy_orbit/swinfo.json @@ -1,10 +1,10 @@ { "mod_id": "lazy_orbit", "name": "Lazy Orbit", - "author": "Halban, XYZ3211, Schlosrat", + "author": "Halban, XYZ3211, schlosrat", "description": "A GUI for teleporting to orbit, keybind is ALT+H.", "source": "https://github.com/Halbann/LazyOrbit", - "version": "v0.5.0", + "version": "0.5.0", "version_check": "https://raw.githubusercontent.com/schlosrat/LazyOrbit/master/lazy_orbit/swinfo.json", "dependencies": [ { @@ -19,4 +19,4 @@ "min": "0.1.1", "max": "*" } -} \ No newline at end of file +} From 014a27196e04d6070da3af04276ca1590737789a Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Fri, 23 Jun 2023 10:27:10 -0400 Subject: [PATCH 09/26] Updated for SpaceWarp 1.3.0 --- LazyOrbit/LazyOrbit.cs | 978 +++++++++++++++++++------------------ LazyOrbit/LazyOrbit.csproj | 10 +- lazy_orbit/swinfo.json | 4 +- 3 files changed, 497 insertions(+), 495 deletions(-) diff --git a/LazyOrbit/LazyOrbit.cs b/LazyOrbit/LazyOrbit.cs index 37f9253..5e3f582 100644 --- a/LazyOrbit/LazyOrbit.cs +++ b/LazyOrbit/LazyOrbit.cs @@ -23,559 +23,561 @@ namespace LazyOrbit { - [BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)] - [BepInDependency(SpaceWarpPlugin.ModGuid, SpaceWarpPlugin.ModVer)] - public class LazyOrbit : BaseSpaceWarpPlugin + [BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)] + [BepInDependency(SpaceWarpPlugin.ModGuid, SpaceWarpPlugin.ModVer)] + public class LazyOrbit : BaseSpaceWarpPlugin + { + // public const string ModGuid = "com.github.halbann.lazyorbit"; + // public const string ModName = "Lazy Orbit"; + public const string ModVer = MyPluginInfo.PLUGIN_VERSION; + // These are useful in case some other mod wants to add a dependency to this one + public const string ModGuid = MyPluginInfo.PLUGIN_GUID; + public const string ModName = MyPluginInfo.PLUGIN_NAME; + // public const string ModVer = MyPluginInfo.PLUGIN_VERSION; + #region Fields + + // Main. + public static bool loaded = false; + public static LazyOrbit instance; + + // Paths. + private static string _assemblyFolder; + private static string AssemblyFolder => + _assemblyFolder ?? (_assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); + + private static string _settingsPath; + private static string SettingsPath => + _settingsPath ?? (_settingsPath = Path.Combine(AssemblyFolder, "settings.json")); + + // GUI. + private static bool guiLoaded = false; + private bool drawUI = false; + private Rect windowRect; + private int windowWidth = 500; + private int windowHeight = 700; + private static GUIStyle boxStyle, errorStyle, warnStyle, peStyle, apStyle, labelStyle; + private static Vector2 scrollPositionBodies; + private static Vector2 scrollPositionVessels; + private static Color labelColor; + private static GameState[] validScenes = new[] { GameState.FlightView, GameState.Map3DView }; + private int spacingAfterEntry = -5; + + // Control click through to the game + private bool gameInputState = true; + public List inputFields = new List(); + + private static bool ValidScene => validScenes.Contains(GameManager.Instance.Game.GlobalGameState.GetState()); + + // Orbit. + private static float altitudeKM = 100; + private static float semiMajorAxisKM = 700; + private static float inclinationDegrees = 0; + private static float eccentricity = 0; + private static float ascendingNode = 0; + private static float argOfPeriapsis = 0; + private static double bodyRadius = 600000; + private static double apKM, peKM; + + private static string altitudeString = altitudeKM.ToString(); + private static string semiMajorAxisString = semiMajorAxisKM.ToString(); + private static string inclinationString = inclinationDegrees.ToString(); + private static string eccentricityString = eccentricity.ToString(); + private static string ascendingNodeString = ascendingNode.ToString(); + private static string argOfPeriapsisString = argOfPeriapsis.ToString(); + + // Body selection. + private string selectedBody = "Kerbin"; + private List bodies; + private bool selectingBody = false; + + // Rendezvous. + private static VesselComponent activeVessel; + private static VesselComponent target; + private static List allVessels; + private static bool selectingVessel = false; + private static float rendezvousDistance = 100f; + private static string rendezvousDistanceString = rendezvousDistance.ToString(); + + // Landing. + private static float latitude = -0.65f; + private static float longitude = 285f; + private static float height = 5f; + private static string latitudeString = latitude.ToString(); + private static string longitudeString = longitude.ToString(); + private static string heightString = height.ToString(); + + // Interface modes. + private static InterfaceMode interfaceMode = InterfaceMode.Simple; + private static string[] interfaceModes = { "Simple", "Advanced", "Landing", "Rendezvous" }; + + private InterfaceMode CurrentInterfaceMode { - // public const string ModGuid = "com.github.halbann.lazyorbit"; - // public const string ModName = "Lazy Orbit"; - public const string ModVer = MyPluginInfo.PLUGIN_VERSION; - // These are useful in case some other mod wants to add a dependency to this one - public const string ModGuid = MyPluginInfo.PLUGIN_GUID; - public const string ModName = MyPluginInfo.PLUGIN_NAME; - // public const string ModVer = MyPluginInfo.PLUGIN_VERSION; - #region Fields - - // Main. - public static bool loaded = false; - public static LazyOrbit instance; - - // Paths. - private static string _assemblyFolder; - private static string AssemblyFolder => - _assemblyFolder ?? (_assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); - - private static string _settingsPath; - private static string SettingsPath => - _settingsPath ?? (_settingsPath = Path.Combine(AssemblyFolder, "settings.json")); - - // GUI. - private static bool guiLoaded = false; - private bool drawUI = false; - private Rect windowRect; - private int windowWidth = 500; - private int windowHeight = 700; - private static GUIStyle boxStyle, errorStyle, warnStyle, peStyle, apStyle, labelStyle; - private static Vector2 scrollPositionBodies; - private static Vector2 scrollPositionVessels; - private static Color labelColor; - private static GameState[] validScenes = new[] { GameState.FlightView, GameState.Map3DView }; - private int spacingAfterEntry = -5; - - // Control click through to the game - private bool gameInputState = true; - public List inputFields = new List(); - - private static bool ValidScene => validScenes.Contains(GameManager.Instance.Game.GlobalGameState.GetState()); - - // Orbit. - private static float altitudeKM = 100; - private static float semiMajorAxisKM = 700; - private static float inclinationDegrees = 0; - private static float eccentricity = 0; - private static float ascendingNode = 0; - private static float argOfPeriapsis = 0; - private static double bodyRadius = 600000; - private static double apKM, peKM; - - private static string altitudeString = altitudeKM.ToString(); - private static string semiMajorAxisString = semiMajorAxisKM.ToString(); - private static string inclinationString = inclinationDegrees.ToString(); - private static string eccentricityString = eccentricity.ToString(); - private static string ascendingNodeString = ascendingNode.ToString(); - private static string argOfPeriapsisString = argOfPeriapsis.ToString(); - - // Body selection. - private string selectedBody = "Kerbin"; - private List bodies; - private bool selectingBody = false; - - // Rendezvous. - private static VesselComponent activeVessel; - private static VesselComponent target; - private static List allVessels; - private static bool selectingVessel = false; - private static float rendezvousDistance = 100f; - private static string rendezvousDistanceString = rendezvousDistance.ToString(); - - // Landing. - private static float latitude = -0.65f; - private static float longitude = 285f; - private static float height = 5f; - private static string latitudeString = latitude.ToString(); - private static string longitudeString = longitude.ToString(); - private static string heightString = height.ToString(); - - // Interface modes. - private static InterfaceMode interfaceMode = InterfaceMode.Simple; - private static string[] interfaceModes = { "Simple", "Advanced", "Landing", "Rendezvous" }; - - private InterfaceMode CurrentInterfaceMode - { - get => interfaceMode; - set - { - if (value == interfaceMode) return; - - interfaceMode = value; - if (new[] { InterfaceMode.Simple, InterfaceMode.Advanced }.Contains(interfaceMode)) - SaveDefaultMode(interfaceMode); - } - } + get => interfaceMode; + set + { + if (value == interfaceMode) return; + + interfaceMode = value; + if (new[] { InterfaceMode.Simple, InterfaceMode.Advanced }.Contains(interfaceMode)) + SaveDefaultMode(interfaceMode); + } + } - #endregion + #endregion - #region Main + #region Main - public override void OnInitialized() - { - if (loaded) - { - Destroy(this); - } + public override void OnInitialized() + { + if (loaded) + { + Destroy(this); + } - loaded = true; - instance = this; + loaded = true; + instance = this; - gameObject.hideFlags = HideFlags.HideAndDontSave; - DontDestroyOnLoad(gameObject); + gameObject.hideFlags = HideFlags.HideAndDontSave; + DontDestroyOnLoad(gameObject); - interfaceMode = GetDefaultMode(); + interfaceMode = GetDefaultMode(); - Logger.LogInfo($"Lazy Orbit: SpaceWarpMetadata.ModID = {SpaceWarpMetadata.ModID}"); + Logger.LogInfo($"Lazy Orbit: SpaceWarpMetadata.ModID = {SpaceWarpMetadata.ModID}"); - Appbar.RegisterAppButton( - "Lazy Orbit", - "BTN-LazyOrbitButton", - AssetManager.GetAsset($"{SpaceWarpMetadata.ModID}/images/icon.png"), - ToggleButton); - } + Appbar.RegisterAppButton( + "Lazy Orbit", + "BTN-LazyOrbitButton", + AssetManager.GetAsset($"{SpaceWarpMetadata.ModID}/images/icon.png"), + ToggleButton); + } - void Awake() - { - windowRect = new Rect((Screen.width * 0.7f) - (windowWidth / 2), (Screen.height / 2) - (windowHeight / 2), 0, 0); - } + void Awake() + { + windowRect = new Rect((Screen.width * 0.7f) - (windowWidth / 2), (Screen.height / 2) - (windowHeight / 2), 0, 0); + if (windowRect.x < 0) windowRect.x = 0; + if (windowRect.y < 0) windowRect.y = 0; + } - void Update() + void Update() + { + if (Input.GetKey(KeyCode.LeftAlt) && Input.GetKeyDown(KeyCode.H) && ValidScene) + ToggleButton(!drawUI); + } + + void OnGUI() + { + //GUIenabled = false; + //var gameState = Game?.GlobalGameState?.GetState(); + //if (gameState == GameState.Map3DView) GUIenabled = true; + //if (gameState == GameState.FlightView) GUIenabled = true; + + if (drawUI && ValidScene) + { + if (!guiLoaded) + GetStyles(); + + GUI.skin = Skins.ConsoleSkin; + + windowRect = GUILayout.Window( + GUIUtility.GetControlID(FocusType.Passive), + windowRect, + FillWindow, + "// LAZY ORBIT", + GUILayout.Height(0), + GUILayout.Width(350)); + + if (gameInputState && inputFields.Contains(GUI.GetNameOfFocusedControl())) { - if (Input.GetKey(KeyCode.LeftAlt) && Input.GetKeyDown(KeyCode.H) && ValidScene) - ToggleButton(!drawUI); + // Logger.LogDebug($"OnGUI: Disabling Game Input: Focused Item '{GUI.GetNameOfFocusedControl()}'"); + gameInputState = false; + GameManager.Instance.Game.Input.Disable(); } - - void OnGUI() + else if (!gameInputState && !inputFields.Contains(GUI.GetNameOfFocusedControl())) { - //GUIenabled = false; - //var gameState = Game?.GlobalGameState?.GetState(); - //if (gameState == GameState.Map3DView) GUIenabled = true; - //if (gameState == GameState.FlightView) GUIenabled = true; - - if (drawUI && ValidScene) - { - if (!guiLoaded) - GetStyles(); - - GUI.skin = Skins.ConsoleSkin; - - windowRect = GUILayout.Window( - GUIUtility.GetControlID(FocusType.Passive), - windowRect, - FillWindow, - "// LAZY ORBIT", - GUILayout.Height(0), - GUILayout.Width(350)); - - if (gameInputState && inputFields.Contains(GUI.GetNameOfFocusedControl())) - { - // Logger.LogDebug($"OnGUI: Disabling Game Input: Focused Item '{GUI.GetNameOfFocusedControl()}'"); - gameInputState = false; - GameManager.Instance.Game.Input.Disable(); - } - else if (!gameInputState && !inputFields.Contains(GUI.GetNameOfFocusedControl())) - { - // Logger.LogDebug($"OnGUI: Enabling Game Input: FYI, Focused Item '{GUI.GetNameOfFocusedControl()}'"); - gameInputState = true; - GameManager.Instance.Game.Input.Enable(); - } - //if (selectingBody) - //{ - // // Do something here to disable mouse wheel control of zoom in and out. - // // Intent: allow player to scroll in the scroll view without causing the game to zoom in and out - // GameManager.Instance._game.MouseManager.enabled = false; - //} - //else - //{ - // // Do something here to re-enable mouse wheel control of zoom in and out. - // GameManager.Instance._game.MouseManager.enabled = true; - //} - } - else - { - if (!gameInputState) - { - // Logger.LogDebug($"OnGUI: Enabling Game Input due to GUI disabled: FYI, Focused Item '{GUI.GetNameOfFocusedControl()}'"); - gameInputState = true; - GameManager.Instance.Game.Input.Enable(); - } - } + // Logger.LogDebug($"OnGUI: Enabling Game Input: FYI, Focused Item '{GUI.GetNameOfFocusedControl()}'"); + gameInputState = true; + GameManager.Instance.Game.Input.Enable(); } - - void ToggleButton(bool toggle) + //if (selectingBody) + //{ + // // Do something here to disable mouse wheel control of zoom in and out. + // // Intent: allow player to scroll in the scroll view without causing the game to zoom in and out + // GameManager.Instance._game.MouseManager.enabled = false; + //} + //else + //{ + // // Do something here to re-enable mouse wheel control of zoom in and out. + // GameManager.Instance._game.MouseManager.enabled = true; + //} + } + else + { + if (!gameInputState) { - drawUI = toggle; - GameObject.Find("BTN-LazyOrbitButton")?.GetComponent()?.SetValue(toggle); + // Logger.LogDebug($"OnGUI: Enabling Game Input due to GUI disabled: FYI, Focused Item '{GUI.GetNameOfFocusedControl()}'"); + gameInputState = true; + GameManager.Instance.Game.Input.Enable(); } + } + } - #endregion + void ToggleButton(bool toggle) + { + drawUI = toggle; + GameObject.Find("BTN-LazyOrbitButton")?.GetComponent()?.SetValue(toggle); + } - #region GUI + #endregion - private void GetStyles() - { - if (boxStyle != null) - return; - - boxStyle = GUI.skin.GetStyle("Box"); - labelStyle = new GUIStyle(GUI.skin.GetStyle("Label")); - errorStyle = new GUIStyle(GUI.skin.GetStyle("Label")); - warnStyle = new GUIStyle(GUI.skin.GetStyle("Label")); - apStyle = new GUIStyle(GUI.skin.GetStyle("Label")); - peStyle = new GUIStyle(GUI.skin.GetStyle("Label")); - errorStyle.normal.textColor = Color.red; - warnStyle.normal.textColor = Color.yellow; - labelColor = GUI.skin.GetStyle("Label").normal.textColor; - - guiLoaded = true; - } + #region GUI - private void FillWindow(int windowID) - { - if ((activeVessel = GameManager.Instance.Game.ViewController.GetActiveSimVessel()) == null) - { - GUILayout.FlexibleSpace(); - GUILayout.Label("No active vessel.", errorStyle); - GUILayout.FlexibleSpace(); - return; - } - - if (GUI.Button(new Rect(windowRect.width - 18, 2, 16, 16), "x")) - { - Logger.LogDebug("FillWindow: Restoring Game Input on window close."); - GameManager.Instance.Game.Input.Enable(); - ToggleButton(false); - } - - GUILayout.BeginVertical(); - - GUILayout.Label($"Active Vessel: {activeVessel.DisplayName}"); - - // Mode selection. - - GUILayout.BeginHorizontal(); - CurrentInterfaceMode = (InterfaceMode)GUILayout.SelectionGrid((int)CurrentInterfaceMode, interfaceModes, 4); - GUILayout.EndHorizontal(); - - // Draw one of the modes. - switch (CurrentInterfaceMode) - { - case InterfaceMode.Simple: SimpleGUI(); break; - case InterfaceMode.Advanced: AdvancedGUI(); break; - case InterfaceMode.Landing: LandingGUI(); break; - case InterfaceMode.Rendezvous: RendezvousGUI(); break; - default: - break; - } - - // Indication to User that its safe to type, or why vessel controls aren't working - GUILayout.BeginHorizontal(); - string inputStateString = gameInputState ? "Enabled" : "Disabled"; - GUILayout.Label("Game Input: ", labelStyle); - if (gameInputState) - GUILayout.Label(inputStateString, labelStyle); - else - GUILayout.Label(inputStateString, warnStyle); - GUILayout.FlexibleSpace(); - GUILayout.EndHorizontal(); - GUILayout.Space(spacingAfterEntry); - - GUILayout.EndVertical(); - GUI.DragWindow(new Rect(0, 0, 10000, 500)); - } + private void GetStyles() + { + if (boxStyle != null) + return; + + boxStyle = GUI.skin.GetStyle("Box"); + labelStyle = new GUIStyle(GUI.skin.GetStyle("Label")); + errorStyle = new GUIStyle(GUI.skin.GetStyle("Label")); + warnStyle = new GUIStyle(GUI.skin.GetStyle("Label")); + apStyle = new GUIStyle(GUI.skin.GetStyle("Label")); + peStyle = new GUIStyle(GUI.skin.GetStyle("Label")); + errorStyle.normal.textColor = Color.red; + warnStyle.normal.textColor = Color.yellow; + labelColor = GUI.skin.GetStyle("Label").normal.textColor; + + guiLoaded = true; + } - void SimpleGUI() - { - bool success = true; + private void FillWindow(int windowID) + { + if ((activeVessel = GameManager.Instance.Game.ViewController.GetActiveSimVessel()) == null) + { + GUILayout.FlexibleSpace(); + GUILayout.Label("No active vessel.", errorStyle); + GUILayout.FlexibleSpace(); + return; + } + + if (GUI.Button(new Rect(windowRect.width - 18, 2, 16, 16), "x")) + { + Logger.LogDebug("FillWindow: Restoring Game Input on window close."); + GameManager.Instance.Game.Input.Enable(); + ToggleButton(false); + } + + GUILayout.BeginVertical(); + + GUILayout.Label($"Active Vessel: {activeVessel.DisplayName}"); + + // Mode selection. + + GUILayout.BeginHorizontal(); + CurrentInterfaceMode = (InterfaceMode)GUILayout.SelectionGrid((int)CurrentInterfaceMode, interfaceModes, 4); + GUILayout.EndHorizontal(); + + // Draw one of the modes. + switch (CurrentInterfaceMode) + { + case InterfaceMode.Simple: SimpleGUI(); break; + case InterfaceMode.Advanced: AdvancedGUI(); break; + case InterfaceMode.Landing: LandingGUI(); break; + case InterfaceMode.Rendezvous: RendezvousGUI(); break; + default: + break; + } + + // Indication to User that its safe to type, or why vessel controls aren't working + GUILayout.BeginHorizontal(); + string inputStateString = gameInputState ? "Enabled" : "Disabled"; + GUILayout.Label("Game Input: ", labelStyle); + if (gameInputState) + GUILayout.Label(inputStateString, labelStyle); + else + GUILayout.Label(inputStateString, warnStyle); + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + GUILayout.Space(spacingAfterEntry); + + GUILayout.EndVertical(); + GUI.DragWindow(new Rect(0, 0, 10000, 500)); + } - TextField("Altitude (km):", ref altitudeString, ref altitudeKM, ref success); - BodySelectionGUI(); + void SimpleGUI() + { + bool success = true; - ConditionalButton("Set Orbit", success, SetOrbit); - } + TextField("Altitude (km):", ref altitudeString, ref altitudeKM, ref success); + BodySelectionGUI(); + ConditionalButton("Set Orbit", success, SetOrbit); + } - void LandingGUI() - { - bool success = true; - TextField("Latitude (Degrees):", ref latitudeString, ref latitude, ref success); - TextField("Longitude (Degrees):", ref longitudeString, ref longitude, ref success); - TextField("Height (m):", ref heightString, ref height, ref success); - BodySelectionGUI(); + void LandingGUI() + { + bool success = true; - ConditionalButton("Land", success, Land); - } + TextField("Latitude (Degrees):", ref latitudeString, ref latitude, ref success); + TextField("Longitude (Degrees):", ref longitudeString, ref longitude, ref success); + TextField("Height (m):", ref heightString, ref height, ref success); + BodySelectionGUI(); - void AdvancedGUI() - { - bool success = true; + ConditionalButton("Land", success, Land); + } - TextField("Semi-Major Axis (km):", ref semiMajorAxisString, ref semiMajorAxisKM, ref success); + void AdvancedGUI() + { + bool success = true; - bodyRadius = GameManager.Instance.Game.CelestialBodies.GetRadius(selectedBody) / 1000f; - apKM = (semiMajorAxisKM * (1 + eccentricity) - bodyRadius); - peKM = (semiMajorAxisKM * (1 - eccentricity) - bodyRadius); - apStyle.normal.textColor = apKM < 1 ? warnStyle.normal.textColor : labelColor; - peStyle.normal.textColor = peKM < 1 ? warnStyle.normal.textColor : labelColor; + TextField("Semi-Major Axis (km):", ref semiMajorAxisString, ref semiMajorAxisKM, ref success); - GUILayout.BeginHorizontal(); - GUILayout.Label("AP (km): ", apStyle, GUILayout.Width(windowWidth / 4)); - GUILayout.Label(apKM.ToString("n2"), apStyle, GUILayout.Width(windowWidth / 4)); - GUILayout.Label("PE (km): ", peStyle, GUILayout.Width(windowWidth / 4)); - GUILayout.Label(peKM.ToString("n2"), peStyle, GUILayout.Width(windowWidth / 4)); - GUILayout.EndHorizontal(); + bodyRadius = GameManager.Instance.Game.CelestialBodies.GetRadius(selectedBody) / 1000f; + apKM = (semiMajorAxisKM * (1 + eccentricity) - bodyRadius); + peKM = (semiMajorAxisKM * (1 - eccentricity) - bodyRadius); + apStyle.normal.textColor = apKM < 1 ? warnStyle.normal.textColor : labelColor; + peStyle.normal.textColor = peKM < 1 ? warnStyle.normal.textColor : labelColor; - TextField("Inclination (Degrees):", ref inclinationString, ref inclinationDegrees, ref success); - TextField("Eccentricity:", ref eccentricityString, ref eccentricity, ref success); + GUILayout.BeginHorizontal(); + GUILayout.Label("AP (km): ", apStyle, GUILayout.Width(windowWidth / 4)); + GUILayout.Label(apKM.ToString("n2"), apStyle, GUILayout.Width(windowWidth / 4)); + GUILayout.Label("PE (km): ", peStyle, GUILayout.Width(windowWidth / 4)); + GUILayout.Label(peKM.ToString("n2"), peStyle, GUILayout.Width(windowWidth / 4)); + GUILayout.EndHorizontal(); - if (eccentricity >= 1 || eccentricity < 0) - { - GUILayout.BeginHorizontal(); - GUILayout.Label("Eccentricity must be between 0 and 1.", errorStyle); - GUILayout.EndHorizontal(); - } + TextField("Inclination (Degrees):", ref inclinationString, ref inclinationDegrees, ref success); + TextField("Eccentricity:", ref eccentricityString, ref eccentricity, ref success); - TextField("Longitude of Ascending Node (Degrees):", ref ascendingNodeString, ref ascendingNode, ref success); - TextField("Argument of Periapsis (Degrees):", ref argOfPeriapsisString, ref argOfPeriapsis, ref success); + if (eccentricity >= 1 || eccentricity < 0) + { + GUILayout.BeginHorizontal(); + GUILayout.Label("Eccentricity must be between 0 and 1.", errorStyle); + GUILayout.EndHorizontal(); + } - BodySelectionGUI(); + TextField("Longitude of Ascending Node (Degrees):", ref ascendingNodeString, ref ascendingNode, ref success); + TextField("Argument of Periapsis (Degrees):", ref argOfPeriapsisString, ref argOfPeriapsis, ref success); - ConditionalButton("Set Orbit", success, SetOrbit); - } + BodySelectionGUI(); - void RendezvousGUI() - { - bool success = true; - - allVessels = GameManager.Instance.Game.SpaceSimulation.UniverseModel.GetAllVessels(); - allVessels.Remove(activeVessel); - allVessels.RemoveAll(v => v.IsDebris()); - - if (allVessels.Count < 1) - { - GUILayout.Label("No other vessels."); - return; - } - - if (target == null) - target = allVessels.First(); - - TextField("Distance (m):", ref rendezvousDistanceString, ref rendezvousDistance, ref success); - - GUILayout.BeginHorizontal(); - GUILayout.Label("Target: ", GUILayout.Width(0)); - if (!selectingVessel) - { - if (GUILayout.Button(target.DisplayName)) - selectingVessel = true; - } - else - { - GUILayout.BeginVertical(boxStyle); - scrollPositionVessels = GUILayout.BeginScrollView(scrollPositionVessels, false, true, GUILayout.Height(150)); - foreach (VesselComponent vessel in allVessels) - { - if (GUILayout.Button(vessel.DisplayName)) - { - target = vessel; - selectingVessel = false; - } - } - GUILayout.EndScrollView(); - GUILayout.EndVertical(); - } - GUILayout.EndHorizontal(); - - ConditionalButton("Rendezvous", success, Rendezvous); - } + ConditionalButton("Set Orbit", success, SetOrbit); + } - // Draws the body selection GUI. - void BodySelectionGUI() + void RendezvousGUI() + { + bool success = true; + + allVessels = GameManager.Instance.Game.SpaceSimulation.UniverseModel.GetAllVessels(); + allVessels.Remove(activeVessel); + allVessels.RemoveAll(v => v.IsDebris()); + + if (allVessels.Count < 1) + { + GUILayout.Label("No other vessels."); + return; + } + + if (target == null) + target = allVessels.First(); + + TextField("Distance (m):", ref rendezvousDistanceString, ref rendezvousDistance, ref success); + + GUILayout.BeginHorizontal(); + GUILayout.Label("Target: ", GUILayout.Width(0)); + if (!selectingVessel) + { + if (GUILayout.Button(target.DisplayName)) + selectingVessel = true; + } + else + { + GUILayout.BeginVertical(boxStyle); + scrollPositionVessels = GUILayout.BeginScrollView(scrollPositionVessels, false, true, GUILayout.Height(150)); + foreach (VesselComponent vessel in allVessels) { - bodies = GameManager.Instance.Game.SpaceSimulation.GetBodyNameKeys().ToList(); - - GUILayout.BeginHorizontal(); - GUILayout.Label("Body: ", GUILayout.Width(windowWidth / 2)); - if (!selectingBody) - { - if (GUILayout.Button(selectedBody)) - selectingBody = true; - } - else - { - GUILayout.BeginVertical(boxStyle); - scrollPositionBodies = GUILayout.BeginScrollView(scrollPositionBodies, false, true, GUILayout.Height(150)); - foreach (string body in bodies) - { - if (GUILayout.Button(body)) - { - selectedBody = body; - selectingBody = false; - } - } - GUILayout.EndScrollView(); - GUILayout.EndVertical(); - } - GUILayout.EndHorizontal(); + if (GUILayout.Button(vessel.DisplayName)) + { + target = vessel; + selectingVessel = false; + } } + GUILayout.EndScrollView(); + GUILayout.EndVertical(); + } + GUILayout.EndHorizontal(); - void TextField(string label, ref string field, ref float number, ref bool success) + ConditionalButton("Rendezvous", success, Rendezvous); + } + + // Draws the body selection GUI. + void BodySelectionGUI() + { + bodies = GameManager.Instance.Game.SpaceSimulation.GetBodyNameKeys().ToList(); + + GUILayout.BeginHorizontal(); + GUILayout.Label("Body: ", GUILayout.Width(windowWidth / 2)); + if (!selectingBody) + { + if (GUILayout.Button(selectedBody)) + selectingBody = true; + } + else + { + GUILayout.BeginVertical(boxStyle); + scrollPositionBodies = GUILayout.BeginScrollView(scrollPositionBodies, false, true, GUILayout.Height(150)); + foreach (string body in bodies) { - // Setup the list of input field names (most are the same as the entry string text displayed in the GUI window) - if (!inputFields.Contains(label)) - inputFields.Add(label); + if (GUILayout.Button(body)) + { + selectedBody = body; + selectingBody = false; + } + } + GUILayout.EndScrollView(); + GUILayout.EndVertical(); + } + GUILayout.EndHorizontal(); + } - GUILayout.BeginHorizontal(); - GUILayout.Label(label, GUILayout.Width(windowWidth / 2)); + void TextField(string label, ref string field, ref float number, ref bool success) + { + // Setup the list of input field names (most are the same as the entry string text displayed in the GUI window) + if (!inputFields.Contains(label)) + inputFields.Add(label); - bool parsed = float.TryParse(field, out number); - if (!parsed) GUI.color = Color.red; - GUI.SetNextControlName(label); - field = GUILayout.TextField(field); - GUI.color = Color.white; + GUILayout.BeginHorizontal(); + GUILayout.Label(label, GUILayout.Width(windowWidth / 2)); - if (success && !parsed) - success = false; + bool parsed = float.TryParse(field, out number); + if (!parsed) GUI.color = Color.red; + GUI.SetNextControlName(label); + field = GUILayout.TextField(field); + GUI.color = Color.white; - GUILayout.EndHorizontal(); - } + if (success && !parsed) + success = false; - void ConditionalButton(string text, bool condition, Action pressed) - { - GUI.enabled = condition; + GUILayout.EndHorizontal(); + } - if (GUILayout.Button(text)) - pressed(); + void ConditionalButton(string text, bool condition, Action pressed) + { + GUI.enabled = condition; - GUI.enabled = true; - } + if (GUILayout.Button(text)) + pressed(); - #endregion + GUI.enabled = true; + } - #region Functions + #endregion - // Sets vessel orbit according to the current interfaceMode. - void SetOrbit() - { - GameInstance game = GameManager.Instance.Game; - - if (CurrentInterfaceMode == InterfaceMode.Simple) - { - // Set orbit using just altitude. - game.SpaceSimulation.Lua.TeleportToOrbit( - activeVessel.Guid, - selectedBody, - 0, - 0, - (double)altitudeKM * 1000f + GameManager.Instance.Game.CelestialBodies.GetRadius(selectedBody), - 0, - 0, - 0, - 0); - } - else - { - // Set orbit using semi-major axis and other orbital parameters. - game.SpaceSimulation.Lua.TeleportToOrbit( - activeVessel.Guid, - selectedBody, - inclinationDegrees, - eccentricity, - (double)semiMajorAxisKM * 1000f, - ascendingNode, - argOfPeriapsis, - 0, - 0); - } - } + #region Functions - void Rendezvous() - { - GameInstance game = GameManager.Instance.Game; - - if (target.Guid == activeVessel.Guid) - return; + // Sets vessel orbit according to the current interfaceMode. + void SetOrbit() + { + GameInstance game = GameManager.Instance.Game; + + if (CurrentInterfaceMode == InterfaceMode.Simple) + { + // Set orbit using just altitude. + game.SpaceSimulation.Lua.TeleportToOrbit( + activeVessel.Guid, + selectedBody, + 0, + 0, + (double)altitudeKM * 1000f + GameManager.Instance.Game.CelestialBodies.GetRadius(selectedBody), + 0, + 0, + 0, + 0); + } + else + { + // Set orbit using semi-major axis and other orbital parameters. + game.SpaceSimulation.Lua.TeleportToOrbit( + activeVessel.Guid, + selectedBody, + inclinationDegrees, + eccentricity, + (double)semiMajorAxisKM * 1000f, + ascendingNode, + argOfPeriapsis, + 0, + 0); + } + } - game.SpaceSimulation.Lua.TeleportToRendezvous( - activeVessel.Guid, - target.Guid, - rendezvousDistance, - 0, 0, 0, 0, 0); - } + void Rendezvous() + { + GameInstance game = GameManager.Instance.Game; - void Land() - { - GameInstance game = GameManager.Instance.Game; - - game.SpaceSimulation.Lua.TeleportToSurface( - activeVessel.Guid, - selectedBody, - height, - latitude, - longitude, - 0); - } + if (target.Guid == activeVessel.Guid) + return; - #endregion + game.SpaceSimulation.Lua.TeleportToRendezvous( + activeVessel.Guid, + target.Guid, + rendezvousDistance, + 0, 0, 0, 0, 0); + } - #region Settings + void Land() + { + GameInstance game = GameManager.Instance.Game; + + game.SpaceSimulation.Lua.TeleportToSurface( + activeVessel.Guid, + selectedBody, + height, + latitude, + longitude, + 0); + } - private void SaveDefaultMode(InterfaceMode mode) - { - LazyOrbitSettings settings = new LazyOrbitSettings() - { - defaultMode = mode - }; + #endregion - File.WriteAllText(SettingsPath, JsonConvert.SerializeObject(settings)); - } + #region Settings - private InterfaceMode GetDefaultMode() - { - LazyOrbitSettings settings; - try - { - settings = JsonConvert.DeserializeObject(File.ReadAllText(SettingsPath)); - } - catch (FileNotFoundException) - { - settings = new LazyOrbitSettings(); - } - - return settings.defaultMode; - } + private void SaveDefaultMode(InterfaceMode mode) + { + LazyOrbitSettings settings = new LazyOrbitSettings() + { + defaultMode = mode + }; - #endregion + File.WriteAllText(SettingsPath, JsonConvert.SerializeObject(settings)); } - public class LazyOrbitSettings + private InterfaceMode GetDefaultMode() { - public InterfaceMode defaultMode = InterfaceMode.Simple; + LazyOrbitSettings settings; + try + { + settings = JsonConvert.DeserializeObject(File.ReadAllText(SettingsPath)); + } + catch (FileNotFoundException) + { + settings = new LazyOrbitSettings(); + } + + return settings.defaultMode; } - public enum InterfaceMode - { - Simple, - Advanced, - Landing, - Rendezvous, - } + #endregion + } + + public class LazyOrbitSettings + { + public InterfaceMode defaultMode = InterfaceMode.Simple; + } + + public enum InterfaceMode + { + Simple, + Advanced, + Landing, + Rendezvous, + } } \ No newline at end of file diff --git a/LazyOrbit/LazyOrbit.csproj b/LazyOrbit/LazyOrbit.csproj index 0d52d6e..4cbcb95 100644 --- a/LazyOrbit/LazyOrbit.csproj +++ b/LazyOrbit/LazyOrbit.csproj @@ -8,10 +8,10 @@ com.github.halbann.lazy_orbit Lazy Orbit A GUI for teleporting to orbit, keybind is ALT+H. - 0.5.0 + 0.5.1 - https://nuget.spacewarp.org/v3/index.json - + https://nuget.spacewarp.org/v3/index.json + LazyOrbit lazy_orbit @@ -28,8 +28,8 @@ - - + + diff --git a/lazy_orbit/swinfo.json b/lazy_orbit/swinfo.json index 2c5e316..4edea44 100644 --- a/lazy_orbit/swinfo.json +++ b/lazy_orbit/swinfo.json @@ -4,13 +4,13 @@ "author": "Halban, XYZ3211, schlosrat", "description": "A GUI for teleporting to orbit, keybind is ALT+H.", "source": "https://github.com/Halbann/LazyOrbit", - "version": "0.5.0", + "version": "0.5.1", "version_check": "https://raw.githubusercontent.com/schlosrat/LazyOrbit/master/lazy_orbit/swinfo.json", "dependencies": [ { "id": "SpaceWarp", "version": { - "min": "1.0.1", + "min": "1.3.0", "max": "*" } } From db64038d35e09bb14d7a4f093dff435e2a34662b Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Fri, 23 Jun 2023 11:02:40 -0400 Subject: [PATCH 10/26] Took over mod. Updated to SW 1.3.0 --- LazyOrbit/LazyOrbit.csproj | 68 +++++++++++++++++++------------------- lazy_orbit/swinfo.json | 2 +- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/LazyOrbit/LazyOrbit.csproj b/LazyOrbit/LazyOrbit.csproj index 4cbcb95..6fbddec 100644 --- a/LazyOrbit/LazyOrbit.csproj +++ b/LazyOrbit/LazyOrbit.csproj @@ -1,37 +1,37 @@  - - netstandard2.0 - true - latest - true - com.github.halbann.lazy_orbit - Lazy Orbit - A GUI for teleporting to orbit, keybind is ALT+H. - 0.5.1 - - https://nuget.spacewarp.org/v3/index.json - - LazyOrbit - lazy_orbit - - - - ..\external_dlls\Assembly-CSharp.dll - true - false - - - - - - - - - - - - - - + + netstandard2.0 + true + latest + true + com.github.schlosrat.lazy_orbit + Lazy Orbit + A GUI for teleporting to orbit, keybind is ALT+H. + 0.5.1 + + https://nuget.spacewarp.org/v3/index.json + + LazyOrbit + lazy_orbit + + + + + + + + + + + + + ..\external_dlls\Assembly-CSharp.dll + true + false + + + + + diff --git a/lazy_orbit/swinfo.json b/lazy_orbit/swinfo.json index 4edea44..18d16a1 100644 --- a/lazy_orbit/swinfo.json +++ b/lazy_orbit/swinfo.json @@ -3,7 +3,7 @@ "name": "Lazy Orbit", "author": "Halban, XYZ3211, schlosrat", "description": "A GUI for teleporting to orbit, keybind is ALT+H.", - "source": "https://github.com/Halbann/LazyOrbit", + "source": "https://github.com/schlosrat/LazyOrbit", "version": "0.5.1", "version_check": "https://raw.githubusercontent.com/schlosrat/LazyOrbit/master/lazy_orbit/swinfo.json", "dependencies": [ From 1242a93927b42fd23991d4a3faad794ffc475c41 Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Fri, 23 Jun 2023 11:03:06 -0400 Subject: [PATCH 11/26] Added batch scripts for release --- batches/copy_to_ksp.bat | 21 ++++++++++++++++ batches/get_dlls.bat | 32 ++++++++++++++++++++++++ batches/local_dev_options.bat | 18 ++++++++++++++ batches/local_dev_options.exemple.bat | 18 ++++++++++++++ batches/make_zip.bat | 35 +++++++++++++++++++++++++++ batches/post_build.bat | 35 +++++++++++++++++++++++++++ batches/set_debug_dll.bat | 9 +++++++ batches/set_release_dll.bat | 10 ++++++++ 8 files changed, 178 insertions(+) create mode 100644 batches/copy_to_ksp.bat create mode 100644 batches/get_dlls.bat create mode 100644 batches/local_dev_options.bat create mode 100644 batches/local_dev_options.exemple.bat create mode 100644 batches/make_zip.bat create mode 100644 batches/post_build.bat create mode 100644 batches/set_debug_dll.bat create mode 100644 batches/set_release_dll.bat diff --git a/batches/copy_to_ksp.bat b/batches/copy_to_ksp.bat new file mode 100644 index 0000000..f3932e2 --- /dev/null +++ b/batches/copy_to_ksp.bat @@ -0,0 +1,21 @@ +echo off +set ConfigurationName=%1 +set PROJECT_NAME=%2 + +set SOURCE_DIR=..\%ConfigurationName%\BepInEx\plugins\%PROJECT_NAME%\ + +@REM call the local_dev_options +call local_dev_options.bat + +echo ####################### Copy to target Ksp dir ####################### +set DEST_PATH="%KSP2_LOCATION%\BepInEx\plugins\%PROJECT_NAME%\" +echo dest path is : %DEST_PATH% + +@REM rd /s/q %DEST_PATH% +if not exist %DEST_PATH% mkdir %DEST_PATH% + +@REM dir %SOURCE_DIR% +@REM dir %DEST_PATH% + +xcopy /Y /s /d %SOURCE_DIR% %DEST_PATH% + diff --git a/batches/get_dlls.bat b/batches/get_dlls.bat new file mode 100644 index 0000000..9d6927e --- /dev/null +++ b/batches/get_dlls.bat @@ -0,0 +1,32 @@ +@REM used to get all dlls from skp 2 and unity. saved to externals_dll directory + +@REM call the ksp_location +call local_dev_options.bat + +@REM echo loc:%KSP2_LOCATION% +echo off + +set OUTPUT=output +set DEST_DIR=..\external_dlls + +echo KSP_LOC : %KSP2_LOCATION% +echo Dest_Dir is : %DEST_DIR% + +echo create local dir %DEST_DIR% +if not exist %DEST_DIR% mkdir %DEST_DIR% + +echo ####################### Get assembly dll ####################### +copy %KSP2_LOCATION%\KSP2_x64_Data\Managed\Assembly-CSharp.dll %DEST_DIR% + +copy %KSP2_LOCATION%\BepInEx\core\BepInEx.dll %DEST_DIR% +copy %KSP2_LOCATION%\BepInEx\plugins\SpaceWarp\SpaceWarp.dll %DEST_DIR% + +copy %KSP2_LOCATION%\KSP2_x64_Data\Managed\Newtonsoft.Json.dll %DEST_DIR% + +copy %KSP2_LOCATION%\KSP2_x64_Data\Managed\UnityEngine.TextRenderingModule.dll %DEST_DIR% +copy %KSP2_LOCATION%\KSP2_x64_Data\Managed\UnityEngine.InputLegacyModule.dll %DEST_DIR% +copy %KSP2_LOCATION%\KSP2_x64_Data\Managed\UnityEngine.IMGUIModule.dll %DEST_DIR% +copy %KSP2_LOCATION%\KSP2_x64_Data\Managed\UnityEngine.CoreModule.dll %DEST_DIR% +copy %KSP2_LOCATION%\KSP2_x64_Data\Managed\UnityEngine.dll %DEST_DIR% + + diff --git a/batches/local_dev_options.bat b/batches/local_dev_options.bat new file mode 100644 index 0000000..d68f58c --- /dev/null +++ b/batches/local_dev_options.bat @@ -0,0 +1,18 @@ +@REM this exemple file should be renamed to ksp_location.bat. +@REM ksp_location.bat is git ignored and therefore can contains informations depending on dev local machine + +@REM set your own KSP2_LOCATION and rename me to ksp_location.bat (git ignored) +@REM ps : don't use "" +set KSP2_LOCATION=C:\Kerbal Space Program 2 Debug + +@REM Create Zip package (require 7zip) +set Create_zip=True + +@REM CLOSE KSP before build +set Close_KSP2=True + +@REM Open KSP after build +set Open_KSP2=True + +@REM Copy to Other Mods repos +@REM set PostBuildCopy=..\FlightPlan\FlightPlanProject\external_dlls;..\ManeuverNodeController\ManeuverNodeControllerProject\external_dlls diff --git a/batches/local_dev_options.exemple.bat b/batches/local_dev_options.exemple.bat new file mode 100644 index 0000000..d2f59f1 --- /dev/null +++ b/batches/local_dev_options.exemple.bat @@ -0,0 +1,18 @@ +@REM this exemple file should be renamed to ksp_location.bat. +@REM ksp_location.bat is git ignored and therefore can contains informations depending on dev local machine + +@REM set your own KSP2_LOCATION and rename me to ksp_location.bat (git ignored) +@REM ps : don't use "" +set KSP2_LOCATION=Z:\SteamLibrary\steamapps\common\Kerbal Space Program 2 + +@REM Create Zip package (require 7zip) +set Create_zip=True + +@REM CLOSE KSP before build +set Close_KSP2=True + +@REM Open KSP after build +set Open_KSP2=True + +@REM Copy to Other Mods repos +set PostBuildCopy=..\FlightPlan\FlightPlanProject\external_dlls;..\ManeuverNodeController\ManeuverNodeControllerProject\external_dlls diff --git a/batches/make_zip.bat b/batches/make_zip.bat new file mode 100644 index 0000000..849f385 --- /dev/null +++ b/batches/make_zip.bat @@ -0,0 +1,35 @@ +@REM Create the zip for SpaceDock +echo off +set ConfigurationName=%1 +set PROJECT_NAME=%2 + +@REM call the local_dev_options +call local_dev_options.bat + +@REM define the default build mode to Debug + +set swinfo_json=..\%PROJECT_NAME%\swinfo.json + +@echo off +@REM Title Get Version from swinfo_json.json using PowerShell with a batch file +Set PSCMD=Powershell -C "$(GC %swinfo_json% | ConvertFrom-Json).version" +@for /f %%a in ('%PSCMD%') do set "Ver=%%a" +@REM echo Version=%Ver% + +set ZIP_File=%PROJECT_NAME%_v%Ver%.zip +SET OUTPUT=..\%ConfigurationName% + +set CWD=%cd% +cd %OUTPUT% + +echo ###################### Build %ZIP_File% #################### +del %ZIP_File% +"C:\Program Files\7-Zip\7z.exe" a %ZIP_File% BepInEx + +if not exist ..\releases mkdir ..\releases + +move %ZIP_File% ..\releases + +cd %CWD% + +:end \ No newline at end of file diff --git a/batches/post_build.bat b/batches/post_build.bat new file mode 100644 index 0000000..66906aa --- /dev/null +++ b/batches/post_build.bat @@ -0,0 +1,35 @@ +echo off + +@REM call the local_dev_options +call local_dev_options.bat + +set ConfigurationName=%1 +set PROJECT_NAME=%2 + +if "%Close_KSP2%"=="True" ( + @REM test if KSP2_x64.exe is running + tasklist /fi "imagename eq KSP2_x64.exe" |find ":" > nul + if errorlevel 1 ( + echo "Kill KSP2 !!!!" + taskkill /f /im "KSP2_x64.exe" + timeout 2 + ) else echo "KSP2 Not running" +) + +if "%Create_zip%"=="True" ( + call make_zip.bat %ConfigurationName% %Project_name% +) + +call copy_to_ksp.bat %ConfigurationName% %Project_name% + +if "%Open_KSP2%"=="True" ( + "%KSP2_LOCATION%\KSP2_x64.exe" +) + +@REM copy to dependencies dll +set SOURCE_DIR=..\%ConfigurationName%\BepInEx\plugins\%PROJECT_NAME%\ +SET Copies=%PostBuildCopy:;= % +FOR %%e in (%Copies%) DO ( + echo copy to ..\%%e + xcopy /Y /s %SOURCE_DIR%\%PROJECT_NAME%.dll ..\%%e +) diff --git a/batches/set_debug_dll.bat b/batches/set_debug_dll.bat new file mode 100644 index 0000000..e64623f --- /dev/null +++ b/batches/set_debug_dll.bat @@ -0,0 +1,9 @@ +@REM copy debug dll (unity) to ksp, useful for debuging +echo off + +@REM call the local_dev_options +call local_dev_options.bat +call kill_ksp.bat + +copy "%KSP2_LOCATION%\backup_dll\UnityPlayer_debug.dll" "%KSP2_LOCATION%\UnityPlayer.dll" + diff --git a/batches/set_release_dll.bat b/batches/set_release_dll.bat new file mode 100644 index 0000000..02f4f7e --- /dev/null +++ b/batches/set_release_dll.bat @@ -0,0 +1,10 @@ +@REM copy release dll (unity) to ksp, quick and official version +echo off + +@REM call the local_dev_options +call local_dev_options.bat + +call kill_ksp.bat + +copy "%KSP2_LOCATION%\backup_dll\UnityPlayer_release.dll" "%KSP2_LOCATION%\UnityPlayer.dll" + From 323d2e33bfc265cfc752b76f71fb0c902c63f17b Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Fri, 23 Jun 2023 11:10:17 -0400 Subject: [PATCH 12/26] Reverted ModId to LazyOrbit so that it will properly update any old installs. Added use of build scripts in post build event --- LazyOrbit/LazyOrbit.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LazyOrbit/LazyOrbit.csproj b/LazyOrbit/LazyOrbit.csproj index 6fbddec..ea1ecf6 100644 --- a/LazyOrbit/LazyOrbit.csproj +++ b/LazyOrbit/LazyOrbit.csproj @@ -13,7 +13,7 @@ https://nuget.spacewarp.org/v3/index.json LazyOrbit - lazy_orbit + LazyOrbit @@ -32,6 +32,6 @@ - + From eed48ee5cd32524f45cfa7cf7242cfcbc1fe2a7f Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Fri, 23 Jun 2023 12:57:36 -0400 Subject: [PATCH 13/26] Moved project files to the project dir --- LazyOrbit/LazyOrbit.csproj | 37 - {LazyOrbit => LazyOrbitProject}/LazyOrbit.cs | 1156 +++++++++--------- LazyOrbitProject/LazyOrbit.csproj | 37 + 3 files changed, 611 insertions(+), 619 deletions(-) delete mode 100644 LazyOrbit/LazyOrbit.csproj rename {LazyOrbit => LazyOrbitProject}/LazyOrbit.cs (96%) create mode 100644 LazyOrbitProject/LazyOrbit.csproj diff --git a/LazyOrbit/LazyOrbit.csproj b/LazyOrbit/LazyOrbit.csproj deleted file mode 100644 index ea1ecf6..0000000 --- a/LazyOrbit/LazyOrbit.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - netstandard2.0 - true - latest - true - com.github.schlosrat.lazy_orbit - Lazy Orbit - A GUI for teleporting to orbit, keybind is ALT+H. - 0.5.1 - - https://nuget.spacewarp.org/v3/index.json - - LazyOrbit - LazyOrbit - - - - - - - - - - - - - ..\external_dlls\Assembly-CSharp.dll - true - false - - - - - - diff --git a/LazyOrbit/LazyOrbit.cs b/LazyOrbitProject/LazyOrbit.cs similarity index 96% rename from LazyOrbit/LazyOrbit.cs rename to LazyOrbitProject/LazyOrbit.cs index 5e3f582..1238b6a 100644 --- a/LazyOrbit/LazyOrbit.cs +++ b/LazyOrbitProject/LazyOrbit.cs @@ -1,583 +1,575 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.IO; -using System.Reflection; - -using UnityEngine; -using Newtonsoft.Json; - -using KSP.Sim.impl; -using KSP.Game; -using KSP.Sim.ResourceSystem; -using KSP.UI.Binding; - -using BepInEx; -using SpaceWarp; -using SpaceWarp.API; -using SpaceWarp.API.Mods; -using SpaceWarp.API.Assets; -using SpaceWarp.API.UI; -using SpaceWarp.API.UI.Appbar; - - -namespace LazyOrbit -{ - [BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)] - [BepInDependency(SpaceWarpPlugin.ModGuid, SpaceWarpPlugin.ModVer)] - public class LazyOrbit : BaseSpaceWarpPlugin - { - // public const string ModGuid = "com.github.halbann.lazyorbit"; - // public const string ModName = "Lazy Orbit"; - public const string ModVer = MyPluginInfo.PLUGIN_VERSION; - // These are useful in case some other mod wants to add a dependency to this one - public const string ModGuid = MyPluginInfo.PLUGIN_GUID; - public const string ModName = MyPluginInfo.PLUGIN_NAME; - // public const string ModVer = MyPluginInfo.PLUGIN_VERSION; - #region Fields - - // Main. - public static bool loaded = false; - public static LazyOrbit instance; - - // Paths. - private static string _assemblyFolder; - private static string AssemblyFolder => - _assemblyFolder ?? (_assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); - - private static string _settingsPath; - private static string SettingsPath => - _settingsPath ?? (_settingsPath = Path.Combine(AssemblyFolder, "settings.json")); - - // GUI. - private static bool guiLoaded = false; - private bool drawUI = false; - private Rect windowRect; - private int windowWidth = 500; - private int windowHeight = 700; - private static GUIStyle boxStyle, errorStyle, warnStyle, peStyle, apStyle, labelStyle; - private static Vector2 scrollPositionBodies; - private static Vector2 scrollPositionVessels; - private static Color labelColor; - private static GameState[] validScenes = new[] { GameState.FlightView, GameState.Map3DView }; - private int spacingAfterEntry = -5; - - // Control click through to the game - private bool gameInputState = true; - public List inputFields = new List(); - - private static bool ValidScene => validScenes.Contains(GameManager.Instance.Game.GlobalGameState.GetState()); - - // Orbit. - private static float altitudeKM = 100; - private static float semiMajorAxisKM = 700; - private static float inclinationDegrees = 0; - private static float eccentricity = 0; - private static float ascendingNode = 0; - private static float argOfPeriapsis = 0; - private static double bodyRadius = 600000; - private static double apKM, peKM; - - private static string altitudeString = altitudeKM.ToString(); - private static string semiMajorAxisString = semiMajorAxisKM.ToString(); - private static string inclinationString = inclinationDegrees.ToString(); - private static string eccentricityString = eccentricity.ToString(); - private static string ascendingNodeString = ascendingNode.ToString(); - private static string argOfPeriapsisString = argOfPeriapsis.ToString(); - - // Body selection. - private string selectedBody = "Kerbin"; - private List bodies; - private bool selectingBody = false; - - // Rendezvous. - private static VesselComponent activeVessel; - private static VesselComponent target; - private static List allVessels; - private static bool selectingVessel = false; - private static float rendezvousDistance = 100f; - private static string rendezvousDistanceString = rendezvousDistance.ToString(); - - // Landing. - private static float latitude = -0.65f; - private static float longitude = 285f; - private static float height = 5f; - private static string latitudeString = latitude.ToString(); - private static string longitudeString = longitude.ToString(); - private static string heightString = height.ToString(); - - // Interface modes. - private static InterfaceMode interfaceMode = InterfaceMode.Simple; - private static string[] interfaceModes = { "Simple", "Advanced", "Landing", "Rendezvous" }; - - private InterfaceMode CurrentInterfaceMode - { - get => interfaceMode; - set - { - if (value == interfaceMode) return; - - interfaceMode = value; - if (new[] { InterfaceMode.Simple, InterfaceMode.Advanced }.Contains(interfaceMode)) - SaveDefaultMode(interfaceMode); - } - } - - #endregion - - #region Main - - public override void OnInitialized() - { - if (loaded) - { - Destroy(this); - } - - loaded = true; - instance = this; - - gameObject.hideFlags = HideFlags.HideAndDontSave; - DontDestroyOnLoad(gameObject); - - interfaceMode = GetDefaultMode(); - - Logger.LogInfo($"Lazy Orbit: SpaceWarpMetadata.ModID = {SpaceWarpMetadata.ModID}"); - - Appbar.RegisterAppButton( - "Lazy Orbit", - "BTN-LazyOrbitButton", - AssetManager.GetAsset($"{SpaceWarpMetadata.ModID}/images/icon.png"), - ToggleButton); - } - - void Awake() - { - windowRect = new Rect((Screen.width * 0.7f) - (windowWidth / 2), (Screen.height / 2) - (windowHeight / 2), 0, 0); - if (windowRect.x < 0) windowRect.x = 0; - if (windowRect.y < 0) windowRect.y = 0; - } - - void Update() - { - if (Input.GetKey(KeyCode.LeftAlt) && Input.GetKeyDown(KeyCode.H) && ValidScene) - ToggleButton(!drawUI); - } - - void OnGUI() - { - //GUIenabled = false; - //var gameState = Game?.GlobalGameState?.GetState(); - //if (gameState == GameState.Map3DView) GUIenabled = true; - //if (gameState == GameState.FlightView) GUIenabled = true; - - if (drawUI && ValidScene) - { - if (!guiLoaded) - GetStyles(); - - GUI.skin = Skins.ConsoleSkin; - - windowRect = GUILayout.Window( - GUIUtility.GetControlID(FocusType.Passive), - windowRect, - FillWindow, - "// LAZY ORBIT", - GUILayout.Height(0), - GUILayout.Width(350)); - - if (gameInputState && inputFields.Contains(GUI.GetNameOfFocusedControl())) - { - // Logger.LogDebug($"OnGUI: Disabling Game Input: Focused Item '{GUI.GetNameOfFocusedControl()}'"); - gameInputState = false; - GameManager.Instance.Game.Input.Disable(); - } - else if (!gameInputState && !inputFields.Contains(GUI.GetNameOfFocusedControl())) - { - // Logger.LogDebug($"OnGUI: Enabling Game Input: FYI, Focused Item '{GUI.GetNameOfFocusedControl()}'"); - gameInputState = true; - GameManager.Instance.Game.Input.Enable(); - } - //if (selectingBody) - //{ - // // Do something here to disable mouse wheel control of zoom in and out. - // // Intent: allow player to scroll in the scroll view without causing the game to zoom in and out - // GameManager.Instance._game.MouseManager.enabled = false; - //} - //else - //{ - // // Do something here to re-enable mouse wheel control of zoom in and out. - // GameManager.Instance._game.MouseManager.enabled = true; - //} - } - else - { - if (!gameInputState) - { - // Logger.LogDebug($"OnGUI: Enabling Game Input due to GUI disabled: FYI, Focused Item '{GUI.GetNameOfFocusedControl()}'"); - gameInputState = true; - GameManager.Instance.Game.Input.Enable(); - } - } - } - - void ToggleButton(bool toggle) - { - drawUI = toggle; - GameObject.Find("BTN-LazyOrbitButton")?.GetComponent()?.SetValue(toggle); - } - - #endregion - - #region GUI - - private void GetStyles() - { - if (boxStyle != null) - return; - - boxStyle = GUI.skin.GetStyle("Box"); - labelStyle = new GUIStyle(GUI.skin.GetStyle("Label")); - errorStyle = new GUIStyle(GUI.skin.GetStyle("Label")); - warnStyle = new GUIStyle(GUI.skin.GetStyle("Label")); - apStyle = new GUIStyle(GUI.skin.GetStyle("Label")); - peStyle = new GUIStyle(GUI.skin.GetStyle("Label")); - errorStyle.normal.textColor = Color.red; - warnStyle.normal.textColor = Color.yellow; - labelColor = GUI.skin.GetStyle("Label").normal.textColor; - - guiLoaded = true; - } - - private void FillWindow(int windowID) - { - if ((activeVessel = GameManager.Instance.Game.ViewController.GetActiveSimVessel()) == null) - { - GUILayout.FlexibleSpace(); - GUILayout.Label("No active vessel.", errorStyle); - GUILayout.FlexibleSpace(); - return; - } - - if (GUI.Button(new Rect(windowRect.width - 18, 2, 16, 16), "x")) - { - Logger.LogDebug("FillWindow: Restoring Game Input on window close."); - GameManager.Instance.Game.Input.Enable(); - ToggleButton(false); - } - - GUILayout.BeginVertical(); - - GUILayout.Label($"Active Vessel: {activeVessel.DisplayName}"); - - // Mode selection. - - GUILayout.BeginHorizontal(); - CurrentInterfaceMode = (InterfaceMode)GUILayout.SelectionGrid((int)CurrentInterfaceMode, interfaceModes, 4); - GUILayout.EndHorizontal(); - - // Draw one of the modes. - switch (CurrentInterfaceMode) - { - case InterfaceMode.Simple: SimpleGUI(); break; - case InterfaceMode.Advanced: AdvancedGUI(); break; - case InterfaceMode.Landing: LandingGUI(); break; - case InterfaceMode.Rendezvous: RendezvousGUI(); break; - default: - break; - } - - // Indication to User that its safe to type, or why vessel controls aren't working - GUILayout.BeginHorizontal(); - string inputStateString = gameInputState ? "Enabled" : "Disabled"; - GUILayout.Label("Game Input: ", labelStyle); - if (gameInputState) - GUILayout.Label(inputStateString, labelStyle); - else - GUILayout.Label(inputStateString, warnStyle); - GUILayout.FlexibleSpace(); - GUILayout.EndHorizontal(); - GUILayout.Space(spacingAfterEntry); - - GUILayout.EndVertical(); - GUI.DragWindow(new Rect(0, 0, 10000, 500)); - } - - void SimpleGUI() - { - bool success = true; - - TextField("Altitude (km):", ref altitudeString, ref altitudeKM, ref success); - BodySelectionGUI(); - - ConditionalButton("Set Orbit", success, SetOrbit); - } - - - void LandingGUI() - { - bool success = true; - - TextField("Latitude (Degrees):", ref latitudeString, ref latitude, ref success); - TextField("Longitude (Degrees):", ref longitudeString, ref longitude, ref success); - TextField("Height (m):", ref heightString, ref height, ref success); - BodySelectionGUI(); - - ConditionalButton("Land", success, Land); - } - - void AdvancedGUI() - { - bool success = true; - - TextField("Semi-Major Axis (km):", ref semiMajorAxisString, ref semiMajorAxisKM, ref success); - - bodyRadius = GameManager.Instance.Game.CelestialBodies.GetRadius(selectedBody) / 1000f; - apKM = (semiMajorAxisKM * (1 + eccentricity) - bodyRadius); - peKM = (semiMajorAxisKM * (1 - eccentricity) - bodyRadius); - apStyle.normal.textColor = apKM < 1 ? warnStyle.normal.textColor : labelColor; - peStyle.normal.textColor = peKM < 1 ? warnStyle.normal.textColor : labelColor; - - GUILayout.BeginHorizontal(); - GUILayout.Label("AP (km): ", apStyle, GUILayout.Width(windowWidth / 4)); - GUILayout.Label(apKM.ToString("n2"), apStyle, GUILayout.Width(windowWidth / 4)); - GUILayout.Label("PE (km): ", peStyle, GUILayout.Width(windowWidth / 4)); - GUILayout.Label(peKM.ToString("n2"), peStyle, GUILayout.Width(windowWidth / 4)); - GUILayout.EndHorizontal(); - - TextField("Inclination (Degrees):", ref inclinationString, ref inclinationDegrees, ref success); - TextField("Eccentricity:", ref eccentricityString, ref eccentricity, ref success); - - if (eccentricity >= 1 || eccentricity < 0) - { - GUILayout.BeginHorizontal(); - GUILayout.Label("Eccentricity must be between 0 and 1.", errorStyle); - GUILayout.EndHorizontal(); - } - - TextField("Longitude of Ascending Node (Degrees):", ref ascendingNodeString, ref ascendingNode, ref success); - TextField("Argument of Periapsis (Degrees):", ref argOfPeriapsisString, ref argOfPeriapsis, ref success); - - BodySelectionGUI(); - - ConditionalButton("Set Orbit", success, SetOrbit); - } - - void RendezvousGUI() - { - bool success = true; - - allVessels = GameManager.Instance.Game.SpaceSimulation.UniverseModel.GetAllVessels(); - allVessels.Remove(activeVessel); - allVessels.RemoveAll(v => v.IsDebris()); - - if (allVessels.Count < 1) - { - GUILayout.Label("No other vessels."); - return; - } - - if (target == null) - target = allVessels.First(); - - TextField("Distance (m):", ref rendezvousDistanceString, ref rendezvousDistance, ref success); - - GUILayout.BeginHorizontal(); - GUILayout.Label("Target: ", GUILayout.Width(0)); - if (!selectingVessel) - { - if (GUILayout.Button(target.DisplayName)) - selectingVessel = true; - } - else - { - GUILayout.BeginVertical(boxStyle); - scrollPositionVessels = GUILayout.BeginScrollView(scrollPositionVessels, false, true, GUILayout.Height(150)); - foreach (VesselComponent vessel in allVessels) - { - if (GUILayout.Button(vessel.DisplayName)) - { - target = vessel; - selectingVessel = false; - } - } - GUILayout.EndScrollView(); - GUILayout.EndVertical(); - } - GUILayout.EndHorizontal(); - - ConditionalButton("Rendezvous", success, Rendezvous); - } - - // Draws the body selection GUI. - void BodySelectionGUI() - { - bodies = GameManager.Instance.Game.SpaceSimulation.GetBodyNameKeys().ToList(); - - GUILayout.BeginHorizontal(); - GUILayout.Label("Body: ", GUILayout.Width(windowWidth / 2)); - if (!selectingBody) - { - if (GUILayout.Button(selectedBody)) - selectingBody = true; - } - else - { - GUILayout.BeginVertical(boxStyle); - scrollPositionBodies = GUILayout.BeginScrollView(scrollPositionBodies, false, true, GUILayout.Height(150)); - foreach (string body in bodies) - { - if (GUILayout.Button(body)) - { - selectedBody = body; - selectingBody = false; - } - } - GUILayout.EndScrollView(); - GUILayout.EndVertical(); - } - GUILayout.EndHorizontal(); - } - - void TextField(string label, ref string field, ref float number, ref bool success) - { - // Setup the list of input field names (most are the same as the entry string text displayed in the GUI window) - if (!inputFields.Contains(label)) - inputFields.Add(label); - - GUILayout.BeginHorizontal(); - GUILayout.Label(label, GUILayout.Width(windowWidth / 2)); - - bool parsed = float.TryParse(field, out number); - if (!parsed) GUI.color = Color.red; - GUI.SetNextControlName(label); - field = GUILayout.TextField(field); - GUI.color = Color.white; - - if (success && !parsed) - success = false; - - GUILayout.EndHorizontal(); - } - - void ConditionalButton(string text, bool condition, Action pressed) - { - GUI.enabled = condition; - - if (GUILayout.Button(text)) - pressed(); - - GUI.enabled = true; - } - - #endregion - - #region Functions - - // Sets vessel orbit according to the current interfaceMode. - void SetOrbit() - { - GameInstance game = GameManager.Instance.Game; - - if (CurrentInterfaceMode == InterfaceMode.Simple) - { - // Set orbit using just altitude. - game.SpaceSimulation.Lua.TeleportToOrbit( - activeVessel.Guid, - selectedBody, - 0, - 0, - (double)altitudeKM * 1000f + GameManager.Instance.Game.CelestialBodies.GetRadius(selectedBody), - 0, - 0, - 0, - 0); - } - else - { - // Set orbit using semi-major axis and other orbital parameters. - game.SpaceSimulation.Lua.TeleportToOrbit( - activeVessel.Guid, - selectedBody, - inclinationDegrees, - eccentricity, - (double)semiMajorAxisKM * 1000f, - ascendingNode, - argOfPeriapsis, - 0, - 0); - } - } - - void Rendezvous() - { - GameInstance game = GameManager.Instance.Game; - - if (target.Guid == activeVessel.Guid) - return; - - game.SpaceSimulation.Lua.TeleportToRendezvous( - activeVessel.Guid, - target.Guid, - rendezvousDistance, - 0, 0, 0, 0, 0); - } - - void Land() - { - GameInstance game = GameManager.Instance.Game; - - game.SpaceSimulation.Lua.TeleportToSurface( - activeVessel.Guid, - selectedBody, - height, - latitude, - longitude, - 0); - } - - #endregion - - #region Settings - - private void SaveDefaultMode(InterfaceMode mode) - { - LazyOrbitSettings settings = new LazyOrbitSettings() - { - defaultMode = mode - }; - - File.WriteAllText(SettingsPath, JsonConvert.SerializeObject(settings)); - } - - private InterfaceMode GetDefaultMode() - { - LazyOrbitSettings settings; - try - { - settings = JsonConvert.DeserializeObject(File.ReadAllText(SettingsPath)); - } - catch (FileNotFoundException) - { - settings = new LazyOrbitSettings(); - } - - return settings.defaultMode; - } - - #endregion - } - - public class LazyOrbitSettings - { - public InterfaceMode defaultMode = InterfaceMode.Simple; - } - - public enum InterfaceMode - { - Simple, - Advanced, - Landing, - Rendezvous, - } +using BepInEx; +using KSP.Game; +using KSP.Sim.impl; +using KSP.Sim.ResourceSystem; +using KSP.UI.Binding; +using Newtonsoft.Json; +using SpaceWarp; +using SpaceWarp.API.Assets; +using SpaceWarp.API.Mods; +using SpaceWarp.API.UI; +using SpaceWarp.API.UI.Appbar; +using System.Reflection; +using UnityEngine; + + +namespace LazyOrbit +{ + [BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)] + [BepInDependency(SpaceWarpPlugin.ModGuid, SpaceWarpPlugin.ModVer)] + public class LazyOrbit : BaseSpaceWarpPlugin + { + // public const string ModGuid = "com.github.halbann.lazyorbit"; + // public const string ModName = "Lazy Orbit"; + public const string ModVer = MyPluginInfo.PLUGIN_VERSION; + // These are useful in case some other mod wants to add a dependency to this one + public const string ModGuid = MyPluginInfo.PLUGIN_GUID; + public const string ModName = MyPluginInfo.PLUGIN_NAME; + // public const string ModVer = MyPluginInfo.PLUGIN_VERSION; + #region Fields + + // Main. + public static bool loaded = false; + public static LazyOrbit instance; + + // Paths. + private static string _assemblyFolder; + private static string AssemblyFolder => + _assemblyFolder ?? (_assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); + + private static string _settingsPath; + private static string SettingsPath => + _settingsPath ?? (_settingsPath = Path.Combine(AssemblyFolder, "settings.json")); + + // GUI. + private static bool guiLoaded = false; + private bool drawUI = false; + private Rect windowRect; + private int windowWidth = 500; + private int windowHeight = 700; + private static GUIStyle boxStyle, errorStyle, warnStyle, peStyle, apStyle, labelStyle; + private static Vector2 scrollPositionBodies; + private static Vector2 scrollPositionVessels; + private static Color labelColor; + private static GameState[] validScenes = new[] { GameState.FlightView, GameState.Map3DView }; + private int spacingAfterEntry = -5; + + // Control click through to the game + private bool gameInputState = true; + public List inputFields = new List(); + + private static bool ValidScene => validScenes.Contains(GameManager.Instance.Game.GlobalGameState.GetState()); + + // Orbit. + private static float altitudeKM = 100; + private static float semiMajorAxisKM = 700; + private static float inclinationDegrees = 0; + private static float eccentricity = 0; + private static float ascendingNode = 0; + private static float argOfPeriapsis = 0; + private static double bodyRadius = 600000; + private static double apKM, peKM; + + private static string altitudeString = altitudeKM.ToString(); + private static string semiMajorAxisString = semiMajorAxisKM.ToString(); + private static string inclinationString = inclinationDegrees.ToString(); + private static string eccentricityString = eccentricity.ToString(); + private static string ascendingNodeString = ascendingNode.ToString(); + private static string argOfPeriapsisString = argOfPeriapsis.ToString(); + + // Body selection. + private string selectedBody = "Kerbin"; + private List bodies; + private bool selectingBody = false; + + // Rendezvous. + private static VesselComponent activeVessel; + private static VesselComponent target; + private static List allVessels; + private static bool selectingVessel = false; + private static float rendezvousDistance = 100f; + private static string rendezvousDistanceString = rendezvousDistance.ToString(); + + // Landing. + private static float latitude = -0.65f; + private static float longitude = 285f; + private static float height = 5f; + private static string latitudeString = latitude.ToString(); + private static string longitudeString = longitude.ToString(); + private static string heightString = height.ToString(); + + // Interface modes. + private static InterfaceMode interfaceMode = InterfaceMode.Simple; + private static string[] interfaceModes = { "Simple", "Advanced", "Landing", "Rendezvous" }; + + private InterfaceMode CurrentInterfaceMode + { + get => interfaceMode; + set + { + if (value == interfaceMode) return; + + interfaceMode = value; + if (new[] { InterfaceMode.Simple, InterfaceMode.Advanced }.Contains(interfaceMode)) + SaveDefaultMode(interfaceMode); + } + } + + #endregion + + #region Main + + public override void OnInitialized() + { + if (loaded) + { + Destroy(this); + } + + loaded = true; + instance = this; + + gameObject.hideFlags = HideFlags.HideAndDontSave; + DontDestroyOnLoad(gameObject); + + interfaceMode = GetDefaultMode(); + + Logger.LogInfo($"Lazy Orbit: SpaceWarpMetadata.ModID = {SpaceWarpMetadata.ModID}"); + + Appbar.RegisterAppButton( + "Lazy Orbit", + "BTN-LazyOrbitButton", + AssetManager.GetAsset($"{SpaceWarpMetadata.ModID}/images/icon.png"), + ToggleButton); + } + + void Awake() + { + windowRect = new Rect((Screen.width * 0.7f) - (windowWidth / 2), (Screen.height / 2) - (windowHeight / 2), 0, 0); + if (windowRect.x < 0) windowRect.x = 0; + if (windowRect.y < 0) windowRect.y = 0; + } + + void Update() + { + if (Input.GetKey(KeyCode.LeftAlt) && Input.GetKeyDown(KeyCode.H) && ValidScene) + ToggleButton(!drawUI); + } + + void OnGUI() + { + //GUIenabled = false; + //var gameState = Game?.GlobalGameState?.GetState(); + //if (gameState == GameState.Map3DView) GUIenabled = true; + //if (gameState == GameState.FlightView) GUIenabled = true; + + if (drawUI && ValidScene) + { + if (!guiLoaded) + GetStyles(); + + GUI.skin = Skins.ConsoleSkin; + + windowRect = GUILayout.Window( + GUIUtility.GetControlID(FocusType.Passive), + windowRect, + FillWindow, + "// LAZY ORBIT", + GUILayout.Height(0), + GUILayout.Width(350)); + + if (gameInputState && inputFields.Contains(GUI.GetNameOfFocusedControl())) + { + // Logger.LogDebug($"OnGUI: Disabling Game Input: Focused Item '{GUI.GetNameOfFocusedControl()}'"); + gameInputState = false; + GameManager.Instance.Game.Input.Disable(); + } + else if (!gameInputState && !inputFields.Contains(GUI.GetNameOfFocusedControl())) + { + // Logger.LogDebug($"OnGUI: Enabling Game Input: FYI, Focused Item '{GUI.GetNameOfFocusedControl()}'"); + gameInputState = true; + GameManager.Instance.Game.Input.Enable(); + } + //if (selectingBody) + //{ + // // Do something here to disable mouse wheel control of zoom in and out. + // // Intent: allow player to scroll in the scroll view without causing the game to zoom in and out + // GameManager.Instance._game.MouseManager.enabled = false; + //} + //else + //{ + // // Do something here to re-enable mouse wheel control of zoom in and out. + // GameManager.Instance._game.MouseManager.enabled = true; + //} + } + else + { + if (!gameInputState) + { + // Logger.LogDebug($"OnGUI: Enabling Game Input due to GUI disabled: FYI, Focused Item '{GUI.GetNameOfFocusedControl()}'"); + gameInputState = true; + GameManager.Instance.Game.Input.Enable(); + } + } + } + + void ToggleButton(bool toggle) + { + drawUI = toggle; + GameObject.Find("BTN-LazyOrbitButton")?.GetComponent()?.SetValue(toggle); + } + + #endregion + + #region GUI + + private void GetStyles() + { + if (boxStyle != null) + return; + + boxStyle = GUI.skin.GetStyle("Box"); + labelStyle = new GUIStyle(GUI.skin.GetStyle("Label")); + errorStyle = new GUIStyle(GUI.skin.GetStyle("Label")); + warnStyle = new GUIStyle(GUI.skin.GetStyle("Label")); + apStyle = new GUIStyle(GUI.skin.GetStyle("Label")); + peStyle = new GUIStyle(GUI.skin.GetStyle("Label")); + errorStyle.normal.textColor = Color.red; + warnStyle.normal.textColor = Color.yellow; + labelColor = GUI.skin.GetStyle("Label").normal.textColor; + + guiLoaded = true; + } + + private void FillWindow(int windowID) + { + if ((activeVessel = GameManager.Instance.Game.ViewController.GetActiveSimVessel()) == null) + { + GUILayout.FlexibleSpace(); + GUILayout.Label("No active vessel.", errorStyle); + GUILayout.FlexibleSpace(); + return; + } + + if (GUI.Button(new Rect(windowRect.width - 18, 2, 16, 16), "x")) + { + Logger.LogDebug("FillWindow: Restoring Game Input on window close."); + GameManager.Instance.Game.Input.Enable(); + ToggleButton(false); + } + + GUILayout.BeginVertical(); + + GUILayout.Label($"Active Vessel: {activeVessel.DisplayName}"); + + // Mode selection. + + GUILayout.BeginHorizontal(); + CurrentInterfaceMode = (InterfaceMode)GUILayout.SelectionGrid((int)CurrentInterfaceMode, interfaceModes, 4); + GUILayout.EndHorizontal(); + + // Draw one of the modes. + switch (CurrentInterfaceMode) + { + case InterfaceMode.Simple: SimpleGUI(); break; + case InterfaceMode.Advanced: AdvancedGUI(); break; + case InterfaceMode.Landing: LandingGUI(); break; + case InterfaceMode.Rendezvous: RendezvousGUI(); break; + default: + break; + } + + // Indication to User that its safe to type, or why vessel controls aren't working + GUILayout.BeginHorizontal(); + string inputStateString = gameInputState ? "Enabled" : "Disabled"; + GUILayout.Label("Game Input: ", labelStyle); + if (gameInputState) + GUILayout.Label(inputStateString, labelStyle); + else + GUILayout.Label(inputStateString, warnStyle); + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + GUILayout.Space(spacingAfterEntry); + + GUILayout.EndVertical(); + GUI.DragWindow(new Rect(0, 0, 10000, 500)); + } + + void SimpleGUI() + { + bool success = true; + + TextField("Altitude (km):", ref altitudeString, ref altitudeKM, ref success); + BodySelectionGUI(); + + ConditionalButton("Set Orbit", success, SetOrbit); + } + + + void LandingGUI() + { + bool success = true; + + TextField("Latitude (Degrees):", ref latitudeString, ref latitude, ref success); + TextField("Longitude (Degrees):", ref longitudeString, ref longitude, ref success); + TextField("Height (m):", ref heightString, ref height, ref success); + BodySelectionGUI(); + + ConditionalButton("Land", success, Land); + } + + void AdvancedGUI() + { + bool success = true; + + TextField("Semi-Major Axis (km):", ref semiMajorAxisString, ref semiMajorAxisKM, ref success); + + bodyRadius = GameManager.Instance.Game.CelestialBodies.GetRadius(selectedBody) / 1000f; + apKM = (semiMajorAxisKM * (1 + eccentricity) - bodyRadius); + peKM = (semiMajorAxisKM * (1 - eccentricity) - bodyRadius); + apStyle.normal.textColor = apKM < 1 ? warnStyle.normal.textColor : labelColor; + peStyle.normal.textColor = peKM < 1 ? warnStyle.normal.textColor : labelColor; + + GUILayout.BeginHorizontal(); + GUILayout.Label("AP (km): ", apStyle, GUILayout.Width(windowWidth / 4)); + GUILayout.Label(apKM.ToString("n2"), apStyle, GUILayout.Width(windowWidth / 4)); + GUILayout.Label("PE (km): ", peStyle, GUILayout.Width(windowWidth / 4)); + GUILayout.Label(peKM.ToString("n2"), peStyle, GUILayout.Width(windowWidth / 4)); + GUILayout.EndHorizontal(); + + TextField("Inclination (Degrees):", ref inclinationString, ref inclinationDegrees, ref success); + TextField("Eccentricity:", ref eccentricityString, ref eccentricity, ref success); + + if (eccentricity >= 1 || eccentricity < 0) + { + GUILayout.BeginHorizontal(); + GUILayout.Label("Eccentricity must be between 0 and 1.", errorStyle); + GUILayout.EndHorizontal(); + } + + TextField("Longitude of Ascending Node (Degrees):", ref ascendingNodeString, ref ascendingNode, ref success); + TextField("Argument of Periapsis (Degrees):", ref argOfPeriapsisString, ref argOfPeriapsis, ref success); + + BodySelectionGUI(); + + ConditionalButton("Set Orbit", success, SetOrbit); + } + + void RendezvousGUI() + { + bool success = true; + + allVessels = GameManager.Instance.Game.SpaceSimulation.UniverseModel.GetAllVessels(); + allVessels.Remove(activeVessel); + allVessels.RemoveAll(v => v.IsDebris()); + + if (allVessels.Count < 1) + { + GUILayout.Label("No other vessels."); + return; + } + + if (target == null) + target = allVessels.First(); + + TextField("Distance (m):", ref rendezvousDistanceString, ref rendezvousDistance, ref success); + + GUILayout.BeginHorizontal(); + GUILayout.Label("Target: ", GUILayout.Width(0)); + if (!selectingVessel) + { + if (GUILayout.Button(target.DisplayName)) + selectingVessel = true; + } + else + { + GUILayout.BeginVertical(boxStyle); + scrollPositionVessels = GUILayout.BeginScrollView(scrollPositionVessels, false, true, GUILayout.Height(150)); + foreach (VesselComponent vessel in allVessels) + { + if (GUILayout.Button(vessel.DisplayName)) + { + target = vessel; + selectingVessel = false; + } + } + GUILayout.EndScrollView(); + GUILayout.EndVertical(); + } + GUILayout.EndHorizontal(); + + ConditionalButton("Rendezvous", success, Rendezvous); + } + + // Draws the body selection GUI. + void BodySelectionGUI() + { + bodies = GameManager.Instance.Game.SpaceSimulation.GetBodyNameKeys().ToList(); + + GUILayout.BeginHorizontal(); + GUILayout.Label("Body: ", GUILayout.Width(windowWidth / 2)); + if (!selectingBody) + { + if (GUILayout.Button(selectedBody)) + selectingBody = true; + } + else + { + GUILayout.BeginVertical(boxStyle); + scrollPositionBodies = GUILayout.BeginScrollView(scrollPositionBodies, false, true, GUILayout.Height(150)); + foreach (string body in bodies) + { + if (GUILayout.Button(body)) + { + selectedBody = body; + selectingBody = false; + } + } + GUILayout.EndScrollView(); + GUILayout.EndVertical(); + } + GUILayout.EndHorizontal(); + } + + void TextField(string label, ref string field, ref float number, ref bool success) + { + // Setup the list of input field names (most are the same as the entry string text displayed in the GUI window) + if (!inputFields.Contains(label)) + inputFields.Add(label); + + GUILayout.BeginHorizontal(); + GUILayout.Label(label, GUILayout.Width(windowWidth / 2)); + + bool parsed = float.TryParse(field, out number); + if (!parsed) GUI.color = Color.red; + GUI.SetNextControlName(label); + field = GUILayout.TextField(field); + GUI.color = Color.white; + + if (success && !parsed) + success = false; + + GUILayout.EndHorizontal(); + } + + void ConditionalButton(string text, bool condition, Action pressed) + { + GUI.enabled = condition; + + if (GUILayout.Button(text)) + pressed(); + + GUI.enabled = true; + } + + #endregion + + #region Functions + + // Sets vessel orbit according to the current interfaceMode. + void SetOrbit() + { + GameInstance game = GameManager.Instance.Game; + + if (CurrentInterfaceMode == InterfaceMode.Simple) + { + // Set orbit using just altitude. + game.SpaceSimulation.Lua.TeleportToOrbit( + activeVessel.Guid, + selectedBody, + 0, + 0, + (double)altitudeKM * 1000f + GameManager.Instance.Game.CelestialBodies.GetRadius(selectedBody), + 0, + 0, + 0, + 0); + } + else + { + // Set orbit using semi-major axis and other orbital parameters. + game.SpaceSimulation.Lua.TeleportToOrbit( + activeVessel.Guid, + selectedBody, + inclinationDegrees, + eccentricity, + (double)semiMajorAxisKM * 1000f, + ascendingNode, + argOfPeriapsis, + 0, + 0); + } + } + + void Rendezvous() + { + GameInstance game = GameManager.Instance.Game; + + if (target.Guid == activeVessel.Guid) + return; + + game.SpaceSimulation.Lua.TeleportToRendezvous( + activeVessel.Guid, + target.Guid, + rendezvousDistance, + 0, 0, 0, 0, 0); + } + + void Land() + { + GameInstance game = GameManager.Instance.Game; + + game.SpaceSimulation.Lua.TeleportToSurface( + activeVessel.Guid, + selectedBody, + height, + latitude, + longitude, + 0); + } + + #endregion + + #region Settings + + private void SaveDefaultMode(InterfaceMode mode) + { + LazyOrbitSettings settings = new LazyOrbitSettings() + { + defaultMode = mode + }; + + File.WriteAllText(SettingsPath, JsonConvert.SerializeObject(settings)); + } + + private InterfaceMode GetDefaultMode() + { + LazyOrbitSettings settings; + try + { + settings = JsonConvert.DeserializeObject(File.ReadAllText(SettingsPath)); + } + catch (FileNotFoundException) + { + settings = new LazyOrbitSettings(); + } + + return settings.defaultMode; + } + + #endregion + } + + public class LazyOrbitSettings + { + public InterfaceMode defaultMode = InterfaceMode.Simple; + } + + public enum InterfaceMode + { + Simple, + Advanced, + Landing, + Rendezvous, + } } \ No newline at end of file diff --git a/LazyOrbitProject/LazyOrbit.csproj b/LazyOrbitProject/LazyOrbit.csproj new file mode 100644 index 0000000..e17b0fa --- /dev/null +++ b/LazyOrbitProject/LazyOrbit.csproj @@ -0,0 +1,37 @@ + + + + netstandard2.0 + true + latest + true + com.github.schlosrat.LazyOrbit + Lazy Orbit + A GUI for teleporting to orbit, keybind is ALT+H. + 0.5.1 + + https://nuget.spacewarp.org/v3/index.json + + LazyOrbit + LazyOrbit + + + + + + + + + + + + + ..\external_dlls\Assembly-CSharp.dll + true + false + + + + + + From 52a32212dc3ef34294f462f58fe9b51848fb6862 Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Fri, 23 Jun 2023 12:58:23 -0400 Subject: [PATCH 14/26] Renamed the release folder to be the same as the original --- {lazy_orbit => LazyOrbit}/assets/images/icon.png | Bin {lazy_orbit => LazyOrbit}/swinfo.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename {lazy_orbit => LazyOrbit}/assets/images/icon.png (100%) rename {lazy_orbit => LazyOrbit}/swinfo.json (95%) diff --git a/lazy_orbit/assets/images/icon.png b/LazyOrbit/assets/images/icon.png similarity index 100% rename from lazy_orbit/assets/images/icon.png rename to LazyOrbit/assets/images/icon.png diff --git a/lazy_orbit/swinfo.json b/LazyOrbit/swinfo.json similarity index 95% rename from lazy_orbit/swinfo.json rename to LazyOrbit/swinfo.json index 18d16a1..f2fea6b 100644 --- a/lazy_orbit/swinfo.json +++ b/LazyOrbit/swinfo.json @@ -1,5 +1,5 @@ { - "mod_id": "lazy_orbit", + "mod_id": "LazyOrbit", "name": "Lazy Orbit", "author": "Halban, XYZ3211, schlosrat", "description": "A GUI for teleporting to orbit, keybind is ALT+H.", From a88bdff0cf967f1271631763fd9a5cff0734d8f6 Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Fri, 23 Jun 2023 12:58:51 -0400 Subject: [PATCH 15/26] Fixed solution file for new project folder name --- LazyOrbit.sln | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/LazyOrbit.sln b/LazyOrbit.sln index ae0c002..c14c939 100644 --- a/LazyOrbit.sln +++ b/LazyOrbit.sln @@ -1,9 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 -VisualStudioVersion = 17.4.33403.182 +VisualStudioVersion = 17.5.33502.453 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LazyOrbit", "LazyOrbit\LazyOrbit.csproj", "{C0BDE81C-46FF-40A1-B3A1-07E40830115C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LazyOrbit", "LazyOrbitProject\LazyOrbit.csproj", "{C0BDE81C-46FF-40A1-B3A1-07E40830115C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -19,7 +19,4 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {1928799A-1D41-4C13-995B-265DF15A63C9} - EndGlobalSection EndGlobal From f6fc0d1969a3c1442e8d1ca0cf25674998f31e79 Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Fri, 23 Jun 2023 12:59:41 -0400 Subject: [PATCH 16/26] Added debug logging to the batch files --- batches/copy_to_ksp.bat | 7 +++++-- batches/get_dlls.bat | 4 +++- batches/local_dev_options.bat | 2 ++ batches/make_zip.bat | 7 +++++-- batches/post_build.bat | 5 ++++- batches/set_debug_dll.bat | 4 +++- 6 files changed, 22 insertions(+), 7 deletions(-) diff --git a/batches/copy_to_ksp.bat b/batches/copy_to_ksp.bat index f3932e2..d1909aa 100644 --- a/batches/copy_to_ksp.bat +++ b/batches/copy_to_ksp.bat @@ -1,7 +1,10 @@ -echo off +echo on +echo "Starting copy_to_ksp.bat" set ConfigurationName=%1 set PROJECT_NAME=%2 +echo ConfigurationName = %ConfigurationName% +echo PROJECT_NAME = %PROJECT_NAME% set SOURCE_DIR=..\%ConfigurationName%\BepInEx\plugins\%PROJECT_NAME%\ @REM call the local_dev_options @@ -9,6 +12,7 @@ call local_dev_options.bat echo ####################### Copy to target Ksp dir ####################### set DEST_PATH="%KSP2_LOCATION%\BepInEx\plugins\%PROJECT_NAME%\" +echo source path is : %SOURCE_DIR% echo dest path is : %DEST_PATH% @REM rd /s/q %DEST_PATH% @@ -18,4 +22,3 @@ if not exist %DEST_PATH% mkdir %DEST_PATH% @REM dir %DEST_PATH% xcopy /Y /s /d %SOURCE_DIR% %DEST_PATH% - diff --git a/batches/get_dlls.bat b/batches/get_dlls.bat index 9d6927e..76f5c3a 100644 --- a/batches/get_dlls.bat +++ b/batches/get_dlls.bat @@ -1,10 +1,12 @@ @REM used to get all dlls from skp 2 and unity. saved to externals_dll directory +echo "Starting get_dlls.bat" + @REM call the ksp_location call local_dev_options.bat @REM echo loc:%KSP2_LOCATION% -echo off +echo on set OUTPUT=output set DEST_DIR=..\external_dlls diff --git a/batches/local_dev_options.bat b/batches/local_dev_options.bat index d68f58c..8948c05 100644 --- a/batches/local_dev_options.bat +++ b/batches/local_dev_options.bat @@ -1,6 +1,8 @@ @REM this exemple file should be renamed to ksp_location.bat. @REM ksp_location.bat is git ignored and therefore can contains informations depending on dev local machine +echo "Starting local_dev_options.bat" + @REM set your own KSP2_LOCATION and rename me to ksp_location.bat (git ignored) @REM ps : don't use "" set KSP2_LOCATION=C:\Kerbal Space Program 2 Debug diff --git a/batches/make_zip.bat b/batches/make_zip.bat index 849f385..0972430 100644 --- a/batches/make_zip.bat +++ b/batches/make_zip.bat @@ -1,5 +1,8 @@ @REM Create the zip for SpaceDock -echo off +echo on + +echo "Starting make_zip.bat" + set ConfigurationName=%1 set PROJECT_NAME=%2 @@ -10,7 +13,7 @@ call local_dev_options.bat set swinfo_json=..\%PROJECT_NAME%\swinfo.json -@echo off +@echo on @REM Title Get Version from swinfo_json.json using PowerShell with a batch file Set PSCMD=Powershell -C "$(GC %swinfo_json% | ConvertFrom-Json).version" @for /f %%a in ('%PSCMD%') do set "Ver=%%a" diff --git a/batches/post_build.bat b/batches/post_build.bat index 66906aa..220aa81 100644 --- a/batches/post_build.bat +++ b/batches/post_build.bat @@ -1,4 +1,7 @@ -echo off +echo on + +echo "Starting post_build.bat" + @REM call the local_dev_options call local_dev_options.bat diff --git a/batches/set_debug_dll.bat b/batches/set_debug_dll.bat index e64623f..201e2ff 100644 --- a/batches/set_debug_dll.bat +++ b/batches/set_debug_dll.bat @@ -1,5 +1,7 @@ @REM copy debug dll (unity) to ksp, useful for debuging -echo off +echo on + +echo "Starting set_debug_dll.bat" @REM call the local_dev_options call local_dev_options.bat From 122f436cbda1b71b6b21c4af9c75b9e3a2036090 Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Fri, 23 Jun 2023 13:02:22 -0400 Subject: [PATCH 17/26] Updated gitignore in prep to switch to UITK --- .gitignore | 347 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 275 insertions(+), 72 deletions(-) diff --git a/.gitignore b/.gitignore index d23b451..552883f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,42 +1,163 @@ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +## Unity Project ignores + +# This .gitignore file should be placed at the root of your Unity project directory +# +# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore +# +/UI/[Ll]ibrary/ +/UI/[Tt]emp/ +/UI/[Oo]bj/ +/UI/[Bb]uild/ +/UI/[Bb]uilds/ +/UI/[Ll]ogs/ +/UI/[Uu]ser[Ss]ettings/ + +# MemoryCaptures can get excessive in size. +# They also could contain extremely sensitive data +/UI/[Mm]emoryCaptures/ + +# Recordings can get excessive in size +/UI/[Rr]ecordings/ + +# Uncomment this line if you wish to ignore the asset store tools plugin +/UI/[Aa]ssets/AssetStoreTools* + +# Autogenerated Jetbrains Rider plugin +/UI/[Aa]ssets/Plugins/Editor/JetBrains* + +# Visual Studio cache directory +.vs/ + +# Gradle cache directory +/UI/.gradle/ + +# Autogenerated VS/MD/Consulo solution and project files +/UI/ExportedObj/ +/UI/.consulo/ +/UI/*.csproj +/UI/*.unityproj +/UI/*.sln +/UI/*.suo +/UI/*.tmp +/UI/*.user +/UI/*.userprefs +/UI/*.pidb +/UI/*.booproj +/UI/*.svd +/UI/*.pdb +/UI/*.mdb +/UI/*.opendb +/UI/*.VC.db + +# Unity3D generated meta files +*.pidb.meta +*.pdb.meta +*.mdb.meta + +# Unity3D generated file on crash reports +sysinfo.txt + +# Builds +*.apk +*.aab +*.unitypackage +*.app + +# Crashlytics generated file +crashlytics-build.properties + +# Packed Addressables +/UI/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin* + +# Temporary auto-generated Android Assets +/UI/[Aa]ssets/[Ss]treamingAssets/aa.meta +/UI/[Aa]ssets/[Ss]treamingAssets/aa/* # User-specific files +*.rsuser *.suo *.user +*.userosscache *.sln.docstates +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# KSP dlls +external_dlls/ + # Build results [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ +[Rr]eleases/ x64/ -build/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ bld/ [Bb]in/ [Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* -#NUNIT +# NUnit *.VisualState.xml TestResult.xml +nunit-*.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio *_i.c *_p.c -*_i.h +*_h.h *.ilk *.meta *.obj +*.iobj *.pch *.pdb +*.ipdb *.pgc *.pgd *.rsp @@ -46,6 +167,7 @@ dlldata.c *.tlh *.tmp *.tmp_proj +*_wpftmp.csproj *.log *.vspscc *.vssscc @@ -61,14 +183,21 @@ _Chutzpah* ipch/ *.aps *.ncb +*.opendb *.opensdf *.sdf *.cachefile +*.VC.db +*.VC.VC.opendb # Visual Studio profiler *.psess *.vsp *.vspx +*.sap + +# Visual Studio Trace Files +*.e2e # TFS 2012 Local Workspace $tf/ @@ -81,19 +210,29 @@ _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user -# JustCode is a .NET coding addin-in -.JustCode - # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + # NCrunch -*.ncrunch* _NCrunch_* .*crunch*.local.xml +nCrunchTemp_* # MightyMoose *.mm.* @@ -121,118 +260,182 @@ publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml - -# NuGet Packages Directory -packages/ -## TODO: If the tool you use requires repositories.config uncomment the next line -#!packages/repositories.config - -# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets -# This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented) -!packages/build/ - -# Windows Azure Build Output +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output csx/ *.build.csdef -# Windows Store app package directory +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ # Others -sql/ -*.Cache ClientBin/ -[Ss]tyle[Cc]op.* ~$* *~ *.dbmdl *.dbproj.schemaview +*.jfm *.pfx *.publishsettings -node_modules/ +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ # RIA/Silverlight projects Generated_Code/ -# Backup & report files from converting an old project file to a newer -# Visual Studio version. Backup files are not needed, because we have git ;-) +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak # SQL Server files *.mdf *.ldf +*.ndf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl # Microsoft Fakes FakesAssemblies/ -# ========================= -# Operating System Files -# ========================= +# GhostDoc plugin setting file +*.GhostDoc.xml -# OSX -# ========================= +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ -.DS_Store -.AppleDouble -.LSOverride +# Visual Studio 6 build log +*.plg -# Icon must ends with two \r. -Icon +# Visual Studio 6 workspace options file +*.opt -# Thumbnails -._* +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw -# Files that might appear on external disk -.Spotlight-V100 -.Trashes +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk +# Paket dependency manager +.paket/paket.exe +paket-files/ +# FAKE - F# Make +.fake/ +# CodeRush personal settings +.cr/personal -# Windows -# ========================= +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc -# Windows image file caches -Thumbs.db -ehthumbs.db +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config -# Folder config file -Desktop.ini +# Tabs Studio +*.tss -# Recycle Bin used on file shares -$RECYCLE.BIN/ +# Telerik's JustMock configuration file +*.jmconfig -# Windows Installer files -*.cab -*.msi -*.msm -*.msp +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs -# Windows shortcuts -*.lnk +# OpenCover UI analysis results +OpenCover/ -# -# Vim files -# -*~ -*.swp -*.dll -*.pdb -.vs +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ -*.exe -readme.txt \ No newline at end of file +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file From 17c04bd057d7ca5a3b101e6aea3c31e5d675b822 Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Mon, 26 Jun 2023 12:34:31 -0400 Subject: [PATCH 18/26] Updated for version 0.5.2 --- LazyOrbit/swinfo.json | 2 +- LazyOrbitProject/LazyOrbit.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LazyOrbit/swinfo.json b/LazyOrbit/swinfo.json index f2fea6b..82395ef 100644 --- a/LazyOrbit/swinfo.json +++ b/LazyOrbit/swinfo.json @@ -4,7 +4,7 @@ "author": "Halban, XYZ3211, schlosrat", "description": "A GUI for teleporting to orbit, keybind is ALT+H.", "source": "https://github.com/schlosrat/LazyOrbit", - "version": "0.5.1", + "version": "0.5.2", "version_check": "https://raw.githubusercontent.com/schlosrat/LazyOrbit/master/lazy_orbit/swinfo.json", "dependencies": [ { diff --git a/LazyOrbitProject/LazyOrbit.csproj b/LazyOrbitProject/LazyOrbit.csproj index e17b0fa..ffff0fd 100644 --- a/LazyOrbitProject/LazyOrbit.csproj +++ b/LazyOrbitProject/LazyOrbit.csproj @@ -8,7 +8,7 @@ com.github.schlosrat.LazyOrbit Lazy Orbit A GUI for teleporting to orbit, keybind is ALT+H. - 0.5.1 + 0.5.2 https://nuget.spacewarp.org/v3/index.json From ee522d38a774655598ec29cd12d9401187304f74 Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Mon, 26 Jun 2023 12:35:32 -0400 Subject: [PATCH 19/26] Fixed bug in getting the filtered list of vessels --- LazyOrbitProject/LazyOrbit.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/LazyOrbitProject/LazyOrbit.cs b/LazyOrbitProject/LazyOrbit.cs index 1238b6a..06b1573 100644 --- a/LazyOrbitProject/LazyOrbit.cs +++ b/LazyOrbitProject/LazyOrbit.cs @@ -1,5 +1,6 @@ using BepInEx; using KSP.Game; +using KSP.Messages.PropertyWatchers; using KSP.Sim.impl; using KSP.Sim.ResourceSystem; using KSP.UI.Binding; @@ -359,18 +360,18 @@ void RendezvousGUI() { bool success = true; - allVessels = GameManager.Instance.Game.SpaceSimulation.UniverseModel.GetAllVessels(); - allVessels.Remove(activeVessel); - allVessels.RemoveAll(v => v.IsDebris()); + allVessels = Game.SpaceSimulation.UniverseModel.GetAllVessels(); + List filteredVessels = new(allVessels.Where(v => !v.IsDebris() && v.GlobalId != activeVessel.GlobalId)); + // allVessels.Remove(activeVessel); + // allVessels.RemoveAll(v => v.IsDebris()); - if (allVessels.Count < 1) + if (filteredVessels.Count < 1) { GUILayout.Label("No other vessels."); return; } - if (target == null) - target = allVessels.First(); + target ??= filteredVessels.First(); TextField("Distance (m):", ref rendezvousDistanceString, ref rendezvousDistance, ref success); @@ -385,7 +386,7 @@ void RendezvousGUI() { GUILayout.BeginVertical(boxStyle); scrollPositionVessels = GUILayout.BeginScrollView(scrollPositionVessels, false, true, GUILayout.Height(150)); - foreach (VesselComponent vessel in allVessels) + foreach (VesselComponent vessel in filteredVessels) { if (GUILayout.Button(vessel.DisplayName)) { From ec290952f543cfcad419c56b3866dd7317ea6bb3 Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Mon, 26 Jun 2023 16:55:41 -0400 Subject: [PATCH 20/26] Update README.md Updated install guide for clarity. Added warning about use of mod when reporting bugs or teleporting craft. --- README.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 027e7af..8503656 100644 --- a/README.md +++ b/README.md @@ -5,24 +5,32 @@ Lazy Orbit is a simple mod that allows you to set a vessel's orbit, land it on a surface, or teleport it to another vessel. Open the GUI by clicking the button in the APP.BAR (or press ALT+H), select a body and an altitude, and press Set Orbit. Great for testing and modding, don't use it for anything nefarious! ## Installation -1. Download and extract SpaceWarp into your game folder. If you've installed the game via Steam, then this is probably here: *C:\Program Files (x86)\Steam\steamapps\common\Kerbal Space Program 2*. If you complete this step correctly you'll have a **BepInEx** subfolder in that directory along with the following files (in addition to what was there before): **changelog.txt, doorstop_config.ini, winhttp.dll** -1. Download and extract this mod into the game folder. The mod's ZIP file contains a single BepInEx folder. You can drag that right onto your KSP2 folder to install the mod. If done correctly, you should have the following folder structure within your KSP2 game folder: *KSP2GameFolder*/**BepInEx/plugins/lazy_orbit**. +1. Install [BepInEx/SpaceWarp](https://spacedock.info/mod/3277/Space%20Warp%20+%20BepInEx). (Skip if you've done this previously) + 1. Download and extract BepInEx/SpaceWarp into your game folder. If you've installed the game via Steam, then this is probably here: *C:\Program Files (x86)\Steam\steamapps\common\Kerbal Space Program 2*. +1. Download and extract [Lazy Orbit Boosted](https://spacedock.info/mod/3410/Lazy%20Orbit%20Boosted) into your game's BepInEx/plugins folder. + 1. The mod's ZIP file contains a single BepInEx folder. You can drag that right onto your KSP2 folder (e.g., *C:\Program Files (x86)\Steam\steamapps\common\Kerbal Space Program 2*) to install the mod. + 2. Alternatively you may install the mod via CKAN + 1. If done correctly, you should have the following folder structure within your KSP2 game folder: *KSP2GameFolder*/**BepInEx/plugins/LazyOrbit**. ## Compatibility * Tested with Kerbal Space Program 2 v0.1.2.0.22258 & SpaceWarp 1.1.3 * Requires SpaceWarp 1.0.1 +## Warning! +* Do not use this mod when preparing bug reports for the Early Access game as teleporting craft is incompatible with this purpose. +* It is advisable to perform a Quick Save (F5) prior to teleporting any vessel as teleporting will void the warranty and may damage your craft. Not kidding here, it may do damage to your craft. + ## Features * **Simple Mode**: Set the **Altitude** you want, pick the **Body** you'd like to be in orbit about, and press the **Set Orbit** button! What could possibly be simpler? -* **Advanced Mode**: Pic the **Body** you want to be in orbit about, then configure specific parameters you want to get the exact orbit you need. Set your **Semi-Major Axis** and see what you'll get for *Ap* and *Pe*. Set your **Inclination**, **Eccentricity**, **Longitude of Ascending Node**, and **Argument of Periapsis**. With these configured, press the **Set Orbit** button and before you know it you'll be in the exact orbit you want! +* **Advanced Mode**: Pick the **Body** you want to be in orbit about, then configure specific parameters you want to get the exact orbit you need. Set your **Semi-Major Axis** and see what you'll get for *Ap* and *Pe*. Set your **Inclination**, **Eccentricity**, **Longitude of Ascending Node**, and **Argument of Periapsis**. With these configured, press the **Set Orbit** button and before you know it you'll be in the exact orbit you want! * **Landing Mode**: Here you can set the **Lattitude**, **Longitude**, and **Height** above ground level for the point you'd like to have your craft dropped at on the **Body** you've selected. Be sure to have landing legs and/or parachutes ready, or this might be a bumpy ride! -* **Rendezvous Mode**: Set the **Distance** (in meters) you'd like to be from a **Target** you can pick from the drop down menu, then just press the **Rendezvous** button and you'll be there in a flash! +* **Rendezvous Mode**: Set the **Distance** (in meters) you'd like to be from a **Target** you can pick from the dropdown menu, then just press the **Rendezvous** button and you'll be there in a flash! -In all modes, if you click inside a text entry field that will automaticaly disable game input from the keyboard and mouse. This allows you to type you need to without inadvertently increasing time warp or muting the game or music. Your current Game Input state is displayed on the bottom of the GUI, and will be bright Yellow when game input is disabled. Game input from your keyboard and mouse are automatically restored when you click anywhere outside a text input field, or if you shoudl close the mod. In the image below note that Game Input is shown as Disabled. +In all modes, clicking inside a text entry field will automatically disable game input from the keyboard and mouse. This allows you to type what you need to without inadvertently affecting the timewarp or muting the game or music. Your current Game Input state is displayed on the bottom of the GUI and will be bright Yellow when game input is disabled. Game input from your keyboard and mouse is automatically restored when you click anywhere outside a text input field, or if you should close the mod. In the image below note that Game Input is shown as Disabled. ![Lazy Orbit - Advanced Mode](https://i.imgur.com/GuGAHds.png) -All the text input fields in this mods GUI are designed for entering numbers. If you should accidentally type sonthing that can't be converted to a number (e.g., include non numeric characters or to many decimal points, etc.) the mod will alert you by setting that field to red as shown above. +All the text input fields in this mod's GUI are designed for entering numbers. If you should accidentally type something that can't be converted to a number (e.g., include non-numeric characters or too many decimal points, etc.) the mod will alert you by setting that field to red as shown above. # Contributors From 1b41a5d3cc93ea06f291f5ab0e62f53a0a7d8db6 Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Mon, 26 Jun 2023 17:03:47 -0400 Subject: [PATCH 21/26] Update README.md Corrected compatibility testing info --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8503656..35296a1 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,12 @@ Lazy Orbit is a simple mod that allows you to set a vessel's orbit, land it on a 1. Install [BepInEx/SpaceWarp](https://spacedock.info/mod/3277/Space%20Warp%20+%20BepInEx). (Skip if you've done this previously) 1. Download and extract BepInEx/SpaceWarp into your game folder. If you've installed the game via Steam, then this is probably here: *C:\Program Files (x86)\Steam\steamapps\common\Kerbal Space Program 2*. 1. Download and extract [Lazy Orbit Boosted](https://spacedock.info/mod/3410/Lazy%20Orbit%20Boosted) into your game's BepInEx/plugins folder. - 1. The mod's ZIP file contains a single BepInEx folder. You can drag that right onto your KSP2 folder (e.g., *C:\Program Files (x86)\Steam\steamapps\common\Kerbal Space Program 2*) to install the mod. - 2. Alternatively you may install the mod via CKAN + 1. The mod's ZIP file contains a single BepInEx folder. You can drag the BepInEx folder from the ZIP right onto your KSP2 folder (e.g., *C:\Program Files (x86)\Steam\steamapps\common\Kerbal Space Program 2*) to install the mod. + 1. Alternatively you may install the mod via CKAN 1. If done correctly, you should have the following folder structure within your KSP2 game folder: *KSP2GameFolder*/**BepInEx/plugins/LazyOrbit**. ## Compatibility -* Tested with Kerbal Space Program 2 v0.1.2.0.22258 & SpaceWarp 1.1.3 +* Tested with Kerbal Space Program 2 v0.1.3 & SpaceWarp 1.3.0.1 * Requires SpaceWarp 1.0.1 ## Warning! From 7665c330473ec7b833c26ba36c20ccb77d39ec98 Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Wed, 5 Jul 2023 06:41:42 -0400 Subject: [PATCH 22/26] Corrected version_check string --- LazyOrbit/swinfo.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LazyOrbit/swinfo.json b/LazyOrbit/swinfo.json index 82395ef..441b428 100644 --- a/LazyOrbit/swinfo.json +++ b/LazyOrbit/swinfo.json @@ -5,7 +5,7 @@ "description": "A GUI for teleporting to orbit, keybind is ALT+H.", "source": "https://github.com/schlosrat/LazyOrbit", "version": "0.5.2", - "version_check": "https://raw.githubusercontent.com/schlosrat/LazyOrbit/master/lazy_orbit/swinfo.json", + "version_check": "https://raw.githubusercontent.com/schlosrat/LazyOrbit/master/LazyOrbit/swinfo.json", "dependencies": [ { "id": "SpaceWarp", From b884bc26d00409112136549a18eb58dabe1b6dba Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Wed, 5 Jul 2023 06:43:01 -0400 Subject: [PATCH 23/26] Updated to version 0.5.3 --- LazyOrbit/swinfo.json | 2 +- LazyOrbitProject/LazyOrbit.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LazyOrbit/swinfo.json b/LazyOrbit/swinfo.json index 441b428..b745faf 100644 --- a/LazyOrbit/swinfo.json +++ b/LazyOrbit/swinfo.json @@ -4,7 +4,7 @@ "author": "Halban, XYZ3211, schlosrat", "description": "A GUI for teleporting to orbit, keybind is ALT+H.", "source": "https://github.com/schlosrat/LazyOrbit", - "version": "0.5.2", + "version": "0.5.3", "version_check": "https://raw.githubusercontent.com/schlosrat/LazyOrbit/master/LazyOrbit/swinfo.json", "dependencies": [ { diff --git a/LazyOrbitProject/LazyOrbit.csproj b/LazyOrbitProject/LazyOrbit.csproj index ffff0fd..fbe97a2 100644 --- a/LazyOrbitProject/LazyOrbit.csproj +++ b/LazyOrbitProject/LazyOrbit.csproj @@ -8,7 +8,7 @@ com.github.schlosrat.LazyOrbit Lazy Orbit A GUI for teleporting to orbit, keybind is ALT+H. - 0.5.2 + 0.5.3 https://nuget.spacewarp.org/v3/index.json From d2c9aed91057c1470179283b242c3467b65ccd82 Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Wed, 5 Jul 2023 06:57:47 -0400 Subject: [PATCH 24/26] Update README.md Updated for latest versions in compatibility --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 35296a1..c4bfab6 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Lazy Orbit is a simple mod that allows you to set a vessel's orbit, land it on a 1. If done correctly, you should have the following folder structure within your KSP2 game folder: *KSP2GameFolder*/**BepInEx/plugins/LazyOrbit**. ## Compatibility -* Tested with Kerbal Space Program 2 v0.1.3 & SpaceWarp 1.3.0.1 +* Tested with Kerbal Space Program 2 v0.1.3.1 & SpaceWarp 1.3.0.3 * Requires SpaceWarp 1.0.1 ## Warning! From 2e2e9b395a93c50d6e34fb081395b7b11217c33a Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Thu, 6 Jul 2023 07:23:26 -0400 Subject: [PATCH 25/26] Added user configurable hot key settings. Gave GUI a default starting position of 400, 250 --- LazyOrbitProject/LazyOrbit.cs | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/LazyOrbitProject/LazyOrbit.cs b/LazyOrbitProject/LazyOrbit.cs index 06b1573..c24172b 100644 --- a/LazyOrbitProject/LazyOrbit.cs +++ b/LazyOrbitProject/LazyOrbit.cs @@ -1,4 +1,5 @@ using BepInEx; +using BepInEx.Configuration; using KSP.Game; using KSP.Messages.PropertyWatchers; using KSP.Sim.impl; @@ -27,6 +28,10 @@ public class LazyOrbit : BaseSpaceWarpPlugin public const string ModGuid = MyPluginInfo.PLUGIN_GUID; public const string ModName = MyPluginInfo.PLUGIN_NAME; // public const string ModVer = MyPluginInfo.PLUGIN_VERSION; + + private ConfigEntry _keybind; + private ConfigEntry _keybind2; + #region Fields // Main. @@ -130,6 +135,18 @@ public override void OnInitialized() loaded = true; instance = this; + _keybind = Config.Bind( + new ConfigDefinition("Keybindings", "First Keybind"), + new KeyboardShortcut(KeyCode.H, KeyCode.LeftAlt), + new ConfigDescription("Keybind to open mod window") + ); + + _keybind2 = Config.Bind( + new ConfigDefinition("Keybindings", "Second Keybind"), + new KeyboardShortcut(KeyCode.H, KeyCode.RightAlt, KeyCode.AltGr), + new ConfigDescription("Keybind to open mod window") + ); + gameObject.hideFlags = HideFlags.HideAndDontSave; DontDestroyOnLoad(gameObject); @@ -147,14 +164,20 @@ public override void OnInitialized() void Awake() { windowRect = new Rect((Screen.width * 0.7f) - (windowWidth / 2), (Screen.height / 2) - (windowHeight / 2), 0, 0); - if (windowRect.x < 0) windowRect.x = 0; - if (windowRect.y < 0) windowRect.y = 0; + if (windowRect.x < 0) windowRect.x = 400; + if (windowRect.y < 0) windowRect.y = 250; } void Update() { - if (Input.GetKey(KeyCode.LeftAlt) && Input.GetKeyDown(KeyCode.H) && ValidScene) + if ((_keybind != null && _keybind.Value.IsDown()) || (_keybind2 != null && _keybind2.Value.IsDown())) + { ToggleButton(!drawUI); + if (_keybind != null && _keybind.Value.IsDown()) + Logger.LogDebug($"Update: UI toggled with _keybind, hotkey {_keybind.Value}"); + if (_keybind2 != null && _keybind2.Value.IsDown()) + Logger.LogDebug($"Update: UI toggled with _keybind2, hotkey {_keybind2.Value}"); + } } void OnGUI() From 641608519bc1c5b673def48c1cd33e2901ed40d2 Mon Sep 17 00:00:00 2001 From: Steve Ratts <50781429+schlosrat@users.noreply.github.com> Date: Fri, 2 Feb 2024 21:18:43 -0500 Subject: [PATCH 26/26] Update swinfo.json Set max game version to 0.1.5 --- LazyOrbit/swinfo.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LazyOrbit/swinfo.json b/LazyOrbit/swinfo.json index b745faf..98a664a 100644 --- a/LazyOrbit/swinfo.json +++ b/LazyOrbit/swinfo.json @@ -17,6 +17,6 @@ ], "ksp2_version": { "min": "0.1.1", - "max": "*" + "max": "0.1.5" } }