From 92345d0eed3e9f9cc7b3204d31621521c1acd929 Mon Sep 17 00:00:00 2001 From: asarium Date: Mon, 29 Jul 2013 14:10:26 +0200 Subject: [PATCH 01/19] Some testing leftovers removed. --- PAPIPlugin/PAPIAddon.cs | 1 - PAPIPlugin/PAPIPlugin.csproj | 12 ------------ 2 files changed, 13 deletions(-) diff --git a/PAPIPlugin/PAPIAddon.cs b/PAPIPlugin/PAPIAddon.cs index ccd1367..a7173df 100644 --- a/PAPIPlugin/PAPIAddon.cs +++ b/PAPIPlugin/PAPIAddon.cs @@ -3,7 +3,6 @@ using PAPIPlugin.Impl; using PAPIPlugin.Interfaces; using PAPIPlugin.Internal; -using Tac; using UnityEngine; #endregion diff --git a/PAPIPlugin/PAPIPlugin.csproj b/PAPIPlugin/PAPIPlugin.csproj index 99113bf..201259a 100644 --- a/PAPIPlugin/PAPIPlugin.csproj +++ b/PAPIPlugin/PAPIPlugin.csproj @@ -46,18 +46,6 @@ - - TacLib\Icon.cs - - - TacLib\PopupWindow.cs - - - TacLib\Utilities.cs - - - TacLib\Window.cs - From fc710cbfbd4ee4227545c9badee5558748da81b4 Mon Sep 17 00:00:00 2001 From: asarium Date: Mon, 29 Jul 2013 14:10:48 +0200 Subject: [PATCH 02/19] Added option to alter height above terrain. --- PAPIPlugin/Arrays/PAPIArray.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/PAPIPlugin/Arrays/PAPIArray.cs b/PAPIPlugin/Arrays/PAPIArray.cs index 6cab74c..ff852a0 100644 --- a/PAPIPlugin/Arrays/PAPIArray.cs +++ b/PAPIPlugin/Arrays/PAPIArray.cs @@ -61,12 +61,15 @@ public PAPIArray() public double Heading { get; set; } + public double HeightAboveTerrain { get; set; } + #region IConfigNode Members public void Load(ConfigNode node) { BadGlidepathVariance = node.ConvertValue("BadGlidepath", DefaultBadGlidepathVariance); TargetGlidePath = node.ConvertValue("TargetGlidepath", DefaultTargetGlidePath); + HeightAboveTerrain = node.ConvertValue("Height", 0); try { @@ -201,7 +204,7 @@ private void InitializePAPIParts(double lat, double lon, double heading) maxHeight = Math.Max(0, maxHeight); _relativeSurfacePosition = - parentBody.transform.InverseTransformPoint(parentBody.GetWorldSurfacePosition(lat, lon, maxHeight + PAPILightRadius * 0.5)); + parentBody.transform.InverseTransformPoint(parentBody.GetWorldSurfacePosition(lat, lon, maxHeight + HeightAboveTerrain + PAPILightRadius * 0.5)); _papiGameObject.transform.localPosition = _relativeSurfacePosition; } From 7cf446a77ac1c2b7820fa1184074914bd4eb898a Mon Sep 17 00:00:00 2001 From: asarium Date: Mon, 29 Jul 2013 16:50:14 +0200 Subject: [PATCH 03/19] Changed log util to just use objects. --- PAPIPlugin/Internal/Util.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PAPIPlugin/Internal/Util.cs b/PAPIPlugin/Internal/Util.cs index 94b4692..c14784d 100644 --- a/PAPIPlugin/Internal/Util.cs +++ b/PAPIPlugin/Internal/Util.cs @@ -4,17 +4,17 @@ namespace PAPIPlugin.Internal { public class Util { - public static void LogInfo(string msg) + public static void LogInfo(object msg) { Debug.Log("PAPIPlugin: " + msg); } - public static void LogWarning(string msg) + public static void LogWarning(object msg) { Debug.LogWarning("PAPIPlugin: " + msg); } - public static void LogError(string msg) + public static void LogError(object msg) { Debug.LogError("PAPIPlugin: " + msg); } From 53a7eee8ce83cbff4689d2cc204cfae1dee77900 Mon Sep 17 00:00:00 2001 From: asarium Date: Mon, 29 Jul 2013 16:51:08 +0200 Subject: [PATCH 04/19] Improved the apperance of the PAPI array. Now it uses speheres instead of a rectangle. --- PAPIPlugin/Arrays/PAPIArray.cs | 43 +++++++++++++++++----------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/PAPIPlugin/Arrays/PAPIArray.cs b/PAPIPlugin/Arrays/PAPIArray.cs index ff852a0..54dfee1 100644 --- a/PAPIPlugin/Arrays/PAPIArray.cs +++ b/PAPIPlugin/Arrays/PAPIArray.cs @@ -113,6 +113,11 @@ public override void Update() var currentCamera = Camera.main; + if (currentCamera == null) + { + return; + } + var relativePosition = _papiGameObject.transform.InverseTransformPoint(currentCamera.transform.position); var normalizedPosition = relativePosition.normalized; @@ -190,9 +195,7 @@ private void InitializePAPIParts(double lat, double lon, double heading) _partObjects = new GameObject[PAPIPartCount]; for (var i = 0; i < PAPIPartCount; i++) { - var obj = new GameObject(); - - AddPAPIPart(obj); + var obj = AddPAPIPart(); obj.transform.parent = _papiGameObject.transform; obj.transform.localPosition = (i - (PAPIPartCount / 2)) * PAPILightDifference; @@ -204,7 +207,8 @@ private void InitializePAPIParts(double lat, double lon, double heading) maxHeight = Math.Max(0, maxHeight); _relativeSurfacePosition = - parentBody.transform.InverseTransformPoint(parentBody.GetWorldSurfacePosition(lat, lon, maxHeight + HeightAboveTerrain + PAPILightRadius * 0.5)); + parentBody.transform.InverseTransformPoint(parentBody.GetWorldSurfacePosition(lat, lon, + maxHeight + HeightAboveTerrain + PAPILightRadius)); _papiGameObject.transform.localPosition = _relativeSurfacePosition; } @@ -216,32 +220,29 @@ private static Vector3d Orthonormalise(Vector3d direction, Vector3d firstVector) return direction - Vector3d.Dot(firstVector, direction) * firstVector; } - private static void AddPAPIPart(GameObject obj) + private static GameObject AddPAPIPart() { - var lineRenderer = obj.AddComponent(); - - lineRenderer.useWorldSpace = false; - lineRenderer.transform.parent = obj.transform; - lineRenderer.transform.localPosition = Vector3.zero; - lineRenderer.transform.eulerAngles = Vector3.zero; - - lineRenderer.material = new Material(Shader.Find("Particles/Additive")); - lineRenderer.SetColors(Color.red, Color.red); - lineRenderer.SetWidth(PAPILightRadius, PAPILightRadius); - lineRenderer.SetVertexCount(2); - lineRenderer.SetPosition(0, Vector3.zero); - lineRenderer.SetPosition(1, Vector3.up * PAPILightRadius); + var obj = GameObject.CreatePrimitive(PrimitiveType.Sphere); + + var material = new Material(Shader.Find("Particles/Additive")); + obj.renderer.sharedMaterial = material; + + obj.transform.localScale = new Vector3(PAPILightRadius, PAPILightRadius, PAPILightRadius); + + var sphereCollider = obj.GetComponent(); + sphereCollider.enabled = false; + + return obj; } private void UpdatePAPIPart(int index, double difference, float alpha) { var gameObj = _partObjects[index]; - var lineRenderer = gameObj.GetComponent(); - var color = GetArrayPartColor(index, difference); color.a = alpha; - lineRenderer.SetColors(color, color); + + gameObj.renderer.material.SetColor("_TintColor", color); } private Color GetArrayPartColor(int index, double difference) From d6199398c86b530334afe073957adbe0711372ac Mon Sep 17 00:00:00 2001 From: asarium Date: Tue, 30 Jul 2013 10:30:57 +0200 Subject: [PATCH 05/19] Actually make the config a global instance. --- PAPIPlugin/PAPIAddon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PAPIPlugin/PAPIAddon.cs b/PAPIPlugin/PAPIAddon.cs index a7173df..76de2f2 100644 --- a/PAPIPlugin/PAPIAddon.cs +++ b/PAPIPlugin/PAPIAddon.cs @@ -14,7 +14,7 @@ public class PAPIAddon : MonoBehaviour { private ILightArrayManager _arrayManager; - private ILightArrayConfig _config; + private static ILightArrayConfig _config; public void Awake() { From 71c5e64a81ff04c7f155e98943e58bb8caf97d9f Mon Sep 17 00:00:00 2001 From: asarium Date: Tue, 30 Jul 2013 12:08:08 +0200 Subject: [PATCH 06/19] Added TacLib submodule --- .gitmodules | 3 +++ TacLib | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 TacLib diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..373a55a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "TacLib"] + path = TacLib + url = https://github.com/taraniselsu/TacLib.git diff --git a/TacLib b/TacLib new file mode 160000 index 0000000..13df510 --- /dev/null +++ b/TacLib @@ -0,0 +1 @@ +Subproject commit 13df51047152ddb603eab16f3ce479bc9ea93c4b From ab6dc3f3e4c591a7ab0213cc25d1ef65e6375eef Mon Sep 17 00:00:00 2001 From: asarium Date: Tue, 30 Jul 2013 21:19:38 +0200 Subject: [PATCH 07/19] Renamed some config and property names. --- PAPIPlugin/Arrays/PAPIArray.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/PAPIPlugin/Arrays/PAPIArray.cs b/PAPIPlugin/Arrays/PAPIArray.cs index 54dfee1..ad049bc 100644 --- a/PAPIPlugin/Arrays/PAPIArray.cs +++ b/PAPIPlugin/Arrays/PAPIArray.cs @@ -34,8 +34,8 @@ public class PAPIArray : AbstractLightArray, IConfigNode public PAPIArray() { - TargetGlidePath = DefaultTargetGlidePath; - BadGlidepathVariance = DefaultBadGlidepathVariance; + TargetGlideslope = DefaultTargetGlidePath; + GlideslopeTolerance = DefaultBadGlidepathVariance; EnabledChanged += (sender, args) => { @@ -51,9 +51,9 @@ public PAPIArray() }; } - public double BadGlidepathVariance { get; set; } + public double GlideslopeTolerance { get; set; } - public double TargetGlidePath { get; set; } + public double TargetGlideslope { get; set; } public double Longitude { get; set; } @@ -67,8 +67,8 @@ public PAPIArray() public void Load(ConfigNode node) { - BadGlidepathVariance = node.ConvertValue("BadGlidepath", DefaultBadGlidepathVariance); - TargetGlidePath = node.ConvertValue("TargetGlidepath", DefaultTargetGlidePath); + GlideslopeTolerance = node.ConvertValue("GlideslopeTolerance", DefaultBadGlidepathVariance); + TargetGlideslope = node.ConvertValue("TargetGlideslope", DefaultTargetGlidePath); HeightAboveTerrain = node.ConvertValue("Height", 0); try @@ -128,7 +128,7 @@ public override void Update() var angle = 90 - Math.Acos(normalDot) * (180 / Math.PI); - var difference = angle - TargetGlidePath; + var difference = angle - TargetGlideslope; for (var i = 0; i < PAPIPartCount; i++) { @@ -247,11 +247,11 @@ private void UpdatePAPIPart(int index, double difference, float alpha) private Color GetArrayPartColor(int index, double difference) { - if (difference < -BadGlidepathVariance) + if (difference < -GlideslopeTolerance) { return Color.red; } - if (difference > BadGlidepathVariance) + if (difference > GlideslopeTolerance) { return Color.white; } From f011d843cf462f9e69a24774174c8479d854b343 Mon Sep 17 00:00:00 2001 From: asarium Date: Tue, 30 Jul 2013 21:24:35 +0200 Subject: [PATCH 08/19] Made the name of a light group optional. --- PAPIPlugin/Impl/DefaultLightGroup.cs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/PAPIPlugin/Impl/DefaultLightGroup.cs b/PAPIPlugin/Impl/DefaultLightGroup.cs index 9177568..f706428 100644 --- a/PAPIPlugin/Impl/DefaultLightGroup.cs +++ b/PAPIPlugin/Impl/DefaultLightGroup.cs @@ -22,21 +22,13 @@ public class DefaultLightGroup : ILightGroup, IConfigNode public void Load(ConfigNode node) { - var name = node.GetValue("Name"); - - if (string.IsNullOrEmpty(name)) - { - Util.LogWarning("Name value not found in config!"); - return; - } - - Name = name; + Name = node.GetValue("Name"); var bodyName = node.GetValue("Body"); if (string.IsNullOrEmpty(bodyName)) { - Util.LogWarning(string.Format("The parent body value of light group {0} is missing!", Name)); + Util.LogWarning(string.Format("The parent body value of light group {0} is missing!", Name ?? "")); return; } @@ -44,11 +36,11 @@ public void Load(ConfigNode node) if (ParentBody == null) { - Util.LogWarning(string.Format("The parent body {0} of light group {1} could not be found.", bodyName, Name)); + Util.LogWarning(string.Format("The parent body {0} of light group {1} could not be found.", bodyName, Name ?? "")); return; } - Util.LogInfo(string.Format("Found light group {0} on body {1}.", Name, ParentBody.name)); + Util.LogInfo(string.Format("Found light group {0} on body {1}.", Name ?? "", ParentBody.name)); var configNodes = node.GetNodes(LightNodeName); From 36e97ab013cbaa63b9c97d2a64b502692ceffd56 Mon Sep 17 00:00:00 2001 From: asarium Date: Wed, 31 Jul 2013 12:14:59 +0200 Subject: [PATCH 09/19] Some cleanup here... --- PAPIPlugin/Impl/DefaultLightArrayManager.cs | 23 ++++++++++++--------- PAPIPlugin/Interfaces/ILightArrayManager.cs | 2 +- PAPIPlugin/PAPIAddon.cs | 4 +--- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/PAPIPlugin/Impl/DefaultLightArrayManager.cs b/PAPIPlugin/Impl/DefaultLightArrayManager.cs index 76c3498..b50a08e 100644 --- a/PAPIPlugin/Impl/DefaultLightArrayManager.cs +++ b/PAPIPlugin/Impl/DefaultLightArrayManager.cs @@ -1,7 +1,6 @@ #region Usings using System; -using System.Collections.Generic; using System.Diagnostics; using System.Linq; using PAPIPlugin.Interfaces; @@ -25,7 +24,9 @@ public ILightArrayConfig LightConfig set { if (Equals(_lightConfig, value)) + { return; + } _lightConfig = value; @@ -33,15 +34,7 @@ public ILightArrayConfig LightConfig } } - private void InitializeConfig(ILightArrayConfig lightConfig) - { - foreach (var lightArray in lightConfig.LightArrayGroups.SelectMany(group => group.LightArrays)) - { - lightArray.InitializeDisplay(this); - } - } - - public void LoadConfig() + public ILightArrayConfig LoadConfig() { Util.LogInfo("Starting to parse light definitions..."); @@ -56,6 +49,8 @@ public void LoadConfig() LightConfig.LightArrayGroups.Count(), LightConfig.LightArrayGroups.Sum(group => group.LightArrays.Count()), stopwatch.Elapsed)); OnParsingFinished(); + + return LightConfig; } public void Update() @@ -73,6 +68,14 @@ public void Dispose() #endregion + private void InitializeConfig(ILightArrayConfig lightConfig) + { + foreach (var lightArray in lightConfig.LightArrayGroups.SelectMany(group => group.LightArrays)) + { + lightArray.InitializeDisplay(this); + } + } + protected virtual void OnParsingFinished() { var handler = ParsingFinished; diff --git a/PAPIPlugin/Interfaces/ILightArrayManager.cs b/PAPIPlugin/Interfaces/ILightArrayManager.cs index fc397a0..9be3bb2 100644 --- a/PAPIPlugin/Interfaces/ILightArrayManager.cs +++ b/PAPIPlugin/Interfaces/ILightArrayManager.cs @@ -12,7 +12,7 @@ public interface ILightArrayManager : IDisposable ILightArrayConfig LightConfig { get; set; } - void LoadConfig(); + ILightArrayConfig LoadConfig(); void Update(); } diff --git a/PAPIPlugin/PAPIAddon.cs b/PAPIPlugin/PAPIAddon.cs index 76de2f2..7f33f27 100644 --- a/PAPIPlugin/PAPIAddon.cs +++ b/PAPIPlugin/PAPIAddon.cs @@ -20,7 +20,6 @@ public void Awake() { if (HighLogic.LoadedScene != GameScenes.FLIGHT && HighLogic.LoadedScene != GameScenes.SPACECENTER) { - return; } @@ -30,8 +29,7 @@ public void Awake() if (_config == null) { - _arrayManager.LoadConfig(); - _config = _arrayManager.LightConfig; + _config = _arrayManager.LoadConfig(); } else { From ff3ec8a909a9da952d6dfe3398ba08f3acbe68ef Mon Sep 17 00:00:00 2001 From: asarium Date: Wed, 31 Jul 2013 16:37:24 +0200 Subject: [PATCH 10/19] Reduce code redundancy in ConfigNodeExtensions. --- PAPIPlugin/Internal/ConfigNodeExtensions.cs | 37 +++++++++++---------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/PAPIPlugin/Internal/ConfigNodeExtensions.cs b/PAPIPlugin/Internal/ConfigNodeExtensions.cs index fd06fc4..99a85fe 100644 --- a/PAPIPlugin/Internal/ConfigNodeExtensions.cs +++ b/PAPIPlugin/Internal/ConfigNodeExtensions.cs @@ -9,11 +9,13 @@ namespace PAPIPlugin.Internal { public static class ConfigNodeExtensions { - public static T ConvertValue(this ConfigNode node, string key, T def = default(T)) + public static bool TryConvertValue(this ConfigNode node, string key, out T value) { + value = default(T); + if (!node.HasValue(key)) { - return def; + return false; } var stringValue = node.GetValue(key); @@ -22,37 +24,36 @@ public static class ConfigNodeExtensions try { - return (T) typeConverter.ConvertFromInvariantString(stringValue); + value = (T) typeConverter.ConvertFromInvariantString(stringValue); + + return true; } catch (NotSupportedException) { Util.LogWarning(string.Format("Cannot convert value \"{0}\" to type {1}", stringValue, typeof(T).FullName)); - return def; + return false; } } - public static T ConvertValueWithException(this ConfigNode node, string key) + public static T ConvertValue(this ConfigNode node, string key, T def = default(T)) { - if (!node.HasValue(key)) - { - throw new FormatException(string.Format("The key \"{0}\" could not be found.", key)); - } + T value; - var stringValue = node.GetValue(key); + return TryConvertValue(node, key, out value) ? value : def; + } - var typeConverter = TypeDescriptor.GetConverter(typeof(T)); + public static T ConvertValueWithException(this ConfigNode node, string key) + { + T value; - try + if (TryConvertValue(node, key, out value)) { - return (T) typeConverter.ConvertFromInvariantString(stringValue); + return value; } - catch (NotSupportedException) + else { - Util.LogWarning(string.Format("Cannot convert value \"{0}\" to type {1}", stringValue, typeof(T).FullName)); - - throw new FormatException(string.Format("Failed to convert the value \"{0}\" for key \"{1}\" to type \"{2}\"", stringValue, key, - typeof(T).FullName)); + throw new FormatException(string.Format("Failed to convert the value for key \"{0}\" to type \"{1}\"", key, typeof(T).FullName)); } } } From ba7c28494cba07606bb55d66c91d480375bb13e0 Mon Sep 17 00:00:00 2001 From: asarium Date: Thu, 1 Aug 2013 16:53:27 +0200 Subject: [PATCH 11/19] Also disable the unity script. --- PAPIPlugin/PAPIAddon.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/PAPIPlugin/PAPIAddon.cs b/PAPIPlugin/PAPIAddon.cs index 7f33f27..7171f59 100644 --- a/PAPIPlugin/PAPIAddon.cs +++ b/PAPIPlugin/PAPIAddon.cs @@ -20,6 +20,7 @@ public void Awake() { if (HighLogic.LoadedScene != GameScenes.FLIGHT && HighLogic.LoadedScene != GameScenes.SPACECENTER) { + enabled = false; return; } From 9b5f077c2375fb97e096e19045a14d7b2859cc86 Mon Sep 17 00:00:00 2001 From: asarium Date: Fri, 2 Aug 2013 11:04:45 +0200 Subject: [PATCH 12/19] Changed project to also build a zip Also adds the first version of the group UI. --- PAPIPlugin/PAPIPlugin.csproj | 24 ++++++- PAPIPlugin/UI/GroupWindow.cs | 63 ++++++++++++++++++ .../PluginData/PAPIPlugin/resize.png | Bin assets/{ => GameData/PAPIPlugin}/lights.cfg | 8 +++ 4 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 PAPIPlugin/UI/GroupWindow.cs rename assets/{ => GameData/PAPIPlugin}/PluginData/PAPIPlugin/resize.png (100%) rename assets/{ => GameData/PAPIPlugin}/lights.cfg (67%) diff --git a/PAPIPlugin/PAPIPlugin.csproj b/PAPIPlugin/PAPIPlugin.csproj index 201259a..c0d1e0c 100644 --- a/PAPIPlugin/PAPIPlugin.csproj +++ b/PAPIPlugin/PAPIPlugin.csproj @@ -46,6 +46,18 @@ + + TacLib\Icon.cs + + + TacLib\PopupWindow.cs + + + TacLib\Utilities.cs + + + TacLib\Window.cs + @@ -64,14 +76,20 @@ + - mkdir "$(SolutionDir)assets/Plugins" -xcopy /Y /I "$(TargetPath)" "$(SolutionDir)assets/Plugins" + mkdir "$(SolutionDir)assets/GameData/PAPIPlugin/Plugins" +xcopy /Y /I "$(TargetPath)" "$(SolutionDir)assets/GameData/PAPIPlugin/Plugins" -robocopy "$(SolutionDir)assets" "$(KSP_PATH)/GameData/PAPIPlugin" /PURGE /e +robocopy "$(SolutionDir)assets/GameData/" "$(KSP_PATH)/GameData/" /PURGE /e + +cd /d "$(SolutionDir)assets" +echo %25CD%25 +del "PAPIPlugin.zip" +7z a -r -tzip -y "PAPIPlugin.zip" "GameData" exit 0 diff --git a/PAPIPlugin/UI/GroupWindow.cs b/PAPIPlugin/UI/GroupWindow.cs new file mode 100644 index 0000000..fa394f1 --- /dev/null +++ b/PAPIPlugin/UI/GroupWindow.cs @@ -0,0 +1,63 @@ +#region Usings + +using System.Collections.Generic; +using System.Linq; +using PAPIPlugin.Interfaces; +using Tac; +using UnityEngine; + +#endregion + +namespace PAPIPlugin.UI +{ + public class GroupWindow : Window where T : ILightArrayConfig + { + private readonly T _arrayConfig; + + private readonly IDictionary _toggleState = new Dictionary(); + + private GUIStyle _toggleStyle; + + public GroupWindow(T arrayConfig) : base("Group configuration", 400, 200) + { + _arrayConfig = arrayConfig; + } + + protected override void ConfigureStyles() + { + base.ConfigureStyles(); + + if (_toggleStyle == null) + { + _toggleStyle = new GUIStyle(GUI.skin.button) + { + alignment = TextAnchor.MiddleCenter, + fontStyle = FontStyle.Normal, + padding = {top = 4, bottom = 4}, + stretchWidth = true, + stretchHeight = false + }; + } + } + + protected override void DrawWindowContents(int windowId) + { + foreach (var lightGroup in _arrayConfig.LightArrayGroups.Where(lightGroup => lightGroup.Name != null)) + { + if (!_toggleState.ContainsKey(lightGroup.Name)) + { + _toggleState[lightGroup.Name] = false; + } + + var newVal = GUILayout.Toggle(_toggleState[lightGroup.Name], lightGroup.Name, _toggleStyle); + + if (newVal) + { + lightGroup.OnGui(windowId); + } + + _toggleState[lightGroup.Name] = newVal; + } + } + } +} diff --git a/assets/PluginData/PAPIPlugin/resize.png b/assets/GameData/PAPIPlugin/PluginData/PAPIPlugin/resize.png similarity index 100% rename from assets/PluginData/PAPIPlugin/resize.png rename to assets/GameData/PAPIPlugin/PluginData/PAPIPlugin/resize.png diff --git a/assets/lights.cfg b/assets/GameData/PAPIPlugin/lights.cfg similarity index 67% rename from assets/lights.cfg rename to assets/GameData/PAPIPlugin/lights.cfg index c51e4c1..ea467e4 100644 --- a/assets/lights.cfg +++ b/assets/GameData/PAPIPlugin/lights.cfg @@ -12,6 +12,14 @@ LightGroup Longitude = -74.701944 Heading = 270 + + // Example values + GlideslopeTolerance = 1.5 + TargetGlideslope = 6 + HeightAboveTerrain = 5 + PartCount = 4 + LightRadius = 8 + LightDistance = 6 } LightArray From 086779ce1a5f619c0365e29ce7e266fb7cf41be3 Mon Sep 17 00:00:00 2001 From: asarium Date: Sat, 3 Aug 2013 12:54:06 +0200 Subject: [PATCH 13/19] Prepared the PAPIArray for external changes --- PAPIPlugin/Arrays/PAPIArray.cs | 59 +++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/PAPIPlugin/Arrays/PAPIArray.cs b/PAPIPlugin/Arrays/PAPIArray.cs index ad049bc..2fb31ae 100644 --- a/PAPIPlugin/Arrays/PAPIArray.cs +++ b/PAPIPlugin/Arrays/PAPIArray.cs @@ -13,18 +13,16 @@ namespace PAPIPlugin.Arrays { public class PAPIArray : AbstractLightArray, IConfigNode { - private const int PAPIPartCount = 4; + public const int DefaultPartCount = 4; - private const float PAPILightRadius = 10.0f; + public const float DefaultLightRadius = 10.0f; - private const double DefaultTargetGlidePath = 6; + public const double DefaultTargetGlidePath = 6; /// /// If the difference of the gliepath from the target is more than this the whole array will show either red or white. /// - private const double DefaultBadGlidepathVariance = 1.5; - - private static readonly Vector3 PAPILightDifference = Vector3.right * PAPILightRadius * 1.5f; + public const double DefaultGlideslopeTolerance = 1.5; private GameObject _papiGameObject; @@ -35,7 +33,7 @@ public class PAPIArray : AbstractLightArray, IConfigNode public PAPIArray() { TargetGlideslope = DefaultTargetGlidePath; - GlideslopeTolerance = DefaultBadGlidepathVariance; + GlideslopeTolerance = DefaultGlideslopeTolerance; EnabledChanged += (sender, args) => { @@ -63,13 +61,22 @@ public PAPIArray() public double HeightAboveTerrain { get; set; } + public int PartCount { get; set; } + + public float LightRadius { get; set; } + + public float LightDistance { get; set; } + #region IConfigNode Members public void Load(ConfigNode node) { - GlideslopeTolerance = node.ConvertValue("GlideslopeTolerance", DefaultBadGlidepathVariance); + GlideslopeTolerance = node.ConvertValue("GlideslopeTolerance", DefaultGlideslopeTolerance); TargetGlideslope = node.ConvertValue("TargetGlideslope", DefaultTargetGlidePath); HeightAboveTerrain = node.ConvertValue("Height", 0); + PartCount = node.ConvertValue("PartCount", DefaultPartCount); + LightRadius = node.ConvertValue("LightRadius", DefaultLightRadius); + LightDistance = node.ConvertValue("LightDistance", LightRadius * 0.5f); try { @@ -130,7 +137,7 @@ public override void Update() var difference = angle - TargetGlideslope; - for (var i = 0; i < PAPIPartCount; i++) + for (var i = 0; i < PartCount; i++) { if (directionDot <= 0) { @@ -192,13 +199,13 @@ private void InitializePAPIParts(double lat, double lon, double heading) _papiGameObject.transform.localRotation = Quaternion.LookRotation(headingVector, surfaceNormal); var maxHeight = double.MinValue; - _partObjects = new GameObject[PAPIPartCount]; - for (var i = 0; i < PAPIPartCount; i++) + _partObjects = new GameObject[PartCount]; + for (var i = 0; i < PartCount; i++) { var obj = AddPAPIPart(); obj.transform.parent = _papiGameObject.transform; - obj.transform.localPosition = (i - (PAPIPartCount / 2)) * PAPILightDifference; + obj.transform.localPosition = GetLocalLighPosition(i); maxHeight = Math.Max(maxHeight, parentBody.GetSurfaceHeight(Latitude, Longitude)); @@ -207,11 +214,26 @@ private void InitializePAPIParts(double lat, double lon, double heading) maxHeight = Math.Max(0, maxHeight); _relativeSurfacePosition = - parentBody.transform.InverseTransformPoint(parentBody.GetWorldSurfacePosition(lat, lon, - maxHeight + HeightAboveTerrain + PAPILightRadius)); + parentBody.transform.InverseTransformPoint(parentBody.GetWorldSurfacePosition(lat, lon, maxHeight + HeightAboveTerrain + LightRadius)); _papiGameObject.transform.localPosition = _relativeSurfacePosition; } + /// + /// Gets the local position given a zero-based index. + /// + /// The index of the light, zero-based + /// A local position specifying the light position + private Vector3 GetLocalLighPosition(int i) + { + var countHalf = PartCount / 2.0; + + var offsetMult = (float) (i - countHalf - 0.5); + + var distance = LightRadius + LightDistance; + + return Vector3.right * offsetMult * distance; + } + private static Vector3d Orthonormalise(Vector3d direction, Vector3d firstVector) { // This is basically the first step of a Gram–Schmidt process @@ -220,14 +242,14 @@ private static Vector3d Orthonormalise(Vector3d direction, Vector3d firstVector) return direction - Vector3d.Dot(firstVector, direction) * firstVector; } - private static GameObject AddPAPIPart() + private GameObject AddPAPIPart() { var obj = GameObject.CreatePrimitive(PrimitiveType.Sphere); var material = new Material(Shader.Find("Particles/Additive")); obj.renderer.sharedMaterial = material; - obj.transform.localScale = new Vector3(PAPILightRadius, PAPILightRadius, PAPILightRadius); + obj.transform.localScale = new Vector3(LightRadius, LightRadius, LightRadius); var sphereCollider = obj.GetComponent(); sphereCollider.enabled = false; @@ -257,8 +279,9 @@ private Color GetArrayPartColor(int index, double difference) } // This should map temp into [-1, 1] - double temp = index - (PAPIPartCount / 2); - temp = temp / (PAPIPartCount / 2); + double temp = index - (PartCount / 2); +// ReSharper disable once PossibleLossOfFraction + temp = temp / (PartCount / 2); return temp > difference ? Color.red : Color.white; } From e9ec38ad9c3d864e36c17a1673141ba4fe1afa60 Mon Sep 17 00:00:00 2001 From: asarium Date: Sat, 3 Aug 2013 12:54:57 +0200 Subject: [PATCH 14/19] Added OnGUI method for GUI customization. --- PAPIPlugin/Impl/DefaultLightGroup.cs | 8 ++++++++ PAPIPlugin/Interfaces/ILightGroup.cs | 2 ++ 2 files changed, 10 insertions(+) diff --git a/PAPIPlugin/Impl/DefaultLightGroup.cs b/PAPIPlugin/Impl/DefaultLightGroup.cs index f706428..dab3421 100644 --- a/PAPIPlugin/Impl/DefaultLightGroup.cs +++ b/PAPIPlugin/Impl/DefaultLightGroup.cs @@ -142,6 +142,14 @@ public T GetOrAddTypeManager(Func creatorFunc) where T : ILightTypeManager return newManager; } + public void OnGui(int windowId) + { + foreach (var lightTypeManager in _managers.Values) + { + lightTypeManager.OnGui(windowId); + } + } + public void Destroy() { foreach (var lightArray in _lightArrays) diff --git a/PAPIPlugin/Interfaces/ILightGroup.cs b/PAPIPlugin/Interfaces/ILightGroup.cs index c3e6f93..5128f84 100644 --- a/PAPIPlugin/Interfaces/ILightGroup.cs +++ b/PAPIPlugin/Interfaces/ILightGroup.cs @@ -18,5 +18,7 @@ public interface ILightGroup T GetOrAddTypeManager() where T : ILightTypeManager, new(); T GetOrAddTypeManager(Func creatorFunc) where T : ILightTypeManager; + + void OnGui(int windowId); } } \ No newline at end of file From 72f8b8588aa6861e083dfe54c19ea24aa1fc9ab6 Mon Sep 17 00:00:00 2001 From: asarium Date: Sat, 3 Aug 2013 12:55:31 +0200 Subject: [PATCH 15/19] Added GUI for PAPI arrays. --- PAPIPlugin/Impl/DefaultLightArrayManager.cs | 34 ++++++++ PAPIPlugin/Impl/PAPITypeManager.cs | 85 +++++++++++++++++++- PAPIPlugin/Interfaces/ILightTypeManager.cs | 2 + PAPIPlugin/PAPIPlugin.csproj | 5 +- PAPIPlugin/UI/EditableGUIField.cs | 89 +++++++++++++++++++++ PAPIPlugin/UI/GroupWindow.cs | 1 + 6 files changed, 211 insertions(+), 5 deletions(-) create mode 100644 PAPIPlugin/UI/EditableGUIField.cs diff --git a/PAPIPlugin/Impl/DefaultLightArrayManager.cs b/PAPIPlugin/Impl/DefaultLightArrayManager.cs index b50a08e..fdc6d47 100644 --- a/PAPIPlugin/Impl/DefaultLightArrayManager.cs +++ b/PAPIPlugin/Impl/DefaultLightArrayManager.cs @@ -5,6 +5,9 @@ using System.Linq; using PAPIPlugin.Interfaces; using PAPIPlugin.Internal; +using PAPIPlugin.UI; +using Tac; +using UnityEngine; #endregion @@ -12,8 +15,19 @@ namespace PAPIPlugin.Impl { public class DefaultLightArrayManager : ILightArrayManager { + private readonly Icon _groupWindowIcon; + + private GroupWindow _groupWindow; + private ILightArrayConfig _lightConfig; + public DefaultLightArrayManager() + { + _groupWindowIcon = new Icon(new Rect(Screen.width * 0.8f, 0.0f, 80.0f, 20.0f), "icon.png", "Light groups", + "Opens the light group overview", OnIconClickHandler); + _groupWindowIcon.SetVisible(true); + } + #region ILightArrayManager Members public event EventHandler ParsingFinished; @@ -68,6 +82,19 @@ public void Dispose() #endregion + private void OnIconClickHandler() + { + if (_groupWindow == null) + { + _groupWindow = new GroupWindow(LightConfig); + _groupWindow.SetVisible(true); + } + else + { + _groupWindow.ToggleVisible(); + } + } + private void InitializeConfig(ILightArrayConfig lightConfig) { foreach (var lightArray in lightConfig.LightArrayGroups.SelectMany(group => group.LightArrays)) @@ -93,6 +120,13 @@ protected virtual void OnParsingFinished() protected virtual void Dispose(bool disposing) { LightConfig.Destroy(); + + _groupWindowIcon.SetVisible(false); + + if (_groupWindow != null) + { + _groupWindow.SetVisible(false); + } } } } diff --git a/PAPIPlugin/Impl/PAPITypeManager.cs b/PAPIPlugin/Impl/PAPITypeManager.cs index 45f9a74..ea26484 100644 --- a/PAPIPlugin/Impl/PAPITypeManager.cs +++ b/PAPIPlugin/Impl/PAPITypeManager.cs @@ -1,9 +1,13 @@ #region Usings +using System; using System.Collections.Generic; using System.Linq; using PAPIPlugin.Arrays; using PAPIPlugin.Interfaces; +using PAPIPlugin.Internal; +using PAPIPlugin.UI; +using UnityEngine; #endregion @@ -11,24 +15,97 @@ namespace PAPIPlugin.Impl { public class PAPITypeManager : ILightTypeManager { - private readonly IList _papiArrays = new List(); + private readonly IList _papiArrays = new List(); + + private EditableGUIField _glideslopeField; + + private EditableGUIField _glideslopeToleranceField; + + private bool _guiInitialized = false; #region ILightTypeManager Members public void Initialize(ILightGroup group) { - foreach (var lightArray in group.LightArrays.Where(array => array is PAPIArray)) + Util.LogInfo(group); + + foreach (var lightArray in group.LightArrays.OfType()) { + Util.LogInfo(lightArray); _papiArrays.Add(lightArray); } group.LightArrayAdded += (sender, arguments) => { - if (arguments.Array is PAPIArray) - _papiArrays.Add(arguments.Array); + var papi = arguments.Array as PAPIArray; + if (papi != null) + { + _papiArrays.Add(papi); + } }; } + public void OnGui(int windowID) + { + if (!_guiInitialized) + { + _glideslopeField = new EditableGUIField(PAPIArray.DefaultTargetGlidePath, DoubleConvertDelegate); + _glideslopeToleranceField = new EditableGUIField(PAPIArray.DefaultGlideslopeTolerance, DoubleConvertDelegate); + + _guiInitialized = true; + } + + DoDegreeField("Glideslope", _glideslopeField); + DoDegreeField("Glideslope tolerance", _glideslopeToleranceField); + + ApplyValues(); + } + #endregion + + private void DoDegreeField(string name, EditableGUIField field) + { + GUILayout.BeginHorizontal(); + { + GUILayout.Label(name + ":"); + field.LayoutTextField(); + GUILayout.Label("°"); + } + GUILayout.EndHorizontal(); + } + + private static string DoubleConvertDelegate(string input, out double val) + { + val = 0; + + try + { + val = double.Parse(input); + return null; + } + catch (FormatException e) + { + return string.Format("Failed to convert \"{0}\" to double: {1}", input, e.Message); + } + } + + private void ApplyValues() + { + if (!_glideslopeField.InvalidInput) + { + foreach (var papiArray in _papiArrays) + { + papiArray.TargetGlideslope = _glideslopeField.Value; + } + } + + if (!_glideslopeToleranceField.InvalidInput) + { + foreach (var papiArray in _papiArrays) + { + papiArray.GlideslopeTolerance = _glideslopeToleranceField.Value; + } + } + } } } diff --git a/PAPIPlugin/Interfaces/ILightTypeManager.cs b/PAPIPlugin/Interfaces/ILightTypeManager.cs index f64df82..5820cf4 100644 --- a/PAPIPlugin/Interfaces/ILightTypeManager.cs +++ b/PAPIPlugin/Interfaces/ILightTypeManager.cs @@ -3,5 +3,7 @@ public interface ILightTypeManager { void Initialize(ILightGroup manager); + + void OnGui(int windowID); } } diff --git a/PAPIPlugin/PAPIPlugin.csproj b/PAPIPlugin/PAPIPlugin.csproj index c0d1e0c..c2a5fe5 100644 --- a/PAPIPlugin/PAPIPlugin.csproj +++ b/PAPIPlugin/PAPIPlugin.csproj @@ -37,12 +37,14 @@ False G:\Programme\KSP\0.21\KSP_Data\Managed\Assembly-CSharp.dll + False False G:\Programme\KSP\0.21\KSP_Data\Managed\UnityEngine.dll + False @@ -69,6 +71,7 @@ + @@ -84,7 +87,7 @@ mkdir "$(SolutionDir)assets/GameData/PAPIPlugin/Plugins" xcopy /Y /I "$(TargetPath)" "$(SolutionDir)assets/GameData/PAPIPlugin/Plugins" -robocopy "$(SolutionDir)assets/GameData/" "$(KSP_PATH)/GameData/" /PURGE /e +robocopy "$(SolutionDir)assets/GameData/PAPIPlugin" "$(KSP_PATH)/GameData/PAPIPlugin" /PURGE /e cd /d "$(SolutionDir)assets" echo %25CD%25 diff --git a/PAPIPlugin/UI/EditableGUIField.cs b/PAPIPlugin/UI/EditableGUIField.cs new file mode 100644 index 0000000..238d5a2 --- /dev/null +++ b/PAPIPlugin/UI/EditableGUIField.cs @@ -0,0 +1,89 @@ +#region Usings + +using System; +using System.ComponentModel; +using UnityEngine; + +#endregion + +namespace PAPIPlugin.UI +{ + public class EditableGUIField + { + #region Delegates + + public delegate string TryConvertFromString(string input, out T val); + + #endregion + + private readonly TryConvertFromString _convertDelegate; + + public EditableGUIField(T initial = default(T), TryConvertFromString convertDelegate = null) + { + _convertDelegate = convertDelegate; + Value = initial; + + // Null compare is intentional to guard against NullRefs... +// ReSharper disable once CompareNonConstrainedGenericWithNull + StringValue = initial == null ? string.Empty : initial.ToString(); + + if (_convertDelegate == null) + { + _convertDelegate = DefaultConvertDelegate; + } + + InitializeStyles(); + } + + public T Value { get; set; } + + public string StringValue { get; private set; } + + public bool InvalidInput { get; private set; } + + public string LastErrorText { get; private set; } + + public GUIStyle ValidStyle { get; set; } + + public GUIStyle InvalidStyle { get; set; } + + private void InitializeStyles() + { + ValidStyle = new GUIStyle(GUI.skin.textField); + + InvalidStyle = new GUIStyle(GUI.skin.textField) {normal = new GUIStyleState {textColor = Color.red}}; + } + + public void LayoutTextField(params GUILayoutOption[] options) + { + StringValue = GUILayout.TextField(StringValue, InvalidInput ? InvalidStyle : ValidStyle, options); + + T outVal; + LastErrorText = _convertDelegate(StringValue, out outVal); + + InvalidInput = LastErrorText != null; + if (LastErrorText == null) + { + Value = outVal; + } + } + + private string DefaultConvertDelegate(string input, out T val) + { + val = default(T); + + var typeConverter = TypeDescriptor.GetConverter(typeof(T)); + + try + { + val = (T) typeConverter.ConvertFromInvariantString(input); + + return null; + } + catch (NotSupportedException e) + { + return string.Format("The input \"{0}\" cannot be converted to type \"{1}\":\n{2}.", input, typeof(T).FullName, e.Message); + } + } + } +} diff --git a/PAPIPlugin/UI/GroupWindow.cs b/PAPIPlugin/UI/GroupWindow.cs index fa394f1..fbebafb 100644 --- a/PAPIPlugin/UI/GroupWindow.cs +++ b/PAPIPlugin/UI/GroupWindow.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using PAPIPlugin.Interfaces; +using PAPIPlugin.Internal; using Tac; using UnityEngine; From 6076d893ee13d37b8815fd8d01e914a2afbe8834 Mon Sep 17 00:00:00 2001 From: asarium Date: Sat, 3 Aug 2013 13:30:55 +0200 Subject: [PATCH 16/19] Changed invalid style to actually work... --- PAPIPlugin/UI/EditableGUIField.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/PAPIPlugin/UI/EditableGUIField.cs b/PAPIPlugin/UI/EditableGUIField.cs index 238d5a2..a7d94a6 100644 --- a/PAPIPlugin/UI/EditableGUIField.cs +++ b/PAPIPlugin/UI/EditableGUIField.cs @@ -51,7 +51,11 @@ private void InitializeStyles() { ValidStyle = new GUIStyle(GUI.skin.textField); - InvalidStyle = new GUIStyle(GUI.skin.textField) {normal = new GUIStyleState {textColor = Color.red}}; + InvalidStyle = new GUIStyle(ValidStyle) + { + onHover = {textColor = Color.red}, + normal = {textColor = Color.red} + }; } public void LayoutTextField(params GUILayoutOption[] options) From 83b5e90ad81d58641ca1cbaa828339fa865ef26e Mon Sep 17 00:00:00 2001 From: asarium Date: Sat, 3 Aug 2013 14:51:49 +0200 Subject: [PATCH 17/19] Changed or added git files. --- .gitattributes | 22 ++++++++++++++++++++++ .gitignore | 3 ++- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..412eeda --- /dev/null +++ b/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore index e7194cf..dd255ca 100644 --- a/.gitignore +++ b/.gitignore @@ -108,4 +108,5 @@ Backup*/ UpgradeLog*.XML ### Plugin specific ignores ### -assets/Plugins/ \ No newline at end of file +assets/**/*.dll +assets/**/*.zip \ No newline at end of file From 110fca2a0080edd87f0729cdf916d57238b30ff4 Mon Sep 17 00:00:00 2001 From: asarium Date: Sat, 3 Aug 2013 15:44:11 +0200 Subject: [PATCH 18/19] Updated readme, --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index f46abf6..8ae3b3e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,12 @@ PAPIPlugin ========== +This plugin adds working PAPI arrays to the runways of Kerbal Space Program. + +Building +---------- +First add an environment variable with the name *KSP_PATH* which contains the path to your KSP install where the plugin should be deployed to. +Then open the visual studio solution. You will need to add the assemblies **UnityEngine** and **Assembly-CSharp** from */KSP_Data/Managed* to the references of the project. After that either directly run or build the solition. The plugin will automatically be compied to your KSP install. + +Credits +---------- +TaranisElsu - Author of the TacLib library From ae1cb6e47ffa3ad28191ca8f3115d17b9487758c Mon Sep 17 00:00:00 2001 From: asarium Date: Sat, 3 Aug 2013 19:11:32 +0200 Subject: [PATCH 19/19] Updated TacLib version. --- TacLib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TacLib b/TacLib index 13df510..869ad1e 160000 --- a/TacLib +++ b/TacLib @@ -1 +1 @@ -Subproject commit 13df51047152ddb603eab16f3ce479bc9ea93c4b +Subproject commit 869ad1ee26c47feffed348507e7a03df256e6013