public void addStatic(StaticObject obj)
        {
            String bodyName = ((CelestialBody) obj.getSetting("CelestialBody")).bodyName;
            String groupName = (string) obj.getSetting("Group");

            //Debug.Log("Creating object in group " + obj.groupName);

            if (!groupList.ContainsKey(bodyName))
                groupList.Add(bodyName, new Dictionary<string, StaticGroup>());

            if (!groupList[bodyName].ContainsKey(groupName))
            {
                //StaticGroup group = new StaticGroup(bodyName, groupName);
                StaticGroup group = new StaticGroup(groupName, bodyName);
                //Ungrouped objects get individually cached. New acts the same as Ungrouped but stores unsaved statics instead.
                if (groupName == "Ungrouped")
                {
                    group.alwaysActive = true;
                    //group.active = true;
                }

                group.active = true;

                groupList[bodyName].Add(groupName, group);
            }

            groupList[bodyName][groupName].addStatic(obj);
        }
        public void changeGroup(StaticObject obj, string newGroup)
        {
            String bodyName = ((CelestialBody)obj.getSetting("CelestialBody")).bodyName;
            String groupName = (string)obj.getSetting("Group");

            groupList[bodyName][groupName].removeStatic(obj);
            obj.setSetting("Group", newGroup);
            addStatic(obj);
        }
        public void deleteObject(StaticObject obj)
        {
            if (selectedObject == obj)
            {
                deselectObject();
            }

            staticDB.deleteObject(obj);
        }
        public static void CacheHangaredCraft(StaticObject obj)
        {
            string sInStorage = (string)obj.getSetting("InStorage");
            string sInStorage2 = (string)obj.getSetting("TargetID");
            string sInStorage3 = (string)obj.getSetting("TargetType");

            foreach (Vessel vVesselStored in FlightGlobals.Vessels)
            {
                if (vVesselStored == null) continue;
                if (!vVesselStored.loaded) continue;
                if (vVesselStored.vesselType == VesselType.SpaceObject) continue;
                if (vVesselStored.vesselType == VesselType.Debris) continue;
                if (vVesselStored.vesselType == VesselType.EVA) continue;
                if (vVesselStored.vesselType == VesselType.Flag) continue;
                if (vVesselStored.vesselType == VesselType.Unknown) continue;

                string sHangarSpace = "None";
                // If a vessel is hangared
                if (vVesselStored.id.ToString() == sInStorage)
                    sHangarSpace = "InStorage";
                if (vVesselStored.id.ToString() == sInStorage2)
                    sHangarSpace = "TargetID";
                if (vVesselStored.id.ToString() == sInStorage3)
                    sHangarSpace = "TargetType";

                if (sHangarSpace != "None")
                {
                    if (vVesselStored == FlightGlobals.ActiveVessel)
                    {
                        // Craft has been taken control
                        // Empty the hangar
                        obj.setSetting(sHangarSpace, "None");
                        PersistenceUtils.saveStaticPersistence(obj);
                    }
                    else
                    {
                        // Hide the vessel - it is in the hangar
                        if (vVesselStored != null)
                        {
                            foreach (Part p in vVesselStored.Parts)
                            {
                                if (p != null && p.gameObject != null)
                                    p.gameObject.SetActive(false);
                                else
                                    continue;
                            }

                            vVesselStored.MakeInactive();
                            vVesselStored.enabled = false;

                            if (vVesselStored.loaded)
                                vVesselStored.Unload();
                        }
                    }
                }
            }
        }
        public void drawManager(StaticObject obj)
        {
            KKWindow = new GUIStyle(GUI.skin.window);
            KKWindow.padding = new RectOffset(3, 3, 5, 5);

            if (obj != null)
            {
                if (selectedObject != obj)
                    EditorGUI.updateSelection(obj);
            }

            managerRect = GUI.Window(0xB00B1E2, managerRect, drawBaseManagerWindow, "", KKWindow);
        }
        public static StaticObject NearestBarracks(StaticObject selectedFacility, bool bUnassigned = true)
        {
            StaticObject soNearest = null;
            float fKerbals = 0f;

            foreach (StaticObject obj in KerbalKonstructs.instance.getStaticDB().getAllStatics())
            {
                //if ((string)obj.model.getSetting("DefaultFacilityType") == "None") continue;

                if ((string)obj.getSetting("FacilityType") != "Barracks")
                {
                    if ((string)obj.model.getSetting("DefaultFacilityType") != "Barracks") continue;
                }

                if (obj.pqsCity.sphere == FlightGlobals.currentMainBody.pqsController)
                {
                    var dist = Vector3.Distance(selectedFacility.gameObject.transform.position, obj.gameObject.transform.position);
                    if (dist > 5000f) continue;
                }
                else
                    continue;

                if (bUnassigned)
                {
                    fKerbals = (float)obj.getSetting("ProductionRateCurrent");

                    if (fKerbals < 1) continue;
                    else
                    {
                        soNearest = obj;
                        break;
                    }
                }
                else
                {
                    if ((float)obj.getSetting("StaffCurrent") == 1) continue;

                    if (((float)obj.getSetting("StaffCurrent") -1) == (float)obj.getSetting("ProductionRateCurrent"))
                        continue;
                    else
                    {
                        soNearest = obj;
                        break;
                    }
                }
            }

            return soNearest;
        }
        public static float StationHasLOS(StaticObject soFacility, Vessel vVessel)
        {
            if (vVessel == null || soFacility == null)
            {
                Debug.Log("KK: StationHasLOS borked");
                return 0f;
            }

            float fHasLOS = 0f;
            Vector3d FacPos = soFacility.gameObject.transform.position;
            Vector3d VesselPos = vVessel.gameObject.transform.position;

            Vector3d vDirection = (VesselPos - FacPos);

            float fAngle = Vector3.Angle(soFacility.gameObject.transform.up, vDirection);
            fHasLOS = fAngle;

            return fHasLOS;
        }
        public static void doFuelIn(StaticObject selectedObject)
        {
            if (SelectedResource == null) return;
            if (SelectedTank == null) return;

            string sResource1 = getResourceAlt(selectedObject, "LiquidFuel");
            string sResource2 = getResourceAlt(selectedObject, "Oxidizer");
            string sResource3 = getResourceAlt(selectedObject, "Monopropellant");

            if (SelectedResource.resourceName == sResource3 && !bMoFIn) return;
            if (SelectedResource.resourceName == sResource1 && !bLqFIn) return;
            if (SelectedResource.resourceName == sResource2 && !bOxFIn) return;

            if (SelectedResource.resourceName == sResource3 && fMoFCurrent >= fMoFMax) return;
            if (SelectedResource.resourceName == sResource1 && fLqFCurrent >= fLqFMax) return;
            if (SelectedResource.resourceName == sResource2 && fOxFCurrent >= fOxFMax) return;

            if (SelectedResource.amount <= 0) return;

            float dStaticFuel;

            SelectedResource.amount = SelectedResource.amount - fTransferRate;
            if (SelectedResource.amount < 0) SelectedResource.amount = 0;

            if (SelectedResource.resourceName == sResource3)
            {
                dStaticFuel = ((float)selectedObject.getSetting("MoFCurrent")) + fTransferRate;
                if (dStaticFuel > fMoFMax) dStaticFuel = fMoFMax;
                selectedObject.setSetting("MoFCurrent", dStaticFuel);
            }
            if (SelectedResource.resourceName == sResource1)
            {
                dStaticFuel = ((float)selectedObject.getSetting("LqFCurrent")) + fTransferRate;
                if (dStaticFuel > fLqFMax) dStaticFuel = fLqFMax;
                selectedObject.setSetting("LqFCurrent", dStaticFuel);
            }
            if (SelectedResource.resourceName == sResource2)
            {
                dStaticFuel = ((float)selectedObject.getSetting("OxFCurrent")) + fTransferRate;
                if (dStaticFuel > fOxFMax) dStaticFuel = fOxFMax;
                selectedObject.setSetting("OxFCurrent", dStaticFuel);
            }
        }
        public void CreatePreviewInstance(StaticModel model)
        {
            StaticObject obj = new StaticObject();
            obj.gameObject = GameDatabase.Instance.GetModel(model.path + "/" + model.getSetting("mesh"));
            obj.setSetting("RadiusOffset", (float)FlightGlobals.ActiveVessel.altitude);
            obj.setSetting("CelestialBody", KerbalKonstructs.instance.getCurrentBody());
            obj.setSetting("Group", "Ungrouped");
            obj.setSetting("RadialPosition", KerbalKonstructs.instance.getCurrentBody().transform.InverseTransformPoint(FlightGlobals.ActiveVessel.transform.position));
            obj.setSetting("RotationAngle", 0f);
            obj.setSetting("Orientation", Vector3.up);
            obj.setSetting("VisibilityRange", 25000f);

            obj.model = model;

            KerbalKonstructs.instance.getStaticDB().addStatic(obj);
            obj.spawnObject(true, true);
            // KerbalKonstructs.instance.selectObject(obj, false);
            currPreview = obj;
        }
        public static string GetHangarSpace(StaticObject soHangar, int iMax = 2)
        {
            string sSpace = "None";

            if ((string)soHangar.getSetting("InStorage") == "None")
            {
                sSpace = "InStorage";
                if (iMax < 2) return sSpace;
            }
            else
                if ((string)soHangar.getSetting("TargetID") == "None")
                {
                    sSpace = "TargetID";
                    if (iMax == 2) return sSpace;
                }
                else
                    if ((string)soHangar.getSetting("TargetType") == "None")
                        sSpace = "TargetType";

            return sSpace;
        }
        public static void DestroyPreviewInstance(StaticObject soInstance)
        {
            if (soInstance != null)
            {
                if (currPreview != null)
                {
                    if (currPreview == soInstance)
                        currPreview = null;
                }

                KerbalKonstructs.instance.deleteObject(soInstance);

            }
            else
            {
                if (currPreview != null)
                {
                    KerbalKonstructs.instance.deleteObject(currPreview);
                    currPreview = null;
                }
            }
        }
