Beispiel #1
0
        // called every screen refresh
        private void OnWindow(int windowID)
        {
            GUILayout.BeginHorizontal();
            if (GUILayout.Button(new GUIContent("Asparagus", aspTexture, "Create fuel lines and stage the ship, asparagus-style"), picbutton))
            {
                mystate = ASPState.ADDASP;
                osd("Adding parts in asparagus style...");
            }
            if (GUILayout.Button(new GUIContent("Onion", onionTexture, "Create fuel lines and stage the ship, onion-style"), picbutton))
            {
                mystate = ASPState.ADDONION;
                osd("Adding parts in onion style...");
            }
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            if (GUILayout.Button(new GUIContent("Delete all " + partsWeCanUse [partToUseIndex].title, nofuelTexture, "Delete all " + partsWeCanUse [partToUseIndex].title + " parts on the ship"), picbutton))
            {
                osd("Deleting parts...");
                mystate = ASPState.DELETEFUEL;
            }
            GUILayout.EndHorizontal();

            if (partsWeCanUse.Count() > 1)
            {
                // choose part to use for fuel lines
                GUILayout.BeginHorizontal();
                GUILayout.BeginVertical();
                GUILayout.Label("Part to use:", labelstyle);
                GUILayout.EndVertical();

                GUILayout.BeginVertical();
                int oldPartToUseIndex = partToUseIndex;
                partToUseIndex = GUILayout.SelectionGrid(partToUseIndex, partGrid, 1, togglestyle);
                if (oldPartToUseIndex != partToUseIndex)
                {
                    // shrink window
                    windowRect.height = 0;
                    windowRect.width  = 0;
                }
                GUILayout.EndVertical();
                GUILayout.EndHorizontal();
            }

            if (partTextureNames [partToUseIndex] != null)
            {
                GUILayout.BeginHorizontal();
                GUILayout.BeginVertical();
                GUILayout.Label("Texture:", labelstyle);
                GUILayout.EndVertical();
                GUILayout.BeginVertical();
                int          numTextures = partTextureNames [partToUseIndex].Count();
                GUIContent[] texSelect   = new GUIContent[numTextures];
                for (int i = 0; i < numTextures; i++)
                {
                    texSelect [i] = new GUIContent(partTextureNames [partToUseIndex] [i], partTextures [partToUseIndex] [i]);
                }
                textureIndex = GUILayout.SelectionGrid(textureIndex, texSelect, 2, gridstyle);

                GUILayout.EndVertical();
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                GUILayout.BeginVertical();
                GUILayout.Label("Rainbow:", labelstyle);
                GUILayout.EndVertical();
                GUILayout.BeginVertical();
                rainbow = GUILayout.Toggle(rainbow, new GUIContent("Rainbow", rainbowTexture, "Oh, rainBOWs.  Yeah I like those!"));
                GUILayout.EndVertical();
                GUILayout.EndHorizontal();
            }

            GUILayout.BeginHorizontal();
            GUILayout.Label("Options:");
            GUILayout.EndHorizontal();

            if (SmartStageAvailable)
            {
                GUILayout.BeginHorizontal();
                useSmartStage = GUILayout.Toggle(useSmartStage, new GUIContent(" Use SmartStage", smartstageTexture, "Stage the ship using SmartStage instead of AutoAsparagus"), togglestyle);
                GUILayout.EndHorizontal();
            }
            if (!useSmartStage)
            {
                GUILayout.BeginHorizontal();
                stageParachutes = GUILayout.Toggle(stageParachutes, new GUIContent(" Stage parachutes", parachuteTexture, "Stage parachutes to fire with decouplers"), togglestyle);
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                stagesepratrons = GUILayout.Toggle(stagesepratrons, new GUIContent(" Stage sepratrons", sepratronTexture, "Stage sepratrons to fire with decouplers"), togglestyle);
                GUILayout.EndHorizontal();

                if (!stageLaunchClamps)
                {
                    minheight = windowRect.height;
                    minwidth  = windowRect.width;
                }

                bool oldclamps = stageLaunchClamps;
                GUILayout.BeginHorizontal();
                stageLaunchClamps = GUILayout.Toggle(stageLaunchClamps, new GUIContent(" Stage launch clamps", launchclampTexture, "Move launch clamps to the bottom or next-to-bottom stage"), togglestyle);
                GUILayout.EndHorizontal();
                if (stageLaunchClamps != oldclamps)
                {
                    if (!stageLaunchClamps)
                    {
                        // shrink window to old dimesions
                        windowRect.height = minheight;
                        windowRect.width  = minwidth;
                    }
                }

                if (stageLaunchClamps)
                {
                    GUILayout.BeginHorizontal();
                    //GUILayout.Label ("Launch clamps:");
                    launchClampsStage = GUILayout.SelectionGrid(launchClampsStage, launchClampsText, 1, togglestyle);
                    GUILayout.EndHorizontal();
                }
            }

            GUILayout.BeginHorizontal();
            vizualize = GUILayout.Toggle(vizualize, new GUIContent(" Show visualizations", "Show visualizations such as highlights and levels"), togglestyle);
            GUILayout.EndHorizontal();


#if DEBUG
            GUILayout.BeginHorizontal();
            if (GUILayout.Button("DEV - Reload ship", buttonStyle))
            {
                newReloadShip();
            }
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            if (GUILayout.Button("DEV - Dump the ship", buttonStyle))
            {
                ASPConsoleStuff.ListTheShip();
                tanks = ASPStaging.findFuelTanks(EditorLogic.fetch.ship.Parts);
            }
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            if (GUILayout.Button("DEV - flush output buffer", buttonStyle))
            {
                // flush output buffer
                for (int i = 1; i <= 20; i++)
                {
                    print("");
                }
            }
            GUILayout.EndHorizontal();
#endif


            GUI.DragWindow();

            if (Event.current.type == EventType.Repaint)               // why, Unity, why?
            {
                tooltip = GUI.tooltip;
            }
        }
		// called every screen refresh
		private void OnWindow (int windowID)
		{

			GUILayout.BeginHorizontal ();
			if (GUILayout.Button (new GUIContent ("Asparagus", aspTexture, "Create fuel lines and stage the ship, asparagus-style"), picbutton)) {
				mystate = ASPState.ADDASP;
				osd ("Adding parts in asparagus style...");
			}
			if (GUILayout.Button (new GUIContent ("Onion", onionTexture, "Create fuel lines and stage the ship, onion-style"), picbutton)) {
				mystate = ASPState.ADDONION;
				osd ("Adding parts in onion style...");
			}
			GUILayout.EndHorizontal ();

			GUILayout.BeginHorizontal ();
			if (GUILayout.Button (new GUIContent ("Delete all " + partsWeCanUse [partToUseIndex].title, nofuelTexture, "Delete all " + partsWeCanUse [partToUseIndex].title + " parts on the ship"), picbutton)) {
				osd ("Deleting parts...");
				mystate = ASPState.DELETEFUEL;
			}
			GUILayout.EndHorizontal ();

			if (partsWeCanUse.Count () > 1) {
				// choose part to use for fuel lines
				GUILayout.BeginHorizontal ();
				GUILayout.BeginVertical ();
				GUILayout.Label ("Part to use:", labelstyle);
				GUILayout.EndVertical ();

				GUILayout.BeginVertical ();
				int oldPartToUseIndex = partToUseIndex;
				partToUseIndex = GUILayout.SelectionGrid (partToUseIndex, partGrid, 1, togglestyle);
				if (oldPartToUseIndex != partToUseIndex) {
					// shrink window
					windowRect.height = 0;
					windowRect.width = 0;
				}
				GUILayout.EndVertical ();
				GUILayout.EndHorizontal ();
			}

			if (partTextureNames [partToUseIndex] != null) {
				GUILayout.BeginHorizontal ();
				GUILayout.BeginVertical ();
				GUILayout.Label ("Texture:", labelstyle);
				GUILayout.EndVertical ();
				GUILayout.BeginVertical ();
				int numTextures = partTextureNames [partToUseIndex].Count ();
				GUIContent[] texSelect = new GUIContent[numTextures];
				for (int i = 0; i < numTextures; i++) {
					texSelect [i] = new GUIContent (partTextureNames [partToUseIndex] [i], partTextures [partToUseIndex] [i]);
				}
				textureIndex = GUILayout.SelectionGrid (textureIndex, texSelect, 2, gridstyle);

				GUILayout.EndVertical ();
				GUILayout.EndHorizontal ();

				GUILayout.BeginHorizontal ();
				GUILayout.BeginVertical ();
				GUILayout.Label ("Rainbow:", labelstyle);
				GUILayout.EndVertical ();
				GUILayout.BeginVertical ();
				rainbow = GUILayout.Toggle (rainbow, new GUIContent ("Rainbow", rainbowTexture, "Oh, rainBOWs.  Yeah I like those!"));
				GUILayout.EndVertical ();
				GUILayout.EndHorizontal ();

			}

			GUILayout.BeginHorizontal ();
			GUILayout.Label ("Options:");
			GUILayout.EndHorizontal ();

			if (SmartStageAvailable) {
				GUILayout.BeginHorizontal ();
				useSmartStage = GUILayout.Toggle (useSmartStage, new GUIContent (" Use SmartStage", smartstageTexture, "Stage the ship using SmartStage instead of AutoAsparagus"), togglestyle);
				GUILayout.EndHorizontal ();
			}
			if (!useSmartStage) {
				GUILayout.BeginHorizontal ();
				stageParachutes = GUILayout.Toggle (stageParachutes, new GUIContent (" Stage parachutes", parachuteTexture, "Stage parachutes to fire with decouplers"), togglestyle);
				GUILayout.EndHorizontal ();

				GUILayout.BeginHorizontal ();
				stagesepratrons = GUILayout.Toggle (stagesepratrons, new GUIContent (" Stage sepratrons", sepratronTexture, "Stage sepratrons to fire with decouplers"), togglestyle);
				GUILayout.EndHorizontal ();

				if (!stageLaunchClamps) {
					minheight = windowRect.height;
					minwidth = windowRect.width;
				}

				bool oldclamps = stageLaunchClamps;
				GUILayout.BeginHorizontal ();
				stageLaunchClamps = GUILayout.Toggle (stageLaunchClamps, new GUIContent (" Stage launch clamps", launchclampTexture, "Move launch clamps to the bottom or next-to-bottom stage"), togglestyle);
				GUILayout.EndHorizontal ();
				if (stageLaunchClamps != oldclamps) {
					if (!stageLaunchClamps) {
						// shrink window to old dimesions
						windowRect.height = minheight;
						windowRect.width = minwidth;
					}
				}

				if (stageLaunchClamps) {
					GUILayout.BeginHorizontal ();
					//GUILayout.Label ("Launch clamps:");
					launchClampsStage = GUILayout.SelectionGrid (launchClampsStage, launchClampsText, 1, togglestyle);
					GUILayout.EndHorizontal ();
				}
			}

			if (aspButton != null) {
				GUILayout.BeginHorizontal ();
				useBlizzy = GUILayout.Toggle (useBlizzy, new GUIContent (" Use Blizzy's toolbar", blizzyTexture, "Use Blizzy's toolbar instead of the AppLauncher"), togglestyle);
				GUILayout.EndHorizontal ();
				aspButton.Visible = useBlizzy;
			}

			if (useBlizzy) {
				appButton.VisibleInScenes = ApplicationLauncher.AppScenes.NEVER;
			} else {
				appButton.VisibleInScenes = ApplicationLauncher.AppScenes.VAB | ApplicationLauncher.AppScenes.SPH;
			}

			GUILayout.BeginHorizontal ();
			vizualize = GUILayout.Toggle (vizualize, new GUIContent (" Show visualizations", "Show visualizations such as highlights and levels"), togglestyle);
			GUILayout.EndHorizontal ();

#if DEBUG

			GUILayout.BeginHorizontal ();
			if (GUILayout.Button ("DEV - Reload ship", buttonStyle)) {
				newReloadShip ();
			}
			GUILayout.EndHorizontal ();


			GUILayout.BeginHorizontal ();
			if (GUILayout.Button ("DEV - Dump the ship", buttonStyle)) {
				ASPConsoleStuff.ListTheShip ();
				tanks = ASPStaging.findFuelTanks (EditorLogic.fetch.ship.Parts);
			}
			GUILayout.EndHorizontal ();


			GUILayout.BeginHorizontal ();
			if (GUILayout.Button ("DEV - flush output buffer", buttonStyle)) {
				// flush output buffer
				for (int i = 1; i <= 20; i++) {
					print ("");
				}
			}
			GUILayout.EndHorizontal ();

#endif


			GUI.DragWindow ();

			if (Event.current.type == EventType.Repaint) { // why, Unity, why?
				tooltip = GUI.tooltip;
			}
		}
