From: Andy Date: Fri, 20 Dec 2013 16:39:38 +0000 Subject: ToolbarButtonWrapper: Added an assignment to this.Button so that it can actually work. X-Git-Tag: 0.9.19 X-Git-Url: http://git.toad.homelinux.net/projects/VOID.git/commitdiff/4224b85 --- ToolbarButtonWrapper: Added an assignment to this.Button so that it can actually work. --- --- a/IntCollection.cs +++ b/IntCollection.cs @@ -59,7 +59,6 @@ return (ushort)((this.collection & (this.mask << idx)) >> idx); } set { - Console.WriteLine (value); if (idx < 0) { idx += this.maxCount; } @@ -71,7 +70,6 @@ idx *= wordLength; long packvalue = value & this.mask; - Console.WriteLine (packvalue); this.collection &= ~(this.mask << idx); this.collection |= packvalue << idx; --- /dev/null +++ b/ToolbarButtonWrapper.cs @@ -1,1 +1,443 @@ - +// +// ToolbarWrapper.cs +// +// Author: +// toadicus <> +// +// Copyright (c) 2013 toadicus +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +using System; +using System.Linq; +using System.Reflection; +using UnityEngine; + +namespace VOID +{ + /// + /// Wraps a Toolbar clickable button, after fetching it from a foreign assembly. + /// + internal class ToolbarButtonWrapper + { + protected static System.Type ToolbarManager; + protected static object TBManagerInstance; + protected static MethodInfo TBManagerAdd; + + /// + /// Wraps the ToolbarManager class, if present. + /// + /// true, if ToolbarManager is wrapped, false otherwise. + protected static bool TryWrapToolbarManager() + { + if (ToolbarManager == null) + { + Tools.PostDebugMessage(string.Format( + "{0}: Loading ToolbarManager.", + "ToolbarButtonWrapper" + )); + + ToolbarManager = AssemblyLoader.loadedAssemblies + .Select(a => a.assembly.GetExportedTypes()) + .SelectMany(t => t) + .FirstOrDefault(t => t.FullName == "Toolbar.ToolbarManager"); + + Tools.PostDebugMessage(string.Format( + "{0}: Loaded ToolbarManager. Getting Instance.", + "ToolbarButtonWrapper" + )); + + if (ToolbarManager == null) + { + return false; + } + + TBManagerInstance = ToolbarManager.GetProperty( + "Instance", + System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static + ) + .GetValue(null, null); + + Tools.PostDebugMessage(string.Format( + "{0}: Got ToolbarManager Instance '{1}'. Getting 'add' method.", + "ToolbarButtonWrapper", + TBManagerInstance + )); + + TBManagerAdd = ToolbarManager.GetMethod("add"); + + Tools.PostDebugMessage(string.Format( + "{0}: Got ToolbarManager Instance 'add' method. Loading IButton.", + "ToolbarButtonWrapper" + )); + } + + return true; + } + + /// + /// Gets a value indicating whether is present. + /// + /// true, if ToolbarManager is wrapped, false otherwise. + public static bool ToolbarManagerPresent + { + get + { + return TryWrapToolbarManager(); + } + } + + /// + /// If ToolbarManager is present, initializes a new instance of the class. + /// + /// Namespace, usually the plugin name. + /// Identifier, unique per namespace. + /// If ToolbarManager is present, a new object, null otherwise. + public static ToolbarButtonWrapper TryWrapToolbarButton(string ns, string id) + { + if (ToolbarManagerPresent) + { + object button = TBManagerAdd.Invoke(TBManagerInstance, new object[] { ns, id }); + + Tools.PostDebugMessage(string.Format( + "{0}: Added Button '{1}' with ToolbarManager. Getting 'Text' property", + "ToolbarButtonWrapper", + button.ToString() + )); + + return new ToolbarButtonWrapper(button); + } + else + { + return null; + } + } + + protected System.Type IButton; + protected object Button; + protected PropertyInfo ButtonText; + protected PropertyInfo ButtonTextColor; + protected PropertyInfo ButtonTexturePath; + protected PropertyInfo ButtonToolTip; + protected PropertyInfo ButtonVisible; + protected PropertyInfo ButtonVisibility; + protected PropertyInfo ButtonEnalbed; + protected PropertyInfo ButtonImportant; + protected EventInfo ButtonOnClick; + protected System.Type ClickHandlerType; + protected MethodInfo ButtonDestroy; + protected System.Type GameScenesVisibilityType; + + /// + /// The text displayed on the button. Set to null to hide text. + /// + /// + /// The text can be changed at any time to modify the button's appearance. Note that since this will also + /// modify the button's size, this feature should be used sparingly, if at all. + /// + /// + public string Text + { + get + { + return this.ButtonText.GetValue(this.Button, null) as String; + } + set + { + this.ButtonText.SetValue(this.Button, value, null); + } + } + + /// + /// The color the button text is displayed with. Defaults to Color.white. + /// + /// + /// The text color can be changed at any time to modify the button's appearance. + /// + public Color TextColor + { + get + { + return (Color)this.ButtonTextColor.GetValue(this.Button, null); + } + set + { + this.ButtonTextColor.SetValue(this.Button, value, null); + } + } + + /// + /// The path of a texture file to display an icon on the button. Set to null to hide icon. + /// + /// + /// + /// A texture path on a button will have precedence over text. That is, if both text and texture path + /// have been set on a button, the button will show the texture, not the text. + /// + /// + /// The texture size must not exceed 24x24 pixels. + /// + /// + /// The texture path must be relative to the "GameData" directory, and must not specify a file name suffix. + /// Valid example: MyAddon/Textures/icon_mybutton + /// + /// + /// The texture path can be changed at any time to modify the button's appearance. + /// + /// + /// + public string TexturePath + { + get + { + return this.ButtonTexturePath.GetValue(this.Button, null) as string; + } + set + { + this.ButtonTexturePath.SetValue(this.Button, value, null); + } + } + + /// + /// The button's tool tip text. Set to null if no tool tip is desired. + /// + /// + /// Tool Tip Text Should Always Use Headline Style Like This. + /// + public string ToolTip + { + get + { + return this.ButtonToolTip.GetValue(this.Button, null) as string; + } + set + { + this.ButtonToolTip.SetValue(this.Button, value, null); + } + } + + /// + /// Whether this button is currently visible or not. Can be used in addition to or as a replacement for . + /// + public bool Visible + { + get + { + return (bool)this.ButtonVisible.GetValue(this.Button, null); + } + set + { + this.ButtonVisible.SetValue(this.Button, value, null); + } + } + + /// + /// Whether this button is currently enabled (clickable) or not. This will not affect the player's ability to + /// position the button on their screen. + /// + public bool Enabled + { + get + { + return (bool)this.ButtonEnalbed.GetValue(this.Button, null); + } + set + { + this.ButtonEnalbed.SetValue(this.Button, value, null); + } + } + + /// + /// Whether this button is currently "important." Set to false to return to normal button behaviour. + /// + /// + /// + /// This can be used to temporarily force the button to be shown on the screen regardless of the toolbar being + /// currently in auto-hidden mode. For example, a button that signals the arrival of a private message in a + /// chat room could mark itself as "important" as long as the message has not been read. + /// + /// + /// Setting this property does not change the appearance of the button. use to + /// change the button's icon. + /// + /// + /// This feature should be used only sparingly, if at all, since it forces the button to be displayed on screen + /// even when it normally wouldn't. + /// + /// + /// true if important; otherwise, false. + public bool Important + { + get + { + return (bool)this.ButtonImportant.GetValue(this.Button, null); + } + set + { + this.ButtonImportant.SetValue(this.Button, value, null); + } + } + + private ToolbarButtonWrapper() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Namespace, usually the plugin name. + /// Identifier, unique per namespace. + protected ToolbarButtonWrapper(object button) + { + this.Button = button; + + this.IButton = AssemblyLoader.loadedAssemblies + .Select(a => a.assembly.GetExportedTypes()) + .SelectMany(t => t) + .FirstOrDefault(t => t.FullName == "Toolbar.IButton"); + + Tools.PostDebugMessage(string.Format( + "{0}: Loaded IButton. Adding Button with ToolbarManager.", + this.GetType().Name + )); + + this.ButtonText = this.IButton.GetProperty("Text"); + + Tools.PostDebugMessage(string.Format( + "{0}: Got 'Text' property. Getting 'TextColor' property.", + this.GetType().Name + )); + + this.ButtonTextColor = this.IButton.GetProperty("TextColor"); + + Tools.PostDebugMessage(string.Format( + "{0}: Got 'TextColor' property. Getting 'TexturePath' property.", + this.GetType().Name + )); + + this.ButtonTexturePath = this.IButton.GetProperty("TexturePath"); + + Tools.PostDebugMessage(string.Format( + "{0}: Got 'TexturePath' property. Getting 'ToolTip' property.", + this.GetType().Name + )); + + this.ButtonToolTip = this.IButton.GetProperty("ToolTip"); + + Tools.PostDebugMessage(string.Format( + "{0}: Got 'ToolTip' property. Getting 'Visible' property.", + this.GetType().Name + )); + + this.ButtonVisible = this.IButton.GetProperty("Visible"); + + Tools.PostDebugMessage(string.Format( + "{0}: Got 'Visible' property. Getting 'Visibility' property.", + this.GetType().Name + )); + + this.ButtonVisibility = this.IButton.GetProperty("Visibility"); + + Tools.PostDebugMessage(string.Format( + "{0}: Got 'Visibility' property. Getting 'Enabled' property.", + this.GetType().Name + )); + + this.ButtonEnalbed = this.IButton.GetProperty("Enabled"); + + Tools.PostDebugMessage(string.Format( + "{0}: Got 'Enabled' property. Getting 'OnClick' event.", + this.GetType().Name + )); + + this.ButtonImportant = this.IButton.GetProperty("Important"); + + Tools.PostDebugMessage(string.Format( + "{0}: Got 'Enabled' property. Getting 'OnClick' event.", + this.GetType().Name + )); + + this.ButtonOnClick = this.IButton.GetEvent("OnClick"); + this.ClickHandlerType = this.ButtonOnClick.EventHandlerType; + + Tools.PostDebugMessage(string.Format( + "{0}: Got 'OnClick' event '{1}'. Getting 'Destroy' method.", + this.GetType().Name, + this.ButtonOnClick.ToString() + )); + + this.ButtonDestroy = this.IButton.GetMethod("Destroy"); + + Tools.PostDebugMessage(string.Format( + "{0}: Got 'Destroy' property '{1}'. Loading GameScenesVisibility class.", + this.GetType().Name, + this.ButtonDestroy.ToString() + )); + + this.GameScenesVisibilityType = AssemblyLoader.loadedAssemblies + .Select(a => a.assembly.GetExportedTypes()) + .SelectMany(t => t) + .FirstOrDefault(t => t.FullName == "Toolbar.GameScenesVisibility"); + + Tools.PostDebugMessage(string.Format( + "{0}: Got 'GameScenesVisibility' class '{1}'.", + this.GetType().Name, + this.GameScenesVisibilityType.ToString() + )); + + Tools.PostDebugMessage("ToolbarButtonWrapper built!"); + } + + /// + /// Adds event handler to receive "on click" events. + /// + /// + /// + /// ToolbarButtonWrapper button = ... + /// button.AddButtonClickHandler( + /// (e) => + /// { + /// Debug.Log("button clicked, mouseButton: " + e.Mousebutton"); + /// } + /// ); + /// + /// + /// Delegate to handle "on click" events + public void AddButtonClickHandler(Action Handler) + { + Delegate d = Delegate.CreateDelegate(this.ClickHandlerType, Handler.Target, Handler.Method); + MethodInfo addHandler = this.ButtonOnClick.GetAddMethod(); + addHandler.Invoke(this.Button, new object[] { d }); + } + + /// + /// Sets this button's visibility. Can be used in addition to or as a replacement for . + /// + /// Array of GameScene objects in which the button should be visible. + public void SetButtonVisibility(params GameScenes[] gameScenes) + { + object GameScenesVisibilityObj = Activator.CreateInstance(this.GameScenesVisibilityType, gameScenes); + this.ButtonVisibility.SetValue(this.Button, GameScenesVisibilityObj, null); + } + + /// + /// Permanently destroys this button so that it is no longer displayed. + /// Should be used when a plugin is stopped to remove leftover buttons. + /// + public void Destroy() + { + this.ButtonDestroy.Invoke(this.Button, null); + } + } +} + --- a/Tools.cs +++ b/Tools.cs @@ -25,7 +25,6 @@ // /////////////////////////////////////////////////////////////////////////////// - using System; using System.Collections.Generic; using UnityEngine; @@ -51,9 +50,13 @@ try { CBAttributeMap BiomeMap = vessel.mainBody.BiomeMap; + double lat = vessel.latitude * Math.PI / 180d; double lon = vessel.longitude * Math.PI / 180d; + mapAttribute = BiomeMap.GetAtt(lat, lon); + + /* lon -= Math.PI / 2d; if (lon < 0d) @@ -64,7 +67,7 @@ float v = (float)(lat / Math.PI) + 0.5f; float u = (float)(lon / (2d * Math.PI)); - Color pixelBilinear = BiomeMap.Map.GetPixelBilinear (u, v); + Color pixelBilinear = BiomeMap.Map.GetPixelBilinear(u, v); mapAttribute = BiomeMap.defaultAttribute; if (BiomeMap.Map != null) @@ -85,7 +88,7 @@ float num = 1 / zero; for (int j = 0; j < BiomeMap.Attributes.Length; ++j) { - Color mapColor = BiomeMap.Attributes [j].mapColor; + Color mapColor = BiomeMap.Attributes[j].mapColor; float sqrMagnitude = ((Vector4)(mapColor - pixelBilinear)).sqrMagnitude; if (sqrMagnitude < num) { @@ -103,6 +106,7 @@ } } } + */ } catch (NullReferenceException) { @@ -113,7 +117,7 @@ return mapAttribute; } - public static string GetLongitudeString(Vessel vessel, string format="F4") + public static string GetLongitudeString(Vessel vessel, string format = "F4") { string dir_long = "W"; double v_long = vessel.longitude; @@ -129,16 +133,18 @@ v_long -= 360d; } - if (v_long > 0) dir_long = "E"; + if (v_long > 0) + dir_long = "E"; return string.Format("{0}° {1}", Math.Abs(v_long).ToString(format), dir_long); } - public static string GetLatitudeString(Vessel vessel, string format="F4") + public static string GetLatitudeString(Vessel vessel, string format = "F4") { string dir_lat = "S"; double v_lat = vessel.latitude; - if (v_lat > 0) dir_lat = "N"; + if (v_lat > 0) + dir_lat = "N"; return string.Format("{0}° {1}", Math.Abs(v_lat).ToString(format), dir_lat); } @@ -200,27 +206,25 @@ return value.ToString(format); } } - //From http://svn.mumech.com/KSP/trunk/MuMechLib/VOID.vesselState.cs public static double MuMech_get_heading(Vessel vessel) { Vector3d CoM = vessel.findWorldCenterOfMass(); Vector3d up = (CoM - vessel.mainBody.position).normalized; Vector3d north = Vector3d.Exclude( - up, - (vessel.mainBody.position + - vessel.mainBody.transform.up * (float)vessel.mainBody.Radius - ) - CoM).normalized; + up, + (vessel.mainBody.position + + vessel.mainBody.transform.up * (float)vessel.mainBody.Radius + ) - CoM).normalized; Quaternion rotationSurface = Quaternion.LookRotation(north, up); Quaternion rotationvesselSurface = Quaternion.Inverse( - Quaternion.Euler(90, 0, 0) * - Quaternion.Inverse(vessel.transform.rotation) * - rotationSurface); + Quaternion.Euler(90, 0, 0) * + Quaternion.Inverse(vessel.transform.rotation) * + rotationSurface); return rotationvesselSurface.eulerAngles.y; } - //From http://svn.mumech.com/KSP/trunk/MuMechLib/MuUtils.cs public static string MuMech_ToSI( double d, int digits = 3, int MinMagnitude = 0, int MaxMagnitude = int.MaxValue @@ -233,76 +237,76 @@ { switch ((int)Math.Floor(exponent)) { - case 0: - case 1: - case 2: - return d.ToString("F" + digits); - case 3: - case 4: - case 5: - return (d / 1e3).ToString("F" + digits) + "k"; - case 6: - case 7: - case 8: - return (d / 1e6).ToString("F" + digits) + "M"; - case 9: - case 10: - case 11: - return (d / 1e9).ToString("F" + digits) + "G"; - case 12: - case 13: - case 14: - return (d / 1e12).ToString("F" + digits) + "T"; - case 15: - case 16: - case 17: - return (d / 1e15).ToString("F" + digits) + "P"; - case 18: - case 19: - case 20: - return (d / 1e18).ToString("F" + digits) + "E"; - case 21: - case 22: - case 23: - return (d / 1e21).ToString("F" + digits) + "Z"; - default: - return (d / 1e24).ToString("F" + digits) + "Y"; + case 0: + case 1: + case 2: + return d.ToString("F" + digits); + case 3: + case 4: + case 5: + return (d / 1e3).ToString("F" + digits) + "k"; + case 6: + case 7: + case 8: + return (d / 1e6).ToString("F" + digits) + "M"; + case 9: + case 10: + case 11: + return (d / 1e9).ToString("F" + digits) + "G"; + case 12: + case 13: + case 14: + return (d / 1e12).ToString("F" + digits) + "T"; + case 15: + case 16: + case 17: + return (d / 1e15).ToString("F" + digits) + "P"; + case 18: + case 19: + case 20: + return (d / 1e18).ToString("F" + digits) + "E"; + case 21: + case 22: + case 23: + return (d / 1e21).ToString("F" + digits) + "Z"; + default: + return (d / 1e24).ToString("F" + digits) + "Y"; } } else if (exponent < 0) { switch ((int)Math.Floor(exponent)) { - case -1: - case -2: - case -3: - return (d * 1e3).ToString("F" + digits) + "m"; - case -4: - case -5: - case -6: - return (d * 1e6).ToString("F" + digits) + "μ"; - case -7: - case -8: - case -9: - return (d * 1e9).ToString("F" + digits) + "n"; - case -10: - case -11: - case -12: - return (d * 1e12).ToString("F" + digits) + "p"; - case -13: - case -14: - case -15: - return (d * 1e15).ToString("F" + digits) + "f"; - case -16: - case -17: - case -18: - return (d * 1e18).ToString("F" + digits) + "a"; - case -19: - case -20: - case -21: - return (d * 1e21).ToString("F" + digits) + "z"; - default: - return (d * 1e24).ToString("F" + digits) + "y"; + case -1: + case -2: + case -3: + return (d * 1e3).ToString("F" + digits) + "m"; + case -4: + case -5: + case -6: + return (d * 1e6).ToString("F" + digits) + "μ"; + case -7: + case -8: + case -9: + return (d * 1e9).ToString("F" + digits) + "n"; + case -10: + case -11: + case -12: + return (d * 1e12).ToString("F" + digits) + "p"; + case -13: + case -14: + case -15: + return (d * 1e15).ToString("F" + digits) + "f"; + case -16: + case -17: + case -18: + return (d * 1e18).ToString("F" + digits) + "a"; + case -19: + case -20: + case -21: + return (d * 1e21).ToString("F" + digits) + "z"; + default: + return (d * 1e24).ToString("F" + digits) + "y"; } } else @@ -371,9 +375,7 @@ a[0] = char.ToUpper(a[0]); return new string(a); } - //transfer angles - public static double Nivvy_CalcTransferPhaseAngle(double r_current, double r_target, double grav_param) { double T_target = (2 * Math.PI) * Math.Sqrt(Math.Pow((r_target / 1000), 3) / (grav_param / 1000000000)); @@ -447,25 +449,42 @@ // returns the ejection angle } - public static double Adammada_CurrrentPhaseAngle(double body_LAN, double body_orbitPct, double origin_LAN, double origin_orbitPct) + public static double Adammada_CurrrentPhaseAngle( + double body_LAN, + double body_orbitPct, + double origin_LAN, + double origin_orbitPct + ) { double angle = (body_LAN / 360 + body_orbitPct) - (origin_LAN / 360 + origin_orbitPct); - if (angle > 1) angle = angle - 1; - if (angle < 0) angle = angle + 1; - if (angle > 0.5) angle = angle - 1; + if (angle > 1) + angle = angle - 1; + if (angle < 0) + angle = angle + 1; + if (angle > 0.5) + angle = angle - 1; angle = angle * 360; return angle; } - public static double Adammada_CurrentEjectionAngle(double vessel_long, double origin_rotAngle, double origin_LAN, double origin_orbitPct) + public static double Adammada_CurrentEjectionAngle( + double vessel_long, + double origin_rotAngle, + double origin_LAN, + double origin_orbitPct + ) { //double eangle = ((FlightGlobals.ActiveVOID.vessel.longitude + orbiting.rotationAngle) - (orbiting.orbit.LAN / 360 + orbiting.orbit.orbitPercent) * 360); double eangle = ((vessel_long + origin_rotAngle) - (origin_LAN / 360 + origin_orbitPct) * 360); - while (eangle < 0) eangle = eangle + 360; - while (eangle > 360) eangle = eangle - 360; - if (eangle < 270) eangle = 90 - eangle; - else eangle = 450 - eangle; + while (eangle < 0) + eangle = eangle + 360; + while (eangle > 360) + eangle = eangle - 360; + if (eangle < 270) + eangle = 90 - eangle; + else + eangle = 450 - eangle; return eangle; } @@ -492,7 +511,8 @@ double phase = Vector3d.Angle(vecthis, vectarget); - if (Vector3d.Angle(prograde, vectarget) > 90) phase = 360 - phase; + if (Vector3d.Angle(prograde, vectarget) > 90) + phase = 360 - phase; return (phase + 360) % 360; } @@ -500,7 +520,8 @@ public static double FixAngleDomain(double Angle, bool Degrees = false) { double Extent = 2d * Math.PI; - if (Degrees) { + if (Degrees) + { Extent = 360d; } @@ -515,20 +536,24 @@ public static double FixDegreeDomain(double Angle) { - return FixAngleDomain (Angle, true); + return FixAngleDomain(Angle, true); } public static double adjustCurrPhaseAngle(double transfer_angle, double curr_phase) { if (transfer_angle < 0) { - if (curr_phase > 0) return (-1 * (360 - curr_phase)); - else if (curr_phase < 0) return curr_phase; + if (curr_phase > 0) + return (-1 * (360 - curr_phase)); + else if (curr_phase < 0) + return curr_phase; } else if (transfer_angle > 0) { - if (curr_phase > 0) return curr_phase; - else if (curr_phase < 0) return (360 + curr_phase); + if (curr_phase > 0) + return curr_phase; + else if (curr_phase < 0) + return (360 + curr_phase); } return curr_phase; } @@ -546,8 +571,10 @@ // if < 0, add curr to 360 // 360 + (-17) = 343 // else its good as it is - if (curr_ejection < 0) return 360 + curr_ejection; - else return curr_ejection; + if (curr_ejection < 0) + return 360 + curr_ejection; + else + return curr_ejection; } @@ -557,8 +584,10 @@ //180 + curr_ejection // else if transfer_phase_angle > 0 its good as it is - if (trans_phase < 0) return 180 + trans_ejection; - else return trans_ejection; + if (trans_phase < 0) + return 180 + trans_ejection; + else + return trans_ejection; } @@ -568,7 +597,7 @@ // HACK: This assumes that on worlds with oceans, all water is fixed at 0 m, // and water covers the whole surface at 0 m. - if (vessel.terrainAltitude < 0 && vessel.mainBody.ocean ) + if (vessel.terrainAltitude < 0 && vessel.mainBody.ocean) { trueAltitude = vessel.orbit.altitude; } @@ -578,50 +607,107 @@ public static string get_heading_text(double heading) { - if (heading > 348.75 || heading <= 11.25) return "N"; - else if (heading > 11.25 && heading <= 33.75) return "NNE"; - else if (heading > 33.75 && heading <= 56.25) return "NE"; - else if (heading > 56.25 && heading <= 78.75) return "ENE"; - else if (heading > 78.75 && heading <= 101.25) return "E"; - else if (heading > 101.25 && heading <= 123.75) return "ESE"; - else if (heading > 123.75 && heading <= 146.25) return "SE"; - else if (heading > 146.25 && heading <= 168.75) return "SSE"; - else if (heading > 168.75 && heading <= 191.25) return "S"; - else if (heading > 191.25 && heading <= 213.75) return "SSW"; - else if (heading > 213.75 && heading <= 236.25) return "SW"; - else if (heading > 236.25 && heading <= 258.75) return "WSW"; - else if (heading > 258.75 && heading <= 281.25) return "W"; - else if (heading > 281.25 && heading <= 303.75) return "WNW"; - else if (heading > 303.75 && heading <= 326.25) return "NW"; - else if (heading > 326.25 && heading <= 348.75) return "NNW"; - else return ""; - } - - + if (heading > 348.75 || heading <= 11.25) + return "N"; + else if (heading > 11.25 && heading <= 33.75) + return "NNE"; + else if (heading > 33.75 && heading <= 56.25) + return "NE"; + else if (heading > 56.25 && heading <= 78.75) + return "ENE"; + else if (heading > 78.75 && heading <= 101.25) + return "E"; + else if (heading > 101.25 && heading <= 123.75) + return "ESE"; + else if (heading > 123.75 && heading <= 146.25) + return "SE"; + else if (heading > 146.25 && heading <= 168.75) + return "SSE"; + else if (heading > 168.75 && heading <= 191.25) + return "S"; + else if (heading > 191.25 && heading <= 213.75) + return "SSW"; + else if (heading > 213.75 && heading <= 236.25) + return "SW"; + else if (heading > 236.25 && heading <= 258.75) + return "WSW"; + else if (heading > 258.75 && heading <= 281.25) + return "W"; + else if (heading > 281.25 && heading <= 303.75) + return "WNW"; + else if (heading > 303.75 && heading <= 326.25) + return "NW"; + else if (heading > 326.25 && heading <= 348.75) + return "NNW"; + else + return ""; + } public static void display_transfer_angles_SUN2PLANET(CelestialBody body, Vessel vessel) { GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.Label("Phase angle (curr/trans):"); - GUILayout.Label(Tools.mrenigma03_calcphase(vessel, body).ToString("F3") + "° / " + Tools.Nivvy_CalcTransferPhaseAngle(vessel.orbit.semiMajorAxis, body.orbit.semiMajorAxis, vessel.mainBody.gravParameter).ToString("F3") + "°", GUILayout.ExpandWidth(false)); + GUILayout.Label( + Tools.mrenigma03_calcphase(vessel, body).ToString("F3") + "° / " + Tools.Nivvy_CalcTransferPhaseAngle( + vessel.orbit.semiMajorAxis, + body.orbit.semiMajorAxis, + vessel.mainBody.gravParameter + ).ToString("F3") + "°", + GUILayout.ExpandWidth(false) + ); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.Label("Transfer velocity:"); - GUILayout.Label((Tools.Younata_DeltaVToGetToOtherBody((vessel.mainBody.gravParameter / 1000000000), (vessel.orbit.semiMajorAxis / 1000), (body.orbit.semiMajorAxis / 1000)) * 1000).ToString("F2") + "m/s", GUILayout.ExpandWidth(false)); + GUILayout.Label( + (Tools.Younata_DeltaVToGetToOtherBody( + (vessel.mainBody.gravParameter / 1000000000), + (vessel.orbit.semiMajorAxis / 1000), + (body.orbit.semiMajorAxis / 1000) + ) * 1000).ToString("F2") + "m/s", + GUILayout.ExpandWidth(false) + ); GUILayout.EndHorizontal(); } public static void display_transfer_angles_PLANET2PLANET(CelestialBody body, Vessel vessel) { - double dv1 = Tools.Younata_DeltaVToGetToOtherBody((vessel.mainBody.referenceBody.gravParameter / 1000000000), (vessel.mainBody.orbit.semiMajorAxis / 1000), (body.orbit.semiMajorAxis / 1000)); - double dv2 = Tools.Younata_DeltaVToExitSOI((vessel.mainBody.gravParameter / 1000000000), (vessel.orbit.semiMajorAxis / 1000), (vessel.mainBody.sphereOfInfluence / 1000), Math.Abs(dv1)); - - double trans_ejection_angle = Tools.Younata_TransferBurnPoint((vessel.orbit.semiMajorAxis / 1000), dv2, (Math.PI / 2.0), (vessel.mainBody.gravParameter / 1000000000)); - double curr_ejection_angle = Tools.Adammada_CurrentEjectionAngle(FlightGlobals.ActiveVessel.longitude, FlightGlobals.ActiveVessel.orbit.referenceBody.rotationAngle, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent); - - double trans_phase_angle = Tools.Nivvy_CalcTransferPhaseAngle(vessel.mainBody.orbit.semiMajorAxis, body.orbit.semiMajorAxis, vessel.mainBody.referenceBody.gravParameter) % 360; - double curr_phase_angle = Tools.Adammada_CurrrentPhaseAngle(body.orbit.LAN, body.orbit.orbitPercent, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent); + double dv1 = Tools.Younata_DeltaVToGetToOtherBody( + (vessel.mainBody.referenceBody.gravParameter / 1000000000), + (vessel.mainBody.orbit.semiMajorAxis / 1000), + (body.orbit.semiMajorAxis / 1000) + ); + double dv2 = Tools.Younata_DeltaVToExitSOI( + (vessel.mainBody.gravParameter / 1000000000), + (vessel.orbit.semiMajorAxis / 1000), + (vessel.mainBody.sphereOfInfluence / 1000), + Math.Abs(dv1) + ); + + double trans_ejection_angle = Tools.Younata_TransferBurnPoint( + (vessel.orbit.semiMajorAxis / 1000), + dv2, + (Math.PI / 2.0), + (vessel.mainBody.gravParameter / 1000000000) + ); + double curr_ejection_angle = Tools.Adammada_CurrentEjectionAngle( + FlightGlobals.ActiveVessel.longitude, + FlightGlobals.ActiveVessel.orbit.referenceBody.rotationAngle, + FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN, + FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent + ); + + double trans_phase_angle = Tools.Nivvy_CalcTransferPhaseAngle( + vessel.mainBody.orbit.semiMajorAxis, + body.orbit.semiMajorAxis, + vessel.mainBody.referenceBody.gravParameter + ) % 360; + double curr_phase_angle = Tools.Adammada_CurrrentPhaseAngle( + body.orbit.LAN, + body.orbit.orbitPercent, + FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN, + FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent + ); double adj_phase_angle = Tools.adjustCurrPhaseAngle(trans_phase_angle, curr_phase_angle); double adj_trans_ejection_angle = Tools.adjust_transfer_ejection_angle(trans_ejection_angle, trans_phase_angle); @@ -629,12 +715,18 @@ GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.Label("Phase angle (curr/trans):"); - GUILayout.Label(adj_phase_angle.ToString("F3") + "° / " + trans_phase_angle.ToString("F3") + "°", GUILayout.ExpandWidth(false)); + GUILayout.Label( + adj_phase_angle.ToString("F3") + "° / " + trans_phase_angle.ToString("F3") + "°", + GUILayout.ExpandWidth(false) + ); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.Label("Ejection angle (curr/trans):"); - GUILayout.Label(adj_curr_ejection_angle.ToString("F3") + "° / " + adj_trans_ejection_angle.ToString("F3") + "°", GUILayout.ExpandWidth(false)); + GUILayout.Label( + adj_curr_ejection_angle.ToString("F3") + "° / " + adj_trans_ejection_angle.ToString("F3") + "°", + GUILayout.ExpandWidth(false) + ); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); @@ -645,13 +737,24 @@ public static void display_transfer_angles_PLANET2MOON(CelestialBody body, Vessel vessel) { - double dv1 = Tools.Younata_DeltaVToGetToOtherBody((vessel.mainBody.gravParameter / 1000000000), (vessel.orbit.semiMajorAxis / 1000), (body.orbit.semiMajorAxis / 1000)); - - double trans_phase_angle = Tools.Nivvy_CalcTransferPhaseAngle(vessel.orbit.semiMajorAxis, body.orbit.semiMajorAxis, vessel.mainBody.gravParameter); + double dv1 = Tools.Younata_DeltaVToGetToOtherBody( + (vessel.mainBody.gravParameter / 1000000000), + (vessel.orbit.semiMajorAxis / 1000), + (body.orbit.semiMajorAxis / 1000) + ); + + double trans_phase_angle = Tools.Nivvy_CalcTransferPhaseAngle( + vessel.orbit.semiMajorAxis, + body.orbit.semiMajorAxis, + vessel.mainBody.gravParameter + ); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.Label("Phase angle (curr/trans):"); - GUILayout.Label(Tools.mrenigma03_calcphase(vessel, body).ToString("F3") + "° / " + trans_phase_angle.ToString("F3") + "°", GUILayout.ExpandWidth(false)); + GUILayout.Label( + Tools.mrenigma03_calcphase(vessel, body).ToString("F3") + "° / " + trans_phase_angle.ToString("F3") + "°", + GUILayout.ExpandWidth(false) + ); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); @@ -662,14 +765,42 @@ public static void display_transfer_angles_MOON2MOON(CelestialBody body, Vessel vessel) { - double dv1 = Tools.Younata_DeltaVToGetToOtherBody((vessel.mainBody.referenceBody.gravParameter / 1000000000), (vessel.mainBody.orbit.semiMajorAxis / 1000), (body.orbit.semiMajorAxis / 1000)); - double dv2 = Tools.Younata_DeltaVToExitSOI((vessel.mainBody.gravParameter / 1000000000), (vessel.orbit.semiMajorAxis / 1000), (vessel.mainBody.sphereOfInfluence / 1000), Math.Abs(dv1)); - double trans_ejection_angle = Tools.Younata_TransferBurnPoint((vessel.orbit.semiMajorAxis / 1000), dv2, (Math.PI / 2.0), (vessel.mainBody.gravParameter / 1000000000)); - - double curr_phase_angle = Tools.Adammada_CurrrentPhaseAngle(body.orbit.LAN, body.orbit.orbitPercent, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent); - double curr_ejection_angle = Tools.Adammada_CurrentEjectionAngle(FlightGlobals.ActiveVessel.longitude, FlightGlobals.ActiveVessel.orbit.referenceBody.rotationAngle, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN, FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent); - - double trans_phase_angle = Tools.Nivvy_CalcTransferPhaseAngle(vessel.mainBody.orbit.semiMajorAxis, body.orbit.semiMajorAxis, vessel.mainBody.referenceBody.gravParameter) % 360; + double dv1 = Tools.Younata_DeltaVToGetToOtherBody( + (vessel.mainBody.referenceBody.gravParameter / 1000000000), + (vessel.mainBody.orbit.semiMajorAxis / 1000), + (body.orbit.semiMajorAxis / 1000) + ); + double dv2 = Tools.Younata_DeltaVToExitSOI( + (vessel.mainBody.gravParameter / 1000000000), + (vessel.orbit.semiMajorAxis / 1000), + (vessel.mainBody.sphereOfInfluence / 1000), + Math.Abs(dv1) + ); + double trans_ejection_angle = Tools.Younata_TransferBurnPoint( + (vessel.orbit.semiMajorAxis / 1000), + dv2, + (Math.PI / 2.0), + (vessel.mainBody.gravParameter / 1000000000) + ); + + double curr_phase_angle = Tools.Adammada_CurrrentPhaseAngle( + body.orbit.LAN, + body.orbit.orbitPercent, + FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN, + FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent + ); + double curr_ejection_angle = Tools.Adammada_CurrentEjectionAngle( + FlightGlobals.ActiveVessel.longitude, + FlightGlobals.ActiveVessel.orbit.referenceBody.rotationAngle, + FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.LAN, + FlightGlobals.ActiveVessel.orbit.referenceBody.orbit.orbitPercent + ); + + double trans_phase_angle = Tools.Nivvy_CalcTransferPhaseAngle( + vessel.mainBody.orbit.semiMajorAxis, + body.orbit.semiMajorAxis, + vessel.mainBody.referenceBody.gravParameter + ) % 360; double adj_phase_angle = Tools.adjustCurrPhaseAngle(trans_phase_angle, curr_phase_angle); //double adj_ejection_angle = adjustCurrEjectionAngle(trans_phase_angle, curr_ejection_angle); @@ -683,12 +814,18 @@ GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.Label("Phase angle (curr/trans):"); - GUILayout.Label(adj_phase_angle.ToString("F3") + "° / " + trans_phase_angle.ToString("F3") + "°", GUILayout.ExpandWidth(false)); + GUILayout.Label( + adj_phase_angle.ToString("F3") + "° / " + trans_phase_angle.ToString("F3") + "°", + GUILayout.ExpandWidth(false) + ); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.Label("Ejection angle (curr/trans):"); - GUILayout.Label(adj_curr_ejection_angle.ToString("F3") + "° / " + adj_trans_ejection_angle.ToString("F3") + "°", GUILayout.ExpandWidth(false)); + GUILayout.Label( + adj_curr_ejection_angle.ToString("F3") + "° / " + adj_trans_ejection_angle.ToString("F3") + "°", + GUILayout.ExpandWidth(false) + ); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); @@ -696,12 +833,11 @@ GUILayout.Label((dv2 * 1000).ToString("F2") + "m/s", GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); } - // This implementation is adapted from FARGUIUtils.ClampToScreen public static Rect ClampRectToScreen(Rect window, int xMargin, int yMargin) { - window.x = Mathf.Clamp (window.x, xMargin - window.width, Screen.width - xMargin); - window.y = Mathf.Clamp (window.y, yMargin - window.height, Screen.height - yMargin); + window.x = Mathf.Clamp(window.x, xMargin - window.width, Screen.width - xMargin); + window.y = Mathf.Clamp(window.y, yMargin - window.height, Screen.height - yMargin); return window; } @@ -713,13 +849,13 @@ public static Rect ClampRectToScreen(Rect window) { - return ClampRectToScreen (window, 30); + return ClampRectToScreen(window, 30); } public static Vector2 ClampV2ToScreen(Vector2 vec, uint xMargin, uint yMargin) { - vec.x = Mathf.Clamp (vec.x, xMargin, Screen.width - xMargin); - vec.y = Mathf.Clamp (vec.y, yMargin, Screen.height - yMargin); + vec.x = Mathf.Clamp(vec.x, xMargin, Screen.width - xMargin); + vec.y = Mathf.Clamp(vec.y, yMargin, Screen.height - yMargin); return vec; } @@ -731,24 +867,21 @@ public static Vector2 ClampV2ToScreen(Vector2 vec) { - return ClampV2ToScreen (vec, 15); - } - + return ClampV2ToScreen(vec, 15); + } // UNDONE: This seems messy. Can we clean it up? public static Rect DockToWindow(Rect icon, Rect window) { // We can't set the x and y of the center point directly, so build a new vector. - Vector2 center = new Vector2 (); + Vector2 center = new Vector2(); // If we are near the top or bottom of the screen... if (window.yMax > Screen.height - icon.height || - window.yMin < icon.height - ) + window.yMin < icon.height) { // If we are in a corner... if (window.xMax > Screen.width - icon.width || - window.xMin < icon.width - ) + window.xMin < icon.width) { // If it is a top corner, put the icon below the window. if (window.yMax < Screen.height / 2) @@ -797,8 +930,7 @@ // If we are along a side... if (window.xMax > Screen.width - icon.width || - window.xMin < icon.width - ) + window.xMin < icon.width) { // UNDONE: I'm not sure I like the feel of this part. // If we are along a side towards the bottom, put the icon below the window --- a/VOIDFlightMaster.cs +++ b/VOIDFlightMaster.cs @@ -32,8 +32,6 @@ /////////////////////////////////////////////////////////////////////////////// using System; -using System.Collections.Generic; -using System.Linq; using UnityEngine; using Engineer.VesselSimulator; --- a/VOID_Core.cs +++ b/VOID_Core.cs @@ -33,15 +33,17 @@ * Static Members * */ protected static bool _initialized = false; + public static bool Initialized { - get - { - return _initialized; + get + { + return _initialized; } } protected static VOID_Core _instance; + public static VOID_Core Instance { get @@ -63,98 +65,79 @@ } public static double Constant_G = 6.674e-11; - /* * Fields * */ protected string VoidName = "VOID"; - protected string VoidVersion = "0.9.15"; - + protected string VoidVersion = "0.9.18"; protected bool _factoryReset = false; - [AVOID_SaveValue("configValue")] protected VOID_SaveValue configVersion = 1; - protected List _modules = new List(); protected bool _modulesLoaded = false; - [AVOID_SaveValue("mainWindowPos")] protected VOID_SaveValue mainWindowPos = new Rect(475, 575, 10f, 10f); - [AVOID_SaveValue("mainGuiMinimized")] protected VOID_SaveValue mainGuiMinimized = false; - [AVOID_SaveValue("configWindowPos")] protected VOID_SaveValue configWindowPos = new Rect(825, 625, 10f, 10f); - [AVOID_SaveValue("configWindowMinimized")] protected VOID_SaveValue configWindowMinimized = true; - [AVOID_SaveValue("VOIDIconPos")] - protected VOID_SaveValue VOIDIconPos = new Rect(Screen.width / 2 - 200, Screen.height - 30, 30f, 30f); - protected Texture2D VOIDIconOff = new Texture2D(30, 30, TextureFormat.ARGB32, false); - protected Texture2D VOIDIconOn = new Texture2D(30, 30, TextureFormat.ARGB32, false); + protected VOID_SaveValue VOIDIconPos = new Rect(Screen.width / 2 - 200, Screen.height - 32, 32f, 32f); + protected Texture2D VOIDIconOff; + protected Texture2D VOIDIconOn; protected Texture2D VOIDIconTexture; protected string VOIDIconOnPath = "VOID/Textures/void_icon_on"; protected string VOIDIconOffPath = "VOID/Textures/void_icon_off"; protected bool VOIDIconLocked = true; - + protected GUIStyle iconStyle; protected int windowBaseID = -96518722; protected int _windowID = 0; - protected bool GUIStylesLoaded = false; - protected Dictionary _LabelStyles = new Dictionary(); - [AVOID_SaveValue("togglePower")] public VOID_SaveValue togglePower = true; - public bool powerAvailable = true; - [AVOID_SaveValue("consumeResource")] protected VOID_SaveValue consumeResource = false; - [AVOID_SaveValue("resourceName")] protected VOID_SaveValue resourceName = "ElectricCharge"; - [AVOID_SaveValue("resourceRate")] protected VOID_SaveValue resourceRate = 0.2f; - [AVOID_SaveValue("updatePeriod")] - protected VOID_SaveValue _updatePeriod = 1001f/15000f; + protected VOID_SaveValue _updatePeriod = 1001f / 15000f; protected float _updateTimer = 0f; protected string stringFrequency; - // Celestial Body Housekeeping protected List _allBodies = new List(); protected bool bodiesLoaded = false; - // Vessel Type Housekeeping protected List _allVesselTypes = new List(); protected bool vesselTypesLoaded = false; - public float saveTimer = 0; - protected string defaultSkin = "KSP window 2"; - [AVOID_SaveValue("defaultSkin")] protected VOID_SaveValue _skinName; protected Dictionary skin_list; protected List skinNames; protected string[] forbiddenSkins = - { - "PlaqueDialogSkin", - "FlagBrowserSkin", - "SSUITextAreaDefault", - "ExperimentsDialogSkin", - "ExpRecoveryDialogSkin", - "KSP window 5", - "KSP window 6" - }; + { + "PlaqueDialogSkin", + "FlagBrowserSkin", + "SSUITextAreaDefault", + "ExperimentsDialogSkin", + "ExpRecoveryDialogSkin", + "KSP window 5", + "KSP window 6", + "PartTooltipSkin" + }; protected bool skinsLoaded = false; - public bool configDirty; - + [AVOID_SaveValue("UseBlizzyToolbar")] + protected VOID_SaveValue _UseToolbarManager; + protected bool ToolbarManagerLoaded; + internal ToolbarButtonWrapper ToolbarButton; /* * Properties * */ @@ -192,7 +175,7 @@ { if (this._windowID == 0) { - this._windowID = this.windowBaseID; + this._windowID = this.windowBaseID; } return this._windowID++; } @@ -238,6 +221,27 @@ } } + protected bool UseToolbarManager + { + get + { + return _UseToolbarManager; + } + set + { + if (value == false && this.ToolbarManagerLoaded && this.ToolbarButton != null) + { + this.ToolbarButton.Destroy(); + this.ToolbarButton = null; + } + if (value == true && this.ToolbarManagerLoaded && this.ToolbarButton == null) + { + this.InitializeToolbarButton(); + } + + _UseToolbarManager.value = value; + } + } /* * Methods * */ @@ -247,43 +251,45 @@ this._Active.value = true; - this.VOIDIconOn = GameDatabase.Instance.GetTexture (this.VOIDIconOnPath, false); - this.VOIDIconOff = GameDatabase.Instance.GetTexture (this.VOIDIconOffPath, false); + this.VOIDIconOn = GameDatabase.Instance.GetTexture(this.VOIDIconOnPath, false); + this.VOIDIconOff = GameDatabase.Instance.GetTexture(this.VOIDIconOffPath, false); this._skinName = this.defaultSkin; - this.LoadConfig (); + this.UseToolbarManager = false; + this.ToolbarManagerLoaded = false; + + this.LoadConfig(); } protected void LoadModulesOfType() { var types = AssemblyLoader.loadedAssemblies - .Select (a => a.assembly.GetExportedTypes ()) - .SelectMany (t => t) - .Where (v => typeof(T).IsAssignableFrom (v) - && !(v.IsInterface || v.IsAbstract) && - !typeof(VOID_Core).IsAssignableFrom (v) - ); - - Tools.PostDebugMessage (string.Format ( + .Select(a => a.assembly.GetExportedTypes()) + .SelectMany(t => t) + .Where(v => typeof(T).IsAssignableFrom(v) + && !(v.IsInterface || v.IsAbstract) && + !typeof(VOID_Core).IsAssignableFrom(v) + ); + + Tools.PostDebugMessage(string.Format( "{0}: Found {1} modules to check.", - this.GetType ().Name, - types.Count () + this.GetType().Name, + types.Count() + )); + foreach (var voidType in types) + { + if (!HighLogic.LoadedSceneIsEditor && + typeof(IVOID_EditorModule).IsAssignableFrom(voidType)) + { + continue; + } + + Tools.PostDebugMessage(string.Format( + "{0}: found Type {1}", + this.GetType().Name, + voidType.Name )); - foreach (var voidType in types) - { - if (!HighLogic.LoadedSceneIsEditor && - typeof(IVOID_EditorModule).IsAssignableFrom(voidType) - ) - { - continue; - } - - Tools.PostDebugMessage (string.Format ( - "{0}: found Type {1}", - this.GetType ().Name, - voidType.Name - )); this.LoadModule(voidType); } @@ -299,7 +305,7 @@ protected void LoadModule(Type T) { - var existingModules = this._modules.Where (mod => mod.GetType ().Name == T.Name); + var existingModules = this._modules.Where(mod => mod.GetType().Name == T.Name); if (existingModules.Any()) { Tools.PostDebugMessage(string.Format( @@ -309,9 +315,9 @@ )); return; } - IVOID_Module module = Activator.CreateInstance (T) as IVOID_Module; + IVOID_Module module = Activator.CreateInstance(T) as IVOID_Module; module.LoadConfig(); - this._modules.Add (module); + this._modules.Add(module); Tools.PostDebugMessage(string.Format( "{0}: loaded module {1}.", @@ -320,102 +326,17 @@ )); } - protected void Preload_BeforeUpdate() - { - if (!this.bodiesLoaded) - { - this.LoadAllBodies(); - } - - if (!this.vesselTypesLoaded) - { - this.LoadVesselTypes(); - } - } - - public void Update() - { - this.Preload_BeforeUpdate (); - - if (this.vessel != null) - { - SimManager.Instance.Gravity = VOID_Core.Instance.vessel.mainBody.gravParameter / - Math.Pow(VOID_Core.Instance.vessel.mainBody.Radius, 2); - SimManager.Instance.TryStartSimulation(); - } - - if (!this.guiRunning) - { - this.StartGUI (); - } - - if (!HighLogic.LoadedSceneIsFlight && this.guiRunning) - { - this.StopGUI (); - } - - foreach (IVOID_Module module in this.Modules) - { - if (!module.guiRunning && module.toggleActive) - { - module.StartGUI (); - } - if (module.guiRunning && !module.toggleActive || - !this.togglePower || - !HighLogic.LoadedSceneIsFlight || - this.factoryReset - ) - { - module.StopGUI(); - } - - if (module is IVOID_BehaviorModule) - { - ((IVOID_BehaviorModule)module).Update(); - } - } - - this.CheckAndSave (); - this._updateTimer += Time.deltaTime; - } - - public void FixedUpdate() - { - if (this.consumeResource && - this.vessel.vesselType != VesselType.EVA && - TimeWarp.deltaTime != 0 - ) - { - float powerReceived = this.vessel.rootPart.RequestResource(this.resourceName, - this.resourceRate * TimeWarp.fixedDeltaTime); - if (powerReceived > 0) - { - this.powerAvailable = true; - } - else - { - this.powerAvailable = false; - } - } - - foreach (IVOID_BehaviorModule module in - this._modules.OfType().Where(m => !m.GetType().IsAbstract)) - { - module.FixedUpdate(); - } - } - protected void LoadSkins() { - Tools.PostDebugMessage ("AssetBase has skins: \n" + - string.Join("\n\t", AssetBase.FindObjectsOfTypeIncludingAssets ( - typeof(GUISkin)) - .Select(s => s.ToString()) - .ToArray() - ) + Tools.PostDebugMessage("AssetBase has skins: \n" + + string.Join("\n\t", + Resources.FindObjectsOfTypeAll(typeof(GUISkin)) + .Select(s => s.ToString()) + .ToArray() + ) ); - this.skin_list = AssetBase.FindObjectsOfTypeIncludingAssets(typeof(GUISkin)) + this.skin_list = Resources.FindObjectsOfTypeAll(typeof(GUISkin)) .Where(s => !this.forbiddenSkins.Contains(s.name)) .Select(s => s as GUISkin) .GroupBy(s => s.name) @@ -437,14 +358,14 @@ Tools.PostDebugMessage(string.Format( "{0}: resetting _skinIdx to default.", this.GetType().Name - )); + )); } Tools.PostDebugMessage(string.Format( "{0}: _skinIdx = {1}.", this.GetType().Name, this._skinName.ToString() - )); + )); this.skinsLoaded = true; } @@ -467,14 +388,20 @@ this.LabelStyles["right"].normal.textColor = Color.white; this.LabelStyles["right"].alignment = TextAnchor.UpperRight; - this.LabelStyles ["red"] = new GUIStyle(GUI.skin.label); - this.LabelStyles ["red"].normal.textColor = Color.red; - this.LabelStyles ["red"].alignment = TextAnchor.MiddleCenter; + this.LabelStyles["red"] = new GUIStyle(GUI.skin.label); + this.LabelStyles["red"].normal.textColor = Color.red; + this.LabelStyles["red"].alignment = TextAnchor.MiddleCenter; + + this.iconStyle = new GUIStyle(GUI.skin.button); + this.iconStyle.padding = new RectOffset(0, 0, 0, 0); + // this.iconStyle.margin = new RectOffset(0, 0, 0, 0); + // this.iconStyle.contentOffset = new Vector2(0, 0); + this.iconStyle.overflow = new RectOffset(0, 0, 0, 0); + // this.iconStyle.border = new RectOffset(0, 0, 0, 0); this.GUIStylesLoaded = true; } - protected void LoadAllBodies() { this._allBodies = FlightGlobals.Bodies; @@ -487,26 +414,45 @@ this.vesselTypesLoaded = true; } - protected void CheckAndSave() - { - this.saveTimer += Time.deltaTime; - - if (this.saveTimer > 2f) - { - Tools.PostDebugMessage (string.Format ( - "{0}: Time to save, checking if configDirty: {1}", - this.GetType ().Name, - this.configDirty - )); - - if (!this.configDirty) - { - return; - } - - this.SaveConfig (); - this.saveTimer = 0; - } + protected void LoadBeforeUpdate() + { + if (!this.bodiesLoaded) + { + this.LoadAllBodies(); + } + + if (!this.vesselTypesLoaded) + { + this.LoadVesselTypes(); + } + } + + protected void LoadToolbarManager() + { + this.ToolbarManagerLoaded = ToolbarButtonWrapper.ToolbarManagerPresent; + + if (this.ToolbarManagerLoaded) + { + this.InitializeToolbarButton(); + } + } + + protected void InitializeToolbarButton() + { + this.ToolbarButton = ToolbarButtonWrapper.TryWrapToolbarButton(this.GetType().Name, "coreToggle"); + this.ToolbarButton.Text = this.VoidName; + this.ToolbarButton.TexturePath = this.VOIDIconOffPath; + if (this is VOID_EditorCore) + { + this.ToolbarButton.SetButtonVisibility(new GameScenes[] { GameScenes.EDITOR }); + } + else + { + this.ToolbarButton.SetButtonVisibility(new GameScenes[] { GameScenes.FLIGHT }); + } + this.ToolbarButton.AddButtonClickHandler( + (e) => this.mainGuiMinimized = !this.mainGuiMinimized + ); } public void VOIDMainWindow(int _) @@ -518,24 +464,26 @@ if (!HighLogic.LoadedSceneIsEditor) { string str = "ON"; - if (togglePower) str = "OFF"; - if (GUILayout.Button("Power " + str)) togglePower.value = !togglePower; + if (togglePower) + str = "OFF"; + if (GUILayout.Button("Power " + str)) + togglePower.value = !togglePower; } if (togglePower || HighLogic.LoadedSceneIsEditor) - { + { foreach (IVOID_Module module in this.Modules) { - module.toggleActive = GUILayout.Toggle (module.toggleActive, module.Name); + module.toggleActive = GUILayout.Toggle(module.toggleActive, module.Name); } - } + } } else { - GUILayout.Label("-- POWER LOST --", this.LabelStyles["red"]); - } - - this.configWindowMinimized.value = !GUILayout.Toggle (!this.configWindowMinimized, "Configuration"); + GUILayout.Label("-- POWER LOST --", this.LabelStyles["red"]); + } + + this.configWindowMinimized.value = !GUILayout.Toggle(!this.configWindowMinimized, "Configuration"); GUILayout.EndVertical(); GUI.DragWindow(); @@ -543,12 +491,12 @@ public void VOIDConfigWindow(int _) { - GUILayout.BeginVertical (); - - this.DrawConfigurables (); - - GUILayout.EndVertical (); - GUI.DragWindow (); + GUILayout.BeginVertical(); + + this.DrawConfigurables(); + + GUILayout.EndVertical(); + GUI.DragWindow(); } public override void DrawConfigurables() @@ -559,10 +507,12 @@ if (HighLogic.LoadedSceneIsFlight) { - this.consumeResource.value = GUILayout.Toggle (this.consumeResource, "Consume Resources"); - - this.VOIDIconLocked = GUILayout.Toggle (this.VOIDIconLocked, "Lock Icon Position"); - } + this.consumeResource.value = GUILayout.Toggle(this.consumeResource, "Consume Resources"); + + this.VOIDIconLocked = GUILayout.Toggle(this.VOIDIconLocked, "Lock Icon Position"); + } + + this.UseToolbarManager = GUILayout.Toggle(this.UseToolbarManager, "Use Blizzy's Toolbar If Available"); GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); @@ -587,9 +537,11 @@ _content.tooltip = "Select previous skin"; if (GUILayout.Button(_content, GUILayout.ExpandWidth(true))) { + this.GUIStylesLoaded = false; skinIdx--; - if (skinIdx < 0) skinIdx = skinNames.Count - 1; - Tools.PostDebugMessage (string.Format ( + if (skinIdx < 0) + skinIdx = skinNames.Count - 1; + Tools.PostDebugMessage(string.Format( "{0}: new this._skinIdx = {1} :: skin_list.Count = {2}", this.GetType().Name, this._skinName, @@ -605,14 +557,16 @@ _content.tooltip = "Select next skin"; if (GUILayout.Button(_content, GUILayout.ExpandWidth(true))) { + this.GUIStylesLoaded = false; skinIdx++; - if (skinIdx >= skinNames.Count) skinIdx = 0; - Tools.PostDebugMessage (string.Format ( + if (skinIdx >= skinNames.Count) + skinIdx = 0; + Tools.PostDebugMessage(string.Format( "{0}: new this._skinIdx = {1} :: skin_list.Count = {2}", this.GetType().Name, this._skinName, this.skin_list.Count - )); + )); } if (this._skinName != skinNames[skinIdx]) @@ -640,10 +594,99 @@ foreach (IVOID_Module mod in this.Modules) { - mod.DrawConfigurables (); - } - - this._factoryReset = GUILayout.Toggle (this._factoryReset, "Factory Reset"); + mod.DrawConfigurables(); + } + + this._factoryReset = GUILayout.Toggle(this._factoryReset, "Factory Reset"); + } + + public override void DrawGUI() + { + this._windowID = this.windowBaseID; + + if (!this._modulesLoaded) + { + this.LoadModulesOfType(); + } + + if (this.UseToolbarManager && !this.ToolbarManagerLoaded) + { + this.LoadToolbarManager(); + } + + if (!this.skinsLoaded) + { + this.LoadSkins(); + } + + GUI.skin = this.Skin; + + if (!this.GUIStylesLoaded) + { + this.LoadGUIStyles(); + } + + if (this.UseToolbarManager && this.ToolbarManagerLoaded) + { + this.ToolbarButton.TexturePath = VOIDIconOffPath; + if (this.togglePower) + { + this.ToolbarButton.TexturePath = VOIDIconOnPath; + } + } + else + { + this.VOIDIconTexture = this.VOIDIconOff; //icon off default + if (this.togglePower) + this.VOIDIconTexture = this.VOIDIconOn; //or on if power_toggle==true + + if (GUI.Button(VOIDIconPos, VOIDIconTexture, this.iconStyle) && this.VOIDIconLocked) + { + this.mainGuiMinimized.value = !this.mainGuiMinimized; + } + } + + if (!this.mainGuiMinimized) + { + Rect _mainWindowPos = this.mainWindowPos; + + _mainWindowPos = GUILayout.Window( + this.windowID, + _mainWindowPos, + this.VOIDMainWindow, + string.Join(" ", new string[] { this.VoidName, this.VoidVersion }), + GUILayout.Width(250), + GUILayout.Height(50) + ); + + _mainWindowPos = Tools.ClampRectToScreen(_mainWindowPos); + + if (_mainWindowPos != this.mainWindowPos) + { + this.mainWindowPos = _mainWindowPos; + } + } + + if (!this.configWindowMinimized && !this.mainGuiMinimized) + { + Rect _configWindowPos = this.configWindowPos; + + _configWindowPos = GUILayout.Window( + this.windowID, + _configWindowPos, + this.VOIDConfigWindow, + string.Join(" ", new string[] { this.VoidName, "Configuration" }), + GUILayout.Width(250), + GUILayout.Height(50) + ); + + _configWindowPos = Tools.ClampRectToScreen(_configWindowPos); + + if (_configWindowPos != this.configWindowPos) + { + this.configWindowPos = _configWindowPos; + } + } } public void OnGUI() @@ -671,8 +714,7 @@ if (!this.VOIDIconLocked && VOIDIconPos.value.Contains(Event.current.mousePosition) - && Event.current.type == EventType.mouseDrag - ) + && Event.current.type == EventType.mouseDrag) { Tools.PostDebugMessage(string.Format( "Event.current.type: {0}" + @@ -701,110 +743,131 @@ } } - public override void DrawGUI() - { - if (!this._modulesLoaded) - { - this.LoadModulesOfType (); - } - - this._windowID = this.windowBaseID; - - if (!this.skinsLoaded) - { - this.LoadSkins(); - } - - GUI.skin = this.Skin; - - if (!this.GUIStylesLoaded) - { - this.LoadGUIStyles (); - } - - this.VOIDIconTexture = this.VOIDIconOff; //icon off default - if (this.togglePower) this.VOIDIconTexture = this.VOIDIconOn; //or on if power_toggle==true - if (GUI.Button(VOIDIconPos, VOIDIconTexture, new GUIStyle()) && this.VOIDIconLocked) - { - this.mainGuiMinimized.value = !this.mainGuiMinimized; - } - - if (!this.mainGuiMinimized) - { - Rect _mainWindowPos = this.mainWindowPos; - - _mainWindowPos = GUILayout.Window ( - this.windowID, - _mainWindowPos, - this.VOIDMainWindow, - string.Join (" ", new string[] {this.VoidName, this.VoidVersion}), - GUILayout.Width (250), - GUILayout.Height (50) - ); - - _mainWindowPos = Tools.ClampRectToScreen (_mainWindowPos); - - if (_mainWindowPos != this.mainWindowPos) - { - this.mainWindowPos = _mainWindowPos; - } - } - - if (!this.configWindowMinimized && !this.mainGuiMinimized) - { - Rect _configWindowPos = this.configWindowPos; - - _configWindowPos = GUILayout.Window ( - this.windowID, - _configWindowPos, - this.VOIDConfigWindow, - string.Join (" ", new string[] {this.VoidName, "Configuration"}), - GUILayout.Width (250), - GUILayout.Height (50) - ); - - _configWindowPos = Tools.ClampRectToScreen (_configWindowPos); - - if (_configWindowPos != this.configWindowPos) - { - this.configWindowPos = _configWindowPos; - } + public void Update() + { + this.LoadBeforeUpdate(); + + if (this.vessel != null) + { + SimManager.Instance.Gravity = VOID_Core.Instance.vessel.mainBody.gravParameter / + Math.Pow(VOID_Core.Instance.vessel.mainBody.Radius, 2); + SimManager.Instance.TryStartSimulation(); + } + + if (!this.guiRunning) + { + this.StartGUI(); + } + + if (!HighLogic.LoadedSceneIsFlight && this.guiRunning) + { + this.StopGUI(); + } + + foreach (IVOID_Module module in this.Modules) + { + if (!module.guiRunning && module.toggleActive) + { + module.StartGUI(); + } + if (module.guiRunning && !module.toggleActive || + !this.togglePower || + !HighLogic.LoadedSceneIsFlight || + this.factoryReset) + { + module.StopGUI(); + } + + if (module is IVOID_BehaviorModule) + { + ((IVOID_BehaviorModule)module).Update(); + } + } + + this.CheckAndSave(); + this._updateTimer += Time.deltaTime; + } + + public void FixedUpdate() + { + if (this.consumeResource && + this.vessel.vesselType != VesselType.EVA && + TimeWarp.deltaTime != 0) + { + float powerReceived = this.vessel.rootPart.RequestResource(this.resourceName, + this.resourceRate * TimeWarp.fixedDeltaTime); + if (powerReceived > 0) + { + this.powerAvailable = true; + } + else + { + this.powerAvailable = false; + } + } + + foreach (IVOID_BehaviorModule module in + this._modules.OfType().Where(m => !m.GetType().IsAbstract)) + { + module.FixedUpdate(); } } public void ResetGUI() { - this.StopGUI (); + this.StopGUI(); foreach (IVOID_Module module in this.Modules) { - module.StopGUI (); - module.StartGUI (); - } - - this.StartGUI (); + module.StopGUI(); + module.StartGUI(); + } + + this.StartGUI(); + } + + protected void CheckAndSave() + { + this.saveTimer += Time.deltaTime; + + if (this.saveTimer > 2f) + { + if (!this.configDirty) + { + return; + } + + Tools.PostDebugMessage(string.Format( + "{0}: Time to save, checking if configDirty: {1}", + this.GetType().Name, + this.configDirty + )); + + this.SaveConfig(); + this.saveTimer = 0; + } } public override void LoadConfig() { - base.LoadConfig (); + base.LoadConfig(); foreach (IVOID_Module module in this.Modules) { - module.LoadConfig (); + module.LoadConfig(); } } public void SaveConfig() { - var config = KSP.IO.PluginConfiguration.CreateForType (); - config.load (); + var config = KSP.IO.PluginConfiguration.CreateForType(); + config.load(); this._SaveToConfig(config); foreach (IVOID_Module module in this.Modules) { - module._SaveToConfig (config); + module._SaveToConfig(config); } config.save(); --- a/VOID_Module.cs +++ b/VOID_Module.cs @@ -200,23 +200,13 @@ public virtual void ModuleWindow(int _) { if (VOID_Core.Instance.updateTimer - this.lastUpdate > VOID_Core.Instance.updatePeriod) { - Tools.PostDebugMessage(string.Format( - "{0}: refreshing VOID_DataValues.", - this.GetType().Name - )); - foreach (var fieldinfo in this.GetType().GetFields( BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy - )) { - Tools.PostDebugMessage(string.Format( - "{0}: checking field {1}.", - this.GetType().Name, - fieldinfo.Name - )); - + )) + { object field = null; try @@ -236,19 +226,7 @@ } if (typeof(IVOID_DataValue).IsAssignableFrom (field.GetType ())) { - Tools.PostDebugMessage(string.Format( - "{0}: found field {1}.", - this.GetType().Name, - fieldinfo.Name - )); - (field as IVOID_DataValue).Refresh (); - - Tools.PostDebugMessage(string.Format( - "{0}: refreshed field {1}.", - this.GetType().Name, - fieldinfo.Name - )); } } --- a/VOID_Orbital.cs +++ b/VOID_Orbital.cs @@ -68,7 +68,7 @@ ); protected VOID_StrValue timeToPeri = new VOID_StrValue( - "Time to Apoapsis", + "Time to Periapsis", new Func(() => Tools.ConvertInterval(VOID_Core.Instance.vessel.orbit.timeToPe)) );