diff --git a/EditorExtensionsRedux.sln b/EditorExtensionsRedux.sln index 24971d1..b52c7fb 100644 --- a/EditorExtensionsRedux.sln +++ b/EditorExtensionsRedux.sln @@ -13,8 +13,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "BetaPackage", "Packagers\BetaPackage.mdproj", "{B4D5E5A2-8B35-4CF3-BDFF-0DF9A687AE20}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoOffsetLimits", "NoOffsetLimits\NoOffsetLimits.csproj", "{3368802B-CBC6-4DEA-A68C-3B238C43AF4A}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,10 +25,6 @@ Global {BCEB9124-390F-49D5-9022-49EBAB6446F7}.Release|Any CPU.Build.0 = Release|Any CPU {B4D5E5A2-8B35-4CF3-BDFF-0DF9A687AE20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B4D5E5A2-8B35-4CF3-BDFF-0DF9A687AE20}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3368802B-CBC6-4DEA-A68C-3B238C43AF4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3368802B-CBC6-4DEA-A68C-3B238C43AF4A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3368802B-CBC6-4DEA-A68C-3B238C43AF4A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3368802B-CBC6-4DEA-A68C-3B238C43AF4A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/EditorExtensionsRedux/AssemblyFileVersion.cs b/EditorExtensionsRedux/AssemblyFileVersion.cs index ac59de8..596ed4c 100644 --- a/EditorExtensionsRedux/AssemblyFileVersion.cs +++ b/EditorExtensionsRedux/AssemblyFileVersion.cs @@ -5,4 +5,4 @@ using System.Reflection; - [assembly: AssemblyVersion("3.3.8.0")] \ No newline at end of file + [assembly: AssemblyVersion("3.3.9.0")] \ No newline at end of file diff --git a/EditorExtensionsRedux/EditorExtensionsRedux.cs b/EditorExtensionsRedux/EditorExtensionsRedux.cs index 7ca64dc..e3529ce 100644 --- a/EditorExtensionsRedux/EditorExtensionsRedux.cs +++ b/EditorExtensionsRedux/EditorExtensionsRedux.cs @@ -249,6 +249,8 @@ public class EditorExtensions : MonoBehaviour public bool Visible { get; set; } + public NoOffsetBehaviour.FreeOffsetBehaviour fob; + #region member vars @@ -424,12 +426,6 @@ public void Start() #endif editor = EditorLogic.fetch; Instance = this; - - // FreeOffsetBehaviour needs to be initialized before InitConfig - EditorExtensionsRedux.NoOffsetBehaviour.FreeOffsetBehaviour fob = new NoOffsetBehaviour.FreeOffsetBehaviour(); - // Following needed to get it in memory - fob.Start(); - fob.OnDestroy(); InitConfig(); if (!validVersion) @@ -439,7 +435,8 @@ public void Start() GameEvents.onEditorPartEvent.Add(EditorPartEvent); GameEvents.onEditorSymmetryModeChange.Add(EditorSymmetryModeChange); - + if (cfg.NoOffsetLimitEnabled) + fob = gameObject.AddComponent(); // editor.srfAttachAngleSnap = 0; @@ -466,6 +463,7 @@ void OnDestroy() GameEvents.onEditorPartEvent.Remove(EditorPartEvent); GameEvents.onEditorSymmetryModeChange.Remove(EditorSymmetryModeChange); + Destroy(fob); NoOffsetBehaviour.FreeOffsetBehaviour.Instance = null; } @@ -592,12 +590,7 @@ void InitConfig() ReRootActive = cfg.ReRootEnabled; NoOffsetLimit = cfg.NoOffsetLimitEnabled; - if (cfg.NoOffsetLimitEnabled) - { - Log.Info("InitConfig NoOffsetLimitEnabled is true"); - EditorExtensionsRedux.NoOffsetBehaviour.FreeOffsetBehaviour.Instance.Start(); - } - + Log.Debug("Initializing version " + pluginVersion.ToString()); } catch (Exception ex) @@ -891,7 +884,8 @@ void Update() if (NoOffsetLimit) { OSDMessage(string.Format("No Offset Limit is active")); - EditorExtensionsRedux.NoOffsetBehaviour.FreeOffsetBehaviour.Instance.Start(); + NoOffsetBehaviour.FreeOffsetBehaviour fob = gameObject.AddComponent(); + } else { @@ -900,7 +894,9 @@ void Update() if (p != null) OSDMessage(string.Format("Change will take effect after deselecting current part")); // GameEvents.onEditorPartPlaced.Fire(p); - EditorExtensionsRedux.NoOffsetBehaviour.FreeOffsetBehaviour.Instance.OnDestroy(); + Destroy(fob); + NoOffsetBehaviour.FreeOffsetBehaviour.Instance = null; + // if (p != null) // GameEvents.onEditorPartPicked.Fire(p); } @@ -2087,9 +2083,20 @@ void MenuContent(int WindowID) if (_showMenu || _menuRect.Contains(Event.current.mousePosition)) lastTimeShown = Time.fixedTime; GUILayout.BeginVertical(); - if (GUILayout.Button("Show Angle Snaps")) + if (_showAngleSnaps.isVisible()) { - _showAngleSnaps.Show(cfg); + if (GUILayout.Button("Show Angle Snaps")) + { + _showAngleSnaps.Hide(); + } + + } + else + { + if (GUILayout.Button("Show Angle Snaps")) + { + _showAngleSnaps.Show(cfg); + } } GUILayout.EndVertical(); diff --git a/EditorExtensionsRedux/EditorExtensionsRedux.cs.bak b/EditorExtensionsRedux/EditorExtensionsRedux.cs.bak new file mode 100644 index 0000000..d5999bf --- /dev/null +++ b/EditorExtensionsRedux/EditorExtensionsRedux.cs.bak @@ -0,0 +1,2501 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Text; + +using System.Reflection; +using KSP.IO; +using UnityEngine; +using UnityEngine.UI; +using UnityEngine.EventSystems; + +/* + * + * +If you REALLY want to, here is what you will need to do to fix the Reflection issues, and I suggest you do this BEFORE any more debugging: + +Compile in debug mode + +1. Install and start the game +2. Exit, and open up the output_log.txt file +3. Look in the file EditorExtensionsRedux.cs, near the top, in the Init function, you will see wher a number of constants have their values set depending on the version. +4. Create a new section for 1.2, copy them in from one of the other sections. +5. Look in the log file, for lines beginning with: + EditorLogic Field name + KFSMEvent KFSMEvent Field name + MethodInfo EditorLogic methods name + MethodInfo Part name + MethodInfo KFSMEvent methods name + MethodInfo KFSMState methods name +6. Look in the log for the corresponding value for each line in the Init function, you should find the corresponding number. +7. Update the Init section +8. Now, recompile in Debug mode, restart the game and go into the Editor +9. Place a part, then activate one of the gizmos on it (rotation, etc). +10. Exit the game, and again, open the output_log.txt file +11. This time, look for lines which match: + EditorLogic Gizmo Rotate Field name +12. You need to look for the two items in the Init function which relate to the Grid, update the values as required +Compile and test. + * + * + * + * + * + * + */ +namespace EditorExtensionsRedux +{ + public class Constants + { + // Following for SelectRoot + public int SELECTEDPART = 13; + public int ST_ROOT_SELECT = 77; + public int ST_ROOT_UNSELECTED = 76; + public int MODEMSG = 60; + public int ST_IDLE = 70; + public int ST_PLACE = 71; + public int ONMOUSEISOVER = 250; + public int GET_STATEEVENTS = 0; + + // Following for NoOffsetLimits + public int ST_OFFSET_TWEAK = 73; + public int SYMUPDATEATTACHNODE = 108; + public int GIZMOOFFSET = 66; + public int GIZMOROTATE = 67; + + public int UPDATESYMMETRY = 64; + public int ONOFFSETGIZMOUPDATED = 35; + + public int GRIDSNAPINTERVAL = 1; + public int GRIDSNAPINTERVALFINE = 2; + + // gizmo offsets + public int GIZMOROTATE_ONHANDLEROTATESTART = 8; + public int GIZMOROTATE_ONHANDLEROTATE = 9; + public int GIZMOROTATE_ONHANDLEROTATEEND = 10; + + public int GIZMOOFFSET_ONHANDLEMOVESTART = 8; + public int GIZMOOFFSET_ONHANDLEMOVE = 9; + public int GIZMOOFFSET_ONHANDLEMOVEEND = 10; + + + public bool Init() + { + if (Versioning.version_major == 1 && Versioning.version_minor == 1 && Versioning.Revision == 0 /*&& Versioning.BuildID == 1024 */) + { + // SelectRoot + SELECTEDPART = 13; + ST_ROOT_SELECT = 77; + ST_ROOT_UNSELECTED = 76; + MODEMSG = 60; + ST_IDLE = 70; + ST_PLACE = 71; + ONMOUSEISOVER = 250; + GET_STATEEVENTS = 0; + + // NoOffsetLimits + ST_OFFSET_TWEAK = 73; + SYMUPDATEATTACHNODE = 108; + GIZMOOFFSET = 66; + + UPDATESYMMETRY = 64; + ONOFFSETGIZMOUPDATED = 35; + + return true; + } + if (Versioning.version_major == 1 && Versioning.version_minor == 1 && (Versioning.Revision == 1 || Versioning.Revision == 2) /*&& Versioning.BuildID == 1024 */) + { + // SelectRoot + SELECTEDPART = 13; + ST_ROOT_SELECT = 80; + ST_ROOT_UNSELECTED = 79; + MODEMSG = 63; + ST_IDLE = 73; + ST_PLACE = 74; + ONMOUSEISOVER = 250; // ? + GET_STATEEVENTS = 0; // ?? + + // NoOffsetLimits + ST_OFFSET_TWEAK = 76; + SYMUPDATEATTACHNODE = 111; + GIZMOOFFSET = 69; + + UPDATESYMMETRY = 62; + ONOFFSETGIZMOUPDATED = 35; + + /* Gizmo offsets + * + 1 gridSnapInterval + 2 gridSnapIntervalFine + 3 useAngleSnap + 4 refCamera + 5 pivot + 6 rot0 + 7 hostRot0 + 8 host + 9 onGizmoRotate + 10 onGizmoRotated + 11 isDragging + 12 ssScaling + + * + */ + GRIDSNAPINTERVAL = 1; + GRIDSNAPINTERVALFINE = 2; + + return true; + } + if (Versioning.version_major == 1 && Versioning.version_minor == 1 && Versioning.Revision == 3 /*&& Versioning.BuildID == 1024 */) + { + // SelectRoot + SELECTEDPART = 13; + ST_ROOT_SELECT = 80; + ST_ROOT_UNSELECTED = 79; + MODEMSG = 63; + ST_IDLE = 73; + ST_PLACE = 74; + ONMOUSEISOVER = 252; + GET_STATEEVENTS = 0; + + // NoOffsetLimits + ST_OFFSET_TWEAK = 76; + SYMUPDATEATTACHNODE = 111; + GIZMOOFFSET = 69; + + UPDATESYMMETRY = 62; + ONOFFSETGIZMOUPDATED = 35; + + /* Gizmo offsets + * + 1 gridSnapInterval + 2 gridSnapIntervalFine + 3 useAngleSnap + 4 refCamera + 5 pivot + 6 rot0 + 7 hostRot0 + 8 host + 9 onGizmoRotate + 10 onGizmoRotated + 11 isDragging + 12 ssScaling + + * + */ + GRIDSNAPINTERVAL = 1; + GRIDSNAPINTERVALFINE = 2; + + return true; + } + if (Versioning.version_major == 1 && Versioning.version_minor == 2 && (Versioning.Revision == 0 || Versioning.Revision == 1)) + { + // SelectRoot + SELECTEDPART = 13; + ST_ROOT_SELECT = 79; + ST_ROOT_UNSELECTED = 78; + MODEMSG = 62; + ST_IDLE = 72; + ST_PLACE = 73; + ONMOUSEISOVER = 265; + GET_STATEEVENTS = 0; + + // NoOffsetLimits + ST_OFFSET_TWEAK = 75; + SYMUPDATEATTACHNODE = 110; + GIZMOROTATE = 67; + GIZMOOFFSET = 68; + + UPDATESYMMETRY = 61; + ONOFFSETGIZMOUPDATED = 35; + + /* Gizmo offsets + * + 1 gridSnapInterval + 2 gridSnapIntervalFine + 3 useAngleSnap + 4 refCamera + 5 pivot + 6 rot0 + 7 hostRot0 + 8 host + 9 onGizmoRotate + 10 onGizmoRotated + 11 isDragging + 12 ssScaling + + * + */ + GRIDSNAPINTERVAL = 1; + GRIDSNAPINTERVALFINE = 2; + + return true; + } + return false; + } + } + + [KSPAddon(KSPAddon.Startup.EditorAny, false)] + public class EditorExtensions : MonoBehaviour + { + public static EditorExtensions Instance { get; private set; } + + public static bool validVersion = false; + static bool warningShown; + const string warning = "This version of Editor Extensions Redux is not compatible with this version of KSP"; + + public static Constants c = new Constants(); + + public bool Visible { get; set; } + + #region member vars + + + + const string ConfigFileName = "config.xml"; + const string DegreesSymbol = "\u00B0"; + + EditorLogic editor; + Version pluginVersion; + public ConfigData cfg; + string _pluginDirectory; + string _configFilePath; + //int _symmetryMode = 0; + + SettingsWindow _settingsWindow = null; + ShowAngleSnaps _showAngleSnaps = null; + PartInfoWindow _partInfoWindow = null; + FineAdjustWindow _fineAdjustWindow = null; + //StrutWindow _strutWindow = null; + + bool enableHotkeys = true; + //bool _gizmoActive = false; + + Vector3 cameraLookAt = new Vector3(0, 15, 0); + bool zoomSelected = false; + + Part oldSelectedPart = null; + // Fwiffo + bool rapidZoomActive = false; + // RK + float orgVabZoomSens = 0; + float orgSphZoomSens = 0; + // End Fwiffo + + public bool ReRootActive = true; + public bool NoOffsetLimit = true; + + static float lastSrfAttachAngleSnap = 15.0f; + static float preResetSrfAttachAngleSnap = 0; + static int preResetSymmetryMode = 0; + + static bool last_VAB_USE_ANGLE_SNAP = true; + #endregion + + // public EditorExtensions (){} + + //Unity initialization call, called first + public void Awake() + { + Log.Debug("Awake()"); + Log.Debug("launchSiteName: " + EditorLogic.fetch.launchSiteName); + } + +#if DEBUG + // http://stackoverflow.com/a/1615860 + private static string EncodeNonAsciiCharacters(string value) + { + StringBuilder sb = new StringBuilder(); + foreach (char c in value) + { + // This character is too big for ASCII + string encodedValue = "\\u" + ((int)c).ToString("x4"); + sb.Append(encodedValue); + } + return sb.ToString(); + } + + // + // The following runs when in DEBUG mode, to dump all the reflection fields so we + // can update the offsets + // Also need to do the following to get the gizmo snap values: + // 1. Get initial setting for EEX and have it working + // 2. make sure the following function is active: updateGizmoSnaps + // 3. Go into the editor, and activate the gizmo tools by selecting one of the gizmos + // + void localdumpReflection() + { + //Log.Debug("States:"); + //foreach (var f in EditorLogic.fetch.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { + // if (f.FieldType == typeof(KFSMState)) { + // Log.Debug ("State: " + ((KFSMState)f.GetValue (EditorLogic.fetch)).name + " + " + EncodeNonAsciiCharacters (f.Name)); + // } + //} + //Log.Debug("Events:"); + //foreach (var f in EditorLogic.fetch.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { + // if (f.FieldType == typeof(KFSMEvent)) { + // Log.Debug ("State: " + ((KFSMEvent)f.GetValue (EditorLogic.fetch)).name + " + " + EncodeNonAsciiCharacters (f.Name)); + // } + //} + + //Log.Debug("State/Event enumeration done."); + EditorLogic el = EditorLogic.fetch; + int c = 0; + foreach (FieldInfo FI in el.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) + { + Log.Info("EditorLogic Field name[" + c.ToString() + "]: " + FI.Name + " Fieldtype: " + FI.FieldType.ToString()); + c++; + } + + KFSMEvent ke = new KFSMEvent("a"); + c = 0; + foreach (FieldInfo FI in ke.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) + { + Log.Info("KFSMEvent KFSMEvent Field name[" + c.ToString() + "]: " + FI.Name + " Fieldtype: " + FI.FieldType.ToString()); + c++; + } + + MethodInfo[] leMethods = typeof(EditorLogic).GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + c = 0; + foreach (MethodInfo FI in leMethods) + { + Log.Info("MethodInfo EditorLogic methods name[" + c.ToString() + "]: " + FI.Name); + c++; + } + + MethodInfo[] parts = typeof(Part).GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + c = 0; + foreach (MethodInfo FI in parts) + { + Log.Info("MethodInfo Part name[" + c.ToString() + "]: " + FI.Name); + c++; + } + + + MethodInfo[] cparts = typeof(CompoundPart).GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + c = 0; + foreach (MethodInfo FI in cparts) + { + Log.Info("MethodInfo CompoundPart name[" + c.ToString() + "]: " + FI.Name); + c++; + } + + MethodInfo[] kfe = typeof(KFSMEvent).GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + c = 0; + foreach (MethodInfo FI in kfe) + { + Log.Info("MethodInfo KFSMEvent methods name[" + c.ToString() + "]: " + FI.Name); + c++; + } + + + MethodInfo[] ks = typeof(KFSMState).GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + c = 0; + foreach (MethodInfo FI in ks) + { + Log.Info("MethodInfo KFSMState methods name[" + c.ToString() + "]: " + FI.Name + " " + FI.ToString()); + c++; + } + + + } +#endif + + //Boop: Cache the editor hotkeys so we can keep consistency with whatever is in the settings.cfg file. + KeyCode HotkeyEditor_toggleSymModePrimary = GameSettings.Editor_toggleSymMode.primary; + KeyCode HotkeyEditor_toggleSymModeSecondary = GameSettings.Editor_toggleSymMode.secondary; + KeyCode HotkeyEditor_toggleAngleSnapPrimary = GameSettings.Editor_toggleAngleSnap.primary; + KeyCode HotkeyEditor_toggleAngleSnapSecondary = GameSettings.Editor_toggleAngleSnap.secondary; + + //Unity, called after Awake() + public void Start() + { + Log.Debug("Start()"); + Log.Debug("Version: " + Versioning.Revision); + //Boop: Nuke the editor hotkeys so we can hijack them. + GameSettings.Editor_toggleSymMode.primary = KeyCode.None; + GameSettings.Editor_toggleSymMode.secondary = KeyCode.None; + GameSettings.Editor_toggleAngleSnap.primary = KeyCode.None; + GameSettings.Editor_toggleAngleSnap.secondary = KeyCode.None; + +#if DEBUG + localdumpReflection(); +#endif + editor = EditorLogic.fetch; + Instance = this; + + // FreeOffsetBehaviour needs to be initialized before InitConfig + //NoOffsetBehaviour.FreeOffsetBehaviour fob = new NoOffsetBehaviour.FreeOffsetBehaviour(); + // Following needed to get it in memory + + InitConfig(); + + if (!validVersion) + return; + InitializeGUI(); + + + Log.Info("InitConfig NoOffsetLimitEnabled is true"); + if (NoOffsetBehaviour.FreeOffsetBehaviour.Instance != null) + { + NoOffsetBehaviour.FreeOffsetBehaviour.Instance.Start(); + if (!cfg.NoOffsetLimitEnabled) + NoOffsetBehaviour.FreeOffsetBehaviour.Instance.OnDestroy(); + } + + + GameEvents.onEditorPartEvent.Add(EditorPartEvent); + GameEvents.onEditorSymmetryModeChange.Add(EditorSymmetryModeChange); + + + + + // editor.srfAttachAngleSnap = 0; + editor.srfAttachAngleSnap = lastSrfAttachAngleSnap; + GameSettings.VAB_USE_ANGLE_SNAP = last_VAB_USE_ANGLE_SNAP; + Log.Info("editor.srfAttachAngleSnap: " + editor.srfAttachAngleSnap.ToString()); + + } + + //Unity OnDestroy + void OnDestroy() + { + Log.Debug("OnDestroy()"); + //if (_settingsWindow != null) + // _settingsWindow.enabled = false; + //if (_partInfoWindow != null) + // _partInfoWindow.enabled = false; + + //Boop - restore the hotkeys - without this, the hotkeys fail to work on each subsequent visit to the VAB/SPH after the first. + GameSettings.Editor_toggleSymMode.primary = HotkeyEditor_toggleSymModePrimary; + GameSettings.Editor_toggleSymMode.secondary = HotkeyEditor_toggleSymModeSecondary; + GameSettings.Editor_toggleAngleSnap.primary = HotkeyEditor_toggleAngleSnapPrimary; + GameSettings.Editor_toggleAngleSnap.secondary = HotkeyEditor_toggleAngleSnapSecondary; + + GameEvents.onEditorPartEvent.Remove(EditorPartEvent); + GameEvents.onEditorSymmetryModeChange.Remove(EditorSymmetryModeChange); + + NoOffsetBehaviour.FreeOffsetBehaviour.Instance = null; + } + + ConstructionEventType lastEventType = ConstructionEventType.Unknown; + void EditorPartEvent(ConstructionEventType eventType, Part part) + { + Log.Info("EditorPartEvent eventType: " + eventType.ToString()); + lastEventType = eventType; + if (eventType == ConstructionEventType.PartRotating) + { + Log.Info("eulerAngles attRotation: " + part.attRotation.eulerAngles); + Log.Info("eulerAngles attRotation0: " + part.attRotation0.eulerAngles); + updateGizmoSnaps(); + return; + // UpdateRotationGizmos(); // RK + } + + if (eventType == ConstructionEventType.PartOffsetting) + { + return; + } + + if (eventType == ConstructionEventType.PartDragging) + { + return; + } + + Log.Debug(string.Format("EditorPartEvent {0} part {1}", eventType, part)); + + if (eventType == ConstructionEventType.PartAttached) + { + if (part.parent != null) + { + Log.Debug("Part parent: " + part.parent.name); + Log.Debug("Node attached: " + IsPartNodeAttached(part).ToString()); + } + else + { + Log.Debug("Part parent is null"); + } + } + } + + void EditorSymmetryModeChange(int symMode) + { + Log.Debug("EditorSymmetryModeChange: " + symMode.ToString()); + } + + void InitConfig() + { + validVersion = c.Init(); + + if (!validVersion) + { + return; + } + + Log.Info("EditorExtensionsRedux.InitConfig"); + try + { + //get location and version info of the plugin + Assembly execAssembly = Assembly.GetExecutingAssembly(); + pluginVersion = execAssembly.GetName().Version; + _pluginDirectory = Path.GetDirectoryName(execAssembly.Location); + + //dll's path + filename for the config file + _configFilePath = Path.Combine(_pluginDirectory, ConfigFileName); + + //check if the config file is there and create if its missing + if (ConfigManager.FileExists(_configFilePath)) + { + + cfg = ConfigManager.LoadConfig(_configFilePath); + + if (cfg == null) + { + //failed to load config, create new + cfg = ConfigManager.CreateDefaultConfig(_configFilePath, pluginVersion.ToString()); + } + else + { + //check config file version + Version fileVersion = new Version(); + + if (cfg.FileVersion != null) + { + Log.Debug("Config v" + cfg.FileVersion + " Mod v" + pluginVersion.ToString()); + + try + { + fileVersion = new Version(cfg.FileVersion); + } + catch (Exception ex) + { + Log.Error("Error parsing version from config file: " + ex.Message); + } + } + +#if DEBUG + //for debug, replace if version isn't exactly the same + bool versionMismatch = (cfg.FileVersion == null || fileVersion != pluginVersion); +#else + //replace if x.x doesn't match + bool versionMismatch = (cfg.FileVersion == null || fileVersion.Major < pluginVersion.Major || (fileVersion.Major == pluginVersion.Major && fileVersion.Minor < pluginVersion.Minor)); +#endif + + if (versionMismatch) + { + Log.Info("Config file version mismatch, replacing with new defaults"); + cfg = ConfigManager.CreateDefaultConfig(_configFilePath, pluginVersion.ToString()); + } + else + { + Log.Debug("Config file is current"); + } + } + + } + else + { + cfg = ConfigManager.CreateDefaultConfig(_configFilePath, pluginVersion.ToString()); + Log.Info("No existing config found, created new default config"); + } + + ReRootActive = cfg.ReRootEnabled; + NoOffsetLimit = cfg.NoOffsetLimitEnabled; + + Log.Debug("Initializing version " + pluginVersion.ToString()); + } + catch (Exception ex) + { + Log.Debug("FATAL ERROR - Unable to initialize: " + ex.Message); + //_abort = true; + return; + } + } + + // EditorGizmos.GizmoOffsetHandle gizmoOffsetHandle = null; + // EditorGizmos.GizmoRotateHandle gizmoRotateHandle = null; + //Unity update + Part masterSnapPart = null; + double lastHighlightUpdate = 0; + bool highlightOn = false; + const float highlightCycleTime = 0.5f; + + void Update() + { + if (!validVersion) + return; + + //Boop: Override stock Angle Snap manipulation + if ((Input.GetKeyDown(HotkeyEditor_toggleAngleSnapPrimary) || Input.GetKeyDown(HotkeyEditor_toggleAngleSnapSecondary))) + { + int currentAngleIndex = cfg.AngleSnapValues.IndexOf(editor.srfAttachAngleSnap); + float newAngle; + + if (Input.GetKey(GameSettings.Editor_fineTweak.primary) || Input.GetKey(GameSettings.Editor_fineTweak.secondary)) + { + // Decrease snap + newAngle = cfg.AngleSnapValues[currentAngleIndex == 0 ? cfg.AngleSnapValues.Count - 1 : currentAngleIndex - 1]; + } + else if (Input.GetKey(GameSettings.MODIFIER_KEY.primary) || Input.GetKey(GameSettings.MODIFIER_KEY.secondary)) + { + if (editor.srfAttachAngleSnap > 0) + { + // Reset snap + if (cfg.AnglesnapModIsToggle) + preResetSrfAttachAngleSnap = editor.srfAttachAngleSnap; + newAngle = 0; + } + else + { + if (preResetSrfAttachAngleSnap > 0) + newAngle = preResetSrfAttachAngleSnap; + else + newAngle = editor.srfAttachAngleSnap; + } + } + else + { + // Increase snap + newAngle = cfg.AngleSnapValues[currentAngleIndex == cfg.AngleSnapValues.Count - 1 ? 0 : currentAngleIndex + 1]; + preResetSrfAttachAngleSnap = 0; + } + + currentAngleIndex = cfg.AngleSnapValues.IndexOf(editor.srfAttachAngleSnap); + + editor.srfAttachAngleSnap = newAngle; + + if (editor.srfAttachAngleSnap == 0) + { + GameSettings.VAB_USE_ANGLE_SNAP = false; + } + else + { + GameSettings.VAB_USE_ANGLE_SNAP = true; + } + + lastSrfAttachAngleSnap = editor.srfAttachAngleSnap; + last_VAB_USE_ANGLE_SNAP = GameSettings.VAB_USE_ANGLE_SNAP; + + updateGizmoSnaps(); + + var gizmos = HighLogic.FindObjectsOfType(); + + if (gizmos.Length > 0) + { + var gizmo = gizmos[0]; + if (editor.srfAttachAngleSnap == 0 && gizmo.useGrid) + gizmo.useGrid = false; + else if (editor.srfAttachAngleSnap != 0 && !gizmo.useGrid) + gizmo.useGrid = true; + } + + return; + } + + //Boop: Override stock Symmetry manipulation. + if ((Input.GetKeyDown(HotkeyEditor_toggleSymModePrimary) || Input.GetKeyDown(HotkeyEditor_toggleSymModeSecondary))) + { + if (Input.GetKey(GameSettings.Editor_fineTweak.primary) || Input.GetKey(GameSettings.Editor_fineTweak.secondary)) + { + if (editor.symmetryMethod == SymmetryMethod.Radial) + { + if (editor.symmetryMode > 0) + { + editor.symmetryMode--; + } + } + else if (editor.symmetryMode == 1) + { + editor.symmetryMode = 0; + } + else + { + editor.symmetryMode = 1; + } + return; + } + else if (Input.GetKey(GameSettings.MODIFIER_KEY.primary) || Input.GetKey(GameSettings.MODIFIER_KEY.secondary)) + { + if (preResetSymmetryMode > 0) + { + editor.symmetryMode = preResetSymmetryMode; + preResetSymmetryMode = 0; + } + else + { + if (cfg.CycleSymmetryModeModIsToggle) + preResetSymmetryMode = editor.symmetryMode; + editor.symmetryMode = 0; + } + } + else + { + if (editor.symmetryMethod == SymmetryMethod.Radial) + { + if (editor.symmetryMode < cfg.MaxSymmetry - 1) + { + editor.symmetryMode++; + } + } + else if (editor.symmetryMode == 1) + { + editor.symmetryMode = 0; + } + else + { + editor.symmetryMode = 1; + } + return; + } + } + + //if (editor.shipNameField.Focused || editor.shipDescriptionField.Focused) + // return; + GameObject obj = EventSystem.current.currentSelectedGameObject; + bool inputFieldIsFocused = (obj != null && obj.GetComponent() != null && obj.GetComponent().isFocused); + if (inputFieldIsFocused) + return; + //ignore hotkeys while settings window is open + //if (_settingsWindow != null && _settingsWindow.enabled) + // return; + + //hotkeyed editor functions + if (enableHotkeys) + { + + //check for the configured modifier key + bool modKeyDown = GameSettings.MODIFIER_KEY.GetKey(); + //check for configured editor fine key + bool fineKeyDown = GameSettings.Editor_fineTweak.GetKey(); + + Camera cam = editor.editorCamera; + // Fwiffo + //VABCamera vabCam = Camera.main.GetComponent (); // or EditorDriver.fetch.vabCamera; // RK + //SPHCamera sphCam = Camera.main.GetComponent (); // or EditorDriver.fetch.sphCamera; + + // Zoom cycling - tap then quickly hold a zoom key zoom more rapidly (original idea was to double tap to rapidly cycle through presets) + //if (GameSettings.ZOOM_IN.GetDoubleTapDown()) CycleZoom(cam, true); + //else if (GameSettings.ZOOM_OUT.GetDoubleTapDown()) CycleZoom(cam, false); + if (rapidZoomActive && (GameSettings.ZOOM_IN.GetKeyUp() || GameSettings.ZOOM_OUT.GetKeyUp())) + { + //GameSettings.VAB_CAMERA_ZOOM_SENS = orgZoomSens; + vabCam.mouseZoomSensitivity = orgVabZoomSens; + sphCam.mouseZoomSensitivity = orgSphZoomSens; + rapidZoomActive = false; + //Debug.Log("Rapid zoom deactivated; VAB_CAMERA_ZOOM_SENS = " + GameSettings.VAB_CAMERA_ZOOM_SENS); + Debug.Log("Rapid zoom deactivated; sensitivity = " + + ((EditorDriver.editorFacility == EditorFacility.VAB) ? orgVabZoomSens : orgSphZoomSens).ToString()); + } + else if (cfg.RapidZoom + && !rapidZoomActive + && (GameSettings.ZOOM_IN.GetDoubleTapDown() || GameSettings.ZOOM_OUT.GetDoubleTapDown())) + { + //orgZoomSens = GameSettings.VAB_CAMERA_ZOOM_SENS; + //GameSettings.VAB_CAMERA_ZOOM_SENS = 1; + orgVabZoomSens = vabCam.mouseZoomSensitivity; + orgSphZoomSens = sphCam.mouseZoomSensitivity; + vabCam.mouseZoomSensitivity *= 5; + sphCam.mouseZoomSensitivity *= 5; + rapidZoomActive = true; + Debug.Log("Rapid zoom activated; sensitivity = " + ((EditorDriver.editorFacility == EditorFacility.VAB) + ? vabCam.mouseZoomSensitivity : sphCam.mouseZoomSensitivity).ToString()); + } + // Fwiffo end + + //Zoom selected part - rotate camera around part + if (Input.GetKeyDown(cfg.KeyMap.ZoomSelected)) + { + Part p = Utility.GetPartUnderCursor(); + if (p != null) + { + zoomSelected = true; + cameraLookAt = p.transform.position; + cam.transform.position = new Vector3(cam.transform.position.x, p.transform.position.y, cam.transform.position.z); + OSDMessage(string.Format("Zoom Camera on {0}", p.name)); + } + else + { + cameraLookAt = new Vector3(0, 15, 0); + OSDMessage("Default Camera"); + ResetCamera(); + zoomSelected = false; + } + } + + if (zoomSelected) + { + cam.transform.LookAt(cameraLookAt); + } + + // U - strut/fuel line alignment + // U - snap heights on both parts + // mod-U level/perpendicular to parent part + if (Input.GetKeyDown(cfg.KeyMap.CompoundPartAlign)) + { + Part p = Utility.GetPartUnderCursor(); + if (p != null && p.GetType() == typeof(CompoundPart)) + { + AlignCompoundPart((CompoundPart)p, !modKeyDown); + } + } + + // V - Vertically align part under cursor with the part it is attached to + if (Input.GetKeyDown(cfg.KeyMap.VerticalSnap)) + { + VerticalAlign(); + return; + } + + // H - Horizontally align part under cursor with the part it is attached to + if (Input.GetKeyDown(cfg.KeyMap.HorizontalSnap)) + { + HorizontalAlign(fineKeyDown); + return; + } + + //Space - when no part is selected, reset camera + if (Input.GetKeyDown(cfg.KeyMap.ResetCamera) && !EditorLogic.SelectedPart) + { + ResetCamera(); + return; + } + + // T: Surface attachment toggle + if (Input.GetKeyDown(cfg.KeyMap.AttachmentMode)) + { + SurfaceAttachToggle(); + return; + } + + if (cfg.ReRootEnabled) + { + if (Input.GetKeyDown(cfg.KeyMap.ToggleReRoot)) + { + ReRootActive = !ReRootActive; + Log.Info("ToggleReRoot, ReRootActive: " + ReRootActive.ToString()); + if (ReRootActive) + { + OSDMessage(string.Format("Reroot is active")); + EditorExtensionsRedux.SelectRoot2.SelectRoot2Behaviour.Instance.Start(); + } + else + { + OSDMessage(string.Format("Reroot is not active")); + EditorExtensionsRedux.SelectRoot2.SelectRoot2Behaviour.Instance.OnDestroy(); + } + } + } + // NoOffsetBehaviour.FreeOffsetBehaviour + if (cfg.NoOffsetLimitEnabled) + { + if (Input.GetKeyDown(cfg.KeyMap.ToggleNoOffsetLimit)) + { + NoOffsetLimit = !NoOffsetLimit; + Log.Info("ToggleNoOffsetLimit, NoOffsetLimit: " + NoOffsetLimit.ToString()); + if (NoOffsetLimit) + { + OSDMessage(string.Format("No Offset Limit is active")); + EditorExtensionsRedux.NoOffsetBehaviour.FreeOffsetBehaviour.Instance.Start(); + } + else + { + OSDMessage(string.Format("No Offset Limit is not active")); + Part p = EditorLogic.SelectedPart; + if (p != null) + OSDMessage(string.Format("Change will take effect after deselecting current part")); + // GameEvents.onEditorPartPlaced.Fire(p); + EditorExtensionsRedux.NoOffsetBehaviour.FreeOffsetBehaviour.Instance.OnDestroy(); + // if (p != null) + // GameEvents.onEditorPartPicked.Fire(p); + } + } + } + + + + // ALT+Z : Toggle part clipping (From cheat options) + if (modKeyDown && Input.GetKeyDown(cfg.KeyMap.PartClipping)) + { + PartClippingToggle(); + return; + } + +#if false + //KSP v1.0.3: Change angle snap and symmetry mode actions to GetKeyUp() so that it fires after internal editor actions + + //using gamesettings keybinding Input.GetKeyDown (cfg.KeyMap.AngleSnap) + // C, Shift+C : Increment/Decrement Angle snap + if (GameSettings.Editor_toggleAngleSnap.GetKeyUp()) + { + AngleSnapCycle(modKeyDown, fineKeyDown); + return; + } + + //using gamesettings keybinding Input.GetKeyDown (cfg.KeyMap.Symmetry) + // X, Shift+X : Increment/decrement symmetry mode + + if (GameSettings.Editor_toggleSymMode.GetKeyUp()) + { + SymmetryModeCycle(modKeyDown, fineKeyDown); + return; + } +#endif + if (Input.GetKey(KeyCode.Mouse0)) + { + if (Utility.GetPartUnderCursor() != null) // || Input.GetKey(KeyCode.Mouse1)) + { + if (Input.GetKey(cfg.KeyMap.StartMasterSnap)) + { + masterSnapPart = Utility.GetPartUnderCursor(); + //Utility.HighlightSinglePart(XKCDColors.Blue, XKCDColors.Yellow, masterSnapPart); + OSDMessage(string.Format("Part selected as target for snap: " + masterSnapPart.partInfo.title)); + lastHighlightUpdate = Time.fixedTime + highlightCycleTime; + highlightOn = true; + } + else + { + DisableMasterSnap(); + } + } + else + { + DisableMasterSnap(); + } + } + + + if (masterSnapPart != null) + { + + if (lastHighlightUpdate < Time.fixedTime) + { + lastHighlightUpdate = Time.fixedTime + highlightCycleTime + 0.5; + highlightOn = !highlightOn; + } +#if false + if (highlightOn) + Utility.UnHighlightParts(masterSnapPart); + else + Utility.HighlightChangeSinglePart(Color.clear, Color.clear, XKCDColors.Blue, XKCDColors.Yellow, 1 - (float)(Time.fixedTime - lastHighlightUpdate) / highlightCycleTime, masterSnapPart); +#endif + + if (highlightOn) + Utility.HighlightChangeSinglePart(XKCDColors.Cyan, XKCDColors.Cyan, Color.clear, Color.clear, 1 - (float)(lastHighlightUpdate - Time.fixedTime) / highlightCycleTime, masterSnapPart); + else + Utility.HighlightChangeSinglePart(Color.clear, Color.clear, XKCDColors.Cyan, XKCDColors.Cyan, 1 - (float)(lastHighlightUpdate - Time.fixedTime) / highlightCycleTime, masterSnapPart); + + + } + MoveParts(); +#if true + if (_fineAdjustWindow.isEnabled()) + { + Vector3 axis; + // var gizmosOffset = HighLogic.FindObjectsOfType (); + // if (gizmosOffset.Length > 0) { + if (GizmoEvents.offsetGizmoActive) + { + GizmoEvents.gizmoRotateHandle = null; + GizmoEvents.rotateGizmoActive = false; + if (EditorLogic.SelectedPart != null) + { + //var gizmosOffset = HighLogic.FindObjectsOfType (); + // if (gizmoOffsetHandle == null) + // gizmoOffsetHandle = HighLogic.FindObjectOfType (); + + if (GameSettings.VAB_USE_ANGLE_SNAP) + GameEvents.onEditorSnapModeChange.Fire(false); + + float offset = FineAdjustWindow.Instance.offset; + + Log.Info("\nmoving part: EditorLogic.SelectedPart.attPos: " + EditorLogic.SelectedPart.attPos); + Log.Info("moving part: EditorLogic.SelectedPart.attPos0: " + EditorLogic.SelectedPart.attPos0); + /* + * From WASD: + + public class Config + { + public KeyCode keyForward; + public KeyCode keyBack; + public KeyCode keyRight; + public KeyCode keyLeft; + public KeyCode keyUp; + public KeyCode keyDown; + public KeyCode keyRun; + public KeyCode keySneak; + public KeyCode keySwitchMode; + + */ + + if (Input.GetKey(cfg.KeyMap.Down)) + { + axis = Vector3.down; + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVESTART, GizmoEvents.gizmoOffsetHandle, axis); + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVE, GizmoEvents.gizmoOffsetHandle, axis, offset); + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVEEND, GizmoEvents.gizmoOffsetHandle, axis, 0.0f); + } + if (Input.GetKey(cfg.KeyMap.Up)) + { + axis = Vector3.up; + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVESTART, GizmoEvents.gizmoOffsetHandle, axis); + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVE, GizmoEvents.gizmoOffsetHandle, axis, offset); + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVEEND, GizmoEvents.gizmoOffsetHandle, axis, 0.0f); + } + + if (Input.GetKey(cfg.KeyMap.Left)) + { + if (EditorDriver.editorFacility == EditorFacility.VAB) + axis = Vector3.forward; + else + axis = Vector3.right; + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVESTART, GizmoEvents.gizmoOffsetHandle, axis); + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVE, GizmoEvents.gizmoOffsetHandle, axis, offset); + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVEEND, GizmoEvents.gizmoOffsetHandle, axis, 0.0f); + } + if (Input.GetKey(cfg.KeyMap.Right)) + { + if (EditorDriver.editorFacility == EditorFacility.VAB) + axis = Vector3.back; + else + axis = Vector3.left; + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVESTART, GizmoEvents.gizmoOffsetHandle, axis); + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVE, GizmoEvents.gizmoOffsetHandle, axis, offset); + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVEEND, GizmoEvents.gizmoOffsetHandle, axis, 0.0f); + + } + + if (Input.GetKey(cfg.KeyMap.Forward)) + { + if (EditorDriver.editorFacility == EditorFacility.VAB) + axis = Vector3.right; + else + axis = Vector3.back; + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVESTART, GizmoEvents.gizmoOffsetHandle, axis); + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVE, GizmoEvents.gizmoOffsetHandle, axis, offset); + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVEEND, GizmoEvents.gizmoOffsetHandle, axis, 0.0f); + + } + if (Input.GetKey(cfg.KeyMap.Back)) + { + if (EditorDriver.editorFacility == EditorFacility.VAB) + axis = Vector3.left; + else + axis = Vector3.forward; + + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVESTART, GizmoEvents.gizmoOffsetHandle, axis); + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVE, GizmoEvents.gizmoOffsetHandle, axis, offset); + Refl.Invoke(GizmoEvents.gizmosOffset[0], EditorExtensions.c.GIZMOOFFSET_ONHANDLEMOVEEND, GizmoEvents.gizmoOffsetHandle, axis, 0.0f); + + } + + } + else + { + GizmoEvents.gizmoOffsetHandle = null; + GizmoEvents.offsetGizmoActive = false; + } + } + else + { + GizmoEvents.gizmoOffsetHandle = null; + GizmoEvents.offsetGizmoActive = false; + // var gizmosRotate = HighLogic.FindObjectsOfType (); + // if (gizmosRotate.Length > 0) { + if (GizmoEvents.rotateGizmoActive) + { + if (EditorLogic.SelectedPart != null) + { + //var gizmosRotate = HighLogic.FindObjectsOfType (); + // if (gizmoRotateHandle == null) + // gizmoRotateHandle = HighLogic.FindObjectOfType (); + float rotation = FineAdjustWindow.Instance.rotation; + + if (Input.GetKey(cfg.KeyMap.Down)) + { + if (EditorDriver.editorFacility == EditorFacility.VAB) + axis = Vector3.forward; + else + axis = Vector3.left; + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATESTART, GizmoEvents.gizmoRotateHandle, axis); + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATE, GizmoEvents.gizmoRotateHandle, axis, rotation); + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATEEND, GizmoEvents.gizmoRotateHandle, axis, 0.0f); + } + if (Input.GetKey(cfg.KeyMap.Up)) + { + if (EditorDriver.editorFacility == EditorFacility.VAB) + axis = Vector3.back; + else + axis = Vector3.right; + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATESTART, GizmoEvents.gizmoRotateHandle, axis); + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATE, GizmoEvents.gizmoRotateHandle, axis, rotation); + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATEEND, GizmoEvents.gizmoRotateHandle, axis, 0.0f); + } + if (Input.GetKey(cfg.KeyMap.Left)) + { + if (EditorDriver.editorFacility == EditorFacility.VAB) + axis = Vector3.right; + else + axis = Vector3.forward; + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATESTART, GizmoEvents.gizmoRotateHandle, axis); + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATE, GizmoEvents.gizmoRotateHandle, axis, rotation); + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATEEND, GizmoEvents.gizmoRotateHandle, axis, 0.0f); + } + if (Input.GetKey(cfg.KeyMap.Right)) + { + if (EditorDriver.editorFacility == EditorFacility.VAB) + axis = Vector3.left; + else + axis = Vector3.back; + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATESTART, GizmoEvents.gizmoRotateHandle, axis); + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATE, GizmoEvents.gizmoRotateHandle, axis, rotation); + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATEEND, GizmoEvents.gizmoRotateHandle, axis, 0.0f); + + } + if (Input.GetKey(cfg.KeyMap.Forward)) + { + + axis = Vector3.up; + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATESTART, GizmoEvents.gizmoRotateHandle, axis); + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATE, GizmoEvents.gizmoRotateHandle, axis, rotation); + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATEEND, GizmoEvents.gizmoRotateHandle, axis, 0.0f); + + } + if (Input.GetKey(cfg.KeyMap.Back)) + { + axis = Vector3.down; + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATESTART, GizmoEvents.gizmoRotateHandle, axis); + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATE, GizmoEvents.gizmoRotateHandle, axis, rotation); + Refl.Invoke(GizmoEvents.gizmosRotate[0], EditorExtensions.c.GIZMOROTATE_ONHANDLEROTATEEND, GizmoEvents.gizmoRotateHandle, axis, 0.0f); + + } + } + else + { + GizmoEvents.gizmoRotateHandle = null; + GizmoEvents.rotateGizmoActive = false; + } + } + else + { + GizmoEvents.gizmoRotateHandle = null; + GizmoEvents.rotateGizmoActive = false; + } + } + } +#endif + + }//end if(enableHotKeys) + + if (oldSelectedPart != EditorLogic.SelectedPart) + { + oldSelectedPart = EditorLogic.SelectedPart; + updateGizmoSnaps(); + } + } + + void DisableMasterSnap() + { + if (masterSnapPart != null) + { + Utility.UnHighlightParts(masterSnapPart); + OSDMessage(string.Format("Master Snap mode off")); + masterSnapPart = null; + } + } + + bool IsPartNodeAttached(Part p) + { + if (p.parent == null || p == null) + return false; + + foreach (AttachNode n in p.attachNodes) + { + if (n.attachedPart == p.parent) + { + Log.Debug(string.Format("Part {0} is attached via node on parent {1}", p.name, p.parent.name)); + return true; + } + } + + return false; + } + +#region Alignments + + void AlignToTopOfParent(Part p) + { + if (p.parent.GetPartRendererBound().extents.y >= p.GetPartRendererBound().extents.y) + { + CenterVerticallyOnParent(p); + return; + } + + float newHeight = p.parent.GetPartRendererBound().extents.y - p.GetPartRendererBound().extents.y; + if (p.transform.localPosition.y < 0) + newHeight = -newHeight; + + VerticalPositionOnParent(p, newHeight); + + throw new NotImplementedException(); + } + + void CenterVerticallyOnParent(Part p) + { + VerticalPositionOnParent(p, 0f); + } + + public void AdjustVerticalPositionOnParent(Part p, float position) + { + //move hovered part + VerticalPositionOnParent(p, position); + + //move any symmetry siblings/counterparts + foreach (Part symPart in p.symmetryCounterparts) + { + VerticalPositionOnParent(symPart, position); + } + + } + + public void VerticalPositionOnParent(Part p, float position) + { + if (p.parent != null) + { + Log.Debug(string.Format("Positioning {0} vertically on parent {1}", p.name, p.parent.name)); + if (partMovementContains(p)) + return; + PartMovement pm = new PartMovement(); + pm.p = p; + pm.local = true; + pm.startPos = p.transform.localPosition; + pm.endPos = new Vector3(p.transform.localPosition.x, position, p.transform.localPosition.z); + pm.time = timeToMovePM; + pm.startTime = Time.fixedTime; + pm.endtime = Time.fixedTime + pm.time; + partMovement.Add(pm); + + //p.transform.localPosition = new Vector3(p.transform.localPosition.x, position, p.transform.localPosition.z); + //p.attPos0.y = position; + } + } + + const int timeToMovePM = 1; + class PartMovement + { + public Part p; + public bool local; + public Vector3 startPos; + public Vector3 endPos; + public int time; + public double startTime; + public double endtime; + } + + List partMovement = new List(); + + bool partMovementContains(Part p) + { + foreach (var pm in partMovement) + if (pm.p == p) + return true; + return false; + } + + void MoveParts() + { + List pmToDel = null; + + foreach (PartMovement pm in partMovement) + { + if (pm.local) + { + Vector3 v = Vector3.Lerp(pm.startPos, pm.endPos, (float)((Time.fixedTime - pm.startTime) / pm.time)); + pm.p.transform.localPosition = v; + pm.p.attPos0 = pm.p.transform.localPosition; + } + else + { + Vector3 v = Vector3.Lerp(pm.startPos, pm.endPos, (float)((Time.fixedTime - pm.startTime) / pm.time)); + pm.p.transform.position = v; + pm.p.attPos = pm.p.transform.position; + } + if (Time.fixedTime > pm.endtime) + { + if (pmToDel == null) + pmToDel = new List(); + pmToDel.Add(pm); + } + } + if (pmToDel != null) + foreach (var pm in pmToDel) + partMovement.Remove(pm); + } + + void MatchVerticalPositionWithPart(Part masterSnapPart, Part p) + { + if (partMovementContains(p)) + return; + + PartMovement pm = new PartMovement(); + pm.p = p; + pm.local = false; + pm.startPos = p.transform.position; + pm.endPos = new Vector3(p.transform.position.x, masterSnapPart.transform.position.y, p.transform.position.z); + pm.time = timeToMovePM; + pm.startTime = Time.fixedTime; + pm.endtime = Time.fixedTime + pm.time; + partMovement.Add(pm); + + //p.transform.position = new Vector3(p.transform.position.x, masterSnapPart.transform.position.y, p.transform.position.z); + //p.attPos = p.transform.position; + } + + +#if false + public enum horizontaltype { leftright, forwardback }; + public void AdjustHorizontalPositionOnParent(Part p, horizontaltype type, float position, float adj) + { + + HorizontalPositionOnParent(p, type, position); + foreach (Part sympart in p.symmetryCounterparts) + { + switch (type) + { + case horizontaltype.leftright: + HorizontalPositionOnParent(sympart, type, sympart.attPos0.z - adj); + break; + case horizontaltype.forwardback: + HorizontalPositionOnParent(sympart, type, sympart.attPos0.x - adj); + break; + } + //HorizontalPositionOnParent (sympart, type, position); + } + } + + public void HorizontalPositionOnParent(Part p, horizontaltype type, float position) + { + if (p.parent != null) + { + if (partMovementContains(p)) + return; + + PartMovement pm = new PartMovement(); + pm.p = p; + pm.local = true; + pm.startPos = p.transform.localPosition; + pm.endPos = new Vector3(p.transform.position.x, masterSnapPart.transform.position.y, p.transform.position.z); + pm.time = timeToMovePM; + pm.startTime = Time.fixedTime; + pm.endtime = Time.fixedTime + pm.time; + + + switch (type) + { + case horizontaltype.forwardback: + pm.endPos = new Vector3(position, p.transform.localPosition.y, p.transform.localPosition.z); + //p.transform.localPosition = new Vector3(position, p.transform.localPosition.y, p.transform.localPosition.z); + //p.attPos0.x = position; + break; + case horizontaltype.leftright: + pm.endPos = new Vector3(p.transform.localPosition.x, p.transform.localPosition.y, position); + //p.transform.localPosition = new Vector3(p.transform.localPosition.x, p.transform.localPosition.y, position); + //p.attPos0.z = position; + break; + } + partMovement.Add(pm); + } + } +#endif + public enum axis { x, y, z }; + public void RotatePartOnParent(Part p, axis xyz, float amt) + { + RotatePart(p, xyz, amt); + foreach (Part sympart in p.symmetryCounterparts) + { + RotatePart(sympart, xyz, amt); + } + } + public void RotatePart(Part p, axis xyz, float amt) + { + Quaternion r = p.attRotation0; + switch (xyz) + { + case axis.x: + r *= Quaternion.Euler(Vector3.up * amt); + break; + case axis.y: + r *= Quaternion.Euler(Vector3.left * amt); + break; + case axis.z: + r *= Quaternion.Euler(Vector3.forward * amt); + break; + } + Log.Info("RotatePart attRotation0: " + p.attRotation0.eulerAngles); + Log.Info("RotatePart r: " + r.eulerAngles); + //p.orgRot = r; + p.transform.localRotation = r; + } + + + + + void CenterOnParent(Part p) + { + //check for orientation of parent, if it's on the end of the parent, center on the end + //on the surface, center lengthwise + AttachNode an = p.parent.FindAttachNodeByPart(p); + if (an.nodeType == AttachNode.NodeType.Surface) + { + + } + else if (an.nodeType == AttachNode.NodeType.Stack) + { + + } + else if (an.nodeType == AttachNode.NodeType.Dock) + { + + } + + throw new NotImplementedException(); + } + + void CenterHorizontallyOnParent(Part p, bool otherHorizontal = false) + { + if (partMovementContains(p)) + return; + + PartMovement pm = new PartMovement(); + pm.p = p; + pm.local = true; + pm.startPos = p.transform.localPosition; + pm.time = timeToMovePM; + pm.startTime = Time.fixedTime; + pm.endtime = Time.fixedTime + pm.time; + + if (otherHorizontal) + { + pm.endPos = new Vector3(0f, p.transform.localPosition.y, p.transform.localPosition.z); + //p.transform.localPosition = new Vector3(0f, p.transform.localPosition.y, p.transform.localPosition.z); + //p.attPos0.x = 0f; + } + else + { + pm.endPos = new Vector3(p.transform.localPosition.x, p.transform.localPosition.y, 0f); + //p.transform.localPosition = new Vector3(p.transform.localPosition.x, p.transform.localPosition.y, 0f); + //p.attPos0.z = 0f; + } + partMovement.Add(pm); + } + + void MatchHorizontalPositionWithPart(Part masterSnapPart, Part p, bool otherHorizontal = false) + { + if (partMovementContains(p)) + return; + + PartMovement pm = new PartMovement(); + pm.p = p; + pm.local = false; + pm.startPos = p.transform.position; + pm.time = timeToMovePM; + pm.startTime = Time.fixedTime; + pm.endtime = Time.fixedTime + pm.time; + + if (otherHorizontal) + { + pm.endPos = new Vector3(masterSnapPart.transform.position.x, p.transform.position.y, p.transform.position.z); + //p.transform.position = new Vector3(masterSnapPart.transform.position.x, p.transform.position.y, p.transform.position.z); + //p.attPos = p.transform.position; + } + else + { + pm.endPos = new Vector3(p.transform.position.x, p.transform.position.y, masterSnapPart.transform.position.z); + //p.transform.position = new Vector3(p.transform.position.x, p.transform.position.y, masterSnapPart.transform.position.z); + //p.attPos = p.transform.position; + } + partMovement.Add(pm); + } + + void VerticalAlign() + { + Log.Info("VerticalAlign"); + try + { + Part sp = Utility.GetPartUnderCursor(); + Log.Info("sp: " + sp.partInfo.title); + if (sp != null && sp.srfAttachNode != null && sp.srfAttachNode.attachedPart != null && !GizmoActive() && !IsPartNodeAttached(sp)) + { + + if (masterSnapPart == null) + { + Log.Info("CenterVerticallyOnParent: " + sp.partInfo.title); + //move hovered part + CenterVerticallyOnParent(sp); + + //move any symmetry siblings/counterparts + foreach (Part symPart in sp.symmetryCounterparts) + { + CenterVerticallyOnParent(symPart); + } + } + else + { + MatchVerticalPositionWithPart(masterSnapPart, sp); + //move any symmetry siblings/counterparts + foreach (Part symPart in sp.symmetryCounterparts) + { + MatchVerticalPositionWithPart(masterSnapPart, symPart); + } + } + + AddUndo(); + } + } + catch (Exception ex) + { + Log.Error("Error trying to vertically align: " + ex.Message); + } + + return; + } + + void HorizontalAlign(bool otherHorizontal = false) + { + try + { + Part sp = Utility.GetPartUnderCursor(); + + if (sp != null && sp.srfAttachNode != null && sp.srfAttachNode.attachedPart != null && !GizmoActive() && !IsPartNodeAttached(sp)) + { + + + if (masterSnapPart == null) + { + //move selected part + CenterHorizontallyOnParent(sp, otherHorizontal); + + //move any symmetry siblings/counterparts + foreach (Part symPart in sp.symmetryCounterparts) + { + CenterHorizontallyOnParent(symPart, otherHorizontal); + } + } + else + { + MatchHorizontalPositionWithPart(masterSnapPart, sp, otherHorizontal); + //move any symmetry siblings/counterparts + foreach (Part symPart in sp.symmetryCounterparts) + { + MatchHorizontalPositionWithPart(masterSnapPart, symPart, otherHorizontal); + } + + } + + //Add edit to undo history + AddUndo(); + } + } + catch (Exception ex) + { + Log.Error("Error trying to Horizontally align: " + ex.Message); + } + return; + } + + void AlignCompoundPart(CompoundPart part, bool snapHeights) + { + if (part.target != null && part.parent != null) + { + CompoundPartUtil.AlignCompoundPart(part, snapHeights); + + List symParts = part.symmetryCounterparts; + //move any symmetry siblings/counterparts + foreach (CompoundPart symPart in symParts) + { + CompoundPartUtil.AlignCompoundPart(symPart, snapHeights); + } + AddUndo(); + } + } + +#endregion + +#region Editor Actions + + void AddUndo() + { + //need to verify this is the right way, it does seem to work + editor.SetBackup(); + } + + void ResetCamera() + { + if (!GizmoActive()) + { + + //editor.editorCamera + + VABCamera VABcam = Camera.main.GetComponent(); + VABcam.camPitch = 0; + VABcam.camHdg = 0; + //VABcam.transform.position.y = 9f; + + SPHCamera SPHcam = Camera.main.GetComponent(); + SPHcam.camPitch = 0; + SPHcam.camHdg = 0; + //SPHcam.transform.position.y = 9f; + } + return; + } + + void SurfaceAttachToggle() + { + if (EditorLogic.SelectedPart) + { + //Toggle surface attachment for selected part + EditorLogic.SelectedPart.attachRules.srfAttach ^= true; + + Log.Debug("Toggling srfAttach for " + EditorLogic.SelectedPart.name); + OSDMessage(String.Format("Surface attachment {0} for {1}" + , EditorLogic.SelectedPart.attachRules.srfAttach ? "enabled" : "disabled" + , EditorLogic.SelectedPart.name + )); + } + return; + } + + void PartClippingToggle() + { + CheatOptions.AllowPartClipping ^= true; + Log.Debug("AllowPartClipping " + (CheatOptions.AllowPartClipping ? "enabled" : "disabled")); + OSDMessage("Part clipping " + (CheatOptions.AllowPartClipping ? "enabled" : "disabled")); + return; + } + +#if false + void SymmetryModeCycle(bool modKeyDown, bool fineKeyDown) + { + + //InputLockManager.SetControlLock (ControlTypes.EDITOR_SYM_SNAP_UI, "EEX-SymLock"); + + Log.Debug("Starting symmetryMode: " + editor.symmetryMode.ToString()); + //only inc/dec symmetry in radial mode, mirror is just 1&2 + if (editor.symmetryMethod == SymmetryMethod.Radial) + { + if (modKeyDown || (_symmetryMode < 2 && fineKeyDown)) + { + //Alt+X or Symmetry is at 1(index 2) or lower + _symmetryMode = 0; + } + else if (_symmetryMode > cfg.MaxSymmetry - 2 && !fineKeyDown) + { + //Stop adding at max symmetry + _symmetryMode = cfg.MaxSymmetry - 1; + } + else + { + //inc/dec symmetry + _symmetryMode = _symmetryMode + (fineKeyDown ? -1 : 1); + } + editor.symmetryMode = _symmetryMode; + Log.Debug("Setting symmetryMode to " + _symmetryMode.ToString()); + } + else + { + //editor.symmetryMethod == SymmetryMethod.Mirror + //update var with stock action's result + _symmetryMode = editor.symmetryMode; + } + + //GameEvents.onEditorSymmetryModeChange.Fire(_symmetryMode); + //InputLockManager.RemoveControlLock("EEX-SymLock"); + + Log.Debug("Returning symmetryMode: " + editor.symmetryMode.ToString()); + return; + } +#endif + + void updateGizmoSnaps() + { + // Following code contributed by Fwiffo + + // Look for active rotation gizmo and change its snap resolution + var gizmosRotate = HighLogic.FindObjectsOfType(); + // Following needed to dump values to log +#if DEBUG + if (gizmosRotate.Length > 0) + { + + // Chunk to find the magic variable we need to adjust + + var gizmoRotate = gizmosRotate[0]; + + int cnt = 0; + var fields = gizmoRotate.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + foreach (var f in fields) + { + Log.Info("EditorLogic Gizmo Rotate Field name[" + cnt.ToString() + "]: " + f.Name + " Fieldtype: " + f.GetValue(gizmoRotate).ToString()); + cnt++; + + // Debug.Log(String.Format("{0}: {1}", f.Name, f.GetValue(gizmo).ToString())); + } + + + MethodInfo[] egMethods = typeof(EditorGizmos.GizmoRotate).GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + cnt = 0; + foreach (MethodInfo EG in egMethods) + { + Log.Info("EditorLogic Gizmo Rotate methods name[" + cnt.ToString() + "]: " + EG.Name + " " + EG.ReturnType.ToString()); + cnt++; + + } + + } +#endif +#if false + var gizmosOffsets = HighLogic.FindObjectsOfType (); + if (gizmosOffsets.Length > 0) { + var gizmoOffset = gizmosOffsets [0]; + + var cnt = 0; + var gizmoOffsetFields = gizmoOffset.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); + foreach (var f in gizmoOffsetFields) { + Log.Info ("EditorLogic Gizmo Offset Field name[" + cnt.ToString () + "]: " + f.Name + " Fieldtype: " + f.GetValue(gizmoOffset).ToString()); + cnt++; + + // Debug.Log(String.Format("{0}: {1}", f.Name, f.GetValue(gizmo).ToString())); + } + + + MethodInfo[] gizmoOffsetMethods = typeof(EditorGizmos.GizmoOffset).GetMethods (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + cnt = 0; + foreach (MethodInfo EG in gizmoOffsetMethods) { + Log.Info ("EditorLogic Gizmo Offset methods name[" + cnt.ToString () + "]: " + EG.Name + " " + EG.ReturnType.ToString()); + cnt++; + } + + } +#endif + if (gizmosRotate.Length > 0) + { + var g = gizmosRotate[0]; + //fix1 + g.useAngleSnap = editor.srfAttachAngleSnap != 0 && GameSettings.VAB_USE_ANGLE_SNAP; + // Unfortunately the SnapDegrees property is read-only; some reflection hackery is needed + if (editor.srfAttachAngleSnap != 0 && GameSettings.VAB_USE_ANGLE_SNAP) + { + + + // var field = gizmo.GetType ().GetField ("gridSnapInterval", BindingFlags.NonPublic | BindingFlags.Instance); + // field.SetValue (gizmo, editor.srfAttachAngleSnap); + // field = gizmo.GetType ().GetField ("gridSnapIntervalFine", BindingFlags.NonPublic | BindingFlags.Instance); + float fine = editor.srfAttachAngleSnap / 3f; + // field.SetValue (gizmo, fine); + //fine = (float)field.GetValue(gizmo); + + Refl.SetValue(g, EditorExtensions.c.GRIDSNAPINTERVAL, editor.srfAttachAngleSnap); + Refl.SetValue(g, EditorExtensions.c.GRIDSNAPINTERVALFINE, fine); + + Debug.Log(String.Format("Gizmo SnapDegrees = {0}, fine = {1}", g.SnapDegrees.ToString(), fine.ToString())); + } + } + } + +#if false + void AngleSnapCycle(bool modKeyDown, bool fineKeyDown) + { + if (!modKeyDown) + { + Log.Debug("Starting srfAttachAngleSnap = " + editor.srfAttachAngleSnap.ToString()); + + int currentAngleIndex = cfg.AngleSnapValues.IndexOf(editor.srfAttachAngleSnap); +#if false + if (currentAngleIndex < 0) + currentAngleIndex = 0; +#endif + Log.Debug("currentAngleIndex: " + currentAngleIndex.ToString()); + + //rotate through the angle snap values + float newAngle; + if (fineKeyDown) + { + //lower snap + newAngle = cfg.AngleSnapValues[currentAngleIndex == 0 ? cfg.AngleSnapValues.Count - 1 : currentAngleIndex - 1]; + } + else + { + //higher snap + newAngle = cfg.AngleSnapValues[currentAngleIndex == cfg.AngleSnapValues.Count - 1 ? 0 : currentAngleIndex + 1]; + } + + Log.Debug("Setting srfAttachAngleSnap to " + newAngle.ToString()); + editor.srfAttachAngleSnap = newAngle; + } + else + { + Log.Debug("Resetting srfAttachAngleSnap to 0"); + editor.srfAttachAngleSnap = 0; + } + + + //at angle snap 0, turn off angle snap and show stock circle sprite + if (editor.srfAttachAngleSnap == 0) + { + GameSettings.VAB_USE_ANGLE_SNAP = false; +#if false +editor.srfAttachAngleSnap = 0.01f; +GameSettings.VAB_USE_ANGLE_SNAP = true; +editor.angleSnapSprite.gameObject.SetActive (false); +#endif + } + else + { + GameSettings.VAB_USE_ANGLE_SNAP = true; + } + + lastSrfAttachAngleSnap = editor.srfAttachAngleSnap; + last_VAB_USE_ANGLE_SNAP = GameSettings.VAB_USE_ANGLE_SNAP; + + updateGizmoSnaps(); + // Fwiffo + // Fix offset gizmo if shown + var gizmos = HighLogic.FindObjectsOfType(); + if (gizmos.Length > 0) + { + var gizmo = gizmos[0]; + if (editor.srfAttachAngleSnap == 0 && gizmo.useGrid) + gizmo.useGrid = false; + else if (editor.srfAttachAngleSnap != 0 && !gizmo.useGrid) + gizmo.useGrid = true; + Debug.Log("Offset snap interval = " + gizmo.SnapInterval.ToString() + ", using grid = " + gizmo.useGrid); + } + // Fwiffo end + Log.Debug("Exiting srfAttachAngleSnap = " + editor.srfAttachAngleSnap.ToString()); + return; + } +#endif + + bool GizmoActive() + { + try + { + if (HighLogic.FindObjectsOfType().Length > 0 || HighLogic.FindObjectsOfType().Length > 0) + { + return true; + } + else + { + return false; + } +#if DEBUG + } + catch (Exception ex) + { + Log.Error("Error getting active Gizmos: " + ex.Message); +#else + } catch (Exception) { +#endif + return false; + } + } + +#endregion + +#region GUI + + //private Rect _settingsWindowRect; + GUIStyle osdLabelStyle, symmetryLabelStyle; + VABCamera vabCam; + SPHCamera sphCam; + void InitializeGUI() + { + if (!validVersion) + return; + vabCam = Camera.main.GetComponent(); // or EditorDriver.fetch.vabCamera; // RK + sphCam = Camera.main.GetComponent(); // or EditorDriver.fetch.sphCamera; + + _settingsWindow = this.gameObject.AddComponent(); + _settingsWindow.WindowDisabled += new SettingsWindow.WindowDisabledEventHandler(SettingsWindowClosed); + + _showAngleSnaps = this.gameObject.AddComponent(); + //_showAngleSnaps.WindowDisabled += new ShowAngleSnaps.WindowDisabledEventHandler(ShowAngleSnaps); + + _partInfoWindow = this.gameObject.AddComponent(); + _fineAdjustWindow = this.gameObject.AddComponent(); + + //_strutWindow = this.gameObject.AddComponent (); + + osdLabelStyle = new GUIStyle() + { + stretchWidth = true, + stretchHeight = true, + alignment = TextAnchor.MiddleCenter, + fontSize = 22, + fontStyle = FontStyle.Bold, + name = "OSDLabel" + }; + osdLabelStyle.normal.textColor = Color.yellow; + + symmetryLabelStyle = new GUIStyle() + { + stretchWidth = true, + stretchHeight = true, + alignment = TextAnchor.MiddleCenter, + fontSize = FONTSIZE, + fontStyle = FontStyle.Bold, + name = "SymmetryLabel" + }; + symmetryLabelStyle.normal.textColor = Color.yellow; + + //skin.customStyles = new GUIStyle[]{ osdLabel, symmetryLabel }; + } + + //show the addon's GUI + public void Show() + { + if (!validVersion) + return; + this.Visible = true; + Log.Debug("Show()"); + //if (!_settingsWindow.enabled) { + // _settingsWindow.Show (cfg, _configFilePath, pluginVersion); + //} + } + + //hide the addon's GUI + public void Hide() + { + if (!validVersion) + return; + this.Visible = false; + //Log.Debug ("Hide()"); + //if (_settingsWindow.enabled) { + // _settingsWindow.enabled = false; + //} + } + + public void SettingsWindowClosed() + { + Log.Debug("Settings window closed, reloading config"); + cfg = ConfigManager.LoadConfig(_configFilePath); + Hide(); + } + + bool _showMenu = false; + Rect _menuRect = new Rect(); + const float _menuWidth = 100.0f; + const float _menuHeightSmall = 140.0f; + const float _menuHeightLarge = 380.0f; + const int _toolbarHeight = 42; + //37 + bool oldAllowTweakingWithoutTweakables = GameSettings.ADVANCED_TWEAKABLES; + public void ShowMenu(bool firstTime = true) + { + if (!validVersion) + return; + oldAllowTweakingWithoutTweakables = allowTweakingWithoutTweakables; + Vector3 position = Input.mousePosition; + int toolbarHeight = (int)(_toolbarHeight * GameSettings.UI_SCALE); + float menuHeight; + if (allowTweakingWithoutTweakables || GameSettings.ADVANCED_TWEAKABLES) + menuHeight = _menuHeightLarge; + else + menuHeight = _menuHeightSmall; + if (firstTime) + { + _menuRect = new Rect() + { + xMin = position.x - _menuWidth / 2, + xMax = position.x + _menuWidth / 2, + yMin = Screen.height - toolbarHeight - menuHeight, + yMax = Screen.height - toolbarHeight + }; + _showMenu = true; + } + else + { + _menuRect.Set( + _menuRect.x, + Screen.height - toolbarHeight - menuHeight, + _menuRect.width, + menuHeight + ); + lastTimeShown = Time.fixedTime; + } + + } + + public void HideMenu() + { + _showMenu = false; + } + + + //Unity GUI loop + void OnGUI() + { + if (!validVersion) + { + if (warningShown) + return; + GUIStyle centeredWarningStyle = new GUIStyle(GUI.skin.GetStyle("Label")); + string kspVersion = Versioning.version_major.ToString() + "." + Versioning.version_minor.ToString() + "." + Versioning.Revision.ToString(); + string warning2 = warning + "\nKSP version: " + kspVersion; + Vector2 sizeOfWarningLabel = centeredWarningStyle.CalcSize(new GUIContent(warning2)); + + + Rect _menuRect = new Rect(Screen.width / 2f - (sizeOfWarningLabel.x / 2f), Screen.height / 2 - sizeOfWarningLabel.y, + sizeOfWarningLabel.x, sizeOfWarningLabel.y * 2); + + _menuRect = GUILayout.Window(this.GetInstanceID(), _menuRect, ShowWarning, "EEX Menu"); + return; + } + if (oldAllowTweakingWithoutTweakables != allowTweakingWithoutTweakables) + ShowMenu(false); + + //show and update the angle snap and symmetry mode labels + ShowSnapLabels(); + + ShowAutoStruts(); + + + if (Event.current.type == EventType.Layout) + { + if (_showMenu || _menuRect.Contains(Event.current.mousePosition) || (Time.fixedTime - lastTimeShown < 0.5f)) + _menuRect = GUILayout.Window(this.GetInstanceID(), _menuRect, MenuContent, "EEX Menu"); + else + _menuRect = new Rect(); + } + } + float lastTimeShown = 0.0f; + + //Boop: Variable to hold a list of ship parts for the Mass Rigidifier / Autostrutter. + List parts; + + //Boop: Parts with these AutoStrutModes probably don't want us messing with them, so we'll cache a list of them here. + List doNotMessWithAutoStrutModes = new List + { + Part.AutoStrutMode.ForceGrandparent, + Part.AutoStrutMode.ForceHeaviest, + Part.AutoStrutMode.ForceRoot + }; + + //Boop: By default, don't allow tweaking RigidAttach or Autostruts without Advancewd Tweakables set to on, but allow this to be overridden. + bool allowTweakingWithoutTweakables = false; + + bool showAutostruts = false; + double lastAutostrutshow = 0; + + void MenuContent(int WindowID) + { + if (_showMenu || _menuRect.Contains(Event.current.mousePosition)) + lastTimeShown = Time.fixedTime; + GUILayout.BeginVertical(); + if (GUILayout.Button("Show Angle Snaps")) + { + _showAngleSnaps.Show(cfg); + } + GUILayout.EndVertical(); + + GUILayout.BeginVertical(); + if (GUILayout.Button("Settings")) + { + _settingsWindow.Show(cfg, _configFilePath, pluginVersion); + this.Visible = true; + } +#if true + if (cfg.FineAdjustEnabled) + { + if (GUILayout.Button("Fine Adjust")) + { + _fineAdjustWindow.Show(); + + } + } +#endif + if (cfg.ShowDebugInfo) + { + if (GUILayout.Button("Position Debug")) + { + _partInfoWindow.Show(); + } + } + //_strutWindow.enabled = GUILayout.Toggle (_strutWindow.enabled, "Strut Tool", "Button"); + //if (GUILayout.Button ("Strut tool")) { + // _strutWindow.Show (); + // this.Visible = true; + //} + + //Boop: Advanced Tweakable Override toggle. + if (!GameSettings.ADVANCED_TWEAKABLES) + { + GUILayout.Space(10f); + + allowTweakingWithoutTweakables = GUILayout.Toggle(allowTweakingWithoutTweakables, "Allow Mass Tweakables"); + + } + + if (GameSettings.ADVANCED_TWEAKABLES || allowTweakingWithoutTweakables) + { + //Boop: Rigidifier buttons. + GUILayout.Space(10f); + GUILayout.Label("Mass Tweakables:"); + if (GUILayout.Button("All Rigid")) + { + RefreshParts(); + foreach (Part p in parts) + { + p.rigidAttachment = true; + p.ApplyRigidAttachment(); + } + OSDMessage("RigidAttach turned ON for all current Parts in Vessel."); + } + + if (GUILayout.Button("Disable Rigid")) + { + RefreshParts(); + foreach (Part p in parts) + { + p.rigidAttachment = false; + p.ApplyRigidAttachment(); + } + OSDMessage("RigidAttach turned OFF for all current Parts in Vessel."); + } + + if (GUILayout.Button("Toggle Rigid")) + { + RefreshParts(); + foreach (Part p in parts) + { + p.rigidAttachment = !p.rigidAttachment; + p.ApplyRigidAttachment(); + } + OSDMessage("RigidAttach toggled for all current Parts in Vessel."); + } + + //Boop: Autostrutter buttons. + + if (GUILayout.Button("No Autostruts")) + { + RefreshParts(); + foreach (Part p in parts) + { + if (!doNotMessWithAutoStrutModes.Contains(p.autoStrutMode)) + { + p.autoStrutMode = Part.AutoStrutMode.Off; + p.UpdateAutoStrut(); + } + } + OSDMessage("Autostruts turned OFF for all current Parts in Vessel (except forced)."); + } + + if (GUILayout.Button("AS Grandparent")) + { + RefreshParts(); + foreach (Part p in parts) + { + if (!doNotMessWithAutoStrutModes.Contains(p.autoStrutMode)) + { + // First set off to get timers set properly with the toggle, then update to Grandparent + p.autoStrutMode = Part.AutoStrutMode.Off; + // The ToggleAutoStrut will set the mode to Heaviest + p.ToggleAutoStrut(); + + p.autoStrutMode = Part.AutoStrutMode.Grandparent; + p.UpdateAutoStrut(); + } + } + OSDMessage("Autostruts set to 'Grandparent' for all current Parts in Vessel (except forced)."); + } + + if (GUILayout.Button("AS Heaviest")) + { + RefreshParts(); + foreach (Part p in parts) + { + if (!doNotMessWithAutoStrutModes.Contains(p.autoStrutMode)) + { + // p.autoStrutMode = Part.AutoStrutMode.Heaviest;; + + // p.UpdateAutoStrut(); + p.autoStrutMode = Part.AutoStrutMode.Off; + // The ToggleAutoStrut will set the mode to Heaviest + p.ToggleAutoStrut(); + + } + } + OSDMessage("Autostruts set to 'Heaviest' for all current Parts in Vessel (except forced)."); + } + + if (GUILayout.Button("AS Root")) + { + RefreshParts(); + foreach (Part p in parts) + { + if (!doNotMessWithAutoStrutModes.Contains(p.autoStrutMode)) + { + // p.autoStrutMode = Part.AutoStrutMode.Root; + + // p.UpdateAutoStrut(); + + p.autoStrutMode = Part.AutoStrutMode.Heaviest; + // The ToggleAutoStrut will set the mode to Root + p.ToggleAutoStrut(); + } + } + OSDMessage("Autostruts set to 'Root' for all current Parts in Vessel (except forced)."); + } + GUILayout.Space(10); + if (showAutostruts) + { + if (GUILayout.Button("Hide Autostruts")) + { + showAutostruts = false; + } + } + else + { + if (GUILayout.Button("Show Autostruts")) + { + showAutostruts = true; + } + } + } + + GUILayout.EndVertical(); + } + + //Boop: This sub will refresh our parts list for the Rigidifier / Autostrutter + void RefreshParts() + { + parts = EditorLogic.fetch.ship != null ? EditorLogic.fetch.ship.Parts : new List(); + } + + void ShowWarning(int WindowID) + { + GUILayout.BeginVertical(); + { + float offsetY = Mathf.FloorToInt(0.8f * Screen.height); + GUIStyle centeredWarningStyle = new GUIStyle(GUI.skin.GetStyle("Label")) + { + alignment = TextAnchor.UpperCenter, + fontSize = 16, + normal = { textColor = Color.yellow } + }; + + Vector2 sizeOfWarningLabel = centeredWarningStyle.CalcSize(new GUIContent(warning)); + + GUILayout.Label(warning, centeredWarningStyle); + + offsetY += sizeOfWarningLabel.y; + if (GUILayout.Button("Click to open the Forum thread")) + Application.OpenURL("http://forum.kerbalspaceprogram.com/index.php?/topic/127378-editor-extensions-redux-324-released-for-111-with-selectroot-merge-stripsymmetry-nooffsetlimits/"); + + offsetY += 25; + + + + } + if (GUILayout.Button("Close")) + { + warningShown = true; + } + + GUILayout.EndVertical(); + } + + void OSDMessage(string message) + { + ScreenMessages.PostScreenMessage(message, cfg.OnScreenMessageTime, ScreenMessageStyle.LOWER_CENTER); + } + +#region Snap labels + + const int FONTSIZE = 14; + + string symmetryLabelValue = string.Empty; + //symmetry & angle sprite/label size and position + + //const int advancedModeOffset = 34; + //const int angleSnapLabelSize = 43; + int advancedModeOffset = 34; + int angleSnapLabelSize = 33; + + //const int angleSnapLabelLeftOffset = 209; + //const int angleSnapLabelBottomOffset = 61; + int angleSnapLabelLeftOffset = 231; + int angleSnapLabelBottomOffset = 52; + + //const int symmetryLabelSize = 56; + int symmetryLabelSize = 43; + + //const int symmetryLabelLeftOffset = 152; + //const int symmetryLabelBottomOffset = 63; + int symmetryLabelLeftOffset = 175; + int symmetryLabelBottomOffset = 50; + + + Rect angleSnapLabelRect; + /* = new Rect () { + xMin = angleSnapLabelLeftOffset, + xMax = angleSnapLabelLeftOffset + angleSnapLabelSize, + yMin = Screen.height - angleSnapLabelBottomOffset, + yMax = Screen.height - angleSnapLabelBottomOffset + angleSnapLabelSize + }; */ + Rect symmetryLabelRect; + /* = new Rect () { + xMin = symmetryLabelLeftOffset, + xMax = symmetryLabelLeftOffset + symmetryLabelSize, + yMin = Screen.height - symmetryLabelBottomOffset, + yMax = Screen.height - symmetryLabelBottomOffset + symmetryLabelSize + };*/ + + void AdjustSnapLocations() + { + + if (editor.srfAttachAngleSnap == 0) + { + GameSettings.VAB_USE_ANGLE_SNAP = false; + } + else + { + // GameSettings.VAB_USE_ANGLE_SNAP = true; + } + last_VAB_USE_ANGLE_SNAP = GameSettings.VAB_USE_ANGLE_SNAP; + + //symmetry & angle sprite/label size and position + symmetryLabelStyle.fontSize = (int)Math.Round(FONTSIZE * GameSettings.UI_SCALE); + osdLabelStyle.fontSize = (int)Math.Round(22 * GameSettings.UI_SCALE); + + //const int advancedModeOffset = 34; + //const int angleSnapLabelSize = 43; + advancedModeOffset = (int)Math.Floor(33 * GameSettings.UI_SCALE); + angleSnapLabelSize = (int)Math.Floor(33 * GameSettings.UI_SCALE); + + //const int angleSnapLabelLeftOffset = 209; + //const int angleSnapLabelBottomOffset = 61; + angleSnapLabelLeftOffset = (int)Math.Floor(231 * GameSettings.UI_SCALE); + angleSnapLabelBottomOffset = (int)Math.Floor(52 * GameSettings.UI_SCALE); + + //const int symmetryLabelSize = 56; + symmetryLabelSize = (int)Math.Floor(43 * GameSettings.UI_SCALE); + + //const int symmetryLabelLeftOffset = 152; + //const int symmetryLabelBottomOffset = 63; + symmetryLabelLeftOffset = (int)Math.Floor(175 * GameSettings.UI_SCALE); + symmetryLabelBottomOffset = (int)Math.Floor(50 * GameSettings.UI_SCALE); + + + angleSnapLabelRect = new Rect() + { + xMin = angleSnapLabelLeftOffset, + xMax = angleSnapLabelLeftOffset + angleSnapLabelSize, + yMin = Screen.height - angleSnapLabelBottomOffset, + yMax = Screen.height - angleSnapLabelBottomOffset + angleSnapLabelSize + }; + symmetryLabelRect = new Rect() + { + xMin = symmetryLabelLeftOffset, + xMax = symmetryLabelLeftOffset + symmetryLabelSize, + yMin = Screen.height - symmetryLabelBottomOffset, + yMax = Screen.height - symmetryLabelBottomOffset + symmetryLabelSize + }; + } + + void ShowAutoStruts() + { + if (showAutostruts && Time.time - lastAutostrutshow > 2) + { + lastAutostrutshow = Time.time; + RefreshParts(); + foreach (Part p in parts) + { + if (p.autoStrutMode != Part.AutoStrutMode.Off && !doNotMessWithAutoStrutModes.Contains(p.autoStrutMode)) + { + Part.AutoStrutMode asm = p.autoStrutMode; + p.autoStrutMode = Part.AutoStrutMode.Off; + // The ToggleAutoStrut will set the mode to Heaviest + p.ToggleAutoStrut(); + + p.autoStrutMode = asm; + p.UpdateAutoStrut(); + } + } + } + } + + /// + /// Hides the stock angle & symmetry sprites and replaces with textual labels + /// + private void ShowSnapLabels() + { + if (editor == null) + return; + AdjustSnapLocations(); + //editor.symmetryButton.transform.position? + + //Only show angle/symmetry sprites on parts tab + if (editor.editorScreen == EditorScreen.Parts) + { + if (EditorLogic.Mode == EditorLogic.EditorModes.ADVANCED) + { + //in advanced mode, shift labels to the right + angleSnapLabelRect.xMin = angleSnapLabelLeftOffset + advancedModeOffset; + angleSnapLabelRect.xMax = angleSnapLabelLeftOffset + angleSnapLabelSize + advancedModeOffset; + symmetryLabelRect.xMin = symmetryLabelLeftOffset + advancedModeOffset; + symmetryLabelRect.xMax = symmetryLabelLeftOffset + symmetryLabelSize + advancedModeOffset; + } + else + { + //EditorLogic.EditorModes.SIMPLE + //in simple mode, set back to left position + angleSnapLabelRect.xMin = angleSnapLabelLeftOffset; + angleSnapLabelRect.xMax = angleSnapLabelLeftOffset + angleSnapLabelSize; + symmetryLabelRect.xMin = symmetryLabelLeftOffset; + symmetryLabelRect.xMax = symmetryLabelLeftOffset + symmetryLabelSize; + } + + //Radial mode 'number+R', mirror mode is 'M'/'MM' + if (editor.symmetryMethod == SymmetryMethod.Radial) + { + symmetryLabelValue = (editor.symmetryMode + 1) + "R"; + } + else if (editor.symmetryMethod == SymmetryMethod.Mirror) + { + symmetryLabelValue = (editor.symmetryMode == 0) ? "M" : "MM"; + } + // Log.Info ("ShowSnapLabels disabling sprites, GameSettings.VAB_USE_ANGLE_SNAP: " + GameSettings.VAB_USE_ANGLE_SNAP.ToString()); + + //always hide stock symmetry and mirror sprites + editor.symmetrySprite.gameObject.SetActive(false); + editor.mirrorSprite.gameObject.SetActive(false); + + // Show Symmetry label + GUI.Label(symmetryLabelRect, symmetryLabelValue, symmetryLabelStyle); + + //if angle snap is on hide stock sprite + if (GameSettings.VAB_USE_ANGLE_SNAP) + { + //editor.angleSnapSprite.Hide (true); + editor.angleSnapSprite.gameObject.SetActive(false); + GUI.Label(angleSnapLabelRect, editor.srfAttachAngleSnap + DegreesSymbol, symmetryLabelStyle); + + } + else + { + //angle snap is off, show stock sprite + // editor.angleSnapSprite.PlayAnim (0); + //editor.angleSnapSprite.Hide (false); + + editor.angleSnapSprite.SetState(0); + editor.angleSnapSprite.gameObject.SetActive(true); + } + } + } + +#endregion + +#endregion + } +} diff --git a/EditorExtensionsRedux/EditorExtensionsRedux.version b/EditorExtensionsRedux/EditorExtensionsRedux.version index f4a173b..bd63693 100644 --- a/EditorExtensionsRedux/EditorExtensionsRedux.version +++ b/EditorExtensionsRedux/EditorExtensionsRedux.version @@ -6,7 +6,7 @@ { "MAJOR":3, "MINOR":3, - "PATCH":8, + "PATCH":9, "BUILD":0 }, "KSP_VERSION": diff --git a/EditorExtensionsRedux/GizmoEvents.cs b/EditorExtensionsRedux/GizmoEvents.cs index c0c8055..d3ac36d 100644 --- a/EditorExtensionsRedux/GizmoEvents.cs +++ b/EditorExtensionsRedux/GizmoEvents.cs @@ -83,13 +83,13 @@ private static void AddListenerToGizmo(string prefabName) private void RotateGizmoSpawned(EditorGizmos.GizmoRotate data) { - Log.Info("Rotate gizmo was spawned"); + Log.Info("Rotate gizmo was spawned 1"); } private void OffsetGizmoSpawned(EditorGizmos.GizmoOffset data) { - Log.Info("Offset gizmo was spawned"); + Log.Info("Offset gizmo was spawned 1"); } @@ -120,7 +120,7 @@ private void RotateGizmoSpawned(EditorGizmos.GizmoRotate data) GizmoEvents.offsetGizmoActive = false; GizmoEvents.gizmosRotate = HighLogic.FindObjectsOfType (); GizmoEvents.gizmoRotateHandle = HighLogic.FindObjectOfType (); - Log.Info("Rotate gizmo was spawned"); + Log.Info("Rotate gizmo was spawned 2"); } @@ -130,7 +130,7 @@ private void OffsetGizmoSpawned(EditorGizmos.GizmoOffset data) GizmoEvents.offsetGizmoActive = true; GizmoEvents.gizmosOffset = HighLogic.FindObjectsOfType (); GizmoEvents.gizmoOffsetHandle = HighLogic.FindObjectOfType (); - Log.Info("Offset gizmo was spawned"); + Log.Info("Offset gizmo was spawned 2"); } } #endif diff --git a/EditorExtensionsRedux/NoOffsetLimits/NoOffsetLimitsBehaviour.cs b/EditorExtensionsRedux/NoOffsetLimits/NoOffsetLimitsBehaviour.cs index 69163c7..b65a1b3 100644 --- a/EditorExtensionsRedux/NoOffsetLimits/NoOffsetLimitsBehaviour.cs +++ b/EditorExtensionsRedux/NoOffsetLimits/NoOffsetLimitsBehaviour.cs @@ -23,7 +23,7 @@ public class FreeOffsetBehaviour : MonoBehaviour private delegate void CleanupFn(); private CleanupFn OnCleanup; - private GizmoOffset gizmo; + private GizmoOffset gizmoOffset; public void Start() { @@ -35,7 +35,7 @@ public void Start() Log.Debug("FreeOffsetBehaviour.Start"); // var st_offset_tweak = (KFSMState)Refl.GetValue(EditorLogic.fetch, "st_offset_tweak"); - var st_offset_tweak = (KFSMState)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.ST_OFFSET_TWEAK); + var st_offset_tweak = (KFSMState)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.ST_OFFSET_TWEAK); KFSMStateChange hookOffsetUpdateFn = (from) => { @@ -49,6 +49,8 @@ public void Start() //public static GizmoOffset Attach(Transform host, Quaternion rotOffset, Callback onMove, Callback onMoved, Camera refCamera = null); + + Quaternion rotOffset = p.attRotation; // this.gizmoOffset = GizmoOffset.Attach(this.selectedPart.transform, @@ -58,13 +60,35 @@ public void Start() // this.audioSource.PlayOneShot(this.tweakGrabClip); + // gizmoRotate = (GizmoRotate)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.GIZMOROTATE); - gizmo = GizmoOffset.Attach(EditorLogic.SelectedPart.transform, + gizmoOffset = GizmoOffset.Attach(EditorLogic.SelectedPart.transform, rotOffset, new Callback((offset) => { - p.transform.position = gizmo.transform.position; +#if false + if (lastSpace != gizmo.CoordSpace) + { + Space cs = gizmo.CoordSpace; + gizmo.SetCoordSystem(lastSpace); + + gizmo.SetCoordSystem(cs); + lastSpace = cs; + } +#endif + if (gizmoOffset.CoordSpace == Space.Self) + { + gizmoOffset.transform.rotation = p.transform.rotation; + } + else + { + gizmoOffset.transform.rotation = Quaternion.identity; + } + + Log.Info("coord sys: " + gizmoOffset.CoordSpace.ToString()); + + p.transform.position = gizmoOffset.transform.position; p.attPos = p.transform.localPosition - p.attPos0; Log.Info("symCount: " + symCount.ToString()); @@ -83,12 +107,11 @@ public void Start() Refl.Invoke(EditorLogic.fetch, EditorExtensions.c.ONOFFSETGIZMOUPDATED, offset); }), EditorLogic.fetch.editorCamera); - //((GizmoOffset)Refl.GetValue(EditorLogic.fetch, "\u0012")).Detach(); - //Refl.SetValue(EditorLogic.fetch, "\u0012", gizmo); + //((GizmoOffset)Refl.GetValue(EditorLogic.fetch, "gizmoOffset")).Detach(); ((GizmoOffset)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.GIZMOOFFSET)).Detach(); //Refl.SetValue(EditorLogic.fetch, "gizmoOffset", gizmo); - Refl.SetValue(EditorLogic.fetch, EditorExtensions.c.GIZMOOFFSET, gizmo); + Refl.SetValue(EditorLogic.fetch, EditorExtensions.c.GIZMOOFFSET, gizmoOffset); }; st_offset_tweak.OnEnter += hookOffsetUpdateFn; OnCleanup += () => @@ -97,6 +120,23 @@ public void Start() }; Log.Debug("Installed."); } +#if true + void LateUpdate() + { + if (GameSettings.Editor_coordSystem.GetKeyUp(false) && !gizmoOffset.IsDragging) + { + if (gizmoOffset.CoordSpace == Space.Self) + { + gizmoOffset.transform.rotation = EditorLogic.SelectedPart.transform.rotation; + } + else + { + gizmoOffset.transform.rotation = Quaternion.identity; + } + + } + } +#endif public void OnDestroy() { diff --git a/NoOffsetLimits/NoOffsetLimitsBehaviour.cs b/EditorExtensionsRedux/NoOffsetLimits/NoOffsetLimitsBehaviour.cs.bak similarity index 51% rename from NoOffsetLimits/NoOffsetLimitsBehaviour.cs rename to EditorExtensionsRedux/NoOffsetLimits/NoOffsetLimitsBehaviour.cs.bak index 0b709b3..0ddfe5a 100644 --- a/NoOffsetLimits/NoOffsetLimitsBehaviour.cs +++ b/EditorExtensionsRedux/NoOffsetLimits/NoOffsetLimitsBehaviour.cs.bak @@ -5,114 +5,37 @@ using EditorGizmos; using UnityEngine; using System.Reflection; -using EditorExtensionsRedux; -// DO NOT ENABLE THIS, OLD CODE -#if false +#if true namespace EditorExtensionsRedux.NoOffsetBehaviour { -#if false /** * Removes limits from offset gizmo. Limits are enforced in EditorLogic::onOffsetGizmoUpdate. This recreates the gizmo after the * st_offset_tweak state is entered and reimplements the offset logic without limits. */ - public class Constantsz - { - - // Following for NoOffsetLimits - public int ST_OFFSET_TWEAK = 73; - public int SYMUPDATEATTACHNODE = 108; - public int GIZMOOFFSET = 66; - public int GIZMOROTATE = 67; - - public int UPDATESYMMETRY = 64; - public int ONOFFSETGIZMOUPDATED = 35; - - - - public bool Init() - { - if (Versioning.version_major == 1 && Versioning.version_minor == 1 && Versioning.Revision == 0 /*&& Versioning.BuildID == 1024 */) - { - - - // NoOffsetLimits - ST_OFFSET_TWEAK = 73; - SYMUPDATEATTACHNODE = 108; - GIZMOOFFSET = 66; - - UPDATESYMMETRY = 64; - ONOFFSETGIZMOUPDATED = 35; - - return true; - } - if (Versioning.version_major == 1 && Versioning.version_minor == 1 && (Versioning.Revision == 1 || Versioning.Revision == 2) /*&& Versioning.BuildID == 1024 */) - { - - - // NoOffsetLimits - ST_OFFSET_TWEAK = 76; - SYMUPDATEATTACHNODE = 111; - GIZMOOFFSET = 69; - - return true; - } - if (Versioning.version_major == 1 && Versioning.version_minor == 1 && Versioning.Revision == 3 /*&& Versioning.BuildID == 1024 */) - { - - // NoOffsetLimits - ST_OFFSET_TWEAK = 76; - SYMUPDATEATTACHNODE = 111; - GIZMOOFFSET = 69; - - UPDATESYMMETRY = 62; - ONOFFSETGIZMOUPDATED = 35; - - - return true; - } - if (Versioning.version_major == 1 && Versioning.version_minor == 2 && Versioning.Revision == 0) - { - - // NoOffsetLimits - ST_OFFSET_TWEAK = 75; - SYMUPDATEATTACHNODE = 110; - GIZMOOFFSET = 68; - - UPDATESYMMETRY = 61; - ONOFFSETGIZMOUPDATED = 35; - - return true; - } - return false; - } - } -#endif - [KSPAddon(KSPAddon.Startup.EditorAny, false)] public class FreeOffsetBehaviour : MonoBehaviour { //private Log log; - //public static Constants c = new Constants(); - public static FreeOffsetBehaviour Instance = null; private delegate void CleanupFn(); private CleanupFn OnCleanup; - private GizmoOffset gizmoOffset; - private GizmoRotate gizmoRotate; + private GizmoOffset gizmoOffset; public void Start() { Instance = this; + if (!EditorExtensions.validVersion) + return; //log = new Log(this.GetType().Name); - Log.Debug("Start"); + Log.Debug("FreeOffsetBehaviour.Start"); // var st_offset_tweak = (KFSMState)Refl.GetValue(EditorLogic.fetch, "st_offset_tweak"); - var st_offset_tweak = (KFSMState)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.ST_OFFSET_TWEAK); + var st_offset_tweak = (KFSMState)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.ST_OFFSET_TWEAK); KFSMStateChange hookOffsetUpdateFn = (from) => { @@ -126,49 +49,42 @@ public void Start() //public static GizmoOffset Attach(Transform host, Quaternion rotOffset, Callback onMove, Callback onMoved, Camera refCamera = null); - // gizmoRotate = GizmoRotate.Attach( - // EditorLogic.SelectedPart.transform, - // this.gizmoPivot, - //new Callback(this.onRotateGizmoUpdate), - //new Callback(this.onRotateGizmoUpdated), - //this.editorCamera); - gizmoRotate = (GizmoRotate)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.GIZMOROTATE); Quaternion rotOffset = p.attRotation; - //============================================================================== + // this.gizmoOffset = GizmoOffset.Attach(this.selectedPart.transform, + // new Callback(this.onOffsetGizmoUpdate), + // new Callback(this.onOffsetGizmoUpdated), + // this.editorCamera); + + // this.audioSource.PlayOneShot(this.tweakGrabClip); + + // gizmoRotate = (GizmoRotate)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.GIZMOROTATE); + gizmoOffset = GizmoOffset.Attach(EditorLogic.SelectedPart.transform, rotOffset, - //=== + new Callback((offset) => { - Space coordSpace = gizmoOffset.CoordSpace; - if (coordSpace == Space.Self) - gizmoOffset.SetCoordSystem(Space.World); - else - gizmoOffset.SetCoordSystem(Space.Self); - p.transform.position = gizmoOffset.transform.position; p.attPos = p.transform.localPosition - p.attPos0; Log.Info("symCount: " + symCount.ToString()); if (symCount != 0) { - // Refl.Invoke(EditorLogic.fetch, "UpdateSymmetry", p, symCount, parent, symUpdateAttachNode); + // Refl.Invoke(EditorLogic.fetch, "UpdateSymmetry", p, symCount, parent, symUpdateAttachNode); Refl.Invoke(EditorLogic.fetch, EditorExtensions.c.UPDATESYMMETRY, p, symCount, parent, symUpdateAttachNode); } GameEvents.onEditorPartEvent.Fire(ConstructionEventType.PartOffsetting, EditorLogic.SelectedPart); - }), - //=== + }), + new Callback((offset) => { //Refl.Invoke(EditorLogic.fetch, "onOffsetGizmoUpdated", offset); Refl.Invoke(EditorLogic.fetch, EditorExtensions.c.ONOFFSETGIZMOUPDATED, offset); - }), - //=== - EditorLogic.fetch.editorCamera); + }), EditorLogic.fetch.editorCamera); //((GizmoOffset)Refl.GetValue(EditorLogic.fetch, "\u0012")).Detach(); //Refl.SetValue(EditorLogic.fetch, "\u0012", gizmo); diff --git a/EditorExtensionsRedux/SettingsWindow.cs b/EditorExtensionsRedux/SettingsWindow.cs index 9eb983d..086a933 100644 --- a/EditorExtensionsRedux/SettingsWindow.cs +++ b/EditorExtensionsRedux/SettingsWindow.cs @@ -169,9 +169,13 @@ void WindowContent (int windowID) b = _config.NoOffsetLimitEnabled; _config.NoOffsetLimitEnabled = GUILayout.Toggle(_config.NoOffsetLimitEnabled, new GUIContent("No Offset Limit enabled")); if (!b && _config.NoOffsetLimitEnabled) - EditorExtensionsRedux.NoOffsetBehaviour.FreeOffsetBehaviour.Instance.Start(); + EditorExtensions.Instance.fob = gameObject.AddComponent(); + if (b && !_config.NoOffsetLimitEnabled) - EditorExtensionsRedux.NoOffsetBehaviour.FreeOffsetBehaviour.Instance.OnDestroy(); + { + Destroy(EditorExtensions.Instance.fob); + NoOffsetBehaviour.FreeOffsetBehaviour.Instance = null; + } GUILayout.EndHorizontal(); diff --git a/EditorExtensionsRedux/SettingsWindow.cs.bak b/EditorExtensionsRedux/SettingsWindow.cs.bak new file mode 100644 index 0000000..9eb983d --- /dev/null +++ b/EditorExtensionsRedux/SettingsWindow.cs.bak @@ -0,0 +1,460 @@ +using System; +using UnityEngine; + +namespace EditorExtensionsRedux +{ + public class SettingsWindow : MonoBehaviour + { + public delegate void WindowDisabledEventHandler (); + + public event WindowDisabledEventHandler WindowDisabled; + + protected virtual void OnWindowDisabled () + { + if (WindowDisabled != null) + WindowDisabled (); + } + + ConfigData _config; + string _configFilePath; + KeyCode _lastKeyPressed = KeyCode.None; + string _windowTitle = string.Empty; + string _version = string.Empty; + + Rect _windowRect = new Rect () { + xMin = Screen.width - 325, + xMax = Screen.width - 50, + yMin = 50, + yMax = 50 //0 height, GUILayout resizes it + }; + + //ctor + public SettingsWindow () + { + //start disabled + this.enabled = false; + } + + void Awake () + { + Log.Debug ("SettingsWindow Awake()"); + } + + void Update () + { + if (Event.current.isKey) { + _lastKeyPressed = Event.current.keyCode; + } + } + + void OnEnable () + { + Log.Debug ("SettingsWindow OnEnable()"); + + if (_config == null || string.IsNullOrEmpty (_configFilePath)) { + this.enabled = false; + } + } + + void CloseWindow () + { + this.enabled = false; + OnWindowDisabled (); + } + + //void OnDisable () + //{ + //} + + void OnGUI () + { + if (Event.current.type == EventType.Layout) { + _windowRect.yMax = _windowRect.yMin; + _windowRect = GUILayout.Window (this.GetInstanceID (), _windowRect, WindowContent, _windowTitle); + } + } + + //void OnDestroy () + //{ + //} + + /// + /// Initializes the window content and enables it + /// + public void Show (ConfigData config, string configFilePath, Version version) + { + Log.Debug ("SettingsWindow Show()"); + _config = config; + _configFilePath = configFilePath; + _windowTitle = string.Format ("Editor Extensions v{0}.{1}", version.Major.ToString (), version.Minor.ToString ()); + + _version = version.ToString (); + this.enabled = true; + } + + private int toolbarInt = 0; + private string[] _toolbarStrings = { "Settings 1", "Settings 2", "Angle Snap" }; + string keyMapToUpdate = string.Empty; + string newAngleString = string.Empty; + public int angleGridIndex = -1; + public string[] angleStrings = new string[] { string.Empty }; + object anglesLock = new object (); + GUILayoutOption[] settingsLabelLayout = new GUILayoutOption[] { GUILayout.MinWidth (150) }; + + void WindowContent (int windowID) + { + toolbarInt = GUILayout.Toolbar (toolbarInt, _toolbarStrings); + + GUILayout.BeginVertical ("box"); + + #region Settings + if (toolbarInt == 0) + { + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Version: " + _version.ToString ()); + GUILayout.EndHorizontal (); + +#if DEBUG + GUILayout.Label ("Debug Build"); + GUILayout.Label ("_lastKeyPressed: " + _lastKeyPressed.ToString ()); +#endif + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Message delay:", settingsLabelLayout); + if (GUILayout.Button ("-")) { + _config.OnScreenMessageTime -= 0.5f; + } + GUILayout.Label (_config.OnScreenMessageTime.ToString (), "TextField"); + if (GUILayout.Button ("+")) { + _config.OnScreenMessageTime += 0.5f; + } + GUILayout.EndHorizontal (); + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Max symmetry:", settingsLabelLayout); + if (GUILayout.Button ("-")) { + _config.MaxSymmetry--; + } + GUILayout.Label (_config.MaxSymmetry.ToString (), "TextField"); + if (GUILayout.Button ("+")) { + _config.MaxSymmetry++; + } + GUILayout.EndHorizontal (); + +// Following contributed by Fwiffo + + GUILayout.BeginHorizontal (GUILayout.ExpandWidth (true)); + _config.RapidZoom = GUILayout.Toggle (_config.RapidZoom, new GUIContent ("Tap then hold for rapid zoom" /* , "Tap the zoom hotkey then quickly hold it to zoom faster"*/)); + GUILayout.EndHorizontal (); + + //GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); + ////GUILayout.Label("Double tap zoom to rapidly cycle:", settingsLabelLayout); + //_config.ZoomCycling = GUILayout.Toggle(_config.ZoomCycling, new GUIContent("Double tap for rapid zoom", "Double tapping zoom keys cycles through preset distances")); + //GUILayout.EndHorizontal(); + +// End of Fwiffo + GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); + bool b = _config.ReRootEnabled; + _config.ReRootEnabled = GUILayout.Toggle(_config.ReRootEnabled, new GUIContent("ReRoot enabled")); + if (!b && _config.ReRootEnabled) + EditorExtensionsRedux.SelectRoot2.SelectRoot2Behaviour.Instance.Start(); + if (b && !_config.ReRootEnabled) + EditorExtensionsRedux.SelectRoot2.SelectRoot2Behaviour.Instance.OnDestroy(); + + GUILayout.EndHorizontal(); + + + GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); + b = _config.NoOffsetLimitEnabled; + _config.NoOffsetLimitEnabled = GUILayout.Toggle(_config.NoOffsetLimitEnabled, new GUIContent("No Offset Limit enabled")); + if (!b && _config.NoOffsetLimitEnabled) + EditorExtensionsRedux.NoOffsetBehaviour.FreeOffsetBehaviour.Instance.Start(); + if (b && !_config.NoOffsetLimitEnabled) + EditorExtensionsRedux.NoOffsetBehaviour.FreeOffsetBehaviour.Instance.OnDestroy(); + + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); + b = _config.FineAdjustEnabled; + _config.FineAdjustEnabled = GUILayout.Toggle(_config.FineAdjustEnabled, new GUIContent("Fine Adjust enabled")); + GUILayout.EndHorizontal(); + + + GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); + _config.AnglesnapModIsToggle = GUILayout.Toggle(_config.AnglesnapModIsToggle, new GUIContent("Anglesnap + Mod Toggles")); + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); + _config.CycleSymmetryModeModIsToggle = GUILayout.Toggle(_config.CycleSymmetryModeModIsToggle, new GUIContent("Cycle Symmetry Mode + Mod Toggles")); + GUILayout.EndHorizontal(); + + } + #endregion + #region Fine Adjust settings + if (toolbarInt == 1) + { + + if (keyMapToUpdate == string.Empty) { + GUILayout.Label ("Click button and press key to change"); + } else { + GUILayout.Label ("Waiting for key"); + } + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Surface attachment:", settingsLabelLayout); + if (keyMapToUpdate == "am" && _lastKeyPressed != KeyCode.None) { + _config.KeyMap.AttachmentMode = _lastKeyPressed; + keyMapToUpdate = string.Empty; + } + if (GUILayout.Button (_config.KeyMap.AttachmentMode.ToString ())) { + _lastKeyPressed = KeyCode.None; + keyMapToUpdate = "am"; + } + GUILayout.EndHorizontal (); + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Vertical snap:", settingsLabelLayout); + if (keyMapToUpdate == "vs" && _lastKeyPressed != KeyCode.None) { + _config.KeyMap.VerticalSnap = _lastKeyPressed; + keyMapToUpdate = string.Empty; + } + if (GUILayout.Button (_config.KeyMap.VerticalSnap.ToString ())) { + _lastKeyPressed = KeyCode.None; + keyMapToUpdate = "vs"; + } + GUILayout.EndHorizontal (); + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Horizontal snap:", settingsLabelLayout); + if (keyMapToUpdate == "hs" && _lastKeyPressed != KeyCode.None) { + _config.KeyMap.HorizontalSnap = _lastKeyPressed; + keyMapToUpdate = string.Empty; + } + if (GUILayout.Button (_config.KeyMap.HorizontalSnap.ToString ())) { + _lastKeyPressed = KeyCode.None; + keyMapToUpdate = "hs"; + } + GUILayout.EndHorizontal (); + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Strut/fuel align:", settingsLabelLayout); + if (keyMapToUpdate == "cpa" && _lastKeyPressed != KeyCode.None) { + _config.KeyMap.CompoundPartAlign = _lastKeyPressed; + keyMapToUpdate = string.Empty; + } + if (GUILayout.Button (_config.KeyMap.CompoundPartAlign.ToString ())) { + _lastKeyPressed = KeyCode.None; + keyMapToUpdate = "cpa"; + } + GUILayout.EndHorizontal (); + + + GUILayout.BeginHorizontal(); + GUILayout.Label("Toggle ReRoot:", settingsLabelLayout); + if (keyMapToUpdate == "reroot" && _lastKeyPressed != KeyCode.None) + { + _config.KeyMap.ToggleReRoot = _lastKeyPressed; + keyMapToUpdate = string.Empty; + } + if (GUILayout.Button(_config.KeyMap.ToggleReRoot.ToString())) + { + _lastKeyPressed = KeyCode.None; + keyMapToUpdate = "reroot"; + } + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + GUILayout.Label("Toggle No Offset Limit:", settingsLabelLayout); + if (keyMapToUpdate == "nooffsetlimit" && _lastKeyPressed != KeyCode.None) + { + _config.KeyMap.ToggleNoOffsetLimit = _lastKeyPressed; + keyMapToUpdate = string.Empty; + } + if (GUILayout.Button(_config.KeyMap.ToggleNoOffsetLimit.ToString())) + { + _lastKeyPressed = KeyCode.None; + keyMapToUpdate = "nooffsetlimit"; + } + GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Reset camera:", settingsLabelLayout); + if (keyMapToUpdate == "rc" && _lastKeyPressed != KeyCode.None) { + _config.KeyMap.ResetCamera = _lastKeyPressed; + keyMapToUpdate = string.Empty; + } + if (GUILayout.Button (_config.KeyMap.ResetCamera.ToString ())) { + _lastKeyPressed = KeyCode.None; + keyMapToUpdate = "rc"; + } + GUILayout.EndHorizontal (); + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Zoom Selected:", settingsLabelLayout); + if (keyMapToUpdate == "zs" && _lastKeyPressed != KeyCode.None) { + _config.KeyMap.ZoomSelected = _lastKeyPressed; + keyMapToUpdate = string.Empty; + } + if (GUILayout.Button (_config.KeyMap.ZoomSelected.ToString ())) { + _lastKeyPressed = KeyCode.None; + keyMapToUpdate = "zs"; + } + GUILayout.EndHorizontal (); +#if true + + GUILayout.Label ("Fine Adjust Keys"); + + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Up:", settingsLabelLayout); + if (keyMapToUpdate == "up" && _lastKeyPressed != KeyCode.None) { + _config.KeyMap.Up = _lastKeyPressed; + keyMapToUpdate = string.Empty; + } + if (GUILayout.Button (_config.KeyMap.Up.ToString ())) { + _lastKeyPressed = KeyCode.None; + keyMapToUpdate = "up"; + } + GUILayout.EndHorizontal (); + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Down:", settingsLabelLayout); + if (keyMapToUpdate == "down" && _lastKeyPressed != KeyCode.None) { + _config.KeyMap.Down = _lastKeyPressed; + keyMapToUpdate = string.Empty; + } + if (GUILayout.Button (_config.KeyMap.Down.ToString ())) { + _lastKeyPressed = KeyCode.None; + keyMapToUpdate = "down"; + } + GUILayout.EndHorizontal (); + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Left:", settingsLabelLayout); + if (keyMapToUpdate == "left" && _lastKeyPressed != KeyCode.None) { + _config.KeyMap.Left = _lastKeyPressed; + keyMapToUpdate = string.Empty; + } + if (GUILayout.Button (_config.KeyMap.Left.ToString ())) { + _lastKeyPressed = KeyCode.None; + keyMapToUpdate = "left"; + } + GUILayout.EndHorizontal (); + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Right:", settingsLabelLayout); + if (keyMapToUpdate == "right" && _lastKeyPressed != KeyCode.None) { + _config.KeyMap.Right = _lastKeyPressed; + keyMapToUpdate = string.Empty; + } + if (GUILayout.Button (_config.KeyMap.Right.ToString ())) { + _lastKeyPressed = KeyCode.None; + keyMapToUpdate = "right"; + } + GUILayout.EndHorizontal (); + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Forward:", settingsLabelLayout); + if (keyMapToUpdate == "fwd" && _lastKeyPressed != KeyCode.None) { + _config.KeyMap.Forward = _lastKeyPressed; + keyMapToUpdate = string.Empty; + } + if (GUILayout.Button (_config.KeyMap.Forward.ToString ())) { + _lastKeyPressed = KeyCode.None; + keyMapToUpdate = "fwd"; + } + GUILayout.EndHorizontal (); + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Back:", settingsLabelLayout); + if (keyMapToUpdate == "back" && _lastKeyPressed != KeyCode.None) { + _config.KeyMap.Back = _lastKeyPressed; + keyMapToUpdate = string.Empty; + } + if (GUILayout.Button (_config.KeyMap.Back.ToString ())) { + _lastKeyPressed = KeyCode.None; + keyMapToUpdate = "back"; + } + GUILayout.EndHorizontal (); +#endif + } + +#endregion + +#region angle snap values settings + if (toolbarInt == 2) { + + try { + lock (anglesLock) { + foreach (float a in _config.AngleSnapValues) { + if (a != 0.0f) { + GUILayout.BeginHorizontal (); + GUILayout.Label (a.ToString (), settingsLabelLayout); + if (GUILayout.Button ("Remove")) { + _config.AngleSnapValues.Remove (a); + } + GUILayout.EndHorizontal (); + } + } + } + + GUILayout.BeginHorizontal (); + GUILayout.Label ("Add angle: "); + newAngleString = GUILayout.TextField (newAngleString); + if (GUILayout.Button ("Add")) { + float newAngle = 0.0f; + + if (!string.IsNullOrEmpty (newAngleString) && float.TryParse (newAngleString, out newAngle)) { + lock (anglesLock) { + if (newAngle > 0.0f && newAngle <= 90.0f && _config.AngleSnapValues.IndexOf (newAngle) == -1) { + _config.AngleSnapValues.Add (newAngle); + _config.AngleSnapValues.Sort (); + } + } + } + + } + GUILayout.EndHorizontal (); + + } +#if DEBUG + catch (Exception ex) { + //potential for some intermittent locking/threading issues here + //Debug only to avoid log spam + Log.Error ("Error updating AngleSnapValues: " + ex.Message); + } +#else + catch(Exception){ + //just ignore the error and continue since it's non-critical + } +#endif + } + +#endregion + + GUILayout.EndVertical ();//end main content + + GUILayout.BeginHorizontal (); + if (GUILayout.Button ("Close")) { + //reload config to reset any unsaved changes? + //_config = ConfigManager.LoadConfig (_configFilePath); + CloseWindow (); + } + + if (GUILayout.Button ("Defaults")) { + _config = ConfigManager.CreateDefaultConfig (_configFilePath, _version); + } + + if (GUILayout.Button ("Save")) { + ConfigManager.SaveConfig (_config, _configFilePath); + CloseWindow (); + } + GUILayout.EndHorizontal (); + + GUI.DragWindow (); + } + + } +} + diff --git a/EditorExtensionsRedux/ShowAngleSnaps.cs b/EditorExtensionsRedux/ShowAngleSnaps.cs index e4f9f40..a78859d 100644 --- a/EditorExtensionsRedux/ShowAngleSnaps.cs +++ b/EditorExtensionsRedux/ShowAngleSnaps.cs @@ -36,6 +36,11 @@ public ShowAngleSnaps() this.enabled = false; } + public bool isVisible() + { + return this.enabled; + } + void Awake() { Log.Debug("ShowAngleSnaps Awake()"); @@ -85,6 +90,10 @@ public void Show(ConfigData config) this.enabled = true; } + public void Hide() + { + CloseWindow(); + } // private string[] _toolbarStrings = { "Settings 1", "Settings 2", "Angle Snap" }; string keyMapToUpdate = string.Empty; diff --git a/NoOffsetLimits/License.txt b/NoOffsetLimits/License.txt deleted file mode 100644 index 51ba5a3..0000000 --- a/NoOffsetLimits/License.txt +++ /dev/null @@ -1,7 +0,0 @@ -Copyright (C) 2015 FW Industries - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/NoOffsetLimits/Logging.cs b/NoOffsetLimits/Logging.cs deleted file mode 100644 index 28a89b0..0000000 --- a/NoOffsetLimits/Logging.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using UnityEngine; -using System.Diagnostics; - -namespace NoOffsetBehaviour -{ - public static class Log - { - const string MessagePrefix = "EditorExtensions: "; - - [Conditional("DEBUG")] - public static void Debug (string message) - { - UnityEngine.Debug.Log (MessagePrefix + message); - } - [ConditionalAttribute("DEBUG")] - public static void Info(string message) - { - UnityEngine.Debug.Log (MessagePrefix + message); - } - - public static void Error(string message) - { - UnityEngine.Debug.LogError (MessagePrefix + message); - } - - public static void Warn(string message) - { - UnityEngine.Debug.LogWarning (MessagePrefix + message); - } - } -} - diff --git a/NoOffsetLimits/NoOffsetLimits.csproj b/NoOffsetLimits/NoOffsetLimits.csproj deleted file mode 100644 index 9c1c960..0000000 --- a/NoOffsetLimits/NoOffsetLimits.csproj +++ /dev/null @@ -1,69 +0,0 @@ - - - - - Debug - AnyCPU - {3368802B-CBC6-4DEA-A68C-3B238C43AF4A} - Library - Properties - NoOffsetLimits - NoOffsetLimits - v3.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - R:\KSP_1.1.4_dev\KSP_x64_Data\Managed\Assembly-CSharp.dll - - - R:\KSP_1.1.4_dev\KSP_x64_Data\Managed\Assembly-CSharp-firstpass.dll - - - R:\KSP_1.1.4_dev\KSP_x64_Data\Managed\System.dll - - - R:\KSP_1.1.4_dev\KSP_x64_Data\Managed\UnityEngine.dll - - - R:\KSP_1.1.4_dev\KSP_x64_Data\Managed\UnityEngine.UI.dll - - - - - {BCEB9124-390F-49D5-9022-49EBAB6446F7} - EditorExtensionsRedux - - - - - \ No newline at end of file diff --git a/NoOffsetLimits/Properties/AssemblyInfo.cs b/NoOffsetLimits/Properties/AssemblyInfo.cs deleted file mode 100644 index cda98a7..0000000 --- a/NoOffsetLimits/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("NoOffsetLimits")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("NoOffsetLimits")] -[assembly: AssemblyCopyright("Copyright © 2016")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("3368802b-cbc6-4dea-a68c-3b238c43af4a")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.65")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/NoOffsetLimits/Refl.cs b/NoOffsetLimits/Refl.cs deleted file mode 100644 index 5bcae37..0000000 --- a/NoOffsetLimits/Refl.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Reflection; -using UnityEngine; - - -namespace NoOffsetBehaviour -{ - public static class Refl - { - public static FieldInfo GetField(object obj, int fieldNum) - { - int c = 0; - foreach (FieldInfo FI in obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) - { - if (c == fieldNum) - return FI; - c++; - } - throw new Exception("No such field: " + obj.GetType() + "#" + fieldNum.ToString()); - } - public static object GetValue(object obj, int fieldNum) - { - return GetField(obj, fieldNum).GetValue(obj); - } - public static void SetValue(object obj, int fieldNum, object value) - { - GetField(obj, fieldNum).SetValue(obj, value); - } - - - public static MethodInfo GetMethod(object obj, int methodnum) - { - - MethodInfo[] m = obj.GetType().GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - int c = 0; - foreach (MethodInfo FI in m) - { - if (c == methodnum) - return FI; - c++; - } - - throw new Exception("No such method: " + obj.GetType() + "#" + methodnum); - } - public static object Invoke(object obj, int methodnum, params object[] args) - { - return GetMethod(obj, methodnum).Invoke(obj, args); - - } - - } -} diff --git a/README.md b/README.md index d69ec25..ef2b82f 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,9 @@ ## ## +## Changes in 3.3.9 + Fixed (the right way) the no offset tool for local/absolute offsets + ## changes in 3.3.8 Fixed issue where NoOffsetLimits was not working upon entry into editor Added ability to disable Fine Adjust window