Beispiel #3
0
        /*public static class PartIconGenerator
         * {
         *      private const string IconHiddenTag = "Icon_Hidden";
         *      private const string KerbalEvaSubstring = "kerbal";
         *
         *      private static readonly int GameObjectLayer = LayerMask.NameToLayer ("PartsList_Icons");
         *      // note to future: if creating icons inside editor, you might want to choose a different layer or translate the camera and object out of frame
         *
         *      private static Camera CreateCamera (int pixelWidth, int pixelHeight, Color backgroundColor)
         *      {
         *              //var camGo = new GameObject ("PartIconGenerator.Camera", typeof(Camera));
         *              //var cam = camGo.camera;
         *              Camera cam = new Camera();
         *
         *              cam.enabled = false;
         *              cam.cullingMask = (1 << GameObjectLayer);
         *              cam.clearFlags = ~CameraClearFlags.Nothing;
         *              cam.nearClipPlane = 0.1f;
         *              cam.farClipPlane = 10f;
         *              cam.orthographic = true;
         *              cam.backgroundColor = backgroundColor;
         *              cam.aspect = pixelWidth / (float)pixelHeight;
         *
         *              // Camera Size = x / ((( x / y ) * 2 ) * s )
         *              cam.orthographicSize = pixelWidth / (((pixelWidth / (float)pixelHeight) * 2f) * pixelHeight);
         *              cam.pixelRect = new Rect (0f, 0f, pixelWidth, pixelHeight);
         *
         *              return cam;
         *      }
         *
         *      private static Light CreateLight ()
         *      {
         *              var light = new GameObject ("PartIconGenerator.Light").AddComponent<Light> ();
         *
         *              light.type = LightType.Directional;
         *              light.color = XKCDColors.OffWhite;
         *              light.cullingMask = 1 << GameObjectLayer;
         *              light.intensity = 0.1f;
         *
         *              return light;
         *      }
         *
         *      private static GameObject CreateIcon (AvailablePart part)
         *      {
         *              // kerbalEVA doesn't seem to init at origin if we aren't explicit
         *              var go = UnityEngine.Object.Instantiate (part.iconPrefab, Vector3.zero, Quaternion.identity) as GameObject;
         *
         *              // The kerbals are initially facing along positive Z so we'll be looking at their backs if we don't
         *              // rotate them around
         *              if (part.name.StartsWith (KerbalEvaSubstring))
         *                      go.transform.rotation = Quaternion.AngleAxis (180f, Vector3.up);
         *
         *              go.SetLayerRecursive (GameObjectLayer);
         *              go.SetActive (true);
         *              return go;
         *      }
         *
         *      private static void AdjustScaleAndCameraPosition (GameObject icon, Camera camera)
         *      {
         *              // get size of prefab
         *              var bounds = CalculateBounds (icon);
         *              float sphereDiameter = Mathf.Max (bounds.size.x, bounds.size.y, bounds.size.z);
         *
         *              // rescale to size 1 unit so that object will take up as much viewspace as possible in ortho cam (with ortho size = 0.5)
         *              var currentScale = icon.transform.localScale;
         *              float scaleFactor = 1f / sphereDiameter;
         *              icon.transform.localScale = currentScale * scaleFactor;
         *
         *              icon.transform.position = -bounds.center * scaleFactor;
         *
         *              camera.transform.position = Vector3.zero;
         *
         *              // back out, else we'll be inside the model (which is scaled at 1 unit so this should be plenty)
         *              camera.transform.Translate (new Vector3 (0f, 0f, -5f), Space.Self);
         *              camera.transform.LookAt (Vector3.zero, Vector3.up);
         *      }
         *
         *
         *      public static Texture2D Create2D (AvailablePart part, int width, int height, Quaternion orientation, Color backgroundColor)
         *      {
         *              var cam = CreateCamera (width, height, backgroundColor);
         *              var icon = CreateIcon (part);
         *              var light = CreateLight ();
         *
         *              var texture = new Texture2D (width, height, TextureFormat.ARGB32, false);
         *              var rt = RenderTexture.GetTemporary (width, height, 24);
         *              var prevRt = RenderTexture.active;
         *
         *              RenderTexture.active = rt;
         *
         *              icon.transform.rotation = orientation * icon.transform.rotation;
         *
         *              AdjustScaleAndCameraPosition (icon, cam);
         *
         *              cam.targetTexture = rt;
         *              cam.pixelRect = new Rect (0f, 0f, width, height); // doc says this should be ignored but doesn't seem to be (?) -- rendered area very small once targetTexture is set
         *              cam.Render ();
         *
         *              texture.ReadPixels (new Rect (0f, 0f, width, height), 0, 0, false);
         *              texture.Apply ();
         *
         *              RenderTexture.active = prevRt;
         *              RenderTexture.ReleaseTemporary (rt);
         *              UnityEngine.Object.DestroyImmediate (light);
         *              UnityEngine.Object.DestroyImmediate (cam);
         *              UnityEngine.Object.DestroyImmediate (icon);
         *
         *              return texture;
         *      }
         *
         *      private static Bounds CalculateBounds (GameObject go)
         *      {
         *              var renderers = go.GetComponentsInChildren<Renderer> (true).ToList ();
         *
         *              if (renderers.Count == 0)
         *                      return default(Bounds);
         *
         *              var boundsList = new List<Bounds> ();
         *
         *              renderers.ForEach (r => {
         *                      if (r.tag == IconHiddenTag)
         *                              return;
         *
         *                      if (r is SkinnedMeshRenderer) {
         *                              var smr = r as SkinnedMeshRenderer;
         *
         *                              // the localBounds of the SkinnedMeshRenderer are initially large enough
         *                              // to accomodate all animation frames; they're likely to be far off for
         *                              // parts that do a lot of animation-related movement (like solar panels expanding)
         *                              //
         *                              // We can get correct mesh bounds by baking the current animation into a mesh
         *                              // note: vertex positions in baked mesh are relative to smr.transform; any scaling
         *                              // is already baked in
         *                              var mesh = new Mesh ();
         *                              smr.BakeMesh (mesh);
         *
         *                              // while the mesh bounds will now be correct, they don't consider orientation at all.
         *                              // If a long part is oriented along the wrong axis in world space, the bounds we'd get
         *                              // here could be very wrong. We need to come up with essentially the renderer bounds:
         *                              // a bounding box in world space that encompasses the mesh
         *                              var m = Matrix4x4.TRS (smr.transform.position, smr.transform.rotation, Vector3.one
         *                                              // remember scale already factored in!
         *                                      );
         *                              var vertices = mesh.vertices;
         *
         *                              var smrBounds = new Bounds (m.MultiplyPoint3x4 (vertices [0]), Vector3.zero);
         *
         *                              for (int i = 1; i < vertices.Length; ++i)
         *                                      smrBounds.Encapsulate (m.MultiplyPoint3x4 (vertices [i]));
         *
         *                              UnityEngine.Object.Destroy (mesh);
         *
         *                              boundsList.Add (smrBounds);
         *                      } else if (r is MeshRenderer) { // note: there are ParticleRenderers, LineRenderers, and TrailRenderers
         *                              r.gameObject.GetComponent<MeshFilter> ().sharedMesh.RecalculateBounds ();
         *                              boundsList.Add (r.bounds);
         *                      }
         *              });
         *
         *              Bounds bounds = boundsList [0];
         *
         *              boundsList.Skip (1).ToList ().ForEach (b => bounds.Encapsulate (b));
         *
         *              return bounds;
         *      }
         * }*/

        private void OnGUI()
        {
            if (tooltipstyle == null)
            {
                setStyles();
            }

            if (osdtime > Time.time)
            {
                float osdheight = osdstyle.CalcSize(new GUIContent(osdmessage)).y;
                GUILayout.BeginArea(new Rect(0, Screen.height * 0.1f, Screen.width, osdheight), osdstyle);
                GUILayout.Label(osdmessage, osdstyle);
                GUILayout.EndArea();
            }

            if (visible)
            {
                if (refreshwait > 0)
                {
                    refreshwait = refreshwait - 1;
                }
                else
                {
                    switch (mystate)
                    {
                    case ASPState.IDLE:

                        EditorLogic   editor = EditorLogic.fetch;
                        ShipConstruct ship   = editor.ship;
                        if (ship != null)
                        {
                            List <Part> parts = ship.parts;
                            if ((parts != null) && (parts.Count > 0) && (parts [0] != null))
                            {
                                parts [0].SetHighlight(false, true);
                                if (tanks == null)
                                {
                                    tanks = ASPStaging.findFuelTanks(parts);
                                }
                                else
                                {
                                    if (vizualize)
                                    {
                                        if ((badDestTank != null) && (badStartTank != null))
                                        {
                                            drawLineBetweenBadParts();
                                        }
                                        foreach (Part p in parts)
                                        {
                                            if (p != null)
                                            {
                                                if ((badStartTank != null) && (p == badStartTank))
                                                {
                                                    Vector3 position = Camera.main.WorldToScreenPoint(p.transform.position);
                                                    GUI.Label(new Rect(position.x, Screen.height - position.y, 200, 30), "Start tank");
                                                    badStartTank.SetHighlightColor(Color.blue);
                                                    badStartTank.SetHighlight(true, false);
                                                    badStartTank.highlightType = Part.HighlightType.AlwaysOn;
                                                }
                                                else if ((badDestTank != null) && (p == badDestTank))
                                                {
                                                    Vector3 position = Camera.main.WorldToScreenPoint(p.transform.position);
                                                    GUI.Label(new Rect(position.x, Screen.height - position.y, 200, 30), "Destination tank");
                                                    badDestTank.SetHighlightColor(Color.blue);
                                                    badDestTank.SetHighlight(true, false);
                                                    badDestTank.highlightType = Part.HighlightType.AlwaysOn;
                                                }
                                                else if (blockingTanks.Contains(p))
                                                {
                                                    Vector3 position = Camera.main.WorldToScreenPoint(p.transform.position);
                                                    GUI.Label(new Rect(position.x, Screen.height - position.y, 200, 30), "X");
                                                    p.SetHighlightColor(Color.red);
                                                    p.SetHighlight(true, false);
                                                    p.highlightType = Part.HighlightType.AlwaysOn;
                                                }
                                                else if (tanks.Contains(p))
                                                {
                                                    // draw labels on the tanks
                                                    Vector3 position = Camera.main.WorldToScreenPoint(p.transform.position);
                                                    string  label    = "L" + ASPFuelLine.countDecouplersToRoot(p).ToString();
#if DEBUG
                                                    //label = label+": "+ASPConsoleStuff.getFriendlyName (p.craftID.ToString ());
#endif
                                                    GUI.Label(new Rect(position.x, Screen.height - position.y, 200, 30), label);
                                                    if ((p != badStartTank) && (p != badDestTank) && (!blockingTanks.Contains(p)))
                                                    {
                                                        p.SetHighlightColor(Color.green);
                                                        p.SetHighlight(true, false);
                                                        p.highlightType = Part.HighlightType.AlwaysOn;
                                                    }
                                                }
                                                else if (ASPStaging.isDecoupler(p))
                                                {
                                                    p.SetHighlightColor(Color.magenta);
                                                    p.SetHighlight(true, false);
                                                    p.highlightType = Part.HighlightType.AlwaysOn;
                                                }
                                                else
                                                {
                                                    p.SetHighlight(false, false);
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            windowRect = ClickThruBlocker.GUILayoutWindow(windowID, clampToScreen(windowRect), OnWindow, "AutoAsparagus " + versionString);

                            mousepos = new Vector2(Input.mousePosition.x, Input.mousePosition.y);

                            if ((tooltip != null) && (tooltip.Length > 0))
                            {
                                GUI.depth = 0;
                                Vector2 size = tooltipstyle.CalcSize(new GUIContent(tooltip));
                                Rect    rect = new Rect(Input.mousePosition.x + 20, (Screen.height - Input.mousePosition.y) + 20, size.x, size.y);
                                rect = clampToScreen(rect);
                                GUILayout.BeginArea(rect);
                                GUILayout.Label(tooltip, tooltipstyle);
                                GUILayout.EndArea();
                            }
                        }
                        break;

                    case ASPState.ERROR:
                        vizualize = true;
                        mystate   = ASPState.IDLE;
                        break;

                    case ASPState.ADDASP:
                        ASPConsoleStuff.ListTheShip();
                        mystate = ASPState.CONNECT;
                        ASPFuelLine.AddAsparagusFuelLines(partsWeCanUse [partToUseIndex], textureIndex, partTexturePaths [partToUseIndex], partTextureNames [partToUseIndex], rainbow);
                        if (mystate == ASPState.CONNECT)
                        {
                            osd("Connecting parts...");
                        }
                        refreshwait = 100;
                        break;

                    case ASPState.ADDONION:
                        ASPConsoleStuff.ListTheShip();
                        mystate = ASPState.CONNECT;
                        ASPFuelLine.AddOnionFuelLines(partsWeCanUse [partToUseIndex], textureIndex, partTexturePaths [partToUseIndex], partTextureNames [partToUseIndex], rainbow);
                        if (mystate == ASPState.CONNECT)
                        {
                            osd("Connecting parts...");
                        }
                        refreshwait = 100;
                        break;

                    case ASPState.CONNECT:
                        ASPFuelLine.connectFuelLines();
                        refreshwait = 100;
                        osd("Refreshing ship...");
                        mystate = ASPState.AFTERCONNECT;
                        break;

                    case ASPState.AFTERCONNECT:
                        newReloadShip();
                        refreshwait = 100;
                        if (useSmartStage)
                        {
                            mystate = ASPState.SMARTSTAGE;
                            osd("Calling SmartStage...");
                            ASPConsoleStuff.AAprint("Calling SmartStage");
                        }
                        else
                        {
                            mystate = ASPState.ADDSTAGES;
                            osd("Adding empty stages...");
                        }
                        break;

                    case ASPState.ADDSTAGES:
                        ASPStaging.AddEmptyStages();
                        mystate = ASPState.STAGE;
                        osd("Staging decouplers...");
                        refreshwait = 10;
                        break;

                    case ASPState.STAGE:
                        ASPStaging.AsaparagusTheShip(partsWeCanUse [partToUseIndex].name);
                        mystate = ASPState.AFTERSTAGE;
                        osd("Decoupler staging done, refreshing...");
                        refreshwait = 10;
                        break;

                    case ASPState.CLAMPS:
                        if (stageLaunchClamps)
                        {
                            ASPStaging.StageLaunchClamps(launchClampsStage);
                        }
                        mystate = ASPState.FINALREFRESH;
                        osd("Done!");
                        refreshwait = 10;
                        break;

                    case ASPState.DELETEFUEL:
                        ASPConsoleStuff.ListTheShip();
                        int count = ASPFuelLine.DeleteAllFuelLines(partsWeCanUse [partToUseIndex].name);
                        newReloadShip();
                        osd(count.ToString() + " parts deleted.");
                        mystate = ASPState.IDLE;
                        break;

                    case ASPState.FINALREFRESH:
                        newReloadShip();
                        mystate = ASPState.IDLE;
                        osd("Done!");
                                                #if DEBUG
                        tanks = ASPStaging.findFuelTanks(EditorLogic.fetch.ship.Parts);
                                                #endif
                        break;

                    case ASPState.AFTERSTAGE:
                        newReloadShip();
                        if (stageLaunchClamps)
                        {
                            osd("Staging launch clamps...");
                            mystate     = ASPState.CLAMPS;
                            refreshwait = 10;
                        }
                        else
                        {
                            osd("Done!");
                            mystate = ASPState.IDLE;
                        }
                        break;

                    case ASPState.SMARTSTAGE:
                        mystate = ASPState.FINALREFRESH;
                        try {
                            computeStagesMethod.Invoke(null, new object[] { });
                        } catch (Exception e) {
                            UnityEngine.Debug.LogError("Error invoking method\n" + e.StackTrace);
                        }
                        osd("Done!");
                        break;
                    }
                }
            }
        }
		/*public static class PartIconGenerator
		{
			private const string IconHiddenTag = "Icon_Hidden";
			private const string KerbalEvaSubstring = "kerbal";

			private static readonly int GameObjectLayer = LayerMask.NameToLayer ("PartsList_Icons");
			// note to future: if creating icons inside editor, you might want to choose a different layer or translate the camera and object out of frame

			private static Camera CreateCamera (int pixelWidth, int pixelHeight, Color backgroundColor)
			{
				//var camGo = new GameObject ("PartIconGenerator.Camera", typeof(Camera));
				//var cam = camGo.camera;
				Camera cam = new Camera();

				cam.enabled = false;
				cam.cullingMask = (1 << GameObjectLayer);
				cam.clearFlags = ~CameraClearFlags.Nothing;
				cam.nearClipPlane = 0.1f;
				cam.farClipPlane = 10f;
				cam.orthographic = true;
				cam.backgroundColor = backgroundColor;
				cam.aspect = pixelWidth / (float)pixelHeight;

				// Camera Size = x / ((( x / y ) * 2 ) * s )
				cam.orthographicSize = pixelWidth / (((pixelWidth / (float)pixelHeight) * 2f) * pixelHeight);
				cam.pixelRect = new Rect (0f, 0f, pixelWidth, pixelHeight);

				return cam;
			}

			private static Light CreateLight ()
			{
				var light = new GameObject ("PartIconGenerator.Light").AddComponent<Light> ();

				light.type = LightType.Directional;
				light.color = XKCDColors.OffWhite;
				light.cullingMask = 1 << GameObjectLayer;
				light.intensity = 0.1f;

				return light;
			}

			private static GameObject CreateIcon (AvailablePart part)
			{
				// kerbalEVA doesn't seem to init at origin if we aren't explicit
				var go = UnityEngine.Object.Instantiate (part.iconPrefab, Vector3.zero, Quaternion.identity) as GameObject;

				// The kerbals are initially facing along positive Z so we'll be looking at their backs if we don't
				// rotate them around
				if (part.name.StartsWith (KerbalEvaSubstring))
					go.transform.rotation = Quaternion.AngleAxis (180f, Vector3.up);

				go.SetLayerRecursive (GameObjectLayer);
				go.SetActive (true);
				return go;
			}

			private static void AdjustScaleAndCameraPosition (GameObject icon, Camera camera)
			{
				// get size of prefab
				var bounds = CalculateBounds (icon);
				float sphereDiameter = Mathf.Max (bounds.size.x, bounds.size.y, bounds.size.z);

				// rescale to size 1 unit so that object will take up as much viewspace as possible in ortho cam (with ortho size = 0.5)
				var currentScale = icon.transform.localScale;
				float scaleFactor = 1f / sphereDiameter;
				icon.transform.localScale = currentScale * scaleFactor;

				icon.transform.position = -bounds.center * scaleFactor;

				camera.transform.position = Vector3.zero;

				// back out, else we'll be inside the model (which is scaled at 1 unit so this should be plenty)
				camera.transform.Translate (new Vector3 (0f, 0f, -5f), Space.Self);
				camera.transform.LookAt (Vector3.zero, Vector3.up);
			}


			public static Texture2D Create2D (AvailablePart part, int width, int height, Quaternion orientation, Color backgroundColor)
			{
				var cam = CreateCamera (width, height, backgroundColor);
				var icon = CreateIcon (part);
				var light = CreateLight ();

				var texture = new Texture2D (width, height, TextureFormat.ARGB32, false);
				var rt = RenderTexture.GetTemporary (width, height, 24);
				var prevRt = RenderTexture.active;

				RenderTexture.active = rt;

				icon.transform.rotation = orientation * icon.transform.rotation;

				AdjustScaleAndCameraPosition (icon, cam);

				cam.targetTexture = rt;
				cam.pixelRect = new Rect (0f, 0f, width, height); // doc says this should be ignored but doesn't seem to be (?) -- rendered area very small once targetTexture is set
				cam.Render ();

				texture.ReadPixels (new Rect (0f, 0f, width, height), 0, 0, false);
				texture.Apply ();

				RenderTexture.active = prevRt;
				RenderTexture.ReleaseTemporary (rt);
				UnityEngine.Object.DestroyImmediate (light);
				UnityEngine.Object.DestroyImmediate (cam);
				UnityEngine.Object.DestroyImmediate (icon);

				return texture;
			}

			private static Bounds CalculateBounds (GameObject go)
			{
				var renderers = go.GetComponentsInChildren<Renderer> (true).ToList ();

				if (renderers.Count == 0)
					return default(Bounds);

				var boundsList = new List<Bounds> ();

				renderers.ForEach (r => {
					if (r.tag == IconHiddenTag)
						return;

					if (r is SkinnedMeshRenderer) {
						var smr = r as SkinnedMeshRenderer;

						// the localBounds of the SkinnedMeshRenderer are initially large enough
						// to accomodate all animation frames; they're likely to be far off for 
						// parts that do a lot of animation-related movement (like solar panels expanding)
						//
						// We can get correct mesh bounds by baking the current animation into a mesh
						// note: vertex positions in baked mesh are relative to smr.transform; any scaling
						// is already baked in
						var mesh = new Mesh ();
						smr.BakeMesh (mesh);

						// while the mesh bounds will now be correct, they don't consider orientation at all.
						// If a long part is oriented along the wrong axis in world space, the bounds we'd get
						// here could be very wrong. We need to come up with essentially the renderer bounds:
						// a bounding box in world space that encompasses the mesh
						var m = Matrix4x4.TRS (smr.transform.position, smr.transform.rotation, Vector3.one
								// remember scale already factored in!
						        );
						var vertices = mesh.vertices;

						var smrBounds = new Bounds (m.MultiplyPoint3x4 (vertices [0]), Vector3.zero);

						for (int i = 1; i < vertices.Length; ++i)
							smrBounds.Encapsulate (m.MultiplyPoint3x4 (vertices [i]));

						UnityEngine.Object.Destroy (mesh);

						boundsList.Add (smrBounds);
					} else if (r is MeshRenderer) { // note: there are ParticleRenderers, LineRenderers, and TrailRenderers
						r.gameObject.GetComponent<MeshFilter> ().sharedMesh.RecalculateBounds ();
						boundsList.Add (r.bounds);
					}
				});

				Bounds bounds = boundsList [0];

				boundsList.Skip (1).ToList ().ForEach (b => bounds.Encapsulate (b));

				return bounds;
			}
		}*/

		private void OnGUI ()
		{
			if (tooltipstyle == null) {
				setStyles ();
			}

			if (osdtime > Time.time) {
				float osdheight = osdstyle.CalcSize (new GUIContent (osdmessage)).y;
				GUILayout.BeginArea (new Rect (0, Screen.height * 0.1f, Screen.width, osdheight), osdstyle);
				GUILayout.Label (osdmessage, osdstyle);
				GUILayout.EndArea ();
			}

			if (visible) {
				if (refreshwait > 0) {
					refreshwait = refreshwait - 1;
				} else {
					switch (mystate) {
					case ASPState.IDLE:

						EditorLogic editor = EditorLogic.fetch;
						ShipConstruct ship = editor.ship;
						if (ship != null) {
							List<Part> parts = ship.parts;
							if ((parts != null) && (parts.Count>0) && (parts [0] != null)) {
								parts [0].SetHighlight (false, true);
								if (tanks == null) {
									tanks = ASPStaging.findFuelTanks (parts);
								} else {
									foreach (Part p in parts) {
										if ((vizualize) && (p != null)) {
											if ((badStartTank != null) && (p == badStartTank)) {
												Vector3 position = Camera.main.WorldToScreenPoint (p.transform.position);
												GUI.Label (new Rect (position.x, Screen.height - position.y, 200, 30), "Start tank");
												badStartTank.SetHighlightColor (Color.blue);
												badStartTank.SetHighlight (true, false);
												badStartTank.highlightType = Part.HighlightType.AlwaysOn;
											} else if ((badDestTank != null) && (p == badDestTank)) {
												Vector3 position = Camera.main.WorldToScreenPoint (p.transform.position);
												GUI.Label (new Rect (position.x, Screen.height - position.y, 200, 30), "Destination tank");
												badDestTank.SetHighlightColor (Color.blue);
												badDestTank.SetHighlight (true, false);
												badDestTank.highlightType = Part.HighlightType.AlwaysOn;
											} else if (blockingTanks.Contains (p)) {
												Vector3 position = Camera.main.WorldToScreenPoint (p.transform.position);
												GUI.Label (new Rect (position.x, Screen.height - position.y, 200, 30), "X");
												p.SetHighlightColor (Color.red);
												p.SetHighlight (true, false);
												p.highlightType = Part.HighlightType.AlwaysOn;
											} else if (tanks.Contains (p)) {
												// draw labels on the tanks
												Vector3 position = Camera.main.WorldToScreenPoint (p.transform.position);
												string label = "L" + ASPFuelLine.countDecouplersToRoot (p).ToString ();
												#if DEBUG
												//label = label+": "+ASPConsoleStuff.getFriendlyName (p.craftID.ToString ());
												#endif
												GUI.Label (new Rect (position.x, Screen.height - position.y, 200, 30), label);
												if ((p != badStartTank) && (p != badDestTank) && (!blockingTanks.Contains (p))) {
													p.SetHighlightColor (Color.green);
													p.SetHighlight (true, false);
													p.highlightType = Part.HighlightType.AlwaysOn;
												}
											} else if (ASPStaging.isDecoupler (p)) {
												p.SetHighlightColor (Color.magenta);
												p.SetHighlight (true, false);
												p.highlightType = Part.HighlightType.AlwaysOn;
											} else {
												p.SetHighlight (false, false);
											}
										}
									}
								}
							}
							
							windowRect = GUILayout.Window (windowID, clampToScreen (windowRect), OnWindow, "AutoAsparagus " + versionString);

							mousepos = new Vector2 (Input.mousePosition.x, Input.mousePosition.y);

							if (HighLogic.LoadedSceneIsEditor) {
								if (windowRect.Contains (mousepos)) {
									if (editorlocked == false) {
										EditorLogic.fetch.Lock (true, true, true, "AutoAsparagus");
										editorlocked = true;
									}
								} else if (editorlocked == true) {
									EditorLogic.fetch.Unlock ("AutoAsparagus");
									editorlocked = false;
								}
							}

							if ((tooltip != null) && (tooltip.Length > 0)) {
								GUI.depth = 0;
								Vector2 size = tooltipstyle.CalcSize (new GUIContent (tooltip));
								Rect rect = new Rect (Input.mousePosition.x + 20, (Screen.height - Input.mousePosition.y) + 20, size.x, size.y);
								rect = clampToScreen (rect);
								GUILayout.BeginArea (rect);
								GUILayout.Label (tooltip, tooltipstyle);
								GUILayout.EndArea ();
							}
						}
						break;
					case ASPState.ERROR:
						mystate = ASPState.IDLE;
						break;
					case ASPState.ADDASP:
						ASPConsoleStuff.ListTheShip ();
						mystate = ASPState.CONNECT;
						ASPFuelLine.AddAsparagusFuelLines (partsWeCanUse [partToUseIndex], textureIndex, partTexturePaths [partToUseIndex], partTextureNames [partToUseIndex], rainbow);
						if (mystate == ASPState.CONNECT) {
							osd ("Connecting parts...");
						}
						refreshwait = 100;
						break;
					case ASPState.ADDONION:
						ASPConsoleStuff.ListTheShip ();
						mystate = ASPState.CONNECT;
						ASPFuelLine.AddOnionFuelLines (partsWeCanUse [partToUseIndex], textureIndex, partTexturePaths [partToUseIndex], partTextureNames [partToUseIndex], rainbow);
						if (mystate == ASPState.CONNECT) {
							osd ("Connecting parts...");
						}
						refreshwait = 100;
						break;
					case ASPState.CONNECT:
						ASPFuelLine.connectFuelLines ();
						refreshwait = 100;
						osd ("Refreshing ship...");
						mystate = ASPState.AFTERCONNECT;
						break;
					case ASPState.AFTERCONNECT:
						newReloadShip ();
						refreshwait = 100;
						if (useSmartStage) {
							mystate = ASPState.SMARTSTAGE;
							osd ("Calling SmartStage...");
							ASPConsoleStuff.AAprint ("Calling SmartStage");
						} else {
							mystate = ASPState.ADDSTAGES;
							osd ("Adding empty stages...");
						}
						break;
					case ASPState.ADDSTAGES:
						ASPStaging.AddEmptyStages ();
						mystate = ASPState.STAGE;
						osd ("Staging decouplers...");
						refreshwait = 10;
						break;
					case ASPState.STAGE:
						ASPStaging.AsaparagusTheShip (partsWeCanUse [partToUseIndex].name);
						mystate = ASPState.AFTERSTAGE;
						osd ("Decoupler staging done, refreshing...");
						refreshwait = 10;
						break;
					case ASPState.CLAMPS:
						if (stageLaunchClamps) {
							ASPStaging.StageLaunchClamps (launchClampsStage);
						}
						mystate = ASPState.FINALREFRESH;
						osd ("Done!");
						refreshwait = 10;
						break;
					case ASPState.DELETEFUEL:
						ASPConsoleStuff.ListTheShip ();
						int count = ASPFuelLine.DeleteAllFuelLines (partsWeCanUse [partToUseIndex].name);
						newReloadShip ();
						osd (count.ToString () + " parts deleted.");
						mystate = ASPState.IDLE;
						break;
					case ASPState.FINALREFRESH:
						newReloadShip ();
						mystate = ASPState.IDLE;
						osd ("Done!");
						#if DEBUG
						tanks = ASPStaging.findFuelTanks (EditorLogic.fetch.ship.Parts);
						#endif
						break;
					case ASPState.AFTERSTAGE:
						newReloadShip ();
						if (stageLaunchClamps) {
							osd ("Staging launch clamps...");
							mystate = ASPState.CLAMPS;
							refreshwait = 10;
						} else {
							osd ("Done!");
							mystate = ASPState.IDLE;
						}
						break;
					case ASPState.SMARTSTAGE:
						mystate = ASPState.FINALREFRESH;
						try {
							computeStagesMethod.Invoke (null, new object[] { });
						} catch (Exception e) {
							UnityEngine.Debug.LogError ("Error invoking method\n" + e.StackTrace);
						}
						osd ("Done!");
						break;
					}
				}
			}
		}