Example #12
0
 public void addStatic(StaticObject obj)
 {
     childObjects.Add(obj);
     updateCacheSettings();
 }
        public static void StaffingInterface(StaticObject selectedFacility)
        {
            LabelInfo = new GUIStyle(GUI.skin.label);
            LabelInfo.normal.background = null;
            LabelInfo.normal.textColor = Color.white;
            LabelInfo.fontSize = 13;
            LabelInfo.fontStyle = FontStyle.Bold;
            LabelInfo.padding.left = 3;
            LabelInfo.padding.top = 0;
            LabelInfo.padding.bottom = 0;

            BoxInfo = new GUIStyle(GUI.skin.box);
            BoxInfo.normal.textColor = Color.cyan;
            BoxInfo.fontSize = 13;
            BoxInfo.padding.top = 2;
            BoxInfo.padding.bottom = 1;
            BoxInfo.padding.left = 5;
            BoxInfo.padding.right = 5;
            BoxInfo.normal.background = null;

            ButtonSmallText = new GUIStyle(GUI.skin.button);
            ButtonSmallText.fontSize = 12;
            ButtonSmallText.fontStyle = FontStyle.Normal;

            fStaff = (float)selectedFacility.getSetting("StaffCurrent");
            fMaxStaff = (float)selectedFacility.getSetting("StaffMax");

            bIsBarracks = false;

            if ((string)selectedFacility.getSetting("FacilityType") == "Barracks")
                bIsBarracks = true;
            else
                if ((string)selectedFacility.model.getSetting("DefaultFacilityType") == "Barracks")
                    bIsBarracks = true;

            if (fMaxStaff < 1)
            {
                fMaxStaff = (float)selectedFacility.model.getSetting("DefaultStaffMax");

                if (fMaxStaff < 1)
                {
                    selectedFacility.setSetting("StaffMax", (float)0);
                    //PersistenceUtils.saveStaticPersistence(selectedFacility);
                }
                else
                {
                    selectedFacility.setSetting("StaffMax", (float)fMaxStaff);
                    PersistenceUtils.saveStaticPersistence(selectedFacility);
                }
            }

            if (fMaxStaff > 0)
            {
                float fHireFundCost = 5000;
                float fFireRefund = 2500;
                float fFireRepCost = 1;

                bIsOpen = ((string)selectedFacility.getSetting("OpenCloseState") == "Open");

                if (!bIsOpen)
                {
                    iFundsOpen2 = (float)selectedFacility.model.getSetting("cost");
                    if (iFundsOpen2 == 0) bIsOpen = true;
                }

                GUILayout.Space(5);

                float CountCurrent = fStaff;
                float CountEmpty = fMaxStaff - fStaff;
                float funassigned = (float)selectedFacility.getSetting("ProductionRateCurrent");

                scrollPos = GUILayout.BeginScrollView(scrollPos, GUILayout.Height(58));
                {
                    GUILayout.BeginHorizontal();
                    {
                        while (CountCurrent > 0)
                        {
                            GUILayout.Box(tKerbal, GUILayout.Width(23));
                            CountCurrent = CountCurrent - 1;
                        }

                        while (CountEmpty > 0)
                        {
                            GUILayout.Box(tNoKerbal, GUILayout.Width(23));
                            CountEmpty = CountEmpty - 1;
                        }
                    }
                    GUILayout.EndHorizontal();
                }
                GUILayout.EndScrollView();

                GUI.enabled = bIsOpen;

                if (!bIsBarracks)
                {
                    GUILayout.Box("Assigned Staff: " + fStaff.ToString("#0") + "/" + fMaxStaff.ToString("#0"), BoxInfo);
                }

                if (bIsBarracks)
                {
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("Staff: " + fStaff.ToString("#0") + "/" + fMaxStaff.ToString("#0"), LabelInfo);
                    GUILayout.FlexibleSpace();
                    GUILayout.Label("Unassigned: " + funassigned.ToString("#0") + "/" + fStaff.ToString("#0"), LabelInfo);
                    GUILayout.EndHorizontal();

                    GUILayout.BeginHorizontal();
                    {
                        if (GUILayout.Button("Hire", ButtonSmallText, GUILayout.Height(20)))
                        {
                            if (fStaff == fMaxStaff)
                            {
                                MiscUtils.HUDMessage("Facility is full.", 10,
                                    3);
                            }
                            else
                            {
                                double currentfunds = Funding.Instance.Funds;

                                if (fHireFundCost > currentfunds)
                                    MiscUtils.HUDMessage("Insufficient funds to hire staff!", 10,
                                        3);
                                else
                                {
                                    selectedFacility.setSetting("StaffCurrent", (float)fStaff + 1);
                                    Funding.Instance.AddFunds(-fHireFundCost, TransactionReasons.Cheating);
                                    selectedFacility.setSetting("ProductionRateCurrent", (float)selectedFacility.getSetting("ProductionRateCurrent") + 1);
                                    PersistenceUtils.saveStaticPersistence(selectedFacility);
                                }
                            }

                        }
                        if (GUILayout.Button("Fire", ButtonSmallText, GUILayout.Height(20)))
                        {
                            if (fStaff < 2)
                            {
                                MiscUtils.HUDMessage("This facility must have at least one caretaker.", 10, 3);
                            }
                            else
                            {
                                if ((float)selectedFacility.getSetting("ProductionRateCurrent") < 1)
                                {
                                    MiscUtils.HUDMessage("All staff are assigned to duties. Staff must be unassigned in order to fire them.", 10, 3);
                                }
                                else
                                {
                                    selectedFacility.setSetting("StaffCurrent", (float)fStaff - 1);
                                    selectedFacility.setSetting("ProductionRateCurrent", (float)selectedFacility.getSetting("ProductionRateCurrent") - 1);
                                    PersistenceUtils.saveStaticPersistence(selectedFacility);
                                    Funding.Instance.AddFunds(fFireRefund, TransactionReasons.Cheating);
                                    Reputation.Instance.AddReputation(-fFireRepCost, TransactionReasons.Cheating);
                                }
                            }
                        }
                    }

                    GUI.enabled = true;
                    GUILayout.EndHorizontal();

                    string sHireTip = " Cost to hire next kerbal: " + fHireFundCost.ToString("#0") + " funds.";
                    string sFireTip = " Refund for firing: " + fFireRefund.ToString("#0") + " funds. Rep lost: " + fFireRepCost.ToString("#0") + ".";

                    GUILayout.Space(2);

                    if (fStaff < fMaxStaff)
                        GUILayout.Box(sHireTip, BoxInfo, GUILayout.Height(16));

                    if (fStaff > 1)
                        GUILayout.Box(sFireTip, BoxInfo, GUILayout.Height(16));
                }
                else
                {
                    GUILayout.BeginHorizontal();
                    {
                        if (GUILayout.Button("Assign", ButtonSmallText, GUILayout.Height(20)))
                        {
                            if (fStaff == fMaxStaff)
                            {
                                MiscUtils.HUDMessage("Facility is fully staffed.", 10,
                                    3);
                            }
                            else
                            {
                                float fAvailable = TotalBarracksPool(selectedFacility);

                                if (fAvailable < 1)
                                {
                                    MiscUtils.HUDMessage("No unassigned staff available.", 10, 3);
                                }
                                else
                                {
                                    StaticObject soNearestBarracks = NearestBarracks(selectedFacility);

                                    if (soNearestBarracks != null)
                                    {
                                        DrawFromBarracks(soNearestBarracks);

                                        selectedFacility.setSetting("StaffCurrent", (float)fStaff + 1);
                                        PersistenceUtils.saveStaticPersistence(selectedFacility);
                                        PersistenceUtils.saveStaticPersistence(soNearestBarracks);
                                    }
                                    else
                                        MiscUtils.HUDMessage("No facility with available staff is nearby.", 10, 3);
                                }
                            }
                        }

                        if (GUILayout.Button("Unassign", ButtonSmallText, GUILayout.Height(20)))
                        {
                            if (fStaff < 2)
                            {
                                MiscUtils.HUDMessage("An open facility must have one resident caretaker.", 10, 3);
                            }
                            else
                            {
                                StaticObject soAvailableSpace = NearestBarracks(selectedFacility, false);

                                if (soAvailableSpace != null)
                                {
                                    UnassignToBarracks(soAvailableSpace);
                                    selectedFacility.setSetting("StaffCurrent", (float)fStaff - 1);
                                    PersistenceUtils.saveStaticPersistence(selectedFacility);
                                    PersistenceUtils.saveStaticPersistence(soAvailableSpace);
                                }
                                else
                                {
                                    MiscUtils.HUDMessage("There's no room left in a barracks or apartment for this kerbal to go to.", 10, 3);
                                }
                            }
                        }
                    }

                    GUI.enabled = true;
                    GUILayout.EndHorizontal();
                }

                GUILayout.Space(5);

                if (KerbalKonstructs.instance.DevMode)
                {
                    fXP = (float)selectedFacility.getSetting("FacilityXP");
                    GUILayout.BeginHorizontal();
                    {
                        GUILayout.Space(5);
                        GUILayout.Label("XP: ", LabelInfo, GUILayout.Height(23), GUILayout.Width(55));

                        float CountCurrentXP = fXP;
                        float CountEmptyXP = 5 - fXP;

                        while (CountCurrentXP > 0)
                        {
                            GUILayout.Button(tXPGained, GUILayout.Height(23), GUILayout.Width(23));
                            CountCurrentXP = CountCurrentXP - 1;
                        }

                        while (CountEmptyXP > 0)
                        {
                            GUILayout.Button(tXPUngained, GUILayout.Height(23), GUILayout.Width(23));
                            CountEmptyXP = CountEmptyXP - 1;
                        }

                        GUILayout.FlexibleSpace();
                        if (GUILayout.Button("Spend", ButtonSmallText, GUILayout.Height(23)))
                        {
                            if (fXP < 1)
                            {
                                MiscUtils.HUDMessage("No XP to spend!", 10, 3);
                            }

                        }
                    }
                    GUILayout.EndHorizontal();
                }
            }
            else
            {
                GUILayout.FlexibleSpace();
                GUILayout.Box("This facility does not require staff assigned to it.", BoxInfo, GUILayout.Height(16));
            }
        }
 public static void UnassignToBarracks(StaticObject selectedFacility)
 {
     selectedFacility.setSetting("ProductionRateCurrent", (float)selectedFacility.getSetting("ProductionRateCurrent") + 1);
 }
        public static float TotalBarracksPool(StaticObject selectedFacility, bool bUnassigned = true)
        {
            float fKerbals = 0f;

            foreach (StaticObject obj in KerbalKonstructs.instance.getStaticDB().getAllStatics())
            {
                //if ((string)obj.model.getSetting("DefaultFacilityType") == "None") continue;

                if ((string)obj.getSetting("FacilityType") != "Barracks")
                {
                    if ((string)obj.model.getSetting("DefaultFacilityType") != "Barracks") continue;
                }

                var dist = Vector3.Distance(selectedFacility.gameObject.transform.position, obj.gameObject.transform.position);
                if (dist > 5000f) continue;

                if (bUnassigned)
                {
                    fKerbals = fKerbals + (float)obj.getSetting("ProductionRateCurrent");
                }
                else
                {
                    fKerbals = fKerbals + ((float)obj.getSetting("StaffCurrent") - (float)obj.getSetting("ProductionRateCurrent"));
                }
            }

            return fKerbals;
        }
        public void deselectObject(Boolean disableCam, Boolean enableColliders)
        {
            if (selectedObject != null)
            {
                selectedObject.editing = false;
                if (enableColliders) selectedObject.ToggleAllColliders(true);

                Color highlightColor = new Color(0, 0, 0, 0);
                selectedObject.HighlightObject(highlightColor);

                selectedObject = null;
            }

            InputLockManager.RemoveControlLock("KKShipLock");
            InputLockManager.RemoveControlLock("KKEVALock");
            InputLockManager.RemoveControlLock("KKCamControls");
            InputLockManager.RemoveControlLock("KKCamModes");

            if (disableCam)
                camControl.disable();
        }
        public static void HangarInterface(StaticObject selectedFacility)
        {
            DeadButton = new GUIStyle(GUI.skin.button);
            DeadButton.normal.background = null;
            DeadButton.hover.background = null;
            DeadButton.active.background = null;
            DeadButton.focused.background = null;
            DeadButton.normal.textColor = Color.white;
            DeadButton.hover.textColor = Color.white;
            DeadButton.active.textColor = Color.white;
            DeadButton.focused.textColor = Color.white;
            DeadButton.fontSize = 14;
            DeadButton.fontStyle = FontStyle.Bold;

            DeadButtonRed = new GUIStyle(GUI.skin.button);
            DeadButtonRed.normal.background = null;
            DeadButtonRed.hover.background = null;
            DeadButtonRed.active.background = null;
            DeadButtonRed.focused.background = null;
            DeadButtonRed.normal.textColor = Color.red;
            DeadButtonRed.hover.textColor = Color.yellow;
            DeadButtonRed.active.textColor = Color.red;
            DeadButtonRed.focused.textColor = Color.red;
            DeadButtonRed.fontSize = 12;
            DeadButtonRed.fontStyle = FontStyle.Bold;

            BoxNoBorder = new GUIStyle(GUI.skin.box);
            BoxNoBorder.normal.background = null;
            BoxNoBorder.normal.textColor = Color.white;

            Yellowtext = new GUIStyle(GUI.skin.box);
            Yellowtext.normal.textColor = Color.yellow;
            Yellowtext.normal.background = null;

            LabelInfo = new GUIStyle(GUI.skin.label);
            LabelInfo.normal.background = null;
            LabelInfo.normal.textColor = Color.white;
            LabelInfo.fontSize = 13;
            LabelInfo.fontStyle = FontStyle.Bold;
            LabelInfo.padding.left = 3;
            LabelInfo.padding.top = 0;
            LabelInfo.padding.bottom = 0;

            ButtonSmallText = new GUIStyle(GUI.skin.button);
            ButtonSmallText.fontSize = 12;
            ButtonSmallText.fontStyle = FontStyle.Normal;

            sInStorage = (string)selectedFacility.getSetting("InStorage");
            sInStorage2 = (string)selectedFacility.getSetting("TargetID");
            sInStorage3 = (string)selectedFacility.getSetting("TargetType");

            float fMaxMass = (float)selectedFacility.model.getSetting("DefaultFacilityMassCapacity");
            if (fMaxMass < 1) fMaxMass = 25f;
            float fMaxCrafts = (float)selectedFacility.model.getSetting("DefaultFacilityCraftCapacity");
            if (fMaxCrafts < 1 || fMaxCrafts > 3) fMaxCrafts = 2;

            GUILayout.Space(2);
            GUILayout.Label("Where necessary craft are disassembled for storage or re-assembled before being rolled out. Please note that for game purposes, this procedure is instantaneous.", LabelInfo);
            GUILayout.BeginHorizontal();
            GUILayout.Label("Max Craft: " + fMaxCrafts.ToString("#0"), LabelInfo);
            GUILayout.FlexibleSpace();
            GUILayout.Label("Max Mass/Craft: " + fMaxMass.ToString("#0") + " T", LabelInfo);
            GUILayout.EndHorizontal();

            if (sInStorage == null || sInStorage == "")
            {
                sInStorage = "None";
                selectedFacility.setSetting("InStorage", "None");
                PersistenceUtils.saveStaticPersistence(selectedFacility);
            }
            if (sInStorage2 == null || sInStorage2 == "")
            {
                sInStorage2 = "None";
                selectedFacility.setSetting("TargetID", "None");
                PersistenceUtils.saveStaticPersistence(selectedFacility);
            }
            if (sInStorage3 == null || sInStorage3 == "")
            {
                sInStorage3 = "None";
                selectedFacility.setSetting("TargetType", "None");
                PersistenceUtils.saveStaticPersistence(selectedFacility);
            }

            if (sInStorage == "None" && sInStorage2 == "None" && sInStorage3 == "None")
                GUILayout.Label("No craft currently held in this facility.", LabelInfo);
            else
            {
                int iNumberCrafts = NumberCraftHangared(selectedFacility);

                GUILayout.Box("Stored Craft (" + iNumberCrafts.ToString() + "/" + fMaxCrafts.ToString("#0") + ")", Yellowtext);

                List<Vessel> lVessels = FlightGlobals.Vessels;

                foreach (Vessel vVesselStored in lVessels)
                {
                    if (vVesselStored.id.ToString() == sInStorage)
                    {
                        if (GUILayout.Button("" + vVesselStored.vesselName, ButtonSmallText, GUILayout.Height(20)))
                        {
                            // Empty the hangar
                            if (HangarwayIsClear(selectedFacility))
                            {
                                sInStorage = "None";
                                UnhangarCraft(vVesselStored, selectedFacility);
                                sInStorage = "None";
                            }
                            else
                            {
                                MiscUtils.HUDMessage("Cannot roll craft out. Clear the way first!", 10,
                                    3);
                            }
                        }
                        break;
                    }
                }

                foreach (Vessel vVesselStored in lVessels)
                {
                    if (vVesselStored.id.ToString() == sInStorage2)
                    {
                        if (GUILayout.Button("" + vVesselStored.vesselName, ButtonSmallText, GUILayout.Height(20)))
                        {
                            // Empty the hangar
                            if (HangarwayIsClear(selectedFacility))
                            {
                                sInStorage2 = "None";
                                UnhangarCraft(vVesselStored, selectedFacility);
                                sInStorage2 = "None";
                            }
                            else
                            {
                                MiscUtils.HUDMessage("Cannot roll craft out. Clear the way first!", 10,
                                    3);
                            }
                        }
                        break;
                    }
                }

                foreach (Vessel vVesselStored in lVessels)
                {
                    if (vVesselStored.id.ToString() == sInStorage3)
                    {
                        if (GUILayout.Button("" + vVesselStored.vesselName, ButtonSmallText, GUILayout.Height(20)))
                        {
                            // Empty the hangar
                            if (HangarwayIsClear(selectedFacility))
                            {
                                sInStorage3 = "None";
                                UnhangarCraft(vVesselStored, selectedFacility);
                                sInStorage3 = "None";
                            }
                            else
                            {
                                MiscUtils.HUDMessage("Cannot roll craft out. Clear the way first!", 10,
                                    3);
                            }
                        }
                        break;
                    }
                }
            }

            GUILayout.Space(5);

            scrollNearbyCraft = GUILayout.BeginScrollView(scrollNearbyCraft);

            GUILayout.Box("Nearby Craft", Yellowtext);

            bool bNearbyCraft = false;

            foreach (Vessel vVessel in FlightGlobals.Vessels)
            {
                if (vVessel == null) continue;
                if (!vVessel.loaded) continue;
                if (vVessel.vesselType == VesselType.SpaceObject) continue;
                if (vVessel.vesselType == VesselType.Debris) continue;
                if (vVessel.vesselType == VesselType.EVA) continue;
                if (vVessel.vesselType == VesselType.Flag) continue;
                if (vVessel.vesselType == VesselType.Unknown) continue;
                if (vVessel == FlightGlobals.ActiveVessel) continue;
                if (vVessel.situation != Vessel.Situations.LANDED) continue;
                if (vVessel.GetCrewCount() > 0) continue;

                var vDistToCraft = Vector3.Distance(vVessel.gameObject.transform.position, selectedFacility.gameObject.transform.position);
                if (vDistToCraft > 250) continue;

                bNearbyCraft = true;

                if (GUILayout.Button(" " + vVessel.vesselName + " ", ButtonSmallText, GUILayout.Height(20)))
                {
                    float fMass = vVessel.GetTotalMass();

                    if (fMass > fMaxMass)
                    {
                        MiscUtils.HUDMessage("Craft too heavy for this facility. Max " + fMaxMass.ToString("#0") + "T per craft.", 10,
                            3);
                    }
                    else
                    {
                        float fMaxCraft = (float)selectedFacility.model.getSetting("DefaultFacilityCraftCapacity");
                        if (fMaxCraft < 1 || fMaxCraft > 3) fMaxCraft = 2;

                        int iNumberCraft = NumberCraftHangared(selectedFacility);

                        if (iNumberCraft < (int)fMaxCraft)
                            HangarCraft(vVessel, selectedFacility, (int)fMaxCraft);
                        else
                            MiscUtils.HUDMessage("This facility is full. Max craft: " + fMaxCraft.ToString("#0"), 10,
                                3);
                    }
                }
            }

            if (!bNearbyCraft)
                GUILayout.Label("There are no craft close enough to store in this facility.", LabelInfo);

            GUILayout.EndScrollView();

            GUILayout.FlexibleSpace();
        }
        public static Boolean HangarwayIsClear(StaticObject soHangar)
        {
            Boolean bIsClear = true;

            foreach (Vessel vVessel in FlightGlobals.Vessels)
            {
                if (vVessel == null) continue;
                if (!vVessel.loaded) continue;
                if (vVessel.vesselType == VesselType.EVA) continue;
                if (vVessel.vesselType == VesselType.Flag) continue;
                if (vVessel.situation != Vessel.Situations.LANDED) continue;

                var vDistToCraft = Vector3.Distance(vVessel.gameObject.transform.position, soHangar.gameObject.transform.position);
                if (vDistToCraft > 260) continue;
                else
                    bIsClear = false;
            }

            return bIsClear;
        }
        public static void RemoveCorrectCraft(Vessel vVessel, StaticObject soHangar)
        {
            string sSpace = "InStorage";
            string sVesselID = vVessel.id.ToString();

            if (sVesselID == (string)soHangar.getSetting("TargetID"))
                sSpace = "TargetID";
            if (sVesselID == (string)soHangar.getSetting("TargetType"))
                sSpace = "TargetType";

            soHangar.setSetting(sSpace, "None");
            PersistenceUtils.saveStaticPersistence(soHangar);
        }
 public void setSnapTarget(StaticObject obj)
 {
     snapTargetInstance = obj;
 }
        public void selectObject(StaticObject obj, bool isEditing, bool bFocus, bool bPreview)
        {
            if (bFocus)
            {
                InputLockManager.SetControlLock(ControlTypes.ALL_SHIP_CONTROLS, "KKShipLock");
                InputLockManager.SetControlLock(ControlTypes.EVA_INPUT, "KKEVALock");
                InputLockManager.SetControlLock(ControlTypes.CAMERACONTROLS, "KKCamControls");
                InputLockManager.SetControlLock(ControlTypes.CAMERAMODES, "KKCamModes");

                if (selectedObject != null)
                    deselectObject(true, true);

                if (camControl.active)
                    camControl.disable();

                camControl.enable(obj.gameObject);
            }
            else
            {
                if (selectedObject != null)
                    deselectObject(true, true);
            }

            //obj.preview = bPreview;
            if (DebugMode) Debug.Log("KK: obj.preview is " + obj.preview.ToString());

            selectedObject = obj;
            if (DebugMode) Debug.Log("KK: selectedObject.preview is " + selectedObject.preview.ToString());

            if (isEditing)
            {
                selectedObject.editing = true;
                selectedObject.ToggleAllColliders(false);
            }
        }
        public void loadInstances(ConfigNode confconfig, StaticModel model, bool bSecondPass = false)
        {
            if (model == null)
            {
                Debug.Log("KK: Attempting to loadInstances for a null model. Check your model and config.");
                return;
            }

            if (confconfig == null)
            {
                Debug.Log("KK: Attempting to loadInstances for a null ConfigNode. Check your model and config.");
                return;
            }

            foreach (ConfigNode ins in confconfig.GetNodes("Instances"))
            {
                StaticObject obj = new StaticObject();
                obj.model = model;

                obj.gameObject = GameDatabase.Instance.GetModel(model.path + "/" + model.getSetting("mesh"));

                if (obj.gameObject == null)
                {
                    Debug.Log("KK: Could not find " + model.getSetting("mesh") + ".mu! Did the modder forget to include it or did you actually install it?");
                    continue;
                }

                // Fix colliders
                if (!String.IsNullOrEmpty(model.getSetting("concaveColliders").ToString().Trim()))
                {
                    string value = model.getSetting("concaveColliders").ToString();
                    string[] names = value.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                    MeshCollider[] colliders = obj.gameObject.GetComponentsInChildren<MeshCollider>(true);
                    MeshCollider[] concave = value.ToLower() == "all" ? colliders : colliders.Where(c => names.Contains(c.name)).ToArray();
                    foreach (MeshCollider collider in concave)
                    {
                        if (DebugMode) Debug.Log("KK: Making collider " + collider.name + " concave.");
                        collider.convex = false;
                    }
                }

                obj.settings = KKAPI.loadConfig(ins, KKAPI.getInstanceSettings());

                if (obj.settings == null)
                {
                    Debug.Log("KK: Error loading instances for " + model.getSetting("mesh") + ".mu! Check your model and config.");
                    continue;
                }

                if (bSecondPass)
                {
                    Vector3 secondInstanceKey = (Vector3)obj.getSetting("RadialPosition");
                    bool bSpaceOccupied = false;

                    foreach (StaticObject soThis in KerbalKonstructs.instance.getStaticDB().getAllStatics())
                    {
                        Vector3 firstInstanceKey = (Vector3)soThis.getSetting("RadialPosition");

                        if (firstInstanceKey == secondInstanceKey)
                        {
                            string sThisMesh = (string)soThis.model.getSetting("mesh");
                            string sThatMesh = (string)obj.model.getSetting("mesh");

                            if (DebugMode)
                                Debug.Log("KK: Custom instance has a RadialPosition that already has an instance."
                                + sThisMesh + ":"
                                + (string)soThis.getSetting("Group") + ":" + firstInstanceKey.ToString() + "|"
                                + sThatMesh + ":"
                                + (string)obj.getSetting("Group") + ":" + secondInstanceKey.ToString());

                            if (sThisMesh == sThatMesh)
                            {
                                float fThisOffset = (float)soThis.getSetting("RadiusOffset");
                                float fThatOffset = (float)obj.getSetting("RadiusOffset");
                                float fThisRotation = (float)soThis.getSetting("RotationAngle");
                                float fThatRotation = (float)obj.getSetting("RotationAngle");

                                if ((fThisOffset == fThatOffset) && (fThisRotation == fThatRotation))
                                {
                                    bSpaceOccupied = true;
                                    break;
                                }
                                else
                                {
                                    if (DebugMode) Debug.Log("KK: Different rotation or offset. Allowing. Could be a feature of the same model such as a doorway being used. Will cause z tearing probably.");
                                }
                            }
                            else
                            {
                                if (DebugMode) Debug.Log("KK: Different models. Allowing. Could be a terrain foundation or integrator.");
                            }
                        }
                    }

                    if (bSpaceOccupied)
                    {
                        Debug.Log("KK: Attempted to import identical custom instance to same RadialPosition as existing instance. Skipped. Check for duplicate custom statics you have installed. Did you export the custom instances to make a pack? If not, ask the mod-makers if they are duplicating the same stuff as each other.");
                        continue;
                    }
                }

                if (!obj.settings.ContainsKey("LaunchPadTransform") && obj.settings.ContainsKey("LaunchSiteName"))
                {
                    if (model.settings.Keys.Contains("DefaultLaunchPadTransform"))
                    {
                        obj.settings.Add("LaunchPadTransform", model.getSetting("DefaultLaunchPadTransform"));
                    }
                    else
                    {
                        Debug.Log("KK: Launch site is missing a transform. Defaulting to " + obj.getSetting("LaunchSiteName") + "_spawn...");

                        if (obj.gameObject.transform.Find(obj.getSetting("LaunchSiteName") + "_spawn") != null)
                        {
                            obj.settings.Add("LaunchPadTransform", obj.getSetting("LaunchSiteName") + "_spawn");
                        }
                        else
                        {
                            Debug.Log("KK: FAILED: " + obj.getSetting("LaunchSiteName") + "_spawn does not exist! Attempting to use any transform with _spawn in the name.");
                            Transform lastResort = obj.gameObject.transform.Cast<Transform>().FirstOrDefault(trans => trans.name.EndsWith("_spawn"));

                            if (lastResort != null)
                            {
                                Debug.Log("KK: Using " + lastResort.name + " as launchpad transform");
                                obj.settings.Add("LaunchPadTransform", lastResort.name);
                            }
                            else
                            {
                                Debug.Log("KK: All attempts at finding a launchpad transform have failed (╯°□°)╯︵ ┻━┻ This static isn't configured for KK properly. Tell the modder.");
                            }
                        }
                    }
                }

                staticDB.addStatic(obj);
                obj.spawnObject(false, false);

                if (obj.settings.ContainsKey("LaunchPadTransform") && obj.settings.ContainsKey("LaunchSiteName"))
                    LaunchSiteManager.createLaunchSite(obj);
            }
        }
