Пример #1
0
        private void drawLineBetweenBadParts()
        {
            float dist = ASPFuelLine.distanceBetweenParts(badStartTank, badDestTank);

            line.SetPosition(1, Vector3.forward * dist);

            line.transform.parent           = badStartTank.transform;
            line.transform.localPosition    = Vector3.zero;
            line.transform.localEulerAngles = Vector3.zero;

            //line.SetPosition(1, line.transform.InverseTransformPoint(badDestTank.transform.position).normalized);
            line.transform.localRotation = Quaternion.LookRotation(line.transform.InverseTransformPoint(badDestTank.transform.position).normalized);
            lineObj.layer = lineLayer;
            line.enabled  = true;
        }
Пример #2
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;
                    }
                }
            }
        }
Пример #3
0
        static public void AsaparagusTheShip(string partName)
        {
            var editor = EditorLogic.fetch;

            // Get all the parts of the ship
            var parts = editor.ship.parts;

            ASPConsoleStuff.printPartList("All parts of ship", "Part", parts);

            // Find the symmetrical fuel tanks
            List <Part> tanks = findFuelTanks(parts);

            ASPConsoleStuff.AAprint("=== Tanks ===");

            // print out a list of tanks, partners, and children
            foreach (Part p in tanks)
            {
                ASPConsoleStuff.printPart("Tank", p);
                foreach (Part partner in p.symmetryCounterparts)
                {
                    ASPConsoleStuff.printPart("partner", partner);
                }
                foreach (Part child in p.children)
                {
                    ASPConsoleStuff.printPart("child", child);
                }
            }

            // Make chains by following fuel lines
            List <Part> tanksToStage = new List <Part>();

            foreach (Part p in tanks)
            {
                if (ASPFuelLine.countDecouplersToRoot(p) > 0)
                {
                    tanksToStage.Add(p);
                }
            }
            int safetyfactor = 10000;

            while (tanksToStage.Count > 0)
            {
                safetyfactor = safetyfactor - 1;
                if (safetyfactor == 0)
                {
                    AutoAsparagus.osd("Infinite loop in AsaparagusTheShip:tanksToStage.Count, aborting :(");
                    AutoAsparagus.mystate = AutoAsparagus.ASPState.IDLE;
                    return;
                }
                // start a new chain with the first tank
                Part        p     = tanksToStage [0];
                List <Part> chain = new List <Part> ();
                ASPConsoleStuff.printPart("*** Starting new chain with", p);

                // First, follow the fuel lines
                while (p != null)
                {
                    safetyfactor = safetyfactor - 1;
                    if (safetyfactor == 0)
                    {
                        AutoAsparagus.osd("Infinite loop in AsaparagusTheShip:tanksToStage.Count:p!=null, aborting :(");
                        AutoAsparagus.mystate = AutoAsparagus.ASPState.IDLE;
                        return;
                    }
                    ASPConsoleStuff.printPart("Adding to chain at position " + chain.Count, p);
                    chain.Add(p);

                    // don't try to put that tank in another chain
                    tanksToStage.Remove(p);

                    ASPConsoleStuff.printPart("Following fuel line from", p);
                    Part r = p;
                    p = null;
                    foreach (Part target in ASPFuelLine.getFuelLineTargets(r, partName))
                    {
                        if (tanks.Contains(target))                             // we're only following fuel lines in the asparagus
                        {
                            ASPConsoleStuff.printPart("..followed fuel line to", target);
                            p = target;
                        }
                    }
                }

                // Next, look for fuel lines that lead to the start of our chain

                int x = tanksToStage.Count;
                while (x > 0)
                {
                    p = tanksToStage [x - 1];                     // get last tank
                    ASPConsoleStuff.printPart("Checking tank " + x.ToString() + " of " + tanksToStage.Count + " to insert in chain", p);
                    x = x - 1;

                    foreach (Part target in ASPFuelLine.getFuelLineTargets(p, partName))
                    {
                        if (chain [0] == target)
                        {
                            ASPConsoleStuff.printPart("..prepending to chain", target);
                            chain.Insert(0, p);
                            tanksToStage.Remove(p);
                            x = tanksToStage.Count;                             // reset the countdown
                        }
                    }
                }
                ASPConsoleStuff.printPartList("*** Completed chain", "chain part", chain);
                stageChain(chain);
            }

            // Update staging display
            //StageManager.Instance.DeleteEmptyStages ();
            //StageManager.GenerateStagingSequence (parts [0]);
            //StageManager.Instance.SortIcons (true);
            //StageManager.Instance.UpdateStageGroups (false);

            //foreach (KSP.UI.Screens.StageGroup s in StageManager.Instance.Stages) {
            //}
        }