diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4ce6fdd --- /dev/null +++ b/.gitignore @@ -0,0 +1,340 @@ +## 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 + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# 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 +*.VisualState.xml +TestResult.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/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +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/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-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 + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# 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 +# 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 + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +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 ;-) +_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 +*- Backup*.rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# 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 \ No newline at end of file diff --git a/GameData/SmartDockingAid/Assets/ParallelMinus.png b/GameData/SmartDockingAid/Assets/ParallelMinus.png new file mode 100644 index 0000000..d8e4c75 Binary files /dev/null and b/GameData/SmartDockingAid/Assets/ParallelMinus.png differ diff --git a/GameData/SmartDockingAid/Assets/ParallelPlus.png b/GameData/SmartDockingAid/Assets/ParallelPlus.png new file mode 100644 index 0000000..f726193 Binary files /dev/null and b/GameData/SmartDockingAid/Assets/ParallelPlus.png differ diff --git a/GameData/SmartDockingAid/Assets/assets b/GameData/SmartDockingAid/Assets/assets deleted file mode 100644 index 0749eb5..0000000 Binary files a/GameData/SmartDockingAid/Assets/assets and /dev/null differ diff --git a/GameData/SmartDockingAid/Assets/assets.ksp b/GameData/SmartDockingAid/Assets/assets.ksp deleted file mode 100644 index 0749eb5..0000000 Binary files a/GameData/SmartDockingAid/Assets/assets.ksp and /dev/null differ diff --git a/GameData/SmartDockingAid/SDA.version b/GameData/SmartDockingAid/SDA.version index 1723f9a..a26aa8b 100644 --- a/GameData/SmartDockingAid/SDA.version +++ b/GameData/SmartDockingAid/SDA.version @@ -6,31 +6,31 @@ { "USERNAME":"ValiZockt", "REPOSITORY":"SmartDockingAid", - "ALLOW_PRE_RELEASE":false, + "ALLOW_PRE_RELEASE":false }, "VERSION": { "MAJOR":1, - "MINOR":1, + "MINOR":2, "PATCH":0, "BUILD":0 }, "KSP_VERSION": { "MAJOR":1, - "MINOR":10, - "PATCH":1 + "MINOR":12, + "PATCH":3 }, "KSP_VERSION_MIN": { "MAJOR":1, - "MINOR":8, - "PATCH":0 + "MINOR":12, + "PATCH":3 }, "KSP_VERSION_MAX": { "MAJOR":1, - "MINOR":10, + "MINOR":12, "PATCH":99 } } \ No newline at end of file diff --git a/GameData/SmartDockingAid/SmartDockingAid.cfg b/GameData/SmartDockingAid/SmartDockingAid.cfg index 407895e..af1a786 100644 --- a/GameData/SmartDockingAid/SmartDockingAid.cfg +++ b/GameData/SmartDockingAid/SmartDockingAid.cfg @@ -2,24 +2,18 @@ SDASETTINGS { - minPilotExperience = 3 // Sets the level of a pilot that has to be onboard (if no ModuleDockingAid is avaible) (MIN: 3, MAX:5) -} - - // Adds the ModuleDockingAid to every Part that has the highest SAS Service SASServiceLevel. - // If SAS Level set lower than 3 (i.e. 1 & 2) the buttons will not show. - -@PART[*]:HAS[@MODULE[ModuleSAS]:HAS[#SASServiceLevel[3]]]:FOR[SmartDockingAid] -{ - MODULE - { - name = ModuleDockingAid - } -} - -// Deletes the ModuleDockingAid Module if it was added to a part with SASServiceLevel < 3. + // Define alongise which stock SAS mode the custom parallel/antiparallel SAS modes will be available. + // Possible values : + // StabilityAssist + // Prograde + // Retrograde + // Normal + // Antinormal + // RadialIn + // RadialOut + // Target + // AntiTarget + // Maneuver -@PART[*]:HAS[@MODULE[ModuleDockingAid],@MODULE[ModuleSAS]:HAS[~SASServiceLevel[3]]]:LAST[SmartDockingAid] -{ - !MODULE[ModuleDockingAid],* {} + availableAtSASMode = Target } - diff --git a/GameData/SmartDockingAid/SmartDockingAid.dll b/GameData/SmartDockingAid/SmartDockingAid.dll index 2cf9cf6..64dfd77 100644 Binary files a/GameData/SmartDockingAid/SmartDockingAid.dll and b/GameData/SmartDockingAid/SmartDockingAid.dll differ diff --git a/README.md b/README.md index 40fbfe7..ef60b7b 100644 --- a/README.md +++ b/README.md @@ -6,3 +6,19 @@ Smart Docking Aid adds two new SAS modes to level 3 probe cores and level 3 pilo ### License This work is licensed under the Attribution-NonCommercial-ShareAlike 4.0 International license (CC BY-NC-SA 4.0) + +### Building +After loading the solution in your IDE, add a `ReferencePath` to the root of your KSP install : + +For Visual Studio, right-click on the `SmartDockingAid` project > `Properties` > `Reference Paths`, then save, close and re-open the solution for the changes to propagate. + +Alternatively, create a `SmartDockingAid.csproj.user` file in the `Source` folder, with the following content : +```xml + + + + Absolute\Path\To\Your\KSP\Install\Folder + + +``` +Then close / re-open the solution. \ No newline at end of file diff --git a/Source/AssetLoader.cs b/Source/AssetLoader.cs deleted file mode 100644 index faf673c..0000000 --- a/Source/AssetLoader.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; - -namespace SmartDockingAid -{ - [KSPAddon(KSPAddon.Startup.Instantly, true)] - public class AssetLoader : MonoBehaviour - { - public static Texture2D parallelMinus = new Texture2D(16, 16, TextureFormat.DXT5, false); - public static Texture2D parallelPlus = new Texture2D(16, 16, TextureFormat.DXT5, false); - public static int minPilotLevel = 3; - //public static GameObject rotSlider; - - public void Awake() - { - string path = KSPUtil.ApplicationRootPath + "GameData/SmartDockingAid/"; - AssetBundle asset = AssetBundle.LoadFromFile(path + "Assets/assets"); - - if (asset == null) - { - Debug.Log($"[SmartDockingAid] Failed to load bundle"); - Debug.Log($"[SmartDockingAid] {path}"); - } - else - { - parallelMinus = asset.LoadAsset("ParallelMinus"); - parallelPlus = asset.LoadAsset("ParallelPlus"); - //rotSlider = textures.LoadAsset("SliderPanel") as GameObject; - - Debug.Log($"[SmartDockingAid] Bundle loaded sucessfully"); - Debug.Log($"[SmartDockingAid] {path}"); - } - - if (GameDatabase.Instance.ExistsConfigNode("SmartDockingAid/SDASETTINGS")) - { - ConfigNode node = GameDatabase.Instance.GetConfigNode("SmartDockingAid/SDASETTINGS"); - if (node.HasValue("minPilotExperience")) - { - if (Int32.TryParse(node.GetValue("minPilotExperience"), out minPilotLevel)) - { - Debug.Log($"[SmartDockingAid] Settings applied"); - } - else - { - Debug.Log($"[SmartDockingAid] minPilotExperience is not a valid number"); - Debug.Log($"[SmartDockingAid] Default settings will be applied"); - } - } - } - else - { - Debug.Log($"[SmartDockingAid] Settings file could not be located"); - Debug.Log($"[SmartDockingAid] Default settings will be applied"); - } - } - } -} diff --git a/Source/Extensions/OverwriteModuleText.cs b/Source/Extensions/OverwriteModuleText.cs index cb25ecd..0681faa 100644 --- a/Source/Extensions/OverwriteModuleText.cs +++ b/Source/Extensions/OverwriteModuleText.cs @@ -1,8 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Experience.Effects; +using KSP.Localization; using UnityEngine; namespace SmartDockingAid.Extensions @@ -12,31 +9,43 @@ public class OverwriteModuleText : MonoBehaviour { public void Start() { - List parts = PartLoader.LoadedPartsList.Where(p => p.partPrefab.Modules.GetModule()).ToList(); - - foreach (AvailablePart part in parts) + foreach (AvailablePart part in PartLoader.LoadedPartsList) { - ModuleSAS SASmodule = part.partPrefab.FindModuleImplementing(); - AvailablePart.ModuleInfo moduleInfo = part.moduleInfos.Where(m => m.moduleName == "SAS").First(); - int serviceLevel = (SASmodule.SASServiceLevel + 1); - string moduleText = string.Empty; - for (int i = 0; i < serviceLevel; i++) - moduleText += $"{SASLevels[i]} \n"; + if (part.partPrefab == null) + continue; + + ModuleSAS sasModule = part.partPrefab.FindModuleImplementing(); + if (sasModule == null) + continue; + + int sasServiceLevel = sasModule.SASServiceLevel; + int sdaRequiredLevel = SmartDockingAid.SASLevel; + if (sasServiceLevel < sdaRequiredLevel) + continue; + + AvailablePart.ModuleInfo moduleInfo = part.moduleInfos.Find(p => p.moduleName == "SAS"); + if (moduleInfo == null) + continue; + + string text = string.Empty; + for (int i = 0; i < Mathf.Min(sasServiceLevel + 1, AutopilotSkill.SkillsReadable.Length); i++) + { + if (i != 0) + text += "\n"; - if (part.partPrefab.HasModuleImplementing()) - moduleText += $"{SASLevels[4]} \n"; + if (i == sdaRequiredLevel) + text += "Parallel to target\n"; - moduleInfo.info = moduleText; + text += AutopilotSkill.SkillsReadable[i]; + } + if (sasModule.standalone) + text += sasModule.resHandler.PrintModuleResources(); + + if (!sasModule.moduleIsEnabled) + text += Localizer.Format("#autoLOC_218888"); + + moduleInfo.info = text; } } - - private string[] SASLevels = new string[5] - { - $"S0: Stability Assist", - $"S1: Prograde / Retrograde", - $"S2: Radial / Normal", - $"S3: Maneuver / Target", - $"S{AssetLoader.minPilotLevel}: Parallel+ / Parallel-" - }; } } diff --git a/Source/Modules/ModuleDockingAid.cs b/Source/Modules/ModuleDockingAid.cs deleted file mode 100644 index b6ef33b..0000000 --- a/Source/Modules/ModuleDockingAid.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; - -// Modifies DockingAidAutopilot to be active if this PartModule is presence on the current vessel - -namespace SmartDockingAid -{ - public class ModuleDockingAid : PartModule - { - [KSPField] - public bool active = true; - } -} diff --git a/Source/Modules/VesselDockingAid.cs b/Source/Modules/VesselDockingAid.cs deleted file mode 100644 index 29094fd..0000000 --- a/Source/Modules/VesselDockingAid.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Reflection; -using UnityEngine; -using SmartDockingAid.Flight; - -namespace SmartDockingAid -{ - class VesselDockingAid : VesselModule - { - public SmartDockingAid.TargetMode targetMode { get; private set; } - - private ITargetable target; - - private List crew = new List(); - - private bool pilotAvailable; - private bool moduleAvailable; - private bool active = false; - - public bool Setup() - { - pilotAvailable = false; - moduleAvailable = false; - - pilotAvailable = vessel.GetVesselCrew().Any(c => c.experienceTrait.CrewMemberExperienceLevel() > AssetLoader.minPilotLevel); - - foreach (Part part in vessel.parts) - { - if (part.HasModuleImplementing()) - { - ModuleDockingAid moduleDockingAid = part.Modules.GetModule(); - if (!moduleDockingAid.active) continue; - moduleAvailable = true; - } - } - - return (pilotAvailable || moduleAvailable || HighLogic.CurrentGame.Parameters.CustomParams().EnableFullSASInSandbox); - } - - public void changeSASstate(bool isOn) - { - if (isOn) - { - vessel.Autopilot.Enable(); - } - else - { - vessel.Autopilot.Disable(); - } - } - - - public void onModeChange(SmartDockingAid.TargetMode targetMode) - { - this.targetMode = targetMode; - if (targetMode != SmartDockingAid.TargetMode.OFF) - { - vessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); - active = true; - } - else - { - active = false; - if (vessel.Autopilot.Mode == VesselAutopilot.AutopilotMode.StabilityAssist) - { - vessel.Autopilot.SAS.lockedMode = true; - } - } - } - - public void Update() - { - if (HighLogic.LoadedScene == GameScenes.FLIGHT && active) - { - if (!vessel.IsControllable || !vessel.Autopilot.Enabled) - return; - - if (vessel.targetObject != null) - target = vessel.targetObject; - - vessel.Autopilot.SAS.lockedMode = false; - vessel.Autopilot.SAS.SetTargetOrientation(target.getAttitude(targetMode), false); - } - } - } -} diff --git a/Source/Properties/AssemblyInfo.cs b/Source/Properties/AssemblyInfo.cs index 7e4e2a5..fcab0ed 100644 --- a/Source/Properties/AssemblyInfo.cs +++ b/Source/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -24,8 +24,5 @@ // // Major.Minor.Build.Revision // -// You can specify all the values or you can use the default the Revision and -// Build Numbers by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.2.0.0")] +[assembly: AssemblyFileVersion("1.2.0.0")] diff --git a/Source/SmartDockingAid.cs b/Source/SmartDockingAid.cs index d8084ab..e398b77 100644 --- a/Source/SmartDockingAid.cs +++ b/Source/SmartDockingAid.cs @@ -1,17 +1,117 @@ -using UnityEngine; -using UnityEngine.UI; +using System; +using System.Collections; using KSP.UI; using KSP.UI.TooltipTypes; -using KSP.UI.Screens.Flight; using SmartDockingAid.UI; -using System; +using UnityEngine; +using UnityEngine.UI; namespace SmartDockingAid { [KSPAddon(KSPAddon.Startup.Flight, false)] public class SmartDockingAid : MonoBehaviour { - private const string DISPLAYNAME = "SmartDockingAid"; + private static Sprite _parallelMinusSprite; + private static Sprite _parallelPlusSprite; + private static VesselAutopilot.AutopilotMode? _availableAtSASMode; + + + public static Sprite ParallelMinusSprite + { + get + { + if (_parallelMinusSprite == null) + { + Texture2D tex = GameDatabase.Instance.GetTexture("SmartDockingAid/Assets/ParallelMinus", false); + if (tex == null) + { + tex = new Texture2D(16, 16); + Debug.LogError($"[SmartDockingAid] Failed to load texture \"SmartDockingAid/Assets/ParallelMinus\""); + } + + _parallelMinusSprite = tex.toSprite(); + } + + return _parallelMinusSprite; + } + } + + public static Sprite ParallelPlusSprite + { + get + { + if (_parallelPlusSprite == null) + { + Texture2D tex = GameDatabase.Instance.GetTexture("SmartDockingAid/Assets/ParallelPlus", false); + if (tex == null) + { + tex = new Texture2D(16, 16); + Debug.LogError($"[SmartDockingAid] Failed to load texture \"SmartDockingAid/Assets/ParallelPlus\""); + } + + _parallelPlusSprite = tex.toSprite(); + } + + return _parallelPlusSprite; + } + } + + public static VesselAutopilot.AutopilotMode AvailableAtSASMode + { + get + { + if (_availableAtSASMode == null) + { + ConfigNode node = GameDatabase.Instance.GetConfigNode("SmartDockingAid/SDASETTINGS"); + if (node == null) + { + Debug.LogWarning($"[SmartDockingAid] Settings file could not be located"); + } + else + { + string val = node.GetValue("availableAtSASMode"); + if (string.IsNullOrEmpty(val) || !Enum.TryParse(val, out VesselAutopilot.AutopilotMode mode)) + Debug.LogWarning($"[SmartDockingAid] No valid \"minPilotExperience\" value found in settings file"); + else + _availableAtSASMode = mode; + } + + if (_availableAtSASMode == null) + { + _availableAtSASMode = VesselAutopilot.AutopilotMode.Target; + Debug.Log($"[SmartDockingAid] Default settings will be applied"); + } + } + + return (VesselAutopilot.AutopilotMode)_availableAtSASMode; + } + } + + public static int SASLevel + { + get + { + switch (AvailableAtSASMode) + { + case VesselAutopilot.AutopilotMode.StabilityAssist: + return 0; + case VesselAutopilot.AutopilotMode.Prograde: + case VesselAutopilot.AutopilotMode.Retrograde: + return 1; + case VesselAutopilot.AutopilotMode.Normal: + case VesselAutopilot.AutopilotMode.Antinormal: + case VesselAutopilot.AutopilotMode.RadialIn: + case VesselAutopilot.AutopilotMode.RadialOut: + return 2; + case VesselAutopilot.AutopilotMode.Target: + case VesselAutopilot.AutopilotMode.AntiTarget: + case VesselAutopilot.AutopilotMode.Maneuver: + return 3; + default: + return 0; + } + } + } private UIStateToggleButton[] modebuttons; @@ -21,10 +121,9 @@ public class SmartDockingAid : MonoBehaviour private UIStateToggleButton parallelPlus; private UIStateToggleButton parallelNegative; - private Vessel vessel; - private VesselDockingAid vesselDockingAid; + private VesselModuleDockingAid VesselModule => FlightGlobals.ActiveVessel.FindVesselModuleImplementing(); - private bool autopilotState; + private bool isAvailable; private bool buttonInit = false; private bool SASstate; @@ -38,17 +137,19 @@ public enum TargetMode public void Start() { GameEvents.onFlightReady.Add(onFlightReady); - GameEvents.onVesselSwitching.Add(onVesselChange); + GameEvents.onVesselChange.Add(onVesselChange); GameEvents.onDockingComplete.Add(onDockingComplete); GameEvents.onGameSceneSwitchRequested.Add(onGameScenceSwitch); GameEvents.OnGameSettingsApplied.Add(OnGameSettingsApplied); + GameEvents.onKerbalLevelUp.Add(OnKerbalLevelUp); } private void onFlightReady() { if (!buttonInit) { - modebuttons = FindObjectOfType().modeButtons; + VesselAutopilotUI autopilotUI = FlightUIModeController.Instance.navBall.GetComponentInChildren(); + modebuttons = autopilotUI.modeButtons; modebuttons[0].getSpriteStates(out buttonActive, out buttonDisabled); foreach (UIStateToggleButton button in modebuttons) @@ -87,36 +188,32 @@ private void onFlightReady() this.parallelPlus.transform.position = new Vector3(parallelPlus.gameObject.transform.position.x + ((4 * GameSettings.UI_SCALE_NAVBALL) * GameSettings.UI_SCALE), parallelPlus.gameObject.transform.position.y - ((25 * GameSettings.UI_SCALE_NAVBALL) * GameSettings.UI_SCALE)); parallelNegative.GetComponent().textString = "Parallel -"; - parallelNegative.GetChild("Image").GetComponent().sprite = AssetLoader.parallelMinus.toSprite(); - parallelNegative.transform.SetParent(UnityEngine.Object.FindObjectOfType().transform); + parallelNegative.GetChild("Image").GetComponent().sprite = ParallelMinusSprite; + parallelNegative.transform.SetParent(autopilotUI.transform); parallelPlus.GetComponent().textString = "Parallel +"; - parallelPlus.GetChild("Image").GetComponent().sprite = AssetLoader.parallelPlus.toSprite(); - parallelPlus.transform.SetParent(UnityEngine.Object.FindObjectOfType().transform); + parallelPlus.GetChild("Image").GetComponent().sprite = ParallelPlusSprite; + parallelPlus.transform.SetParent(autopilotUI.transform); buttonInit = true; - - Debug.Log($"[{DISPLAYNAME}] UI initiated"); } - vessel = FlightGlobals.ActiveVessel; - SetNewState(false, true); + SetNewState(true); } - private void SetNewState(bool disable, bool reset) + private void SetNewState(bool reset) { if (reset) { - vesselDockingAid = vessel.GetComponent() as VesselDockingAid; - autopilotState = vesselDockingAid.Setup(); - SASstate = vessel.Autopilot.Enabled; + SASstate = FlightGlobals.ActiveVessel.Autopilot.Enabled; + isAvailable = AvailableAtSASMode.AvailableAtLevel(FlightGlobals.ActiveVessel); } - if (autopilotState && !disable) + if (isAvailable) { parallelPlus.gameObject.SetActive(true); parallelNegative.gameObject.SetActive(true); - switch(vesselDockingAid.targetMode) + switch(VesselModule.targetMode) { case TargetMode.OFF: modebuttons[0].changeState(buttonActive); @@ -137,26 +234,39 @@ private void SetNewState(bool disable, bool reset) } else { + modebuttons[0].changeState(buttonActive); + parallelPlus.SetState(false); + parallelNegative.SetState(false); parallelNegative.gameObject.SetActive(false); parallelPlus.gameObject.SetActive(false); } } - private void onVesselChange(Vessel vessel1, Vessel vessel2) + private void onVesselChange(Vessel vessel) { - vessel = vessel2 != null ? vessel2 : vessel1; - SetNewState(false, true); + SetNewState(true); } private void onDockingComplete(GameEvents.FromToAction part) { - vessel = FlightGlobals.ActiveVessel; - SetNewState(true, true); + SetNewState(true); } private void OnGameSettingsApplied() { - SetNewState(false, true); + SetNewState(true); + } + + private void OnKerbalLevelUp(ProtoCrewMember data) + { + StartCoroutine(OnKerbalLevelUpDelayed()); + } + + private IEnumerator OnKerbalLevelUpDelayed() + { + yield return new WaitForEndOfFrame(); + yield return new WaitForEndOfFrame(); + SetNewState(true); } private void onToggleButtonPressed(UIStateToggleButton button) @@ -165,24 +275,24 @@ private void onToggleButtonPressed(UIStateToggleButton button) if (button == parallelNegative) { - vesselDockingAid.onModeChange(TargetMode.PARALLEL_NEGATIVE); - SetNewState(false, false); + VesselModule.onModeChange(TargetMode.PARALLEL_NEGATIVE); + SetNewState(false); } else { - vesselDockingAid.onModeChange(TargetMode.PARALLEL_PLUS); - SetNewState(false, false); + VesselModule.onModeChange(TargetMode.PARALLEL_PLUS); + SetNewState(false); } } private void onSASbuttonPressed(UIStateToggleButton button) { - if (autopilotState) + if (isAvailable) { parallelNegative.SetState(false); parallelPlus.SetState(false); - vesselDockingAid.onModeChange(TargetMode.OFF); - SetNewState(false, false); + VesselModule.onModeChange(TargetMode.OFF); + SetNewState(false); } } @@ -193,8 +303,8 @@ private void onButtonInteractableStateChanged() if (!modebuttons[8].interactable) { - vesselDockingAid.onModeChange(TargetMode.OFF); - SetNewState(false, false); + VesselModule.onModeChange(TargetMode.OFF); + SetNewState(false); } } @@ -205,24 +315,24 @@ private void onButtonStateChanged() if (!modebuttons[8].gameObject.activeSelf) { - vesselDockingAid.onModeChange(TargetMode.OFF); + VesselModule.onModeChange(TargetMode.OFF); } } private void onSASStateChanged() { - SASstate = vessel.Autopilot.Enabled; + SASstate = FlightGlobals.ActiveVessel.Autopilot.Enabled; - if (!vessel.Autopilot.Enabled) + if (!FlightGlobals.ActiveVessel.Autopilot.Enabled) { - vesselDockingAid.onModeChange(TargetMode.OFF); - SetNewState(false, false); + VesselModule.onModeChange(TargetMode.OFF); + SetNewState(false); } } public void Update() { - if (autopilotState) + if (isAvailable) { if (modebuttons[8].gameObject.activeSelf != parallelNegative.gameObject.activeSelf) onButtonStateChanged(); @@ -230,15 +340,13 @@ public void Update() if (modebuttons[8].interactable != parallelNegative.interactable) onButtonInteractableStateChanged(); - if (vessel.Autopilot.Enabled != SASstate) + if (FlightGlobals.ActiveVessel.Autopilot.Enabled != SASstate) onSASStateChanged(); } } private void onGameScenceSwitch(GameEvents.FromToAction data) { - Debug.Log($"[{DISPLAYNAME}] Destroy()"); - parallelNegative.onClick.RemoveAllListeners(); parallelPlus.onClick.RemoveAllListeners(); @@ -251,17 +359,17 @@ private void onGameScenceSwitch(GameEvents.FromToAction Destroy(parallelPlus.gameObject); buttonInit = false; - vesselDockingAid = null; - autopilotState = false; + isAvailable = false; } public void OnDestroy() { GameEvents.onFlightReady.Remove(onFlightReady); - GameEvents.onVesselSwitching.Remove(onVesselChange); + GameEvents.onVesselChange.Remove(onVesselChange); GameEvents.onDockingComplete.Remove(onDockingComplete); GameEvents.onGameSceneSwitchRequested.Remove(onGameScenceSwitch); GameEvents.OnGameSettingsApplied.Remove(OnGameSettingsApplied); + GameEvents.onKerbalLevelUp.Remove(OnKerbalLevelUp); } } } diff --git a/Source/SmartDockingAid.csproj b/Source/SmartDockingAid.csproj index 2f5ce6d..a58bea8 100644 --- a/Source/SmartDockingAid.csproj +++ b/Source/SmartDockingAid.csproj @@ -1,6 +1,16 @@  + + + KSP_x64.exe + KSP.app + KSP.x86_64 + KSP_x64_Data\Managed + KSP.app\Contents\Resources\Data\Managed + KSP_Data\Managed + $(ReferencePath)\$(ManagedRelativePath) + Debug AnyCPU @@ -12,10 +22,13 @@ v4.7.2 512 true + Program + $(ReferencePath)\$(KSPExecutable) + $(ReferencePath) true - full + portable false bin\Debug\ DEBUG;TRACE @@ -31,63 +44,214 @@ 4 - - G:\SteamLibrary\steamapps\common\Kerbal Space Program\KSP_x64_Data\Managed\Assembly-CSharp.dll + + System (KSP/Mono) + False - - G:\SteamLibrary\steamapps\common\Kerbal Space Program\KSP_x64_Data\Managed\Assembly-CSharp-firstpass.dll + + System.Core (KSP/Mono) + False - - - - - - - - - - G:\SteamLibrary\steamapps\common\Kerbal Space Program\KSP_x64_Data\Managed\UnityEngine.dll + + System.Xml (KSP/Mono) + False - - False - G:\SteamLibrary\steamapps\common\Kerbal Space Program\KSP_x64_Data\Managed\UnityEngine.AssetBundleModule.dll + + UnityEngine + False - - G:\SteamLibrary\steamapps\common\Kerbal Space Program\KSP_x64_Data\Managed\UnityEngine.CoreModule.dll + + Assembly-CSharp + False - - G:\SteamLibrary\steamapps\common\Kerbal Space Program\KSP_x64_Data\Managed\UnityEngine.UI.dll - - - G:\SteamLibrary\steamapps\common\Kerbal Space Program\KSP_x64_Data\Managed\UnityEngine.UIModule.dll + + Assembly-CSharp-firstpass + False - - + - + - - True - True - Settings.settings - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - + - - - - - xcopy /Y "$(TargetPath)" "G:\KSP\1.8.1 QuickTest-Stock\GameData\SmartDockingAid\" + $(SolutionDir)\..\ + SmartDockingAid + false + true + SDA.version + + + + + + + + + + + + + + + + + + + + $(ReferencePath)\GameData\$(GameDataFolderName)\Plugins + $(ReferencePath)\GameData\$(GameDataFolderName) + + + + + + + $(RepoRootPath)\GameData\$(GameDataFolderName)\Plugins + $(RepoRootPath)\GameData\$(GameDataFolderName) + + + + + + + $(RepoRootPath)\Releases + $(PublishFolder)\Temp + $(PublishTempFolderPath)\GameData\$(GameDataFolderName) + $(PublishPluginRootPath)\Plugins + $(PublishPluginRootPath) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = 0) + { + current += itemName.Length; + while (current < content.Length && char.IsNumber(content[current])) + { + Major += content[current]; + current++; + } + } + else + { + Major = "0"; + } + + itemName = "\"MINOR\":"; + current = content.IndexOf(itemName, StringComparison.OrdinalIgnoreCase); + if (current >= 0) + { + current += itemName.Length; + while (current < content.Length && char.IsNumber(content[current])) + { + Minor += content[current]; + current++; + } + } + else + { + Minor = "0"; + } + + itemName = "\"PATCH\":"; + current = content.IndexOf(itemName, StringComparison.OrdinalIgnoreCase); + if (current >= 0) + { + current += itemName.Length; + while (current < content.Length && char.IsNumber(content[current])) + { + Patch += content[current]; + current++; + } + } + else + { + Patch = "0"; + } + + itemName = "\"BUILD\":"; + current = content.IndexOf(itemName, StringComparison.OrdinalIgnoreCase); + if (current >= 0) + { + current += itemName.Length; + while (current < content.Length && char.IsNumber(content[current])) + { + Build += content[current]; + current++; + } + } + else + { + Build = "0"; + } + + FullVersion = Major + "." + Minor + "." + Patch + "." + Build; +]]> + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Source/SmartDockingAid.sln b/Source/SmartDockingAid.sln index a8121a7..88fd4f7 100644 --- a/Source/SmartDockingAid.sln +++ b/Source/SmartDockingAid.sln @@ -5,6 +5,13 @@ VisualStudioVersion = 16.0.30309.148 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartDockingAid", "SmartDockingAid.csproj", "{D0BC8A2F-ADE3-49FF-88CD-C606E356732B}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A61B2D5B-8B56-403E-A367-1BF8FE4B6933}" + ProjectSection(SolutionItems) = preProject + ..\README.md = ..\README.md + ..\GameData\SmartDockingAid\SDA.version = ..\GameData\SmartDockingAid\SDA.version + SmartDockingAid.csproj.user = SmartDockingAid.csproj.user + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/Source/VesselDockingAid.cs b/Source/VesselDockingAid.cs new file mode 100644 index 0000000..1a6e281 --- /dev/null +++ b/Source/VesselDockingAid.cs @@ -0,0 +1,56 @@ +using SmartDockingAid.Flight; + +namespace SmartDockingAid +{ + class VesselModuleDockingAid : VesselModule + { + public SmartDockingAid.TargetMode targetMode { get; private set; } + + private bool active = false; + + public override bool ShouldBeActive() + { + return vessel.loaded && vessel.IsControllable && vessel.Autopilot.Enabled; + } + + public void changeSASstate(bool isOn) + { + if (isOn) + { + vessel.Autopilot.Enable(); + } + else + { + vessel.Autopilot.Disable(); + } + } + + + public void onModeChange(SmartDockingAid.TargetMode targetMode) + { + this.targetMode = targetMode; + if (targetMode != SmartDockingAid.TargetMode.OFF) + { + vessel.Autopilot.SetMode(VesselAutopilot.AutopilotMode.StabilityAssist); + active = true; + } + else + { + active = false; + if (vessel.Autopilot.Mode == VesselAutopilot.AutopilotMode.StabilityAssist) + { + vessel.Autopilot.SAS.lockedMode = true; + } + } + } + + public void Update() + { + if (active && vessel.targetObject != null) + { + vessel.Autopilot.SAS.lockedMode = false; + vessel.Autopilot.SAS.SetTargetOrientation(vessel.targetObject.getAttitude(targetMode), false); + } + } + } +}