Example #23
0
 public void removeStatic(StaticObject obj)
 {
     childObjects.Remove(obj);
     updateCacheSettings();
 }
        public static void CraftConstructionInterface(StaticObject selectedFacility)
        {
            DeadButton = new GUIStyle(GUI.skin.button);
            DeadButton.normal.background = null;
            DeadButton.hover.background = null;
            DeadButton.active.background = null;
            DeadButton.focused.background = null;
            DeadButton.normal.textColor = Color.white;
            DeadButton.hover.textColor = Color.white;
            DeadButton.active.textColor = Color.white;
            DeadButton.focused.textColor = Color.white;
            DeadButton.fontSize = 14;
            DeadButton.fontStyle = FontStyle.Bold;

            DeadButtonRed = new GUIStyle(GUI.skin.button);
            DeadButtonRed.normal.background = null;
            DeadButtonRed.hover.background = null;
            DeadButtonRed.active.background = null;
            DeadButtonRed.focused.background = null;
            DeadButtonRed.normal.textColor = Color.red;
            DeadButtonRed.hover.textColor = Color.yellow;
            DeadButtonRed.active.textColor = Color.red;
            DeadButtonRed.focused.textColor = Color.red;
            DeadButtonRed.fontSize = 12;
            DeadButtonRed.fontStyle = FontStyle.Bold;

            BoxNoBorder = new GUIStyle(GUI.skin.box);
            BoxNoBorder.normal.background = null;
            BoxNoBorder.normal.textColor = Color.white;

            Yellowtext = new GUIStyle(GUI.skin.box);
            Yellowtext.normal.textColor = Color.yellow;
            Yellowtext.normal.background = null;

            LabelInfo = new GUIStyle(GUI.skin.label);
            LabelInfo.normal.background = null;
            LabelInfo.normal.textColor = Color.white;
            LabelInfo.fontSize = 13;
            LabelInfo.fontStyle = FontStyle.Bold;
            LabelInfo.padding.left = 3;
            LabelInfo.padding.top = 0;
            LabelInfo.padding.bottom = 0;

            ButtonSmallText = new GUIStyle(GUI.skin.button);
            ButtonSmallText.fontSize = 12;
            ButtonSmallText.fontStyle = FontStyle.Normal;

            string sProducing = (string)selectedFacility.getSetting("Producing");

            if (sProducing == null || sProducing == "")
            {
                sProducing = "None";
                selectedFacility.setSetting("Producing", "None");
                PersistenceUtils.saveStaticPersistence(selectedFacility);
            }

            if (GUILayout.Button("Construct a Craft", ButtonSmallText, GUILayout.Height(20)))
            {
                if (sProducing != "None")
                    MiscUtils.HUDMessage("Only one craft can be constructed at a time.", 10,
                        3);
            }

            GUILayout.Space(3);
            if (sProducing == "None")
                GUILayout.Label("No craft currently under construction in this facility.", LabelInfo);
            else
            {
                GUILayout.Label("Craft Under Construction: ", LabelInfo);

                // TO DO List of craft
                GUILayout.Label("Cost of Construction: X Funds / X Materials", LabelInfo);
                GUILayout.Label("Total Construction Time: X hours", LabelInfo);
                GUILayout.Label("Time to Completion: X hours", LabelInfo);
                if (GUILayout.Button("Assign a Kerbonaut Engineer", ButtonSmallText, GUILayout.Height(20)))
                { }
            }

            if (GUILayout.Button("Upgrade Production", ButtonSmallText, GUILayout.Height(20)))
            { }

            float fAvailableMaterials;

            fAvailableMaterials = (float)selectedFacility.getSetting("PrOreCurrent");

            GUILayout.Space(3);
            GUILayout.Label("Available Materials (Processed Ore): " + fAvailableMaterials.ToString("#0.0"), LabelInfo);
        }
        public static void HangarCraft(Vessel vVessel, StaticObject soHangar, int iMax = 2)
        {
            string sSpace = GetHangarSpace(soHangar, iMax);

            if (sSpace == "None")
            {
                MiscUtils.HUDMessage("This facility is full.", 10,
                    3);
            }
            else
            {
                string sVesselID = vVessel.id.ToString();
                soHangar.setSetting(sSpace, sVesselID);
                PersistenceUtils.saveStaticPersistence(soHangar);

                // Hangar the vessel - hide it
                foreach (Part p in vVessel.Parts)
                {
                    if (p != null && p.gameObject != null)
                        p.gameObject.SetActive(false);
                    else
                        continue;
                }

                vVessel.MakeInactive();
                vVessel.enabled = false;
                vVessel.Unload();
            }
        }
 public static void DrawFromBarracks(StaticObject selectedFacility)
 {
     selectedFacility.setSetting("ProductionRateCurrent", (float)selectedFacility.getSetting("ProductionRateCurrent") - 1);
 }
        public void ToggleEditor()
        {
            if (selectedObject != null)
                deselectObject(true, true);

            showEditor = !showEditor;

            if (snapTargetInstance != null)
            {
                Color highlightColor = new Color(0, 0, 0, 0);
                snapTargetInstance.HighlightObject(highlightColor);
                snapTargetInstance = null;
            }
        }
        public void deleteObject(StaticObject obj)
        {
            if (selectedObject == obj)
                deselectObject(true, false);

            InputLockManager.RemoveControlLock("KKShipLock");
            InputLockManager.RemoveControlLock("KKEVALock");
            InputLockManager.RemoveControlLock("KKCamControls");
            InputLockManager.RemoveControlLock("KKCamModes");

            if (camControl.active) camControl.disable();

            if (snapTargetInstance == obj)
                snapTargetInstance = null;

            if (DebugMode) Debug.Log("KK: deleteObject");

            staticDB.deleteObject(obj);
        }
        public static int NumberCraftHangared(StaticObject soHangar)
        {
            int iNumber = 0;

            if ((string)soHangar.getSetting("InStorage") != "None") iNumber = iNumber + 1;
            if ((string)soHangar.getSetting("TargetID") != "None") iNumber = iNumber + 1;
            if ((string)soHangar.getSetting("TargetType") != "None") iNumber = iNumber + 1;

            return iNumber;
        }
        public static void FuelTanksInterface(StaticObject selectedObject)
        {
            string smessage = "";
            ScreenMessageStyle smsStyle = (ScreenMessageStyle)2;

            string sFacilityName = (string)selectedObject.model.getSetting("title");
            string sFacilityRole = (string)selectedObject.getSetting("FacilityType");

            fLqFMax = (float)selectedObject.model.getSetting("LqFMax");
            fLqFCurrent = (float)selectedObject.getSetting("LqFCurrent");
            fOxFMax = (float)selectedObject.model.getSetting("OxFMax");
            fOxFCurrent = (float)selectedObject.getSetting("OxFCurrent");
            fMoFMax = (float)selectedObject.model.getSetting("MoFMax");
            fMoFCurrent = (float)selectedObject.getSetting("MoFCurrent");

            float fPurchaseRate = fTransferRate * 100f;

            LabelInfo = new GUIStyle(GUI.skin.label);
            LabelInfo.normal.background = null;
            LabelInfo.normal.textColor = Color.white;
            LabelInfo.fontSize = 13;
            LabelInfo.fontStyle = FontStyle.Bold;
            LabelInfo.padding.left = 3;
            LabelInfo.padding.top = 0;
            LabelInfo.padding.bottom = 0;

            BoxInfo = new GUIStyle(GUI.skin.box);
            BoxInfo.normal.textColor = Color.cyan;
            BoxInfo.fontSize = 13;
            BoxInfo.padding.top = 2;
            BoxInfo.padding.bottom = 1;
            BoxInfo.padding.left = 5;
            BoxInfo.padding.right = 5;
            BoxInfo.normal.background = null;

            if (!FlightGlobals.ActiveVessel.Landed)
            {
                GUILayout.Box("A vessel must be landed to use this facility.", BoxInfo);
                LockFuelTank();
            }

            var vDist = Vector3.Distance(selectedObject.gameObject.transform.position, FlightGlobals.ActiveVessel.transform.position);

            if ((double)vDist < KerbalKonstructs.instance.facilityUseRange)
            { }
            else
            {
                GUILayout.Box("A vessel must be in range to use this facility.", BoxInfo);
                LockFuelTank();
            }

            GUILayout.Space(3);
            GUILayout.Label("Fuel Stores", LabelInfo);
            scrollPos4 = GUILayout.BeginScrollView(scrollPos4);
            if (fLqFMax > 0)
            {
                GUILayout.Label("LiquidFuel", LabelInfo);

                GUILayout.BeginHorizontal();
                GUILayout.Label("Max ", LabelInfo);
                GUI.enabled = false;
                GUILayout.TextField(string.Format("{0}", fLqFMax), GUILayout.Height(18));
                GUI.enabled = true;
                GUILayout.Label("Current ", LabelInfo);
                GUI.enabled = false;
                GUILayout.TextField(fLqFCurrent.ToString("#0.00"), GUILayout.Height(18));
                GUI.enabled = true;
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                if (GUILayout.Button("Order", GUILayout.Height(18)))
                {
                    LockFuelTank();
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                    bOrderedLqF = true;
                }
                GUI.enabled = !bLqFIn;
                if (GUILayout.Button("In", GUILayout.Height(18)))
                {
                    bLqFIn = true;
                    bLqFOut = false;
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                }
                GUI.enabled = !bLqFOut;
                if (GUILayout.Button("Out", GUILayout.Height(18)))
                {
                    bLqFOut = true;
                    bLqFIn = false;
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                }
                GUI.enabled = bLqFIn || bLqFOut;
                if (GUILayout.Button("Stop", GUILayout.Height(18)))
                {
                    bLqFIn = false;
                    bLqFOut = false;
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                    smessage = "Fuel transfer stopped";
                    ScreenMessages.PostScreenMessage(smessage, 10, smsStyle);
                }
                GUI.enabled = true;
                GUILayout.EndHorizontal();
            }

            if (bOrderedLqF)
            {
                GUILayout.BeginHorizontal();
                if (GUILayout.RepeatButton("-", GUILayout.Height(18)))
                {
                    fLqFAmount = (float.Parse(fLqFAmount) - fPurchaseRate).ToString();
                    if ((float.Parse(fLqFAmount)) < 0f) fLqFAmount = "0.00";
                }
                GUI.enabled = false;
                GUILayout.TextField(fLqFAmount, GUILayout.Height(18));
                GUI.enabled = true;
                if (GUILayout.RepeatButton("+", GUILayout.Height(18)))
                {
                    fLqFAmount = (float.Parse(fLqFAmount) + fPurchaseRate).ToString();
                    if ((float.Parse(fLqFAmount)) > (fLqFMax - fLqFCurrent)) fLqFAmount = (fLqFMax - fLqFCurrent).ToString();
                }

                if (GUILayout.Button("Max", GUILayout.Height(18)))
                {
                    fLqFAmount = (fLqFMax - fLqFCurrent).ToString();
                    if ((float.Parse(fLqFAmount)) < 0f) fLqFAmount = "0.00";
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                }

                float flqFPrice = 0.5f;

                float fLqFCost = (float.Parse(fLqFAmount)) * flqFPrice;
                GUILayout.Label("Cost: " + fLqFCost.ToString("#0") + " \\F", LabelInfo);
                if (GUILayout.Button("Buy", GUILayout.Height(18)))
                {
                    if ((float)selectedObject.getSetting("LqFCurrent") + (float.Parse(fLqFAmount)) > fLqFMax)
                    {
                        ScreenMessages.PostScreenMessage("Insufficient fuel capacity!", 10, 0);
                        fLqFAmount = "0.00";
                    }
                    else
                    {
                        if (MiscUtils.isCareerGame())
                        {
                            double currentfunds = Funding.Instance.Funds;

                            if (fLqFCost > currentfunds)
                            {
                                ScreenMessages.PostScreenMessage("Insufficient funds!", 10, 0);
                            }
                            else
                            {
                                Funding.Instance.AddFunds(-fLqFCost, TransactionReasons.Cheating);
                                selectedObject.setSetting("LqFCurrent", (float)selectedObject.getSetting("LqFCurrent") + (float.Parse(fLqFAmount)));
                            }
                        }
                        else
                        {
                            selectedObject.setSetting("LqFCurrent", (float)selectedObject.getSetting("LqFCurrent") + (float.Parse(fLqFAmount)));
                        }
                    }

                    PersistenceUtils.saveStaticPersistence(selectedObject);
                }
                if (GUILayout.Button("Done", GUILayout.Height(18)))
                {
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                    bOrderedLqF = false;
                }
                GUILayout.EndHorizontal();
            }

            if (fOxFMax > 0)
            {
                GUILayout.Label("Oxidizer", LabelInfo);

                GUILayout.BeginHorizontal();
                GUILayout.Label("Max ", LabelInfo);
                GUI.enabled = false;
                GUILayout.TextField(string.Format("{0}", fOxFMax), GUILayout.Height(18));
                GUI.enabled = true;
                GUILayout.Label("Current ", LabelInfo);
                GUI.enabled = false;
                GUILayout.TextField(fOxFCurrent.ToString("#0.00"), GUILayout.Height(18));
                GUI.enabled = true;
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                if (GUILayout.Button("Order", GUILayout.Height(18)))
                {
                    LockFuelTank();
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                    bOrderedOxF = true;
                }
                GUI.enabled = !bOxFIn;
                if (GUILayout.Button("In", GUILayout.Height(18)))
                {
                    bOxFIn = true;
                    bOxFOut = false;
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                }
                GUI.enabled = !bOxFOut;
                if (GUILayout.Button("Out", GUILayout.Height(18)))
                {
                    bOxFOut = true;
                    bOxFIn = false;
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                }
                GUI.enabled = bOxFIn || bOxFOut;
                if (GUILayout.Button("Stop", GUILayout.Height(18)))
                {
                    bOxFIn = false;
                    bOxFOut = false;
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                    smessage = "Fuel transfer stopped";
                    ScreenMessages.PostScreenMessage(smessage, 10, smsStyle);
                }
                GUI.enabled = true;
                GUILayout.EndHorizontal();
            }

            if (bOrderedOxF)
            {
                GUILayout.BeginHorizontal();
                if (GUILayout.RepeatButton("-", GUILayout.Height(18)))
                {
                    fOxFAmount = (float.Parse(fOxFAmount) - fPurchaseRate).ToString();
                    if ((float.Parse(fOxFAmount)) < 0f) fOxFAmount = "0.00";
                }
                GUI.enabled = false;
                GUILayout.TextField(fOxFAmount, GUILayout.Height(18));
                GUI.enabled = true;
                if (GUILayout.RepeatButton("+", GUILayout.Height(18)))
                {
                    fOxFAmount = (float.Parse(fOxFAmount) + fPurchaseRate).ToString();
                    if ((float.Parse(fOxFAmount)) > (fOxFMax - fOxFCurrent)) fOxFAmount = (fOxFMax - fOxFCurrent).ToString();
                }

                if (GUILayout.Button("Max", GUILayout.Height(18)))
                {
                    fOxFAmount = (fOxFMax - fOxFCurrent).ToString();
                    if ((float.Parse(fOxFAmount)) < 0f) fOxFAmount = "0.00";
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                }

                float fOxFPrice = 1.5f;

                float fOxFCost = (float.Parse(fOxFAmount)) * fOxFPrice;
                GUILayout.Label("Cost: " + fOxFCost.ToString("#0") + " \\F", LabelInfo);
                if (GUILayout.Button("Buy", GUILayout.Height(18)))
                {
                    if ((float)selectedObject.getSetting("OxFCurrent") + (float.Parse(fOxFAmount)) > fOxFMax)
                    {
                        ScreenMessages.PostScreenMessage("Insufficient fuel capacity!", 10, 0);
                        fOxFAmount = "0.00";
                    }
                    else
                    {
                        if (MiscUtils.isCareerGame())
                        {
                            double currentfunds = Funding.Instance.Funds;

                            if (fOxFCost > currentfunds)
                            {
                                ScreenMessages.PostScreenMessage("Insufficient funds!", 10, 0);
                            }
                            else
                            {
                                Funding.Instance.AddFunds(-fOxFCost, TransactionReasons.Cheating);
                                selectedObject.setSetting("OxFCurrent", (float)selectedObject.getSetting("OxFCurrent") + (float.Parse(fOxFAmount)));
                            }
                        }
                        else
                        {
                            selectedObject.setSetting("OxFCurrent", (float)selectedObject.getSetting("OxFCurrent") + (float.Parse(fOxFAmount)));
                        }
                    }

                    PersistenceUtils.saveStaticPersistence(selectedObject);
                }
                if (GUILayout.Button("Done", GUILayout.Height(18)))
                {
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                    bOrderedOxF = false;
                }
                GUILayout.EndHorizontal();
            }

            if (fMoFMax > 0)
            {
                GUILayout.Label("Monopropellant", LabelInfo);

                GUILayout.BeginHorizontal();
                GUILayout.Label("Max ", LabelInfo);
                GUI.enabled = false;
                GUILayout.TextField(string.Format("{0}", fMoFMax), GUILayout.Height(18));
                GUI.enabled = true;
                GUILayout.Label("Current ", LabelInfo);
                GUI.enabled = false;
                GUILayout.TextField(fMoFCurrent.ToString("#0.00"), GUILayout.Height(18));
                GUI.enabled = true;
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                if (GUILayout.Button("Order", GUILayout.Height(18)))
                {
                    LockFuelTank();
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                    bOrderedMoF = true;
                }
                GUI.enabled = !bMoFIn;
                if (GUILayout.Button("In", GUILayout.Height(18)))
                {
                    bMoFIn = true;
                    bMoFOut = false;
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                }
                GUI.enabled = !bMoFOut;
                if (GUILayout.Button("Out", GUILayout.Height(18)))
                {
                    bMoFOut = true;
                    bMoFIn = false;
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                }
                GUI.enabled = bMoFIn || bMoFOut;
                if (GUILayout.Button("Stop", GUILayout.Height(18)))
                {
                    bMoFIn = false;
                    bMoFOut = false;
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                    smessage = "Fuel transfer stopped";
                    ScreenMessages.PostScreenMessage(smessage, 10, smsStyle);
                }
                GUI.enabled = true;
                GUILayout.EndHorizontal();
            }

            if (bOrderedMoF)
            {
                GUILayout.BeginHorizontal();
                if (GUILayout.RepeatButton("-", GUILayout.Height(18)))
                {
                    fMoFAmount = (float.Parse(fMoFAmount) - fPurchaseRate).ToString();
                    if ((float.Parse(fMoFAmount)) < 0f) fMoFAmount = "0.00";
                }
                GUI.enabled = false;
                GUILayout.TextField(fMoFAmount, GUILayout.Height(18));
                GUI.enabled = true;
                if (GUILayout.RepeatButton("+", GUILayout.Height(18)))
                {
                    fMoFAmount = (float.Parse(fMoFAmount) + fPurchaseRate).ToString();
                    if ((float.Parse(fMoFAmount)) > (fMoFMax - fMoFCurrent)) fMoFAmount = (fMoFMax - fMoFCurrent).ToString();
                }

                if (GUILayout.Button("Max", GUILayout.Height(18)))
                {
                    fMoFAmount = (fMoFMax - fMoFCurrent).ToString();
                    if ((float.Parse(fMoFAmount)) < 0f) fMoFAmount = "0.00";
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                }

                float fMoFPrice = 1.2f;

                float fMoFCost = (float.Parse(fMoFAmount)) * fMoFPrice;
                GUILayout.Label("Cost: " + fMoFCost.ToString("#0") + " \\F", LabelInfo);
                if (GUILayout.Button("Buy", GUILayout.Height(18)))
                {
                    if ((float)selectedObject.getSetting("MoFCurrent") + (float.Parse(fMoFAmount)) > fMoFMax)
                    {
                        ScreenMessages.PostScreenMessage("Insufficient fuel capacity!", 10, 0);
                        fMoFAmount = "0.00";
                    }
                    else
                    {
                        if (MiscUtils.isCareerGame())
                        {
                            double currentfunds = Funding.Instance.Funds;

                            if (fMoFCost > currentfunds)
                            {
                                ScreenMessages.PostScreenMessage("Insufficient funds!", 10, 0);
                            }
                            else
                            {
                                Funding.Instance.AddFunds(-fMoFCost, TransactionReasons.Cheating);
                                selectedObject.setSetting("MoFCurrent", (float)selectedObject.getSetting("MoFCurrent") + (float.Parse(fMoFAmount)));
                            }
                        }
                        else
                        {
                            selectedObject.setSetting("MoFCurrent", (float)selectedObject.getSetting("MoFCurrent") + (float.Parse(fMoFAmount)));
                        }
                    }

                    PersistenceUtils.saveStaticPersistence(selectedObject);
                }
                if (GUILayout.Button("Done", GUILayout.Height(18)))
                {
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                    bOrderedMoF = false;
                }
                GUILayout.EndHorizontal();
            }
            GUILayout.EndScrollView();

            if (fOxFMax > 0 || fLqFMax > 0 || fMoFMax > 0)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label("Transfer Rate", LabelInfo);

                GUI.enabled = (fTransferRate != 0.01f);
                if (GUILayout.Button(" x1", GUILayout.Height(18)))
                {
                    fTransferRate = 0.01f;
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                    smessage = "Fuel transfer rate set to x1";
                    ScreenMessages.PostScreenMessage(smessage, 10, smsStyle);
                }
                GUI.enabled = (fTransferRate != 0.04f);
                if (GUILayout.Button(" x4", GUILayout.Height(18)))
                {
                    fTransferRate = 0.04f;
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                    smessage = "Fuel transfer rate set to x4";
                    ScreenMessages.PostScreenMessage(smessage, 10, smsStyle);
                }
                GUI.enabled = (fTransferRate != 0.1f);
                if (GUILayout.Button("x10", GUILayout.Height(18)))
                {
                    fTransferRate = 0.1f;
                    PersistenceUtils.saveStaticPersistence(selectedObject);
                    smessage = "Fuel transfer rate set to x10";
                    ScreenMessages.PostScreenMessage(smessage, 10, smsStyle);
                }
                GUI.enabled = true;
                GUILayout.EndHorizontal();

                if (!FlightGlobals.ActiveVessel.isEVA && FlightGlobals.ActiveVessel.Landed)
                {
                    GUILayout.Label(FlightGlobals.ActiveVessel.vesselName + "'s Tanks", LabelInfo);

                    scrollPos3 = GUILayout.BeginScrollView(scrollPos3);
                    foreach (Part fTank in FlightGlobals.ActiveVessel.parts)
                    {
                        foreach (PartResource rResource in fTank.Resources)
                        {
                            if (rResource.resourceName == "LiquidFuel" || rResource.resourceName == "Oxidizer" || rResource.resourceName == "MonoPropellant")
                            {
                                if (SelectedTank == fTank && SelectedResource == rResource)
                                    PartSelected = true;
                                else
                                    PartSelected = false;

                                GUILayout.BeginHorizontal();
                                GUILayout.Box("" + fTank.gameObject.name, GUILayout.Height(18));
                                GUILayout.Box("" + rResource.resourceName, GUILayout.Height(18));
                                GUILayout.EndHorizontal();

                                GUILayout.BeginHorizontal();
                                GUILayout.Label("Fuel", LabelInfo);
                                GUI.enabled = false;
                                GUILayout.TextField("" + rResource.amount.ToString("#0.00"), GUILayout.Height(18));
                                GUI.enabled = true;

                                GUI.enabled = !PartSelected;
                                if (GUILayout.Button(" Select ", GUILayout.Height(18)))
                                {
                                    SelectedResource = rResource;
                                    SelectedTank = fTank;
                                    PersistenceUtils.saveStaticPersistence(selectedObject);
                                }

                                GUI.enabled = PartSelected;
                                if (GUILayout.Button("Deselect", GUILayout.Height(18)))
                                {
                                    SelectedResource = null;
                                    SelectedTank = null;
                                    PersistenceUtils.saveStaticPersistence(selectedObject);
                                }
                                GUI.enabled = true;
                                GUILayout.EndHorizontal();
                            }
                            else
                                continue;
                        }
                    }
                    GUILayout.EndScrollView();

                    GUI.enabled = true;

                    if (SelectedResource != null && SelectedTank != null)
                    {
                        if (bMoFOut || bOxFOut || bLqFOut)
                            doFuelOut(selectedObject);
                        if (bMoFIn || bOxFIn || bLqFIn)
                            doFuelIn(selectedObject);
                    }
                }
            }

            GUI.DragWindow(new Rect(0, 0, 10000, 10000));
        }
        public static void UnhangarCraft(Vessel vVesselStored, StaticObject soHangar)
        {
            RemoveCorrectCraft(vVesselStored, soHangar);

            // Convert the stored protovessel to a new protovessel.
            // Use BackupVessel because that seems to work and protovessel does not. `\o/`
            ProtoVessel pVessel = vVesselStored.BackupVessel();

            // Get rid of the original hidden vessel - even though it was unloaded KSP still 'sees' the original craft.
            // I do not care why. :|
            vVesselStored.state = Vessel.State.DEAD;

            foreach (Part p in vVesselStored.Parts)
            {
                if (p != null && p.gameObject != null)
                    p.gameObject.DestroyGameObject();
            }

            // Load the new protovessel we made. KSP won't reload (or rather render) a vessel that was unloaded - it will only load a protovessel. :$
            pVessel.Load(FlightDriver.FlightStateCache.flightState);
            // I suspect this is actually a KSP bug since the same crap happens with newly spawned static objects. If you query the active state
            // of the invisible craft, it claims it is active. And no, forcing the renderers doesn't work either.

            // Convert protovessel to vessel
            Vessel vNewVessel = pVessel.vesselRef;

            // Unload then reload the vessel - this seems to be the way to properly re-initialise flightstate etc.
            // Don't do this and you get a craft with a stuck surface velocity reading. It looks like KSP transposes orbital
            // and surface velocity or some other stupid s**t. I don't care.
            // And yes, this time KSP does load an unloaded vessel with no need for protovessel b******t. I don't care why.
            vNewVessel.Unload();
            vNewVessel.Load();
        }
        public static void doFuelOut(StaticObject selectedObject)
        {
            if (SelectedResource == null) return;
            if (SelectedTank == null) return;

            if (SelectedResource.resourceName == "MonoPropellant" && !bMoFOut) return;
            if (SelectedResource.resourceName == "LiquidFuel" && !bLqFOut) return;
            if (SelectedResource.resourceName == "Oxidizer" && !bOxFOut) return;

            if (SelectedResource.resourceName == "MonoPropellant" && fMoFCurrent <= 0) return;
            if (SelectedResource.resourceName == "LiquidFuel" && fLqFCurrent <= 0) return;
            if (SelectedResource.resourceName == "Oxidizer" && fOxFCurrent <= 0) return;

            if (SelectedResource.amount >= SelectedResource.maxAmount) return;

            float dStaticFuel;

            SelectedResource.amount = SelectedResource.amount + fTransferRate;
            if (SelectedResource.amount > SelectedResource.maxAmount) SelectedResource.amount = SelectedResource.maxAmount;

            if (SelectedResource.resourceName == "MonoPropellant")
            {
                dStaticFuel = ((float)selectedObject.getSetting("MoFCurrent")) - fTransferRate;
                if (dStaticFuel < 0) dStaticFuel = 0;
                selectedObject.setSetting("MoFCurrent", dStaticFuel);
            }
            if (SelectedResource.resourceName == "LiquidFuel")
            {
                dStaticFuel = ((float)selectedObject.getSetting("LqFCurrent")) - fTransferRate;
                if (dStaticFuel < 0) dStaticFuel = 0;
                selectedObject.setSetting("LqFCurrent", dStaticFuel);
            }
            if (SelectedResource.resourceName == "Oxidizer")
            {
                dStaticFuel = ((float)selectedObject.getSetting("OxFCurrent")) - fTransferRate;
                if (dStaticFuel < 0) dStaticFuel = 0;
                selectedObject.setSetting("OxFCurrent", dStaticFuel);
            }
        }