internal void BuildAndLaunchCraft() { // build craft ShipConstruct nship = new ShipConstruct (); nship.LoadShip (craftConfig); int numParts = vessel.parts.Count; if (craftType != CraftType.SubAss) numParts = 0; ShipConstruction.CreateBackup (nship); StrutFixer.HackStruts (nship, numParts); Vector3 offset = nship.Parts[0].transform.localPosition; nship.Parts[0].transform.Translate (-offset); string landedAt = "External Launchpad"; string flag = flagname; Game state = FlightDriver.FlightStateCache; VesselCrewManifest crew = new VesselCrewManifest (); GetLanchTransform (); ShipConstruction.PutShipToGround (nship, launchTransform); ShipConstruction.AssembleForLaunch (nship, landedAt, flag, state, crew); var FlightVessels = FlightGlobals.Vessels; craftVessel = FlightVessels[FlightVessels.Count - 1]; offset = craftVessel.transform.position - launchTransform.position; craftOffset = launchTransform.InverseTransformDirection (offset); craftVessel.Splashed = craftVessel.Landed = false; SetupCraftResources (craftVessel); FlightGlobals.ForceSetActiveVessel (craftVessel); Staging.beginFlight (); FlightGlobals.overrideOrbit = true; StartCoroutine (CaptureCraft ()); }
internal void BuildAndLaunchCraft() { // build craft ShipConstruct nship = new ShipConstruct(); nship.LoadShip(craftConfig); int numParts = builder.vessel.parts.Count; if (craftType != CraftType.SubAss) { numParts = 0; } string landedAt = "External Launchpad"; string flag = flagname; Game game = FlightDriver.FlightStateCache; VesselCrewManifest crew = new VesselCrewManifest(); Box vessel_bounds = GetVesselBox(nship); launchTransform = builder.PlaceShip(nship, vessel_bounds); EnableExtendingLaunchClamps(nship); ShipConstruction.AssembleForLaunch(nship, landedAt, flag, game, crew); var FlightVessels = FlightGlobals.Vessels; craftVessel = FlightVessels[FlightVessels.Count - 1]; FlightGlobals.ForceSetActiveVessel(craftVessel); if (builder.capture) { craftVessel.Splashed = craftVessel.Landed = false; } else { bool loaded = craftVessel.loaded; bool packed = craftVessel.packed; craftVessel.loaded = true; craftVessel.packed = false; craftVessel.GetHeightFromTerrain(); Debug.Log(String.Format("[EL] hft {0}", craftVessel.heightFromTerrain)); craftVessel.loaded = loaded; craftVessel.packed = packed; } Vector3 offset = craftVessel.transform.position - launchTransform.position; craftOffset = launchTransform.InverseTransformDirection(offset); SetupCraftResources(craftVessel); KSP.UI.Screens.StageManager.BeginFlight(); if (builder.capture) { FlightGlobals.overrideOrbit = true; (builder as PartModule).StartCoroutine(CaptureCraft()); } else { state = State.Idle; } }
private void UpdateValues() { if (EditorLogic.fetch != null) { numCrew = 0; maxCrew = 0; int numOccupiedParts = 0; int numOccupiableParts = 0; double foodValue = 0; double waterValue = 0; double oxygenValue = 0; double electricityValue = 0; double wasteValue = 0; double wasteWaterValue = 0; double carbonDioxideValue = 0; foreach (Part part in EditorLogic.fetch.ship.parts) { if (part.CrewCapacity > 0) { ++numOccupiableParts; maxCrew += part.CrewCapacity; } foreach (PartResource partResource in part.Resources) { if (partResource.info.id == globalSettings.FoodId) { foodValue += partResource.amount; } else if (partResource.info.id == globalSettings.WaterId) { waterValue += partResource.amount; } else if (partResource.info.id == globalSettings.OxygenId) { oxygenValue += partResource.amount; } else if (partResource.info.id == globalSettings.ElectricityId) { electricityValue += partResource.amount; } else if (partResource.info.id == globalSettings.WasteId) { wasteValue += partResource.maxAmount; } else if (partResource.info.id == globalSettings.WasteWaterId) { wasteWaterValue += partResource.maxAmount; } else if (partResource.info.id == globalSettings.CO2Id) { carbonDioxideValue += partResource.maxAmount; } } } CrewAssignmentDialog dialog = CrewAssignmentDialog.Instance; if (dialog != null) { VesselCrewManifest manifest = dialog.GetManifest(); if (manifest != null) { foreach (PartCrewManifest pcm in manifest) { int partCrewCount = pcm.GetPartCrew().Count(c => c != null); if (partCrewCount > 0) { ++numOccupiedParts; numCrew += partCrewCount; } } } } food = foodValue.ToString("#,##0.00"); water = waterValue.ToString("#,##0.00"); oxygen = oxygenValue.ToString("#,##0.00"); electricity = electricityValue.ToString("#,##0.00"); maxWaste = wasteValue.ToString("#,##0.00"); maxWasteWater = wasteWaterValue.ToString("#,##0.00"); maxCarbonDioxide = carbonDioxideValue.ToString("#,##0.00"); if (numCrew > 0) { foodDuration = Utilities.FormatTime(foodValue / globalSettings.FoodConsumptionRate / numCrew); waterDuration = Utilities.FormatTime(waterValue / globalSettings.WaterConsumptionRate / numCrew); oxygenDuration = Utilities.FormatTime(oxygenValue / globalSettings.OxygenConsumptionRate / numCrew); electricityDuration = Utilities.FormatTime(electricityValue / CalculateElectricityConsumptionRate(numCrew, numOccupiedParts)); wasteRoom = Utilities.FormatTime(wasteValue / globalSettings.WasteProductionRate / numCrew); wasteWaterRoom = Utilities.FormatTime(wasteWaterValue / globalSettings.WasteWaterProductionRate / numCrew); carbonDioxideRoom = Utilities.FormatTime(carbonDioxideValue / globalSettings.CO2ProductionRate / numCrew); } else { foodDuration = "-"; waterDuration = "-"; oxygenDuration = "-"; electricityDuration = "-"; wasteRoom = "-"; wasteWaterRoom = "-"; carbonDioxideRoom = "-"; } if (maxCrew > 0) { foodDurationMaxCrew = Utilities.FormatTime(foodValue / globalSettings.FoodConsumptionRate / maxCrew); waterDurationMaxCrew = Utilities.FormatTime(waterValue / globalSettings.WaterConsumptionRate / maxCrew); oxygenDurationMaxCrew = Utilities.FormatTime(oxygenValue / globalSettings.OxygenConsumptionRate / maxCrew); electricityDurationMaxCrew = Utilities.FormatTime(electricityValue / CalculateElectricityConsumptionRate(maxCrew, numOccupiableParts)); wasteRoomMaxCrew = Utilities.FormatTime(wasteValue / globalSettings.WasteProductionRate / maxCrew); wasteWaterRoomMaxCrew = Utilities.FormatTime(wasteWaterValue / globalSettings.WasteWaterProductionRate / maxCrew); carbonDioxideRoomMaxCrew = Utilities.FormatTime(carbonDioxideValue / globalSettings.CO2ProductionRate / maxCrew); } else { foodDurationMaxCrew = "-"; waterDurationMaxCrew = "-"; oxygenDurationMaxCrew = "-"; electricityDurationMaxCrew = "-"; wasteRoomMaxCrew = "-"; wasteWaterRoomMaxCrew = "-"; carbonDioxideRoomMaxCrew = "-"; } } }
private void UpdateGUIInfo(ShipConstruct ship) { ResetValues(); if (EditorLogic.fetch != null) { foreach (var part in EditorLogic.fetch.ship.parts) { maxCrew += part.CrewCapacity; } var dialog = KSP.UI.CrewAssignmentDialog.Instance; if (dialog != null) { VesselCrewManifest manifest = dialog.GetManifest(); if (manifest != null) { curCrew = manifest.CrewCount; } } foreach (var part in EditorLogic.fetch.ship.parts) { var hab = part.Modules.GetModule <ModuleHabitation>(); if (hab != null) { var conList = part.Modules.GetModules <BaseConverter>(); var bayList = part.Modules.GetModules <ModuleSwappableConverter>(); if (bayList == null || bayList.Count == 0) { habs.Add(hab); //Certain modules, in addition to crew capacity, have living space. extraHabTime += hab.KerbalMonths; //Some modules act more as 'multipliers', dramatically extending a hab's workable lifespan. habMult += hab.HabMultiplier * Math.Min(1, hab.CrewCapacity / Math.Max(curCrew, 1)); } else { foreach (var bay in bayList) { var con = conList[bay.currentLoadout] as ModuleHabitation; if (con != null) { habs.Add(con); extraHabTime += con.KerbalMonths; habMult += con.HabMultiplier * Math.Min(1, con.CrewCapacity / Math.Max(curCrew, 1)); } } } } if (part.Resources.Contains("Supplies")) { supplies += part.Resources["Supplies"].amount; } if (part.Resources.Contains("ElectricCharge")) { batteryAmount += part.Resources["ElectricCharge"].maxAmount; } } totalHabSpace = (LifeSupportScenario.Instance.settings.GetSettings().BaseHabTime *maxCrew) + extraHabTime; //A Kerbal month is 30 six-hour Kerbin days. totalHabMult = habMult * LifeSupportScenario.Instance.settings.GetSettings().HabMultiplier *LifeSupportUtilities.SecondsPerMonth(); totalBatteryTime = batteryAmount / LifeSupportScenario.Instance.settings.GetSettings().ECAmount; totalSupplyTime = supplies / LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount; if (EditorLogic.fetch.ship.parts.Count > 0) { foreach (var p in EditorLogic.fetch.ship.parts) { var rec = p.Modules.GetModule <ModuleLifeSupportRecycler>(); if (rec != null) { var conList = p.Modules.GetModules <BaseConverter>(); var bayList = p.Modules.GetModules <ModuleSwappableConverter>(); if (bayList == null || bayList.Count == 0) { recyclers.Add(rec); } else { foreach (var bay in bayList) { var con = conList[bay.currentLoadout] as ModuleLifeSupportRecycler; if (con != null) { recyclers.Add(con); } } } } } var recyclerMultiplier_curCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, curCrew); var recyclerMultiplier_maxCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, maxCrew); supply_curCrew = LifeSupportUtilities.SecondsToKerbinTime( totalSupplyTime / Math.Max(1, curCrew) / recyclerMultiplier_curCrew ); supply_maxCrew = LifeSupportUtilities.SecondsToKerbinTime( totalSupplyTime / Math.Max(1, maxCrew) / recyclerMultiplier_maxCrew ); hab_curCrew = LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, curCrew) * totalHabMult); hab_maxCrew = LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, maxCrew) * totalHabMult); } } }
public static Part CreatePart(AvailablePart avPart, Vector3 position, Quaternion rotation, Part flagFromPart) { UnityEngine.Object obj = UnityEngine.Object.Instantiate(avPart.partPrefab); if (!obj) { KAS_Shared.DebugError("CreatePart(Crate) Failed to instantiate " + avPart.partPrefab.name); return(null); } Part newPart = (Part)obj; newPart.gameObject.SetActive(true); newPart.gameObject.name = avPart.name; newPart.partInfo = avPart; newPart.highlightRecurse = true; newPart.SetMirror(Vector3.one); ShipConstruct newShip = new ShipConstruct(); newShip.Add(newPart); newShip.SaveShip(); newShip.shipName = avPart.title; newShip.shipType = 1; VesselCrewManifest vessCrewManifest = new VesselCrewManifest(); Vessel currentVessel = FlightGlobals.ActiveVessel; Vessel v = newShip.parts[0].localRoot.gameObject.AddComponent <Vessel>(); v.id = Guid.NewGuid(); v.vesselName = newShip.shipName; v.Initialize(false); v.Landed = true; v.rootPart.flightID = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState); v.rootPart.missionID = flagFromPart.missionID; v.rootPart.flagURL = flagFromPart.flagURL; //v.rootPart.collider.isTrigger = true; //v.landedAt = "somewhere"; Staging.beginFlight(); newShip.parts[0].vessel.ResumeStaging(); Staging.GenerateStagingSequence(newShip.parts[0].localRoot); Staging.RecalculateVesselStaging(newShip.parts[0].vessel); FlightGlobals.SetActiveVessel(currentVessel); v.SetPosition(position); v.SetRotation(rotation); // Solar panels from containers don't work otherwise for (int i = 0; i < newPart.Modules.Count; i++) { ConfigNode node = new ConfigNode(); node.AddValue("name", newPart.Modules[i].moduleName); newPart.LoadModule(node, i); } return(newPart); }
private void GenerateWindow() { GUILayout.BeginVertical(); scrollPos = GUILayout.BeginScrollView(scrollPos, _scrollStyle, GUILayout.Width(645), GUILayout.Height(350)); GUILayout.BeginVertical(); var useHabPenalties = (LifeSupportSetup.Instance.LSConfig.NoHomeEffectVets + LifeSupportSetup.Instance.LSConfig.NoHomeEffect > 0); if (EditorLogic.fetch != null) { var curCrew = 0; var maxCrew = 0; var supplies = 0d; var extraHabTime = 0d; var habMult = 1d; var batteryAmount = 0d; List <ModuleHabitation> habs = new List <ModuleHabitation>(); foreach (var part in EditorLogic.fetch.ship.parts) { maxCrew += part.CrewCapacity; } CMAssignmentDialog dialog = CMAssignmentDialog.Instance; if (dialog != null) { VesselCrewManifest manifest = dialog.GetManifest(); if (manifest != null) { foreach (PartCrewManifest pcm in manifest) { int partCrewCount = pcm.GetPartCrew().Count(c => c != null); if (partCrewCount > 0) { curCrew += partCrewCount; } } } } foreach (var part in EditorLogic.fetch.ship.parts) { var hab = part.Modules.GetModules <ModuleHabitation>().FirstOrDefault(); if (hab != null) { habs.Add(hab); //Certain modules, in addition to crew capacity, have living space. extraHabTime += hab.KerbalMonths; //Some modules act more as 'multipliers', dramatically extending a hab's workable lifespan. habMult += hab.HabMultiplier * Math.Min(1, (hab.CrewCapacity / curCrew)); } if (part.Resources.Contains("Supplies")) { supplies += part.Resources["Supplies"].amount; } if (part.Resources.Contains("ElectricCharge")) { batteryAmount += part.Resources["ElectricCharge"].maxAmount; } } var totalHabSpace = (LifeSupportSetup.Instance.LSConfig.BaseHabTime * maxCrew) + extraHabTime; //A Kerbal month is 30 six-hour Kerbin days. var totalHabMult = habMult * LifeSupportSetup.Instance.LSConfig.HabMultiplier * 60d * 60d * 6d * 30d; var totalBatteryTime = batteryAmount / LifeSupportSetup.Instance.LSConfig.ECAmount; var totalSupplyTime = supplies / LifeSupportSetup.Instance.LSConfig.SupplyAmount; if (EditorLogic.fetch.ship.parts.Count > 0) { List <ModuleLifeSupportRecycler> recyclers = new List <ModuleLifeSupportRecycler>(); foreach (var p in EditorLogic.fetch.ship.parts) { var mod = p.FindModuleImplementing <ModuleLifeSupportRecycler>(); if (mod == null) { continue; } recyclers.Add(mod); } var recyclerMultiplier_curCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, curCrew); var recyclerMultiplier_maxCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, maxCrew); var supply_curCrew = LifeSupportUtilities.SecondsToKerbinTime( totalSupplyTime / Math.Max(1, curCrew) / recyclerMultiplier_curCrew ); var supply_maxCrew = LifeSupportUtilities.SecondsToKerbinTime( totalSupplyTime / Math.Max(1, maxCrew) / recyclerMultiplier_maxCrew ); var hab_curCrew = LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, curCrew) * totalHabMult); var hab_maxCrew = LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, maxCrew) * totalHabMult); // Colors string operColor = "99FF33"; string textColor = "FFFFFF"; string crewColor = "ADD8E6"; string fadeColor = "909090"; string partColor = "FFCC00"; // SUMMARY { // column widths const int c1 = 90; const int c2 = 160; const int c3 = 160; const int c4 = 160; // LABELS GUILayout.BeginHorizontal(); GUILayout.Label("Crew", _labelStyle, GUILayout.Width(c1)); GUILayout.Label("Supplies", _labelStyle, GUILayout.Width(c2)); GUILayout.Label("Batteries", _labelStyle, GUILayout.Width(c3)); GUILayout.Label("Habitation", _labelStyle, GUILayout.Width(c4)); GUILayout.EndHorizontal(); // CURRENT CREW GUILayout.BeginHorizontal(); GUILayout.Label(CTag("Current (", textColor) + CTag(Math.Max(1, curCrew).ToString(), crewColor) + CTag(")", textColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(supply_curCrew, textColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label( CTag(LifeSupportUtilities.SecondsToKerbinTime(totalBatteryTime / Math.Max(1, curCrew)), textColor), _labelStyle, GUILayout.Width(c3) ); if (useHabPenalties) { GUILayout.Label(CTag(hab_curCrew, textColor), _labelStyle, GUILayout.Width(160)); } else { GUILayout.Label(CTag("indefinite", textColor), _labelStyle, GUILayout.Width(c4)); } GUILayout.EndHorizontal(); // MAX CREW GUILayout.BeginHorizontal(); GUILayout.Label(CTag("Max (", textColor) + CTag(Math.Max(1, maxCrew).ToString(), crewColor) + CTag(")", textColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(supply_maxCrew, textColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label( CTag(LifeSupportUtilities.SecondsToKerbinTime(totalBatteryTime / Math.Max(1, maxCrew)), textColor), _labelStyle, GUILayout.Width(c3) ); if (useHabPenalties) { GUILayout.Label(CTag(hab_maxCrew, textColor), _labelStyle, GUILayout.Width(160)); } else { GUILayout.Label(CTag("indefinite", textColor), _labelStyle, GUILayout.Width(160)); } GUILayout.EndHorizontal(); } GUILayout.Space(20); GUILayout.BeginHorizontal(); GUILayout.Label("<b>Details</b>", _labelStyle, GUILayout.Width(150)); GUILayout.EndHorizontal(); // HABITATION EQUATION if (useHabPenalties) { // column widths const int c1 = 150; const int c2 = 80; const int c3 = 80; const int c4 = 90; const int c5 = 80; const int c6 = 50; const int c7 = 50; // hab = ((LSConfig.BaseHabTime * maxCrew) + ExtraHabTime) * Hab-Multiplier / Crew * LSConfig.HabMultiplier[Kerbin-Months] GUILayout.BeginHorizontal(); GUILayout.Label("Habitation", _labelStyle, GUILayout.Width(c1 - 30)); GUILayout.Label(CTag("= ( (", operColor), _labelStyle, GUILayout.Width(30)); GUILayout.Label("BaseTime " + CTag("*", operColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label("MaxCrew " + CTag(") +", operColor), _labelStyle, GUILayout.Width(c3)); GUILayout.Label("ExtraTime " + CTag(") *", operColor), _labelStyle, GUILayout.Width(c4)); GUILayout.Label("Multiplier " + CTag("/", operColor), _labelStyle, GUILayout.Width(c5)); GUILayout.Label("Crew " + CTag("*", operColor), _labelStyle, GUILayout.Width(c6)); GUILayout.Label("Months", _labelStyle, GUILayout.Width(c7)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label(CTag(hab_curCrew, textColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(LifeSupportSetup.Instance.LSConfig.BaseHabTime.ToString(), fadeColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label(CTag(maxCrew.ToString(), crewColor), _labelStyle, GUILayout.Width(c3)); GUILayout.Label(CTag(extraHabTime.ToString(), textColor), _labelStyle, GUILayout.Width(c4)); GUILayout.Label(CTag(habMult.ToString(), textColor), _labelStyle, GUILayout.Width(c5)); GUILayout.Label(CTag(Math.Max(1, curCrew).ToString(), crewColor), _labelStyle, GUILayout.Width(c6)); GUILayout.Label(CTag(LifeSupportSetup.Instance.LSConfig.HabMultiplier.ToString(), fadeColor), _labelStyle, GUILayout.Width(c7)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label(CTag(hab_maxCrew, textColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(LifeSupportSetup.Instance.LSConfig.BaseHabTime.ToString(), fadeColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label(CTag(maxCrew.ToString(), crewColor), _labelStyle, GUILayout.Width(c3)); GUILayout.Label(CTag(extraHabTime.ToString(), textColor), _labelStyle, GUILayout.Width(c4)); GUILayout.Label(CTag(habMult.ToString(), textColor), _labelStyle, GUILayout.Width(c5)); GUILayout.Label(CTag(Math.Max(1, maxCrew).ToString(), crewColor), _labelStyle, GUILayout.Width(c6)); GUILayout.Label(CTag(LifeSupportSetup.Instance.LSConfig.HabMultiplier.ToString(), fadeColor), _labelStyle, GUILayout.Width(c7)); GUILayout.EndHorizontal(); } GUILayout.Space(20); GUILayout.BeginHorizontal(); GUILayout.Label("<b>Parts</b>", _labelStyle, GUILayout.Width(150)); GUILayout.EndHorizontal(); // RECYCLERS { // column widths const int c1 = 230; const int c2 = 80; const int c3 = 150; GUILayout.BeginHorizontal(); GUILayout.Label("Recycler", _labelStyle, GUILayout.Width(c1)); GUILayout.Label("Recycle %", _labelStyle, GUILayout.Width(c2)); GUILayout.Label("Crew-Capacity", _labelStyle, GUILayout.Width(c3)); GUILayout.EndHorizontal(); foreach (var recycler in recyclers) { GUILayout.BeginHorizontal(); GUILayout.Label(CTag(recycler.part.partInfo.title, partColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(((int)(recycler.RecyclePercent * 100)).ToString(), textColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label(CTag(recycler.CrewCapacity.ToString(), textColor), _labelStyle, GUILayout.Width(c3)); GUILayout.EndHorizontal(); } // HABITATION if (useHabPenalties) { GUILayout.Space(10); GUILayout.BeginHorizontal(); GUILayout.Label("Habitation", _labelStyle, GUILayout.Width(c1)); GUILayout.Label("ExtraTime", _labelStyle, GUILayout.Width(c2)); GUILayout.Label("Multiplier", _labelStyle, GUILayout.Width(c3)); GUILayout.EndHorizontal(); foreach (var hab in habs) { GUILayout.BeginHorizontal(); GUILayout.Label(CTag(hab.part.partInfo.title, partColor), _labelStyle, GUILayout.Width(c1)); GUILayout.Label(CTag(hab.KerbalMonths.ToString(), textColor), _labelStyle, GUILayout.Width(c2)); GUILayout.Label(CTag(hab.HabMultiplier.ToString(), textColor), _labelStyle, GUILayout.Width(c3)); GUILayout.EndHorizontal(); } } } } } GUILayout.EndVertical(); GUILayout.EndScrollView(); GUILayout.EndVertical(); GUI.DragWindow(); }
private void CrewDialogChange(VesselCrewManifest vcm) { KerbalConstructionTime.Instance.StartEngineersReportClobberCoroutine(); }
///<summary> Run simulators and update the planner UI sub-panels </summary> internal static void Update() { // get vessel crew manifest VesselCrewManifest manifest = KSP.UI.CrewAssignmentDialog.Instance.GetManifest(); if (manifest == null) { return; } // check for number of crew change if (vessel_analyzer.crew_count != manifest.CrewCount) { enforceUpdate = true; } // only update when we need to, repeat update a number of times to allow the simulators to catch up if (!enforceUpdate && update_counter++ > 3) { return; } // clear the panel panel.Clear(); // if there is something in the editor if (EditorLogic.RootPart != null) { // get parts recursively List <Part> parts = Lib.GetPartsRecursively(EditorLogic.RootPart); // analyze using the settings from the panels user input env_analyzer.Analyze(FlightGlobals.Bodies[body_index], altitude_mults[situation_index], sunlight); vessel_analyzer.Analyze(parts, resource_sim, env_analyzer); resource_sim.Analyze(parts, env_analyzer, vessel_analyzer); // add ec panel AddSubPanelEC(panel); // get vessel resources panel_resource.Clear(); foreach (string res in supplies) { if (resource_sim.Resource(res).capacity > 0.0) { panel_resource.Add(res); } } // reset current panel if necessary if (resource_index >= panel_resource.Count) { resource_index = 0; } // add resource panel if (panel_resource.Count > 0) { AddSubPanelResource(panel, panel_resource[resource_index]); } // add special panel if (panel_special.Count > 0) { switch (panel_special[special_index]) { case "qol": AddSubPanelStress(panel); break; case "radiation": AddSubPanelRadiation(panel); break; case "reliability": AddSubPanelReliability(panel); break; } } // add environment panel switch (panel_environment[environment_index]) { case "habitat": AddSubPanelHabitat(panel); break; case "environment": AddSubPanelEnvironment(panel); break; } } enforceUpdate = false; }
private static List <ProtoCrewMember> GetCurrentlyAssignedCrew() { VesselCrewManifest dialogManifest = CurrentDialogContents; return((dialogManifest == null) ? null : dialogManifest.GetAllCrew(true)); }
private void BuildAndLaunchCraft() { // build craft ShipConstruct nship = ShipConstruction.LoadShip(uis.craftfile); Vector3 offset = nship.Parts[0].transform.localPosition; nship.Parts[0].transform.Translate(-offset); string landedAt = "External Launchpad"; string flag = uis.flagname; Game state = FlightDriver.FlightStateCache; VesselCrewManifest crew = new VesselCrewManifest (); ShipConstruction.CreateBackup(nship); ShipConstruction.PutShipToGround(nship, GetLanchTransform()); ShipConstruction.AssembleForLaunch(nship, landedAt, flag, state, crew); Vessel vsl = FlightGlobals.Vessels[FlightGlobals.Vessels.Count - 1]; FlightGlobals.ForceSetActiveVessel(vsl); vsl.Landed = false; if (kethane_present && !DebugPad) UseResources(vsl); if (vessel.situation == Vessel.Situations.ORBITING) { HackStruts(vsl); uis.vesselInfo = new DockedVesselInfo(); uis.vesselInfo.name = vsl.vesselName; uis.vesselInfo.vesselType = vsl.vesselType; uis.vesselInfo.rootPartUId = vsl.rootPart.flightID; vsl.rootPart.Couple(part); FlightGlobals.ForceSetActiveVessel (vessel); } else { uis.timer = 3.0f; uis.launchee = vsl; } Staging.beginFlight(); }
private void setupSimulatorIfNeeded() { //If the vessel parts have changed or crew count has changed then run a new simulation. ShipConstruct ship = EditorLogic.fetch.ship; VesselCrewManifest manifest = CrewAssignmentDialog.Instance.GetManifest(); int consumerCount = SnacksScenario.Instance.resourceProcessors.Count; List <BaseResourceProcessor> resourceProcessors = SnacksScenario.Instance.resourceProcessors; List <ProcessedResource> consumerResources; int resourceCount; int resourceIndex; string resourceName; Snackshot snackshot; if (manifest != null) { currentCrewCount = manifest.CrewCount; } //Get crew capacity crewCapacity = 0; int partCrewCapacity = 0; for (int index = 0; index < ship.parts.Count; index++) { if (ship.parts[index].partInfo.partConfig.HasValue("CrewCapacity")) { int.TryParse(ship.parts[index].partInfo.partConfig.GetValue("CrewCapacity"), out partCrewCapacity); crewCapacity += partCrewCapacity; } } if (ship.parts.Count != partCount || currentCrewCount != previousCrewCount) { previousCrewCount = currentCrewCount; partCount = ship.parts.Count; //No parts? Nothing to do. if (partCount == 0) { snackshots.Clear(); simulationResults = "<color=yellow><b>Vessel has no crewed parts to simulate.</b></color>"; simulationComplete = false; } else if (currentCrewCount == 0) { snackshots.Clear(); simulationResults = "<color=yellow><b>Vessel needs crew to run simulation.</b></color>"; simulationComplete = false; } //Clear existing simulation if any snackThread.ClearJobs(); SimSnacks simSnacks = SimSnacks.CreateSimulator(ship); if (simSnacks != null) { simulationComplete = false; simulationResults = "<color=white><b>Simulation in progress, please wait...</b></color>"; snackshots.Clear(); //Get consumer resource lists for (int consumerIndex = 0; consumerIndex < consumerCount; consumerIndex++) { resourceProcessors[consumerIndex].AddConsumedAndProducedResources(currentCrewCount, simSnacks.secondsPerCycle, simSnacks.consumedResources, simSnacks.producedResources); //First check input list for resources to add to the snapshots window consumerResources = resourceProcessors[consumerIndex].inputList; resourceCount = consumerResources.Count; for (resourceIndex = 0; resourceIndex < resourceCount; resourceIndex++) { resourceName = consumerResources[resourceIndex].resourceName; if (consumerResources[resourceIndex].showInSnapshot && simSnacks.resources.ContainsKey(resourceName)) { snackshot = new Snackshot(); snackshot.showTimeRemaining = true; snackshot.resourceName = consumerResources[resourceIndex].resourceName; snackshot.amount = simSnacks.resources[resourceName].amount; snackshot.maxAmount = simSnacks.resources[resourceName].maxAmount; //Add to snackshots snackshots.Add(snackshot); } } //Next check outputs consumerResources = resourceProcessors[consumerIndex].outputList; resourceCount = consumerResources.Count; for (resourceIndex = 0; resourceIndex < resourceCount; resourceIndex++) { resourceName = consumerResources[resourceIndex].resourceName; if (consumerResources[resourceIndex].showInSnapshot && simSnacks.resources.ContainsKey(resourceName)) { snackshot = new Snackshot(); snackshot.showTimeRemaining = true; snackshot.resourceName = consumerResources[resourceIndex].resourceName; snackshot.amount = simSnacks.resources[resourceName].amount; snackshot.maxAmount = simSnacks.resources[resourceName].maxAmount; //Add to snackshots snackshots.Add(snackshot); } } } //Give mods a chance to add custom converters not already covered by Snacks. SimulatorContext context = new SimulatorContext(); context.shipConstruct = ship; context.simulatedVesselType = SimulatedVesselTypes.simEditor; SnacksScenario.onSimulatorCreated.Fire(simSnacks, context); //Now start the simulation snackThread.AddJob(simSnacks); } else { simulationResults = "<color=yellow><b>Vessel has no crewed parts to simulate.</b></color>"; } } }
private void UpdateGUIInfo(ShipConstruct ship) { ResetValues(); if (EditorLogic.fetch != null) { var parts = EditorLogic.fetch.ship.parts; var count = parts.Count; for (int i = 0; i < count; ++i) { var part = parts[i]; maxCrew += part.CrewCapacity; } var dialog = KSP.UI.CrewAssignmentDialog.Instance; if (dialog != null) { VesselCrewManifest manifest = dialog.GetManifest(); if (manifest != null) { curCrew = manifest.CrewCount; } } for (int i = 0; i < count; ++i) { var part = parts[i]; var swapOptions = part.FindModulesImplementing <AbstractSwapOption>(); var bays = part.FindModulesImplementing <USI_SwappableBay>(); if (swapOptions != null && bays != null && swapOptions.Count > 0 && bays.Count > 0) { for (int x = 0; x < bays.Count; x++) { var bay = bays[x]; var loadout = swapOptions[bay.currentLoadout] as USILS_HabitationSwapOption; if (loadout != null) { habs.Add(loadout); //Certain modules, in addition to crew capacity, have living space. extraHabTime += loadout.BaseKerbalMonths; //Some modules act more as 'multipliers', dramatically extending a hab's workable lifespan. habMult += loadout.BaseHabMultiplier * Math.Min(1, loadout.CrewCapacity / Math.Max(curCrew, 1)); } } } if (part.Resources.Contains("ColonySupplies")) { colonySupplies += part.Resources["ColonySupplies"].amount; } if (part.Resources.Contains("Fertilizer")) { fertilizer += part.Resources["Fertilizer"].amount; } if (part.Resources.Contains("Supplies")) { supplies += part.Resources["Supplies"].amount; } if (part.Resources.Contains("ElectricCharge")) { batteryAmount += part.Resources["ElectricCharge"].maxAmount; } } totalHabSpace = (LifeSupportScenario.Instance.settings.GetSettings().BaseHabTime *maxCrew) + extraHabTime; //A Kerbal month is 30 six-hour Kerbin days. totalHabMult = habMult * LifeSupportScenario.Instance.settings.GetSettings().HabMultiplier *LifeSupportUtilities.SecondsPerMonth(); totalBatteryTime = batteryAmount / LifeSupportScenario.Instance.settings.GetSettings().ECAmount; totalSupplyTime = supplies / LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount; totalFertilizerTime = fertilizer * 10 / LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount; if (EditorLogic.fetch.ship.parts.Count > 0) { for (int i = 0; i < count; ++i) { var part = parts[i]; var swapOptions = part.FindModulesImplementing <AbstractSwapOption>(); var bays = part.FindModulesImplementing <USI_SwappableBay>(); if (swapOptions != null && bays != null && swapOptions.Count > 0 && bays.Count > 0) { for (int x = 0; x < bays.Count; x++) { var bay = bays[x]; var loadout = swapOptions[bay.currentLoadout] as USILS_LifeSupportRecyclerSwapOption; if (loadout != null) { this.recyclers.Add(loadout); } } } } var recyclerMultiplier_curCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, curCrew); var recyclerMultiplier_maxCrew = LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, maxCrew); supply_curCrew = LifeSupportUtilities.DurationDisplay( totalSupplyTime / Math.Max(1, curCrew) / recyclerMultiplier_curCrew ); supply_maxCrew = LifeSupportUtilities.DurationDisplay( totalSupplyTime / Math.Max(1, maxCrew) / recyclerMultiplier_maxCrew ); hab_curCrew = LifeSupportUtilities.DurationDisplay(totalHabSpace / Math.Max(1, curCrew) * totalHabMult); hab_maxCrew = LifeSupportUtilities.DurationDisplay(totalHabSpace / Math.Max(1, maxCrew) * totalHabMult); supplyExt_curCrew = LifeSupportUtilities.DurationDisplay( (totalSupplyTime + totalFertilizerTime) / Math.Max(1, curCrew) / recyclerMultiplier_curCrew ); supplyExt_maxCrew = LifeSupportUtilities.DurationDisplay( (totalSupplyTime + totalFertilizerTime) / Math.Max(1, maxCrew) / recyclerMultiplier_maxCrew ); //Standard is half a colony supply per hour, or 0.000139 per second. var csupPerSecond = 0.000139d; habExt_curCrew = LifeSupportUtilities.DurationDisplay((totalHabSpace / Math.Max(1, curCrew) * totalHabMult) + (colonySupplies / csupPerSecond / curCrew)); habExt_maxCrew = LifeSupportUtilities.DurationDisplay((totalHabSpace / Math.Max(1, maxCrew) * totalHabMult) + (colonySupplies / csupPerSecond / maxCrew)); } } }
public void LaunchShip() { ShipConstruct vehicle = new ShipConstruct(); if (!vehicle.LoadShip(m_VehicleConfig)) return; Game fsc = FlightDriver.FlightStateCache; VesselCrewManifest vesselCrew = new VesselCrewManifest(); Bounds aabb = GetAABB(vehicle); if (aabb.min == null) Application.Quit(); launchData = m_ConstructionPort.PlaceShip(vehicle, aabb); ShipConstruction.AssembleForLaunch(vehicle, "BANAAN", null, fsc, vesselCrew); m_Vessel = FlightGlobals.Vessels[FlightGlobals.Vessels.Count - 1]; FlightGlobals.ForceSetActiveVessel(m_Vessel); Vector3 offset = m_Vessel.transform.position - launchData.position; craftOffset = launchData.InverseTransformDirection(offset); m_Vessel.SetPosition(craftOffset, true); Staging.beginFlight(); FlightGlobals.overrideOrbit = true; m_ConstructionPort.StartCoroutine(CaptureCraft()); }
private void GenerateWindow() { GUILayout.BeginVertical(); scrollPos = GUILayout.BeginScrollView(scrollPos, _scrollStyle, GUILayout.Width(600), GUILayout.Height(350)); GUILayout.BeginVertical(); var useHabPenalties = (LifeSupportSetup.Instance.LSConfig.NoHomeEffectVets + LifeSupportSetup.Instance.LSConfig.NoHomeEffect > 0); if (EditorLogic.fetch != null) { var curCrew = 0; var maxCrew = 0; var supplies = 0d; var extraHabTime = 0d; var habMult = 1d; var batteryAmount = 0d; foreach (var part in EditorLogic.fetch.ship.parts) { maxCrew += part.CrewCapacity; } CMAssignmentDialog dialog = CMAssignmentDialog.Instance; if (dialog != null) { VesselCrewManifest manifest = dialog.GetManifest(); if (manifest != null) { foreach (PartCrewManifest pcm in manifest) { int partCrewCount = pcm.GetPartCrew().Count(c => c != null); if (partCrewCount > 0) { curCrew += partCrewCount; } } } } foreach (var part in EditorLogic.fetch.ship.parts) { var hab = part.Modules.GetModules <ModuleHabitation>().FirstOrDefault(); if (hab != null) { //Certain modules, in addition to crew capacity, have living space. extraHabTime += hab.KerbalMonths; //Some modules act more as 'multipliers', dramatically extending a hab's workable lifespan. habMult += hab.HabMultiplier * Math.Min(1, (hab.CrewCapacity / curCrew)); } if (part.Resources.Contains("Supplies")) { supplies += part.Resources["Supplies"].amount; } if (part.Resources.Contains("ElectricCharge")) { batteryAmount += part.Resources["ElectricCharge"].maxAmount; } } var totalHabSpace = (LifeSupportSetup.Instance.LSConfig.BaseHabTime * maxCrew) + extraHabTime; //A Kerbal month is 30 six-hour Kerbin days. var totalHabMult = habMult * LifeSupportSetup.Instance.LSConfig.HabMultiplier * 60d * 60d * 6d * 30d; var totalBatteryTime = batteryAmount / LifeSupportSetup.Instance.LSConfig.ECAmount; var totalSupplyTime = supplies / LifeSupportSetup.Instance.LSConfig.SupplyAmount; if (EditorLogic.fetch.ship.parts.Count > 0) { GUILayout.BeginHorizontal(); GUILayout.Label("Crew", _labelStyle, GUILayout.Width(90)); GUILayout.Label("Supplies", _labelStyle, GUILayout.Width(160)); GUILayout.Label("Batteries", _labelStyle, GUILayout.Width(160)); GUILayout.Label("Habitation", _labelStyle, GUILayout.Width(160)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Current (" + curCrew + ")", _labelStyle, GUILayout.Width(90)); GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalSupplyTime / Math.Max(1, curCrew) / LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, curCrew)), _labelStyle, GUILayout.Width(160)); GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalBatteryTime / Math.Max(1, curCrew)), _labelStyle, GUILayout.Width(160)); if (useHabPenalties) { GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, curCrew) * totalHabMult), _labelStyle, GUILayout.Width(160)); } else { GUILayout.Label("indefinite", _labelStyle, GUILayout.Width(160)); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Max (" + maxCrew + ")", _labelStyle, GUILayout.Width(90)); GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalSupplyTime / Math.Max(1, maxCrew) / LifeSupportManager.GetRecyclerMultiplierForParts(EditorLogic.fetch.ship.parts, maxCrew)), _labelStyle, GUILayout.Width(160)); GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalBatteryTime / Math.Max(1, maxCrew)), _labelStyle, GUILayout.Width(160)); if (useHabPenalties) { GUILayout.Label(LifeSupportUtilities.SecondsToKerbinTime(totalHabSpace / Math.Max(1, maxCrew) * totalHabMult), _labelStyle, GUILayout.Width(160)); } else { GUILayout.Label("indefinite", _labelStyle, GUILayout.Width(160)); } GUILayout.EndHorizontal(); } } GUILayout.EndVertical(); GUILayout.EndScrollView(); GUILayout.EndVertical(); GUI.DragWindow(); }
internal void BuildAndLaunchCraft () { // build craft ShipConstruct nship = new ShipConstruct (); nship.LoadShip (craftConfig); int numParts = builder.vessel.parts.Count; if (craftType != CraftType.SubAss) numParts = 0; string landedAt = "External Launchpad"; string flag = flagname; Game game = FlightDriver.FlightStateCache; VesselCrewManifest crew = new VesselCrewManifest (); Box vessel_bounds = GetVesselBox (nship); launchTransform = builder.PlaceShip (nship, vessel_bounds); EnableExtendingLaunchClamps (nship); ShipConstruction.AssembleForLaunch (nship, landedAt, flag, game, crew); var FlightVessels = FlightGlobals.Vessels; craftVessel = FlightVessels[FlightVessels.Count - 1]; FlightGlobals.ForceSetActiveVessel (craftVessel); if (builder.capture) { craftVessel.Splashed = craftVessel.Landed = false; } else { bool loaded = craftVessel.loaded; bool packed = craftVessel.packed; craftVessel.loaded = true; craftVessel.packed = false; craftVessel.GetHeightFromTerrain (); Debug.Log (String.Format ("[EL] hft {0}", craftVessel.heightFromTerrain)); craftVessel.loaded = loaded; craftVessel.packed = packed; } Vector3 offset = craftVessel.transform.position - launchTransform.position; craftOffset = launchTransform.InverseTransformDirection (offset); SetupCraftResources (craftVessel); Staging.beginFlight (); if (builder.capture) { FlightGlobals.overrideOrbit = true; (builder as PartModule).StartCoroutine (CaptureCraft ()); } else { state = State.Idle; } }
internal void BuildAndLaunchCraft() { // build craft ShipConstruct nship = new ShipConstruct(); nship.LoadShip(craftConfig); ApplyNodeVariants(nship); string landedAt = ""; string flag = flagname; Game game = FlightDriver.FlightStateCache; VesselCrewManifest crew = new VesselCrewManifest(); Box vessel_bounds = GetVesselBox(nship); launchTransform = builder.PlaceShip(nship, vessel_bounds); EnableExtendingLaunchClamps(nship); ShipConstruction.AssembleForLaunch(nship, landedAt, landedAt, flag, game, crew); var FlightVessels = FlightGlobals.Vessels; craftVessel = FlightVessels[FlightVessels.Count - 1]; craftVessel.launchedFrom = builder.LaunchedFrom; FlightGlobals.ForceSetActiveVessel(craftVessel); builder.PostBuild(craftVessel); if (builder.capture) { craftVessel.Splashed = craftVessel.Landed = false; } else { bool loaded = craftVessel.loaded; bool packed = craftVessel.packed; craftVessel.loaded = true; craftVessel.packed = false; // The default situation for new vessels is PRELAUNCH, but // that is not so good for bases because contracts check for // LANDED. XXX should this be selectable? craftVessel.situation = Vessel.Situations.LANDED; craftVessel.GetHeightFromTerrain(); Debug.Log($"[ELBuildControl] height from terrain {craftVessel.heightFromTerrain}"); craftVessel.loaded = loaded; craftVessel.packed = packed; } Vector3 offset = craftVessel.transform.position - launchTransform.position; craftOffset = launchTransform.InverseTransformDirection(offset); SetupCraftResources(craftVessel); KSP.UI.Screens.StageManager.BeginFlight(); builtStuff = null; // ensure pad mass gets reset SetPadMass(); if (builder.capture) { FlightGlobals.overrideOrbit = true; (builder as PartModule).StartCoroutine(CaptureCraft()); } else { CleaupAfterRelease(); } }
public static Part CreatePart(AvailablePart avPart, Vector3 position, Quaternion rotation, Part flagFromPart) { UnityEngine.Object obj = UnityEngine.Object.Instantiate(avPart.partPrefab); if (!obj) { KAS_Shared.DebugError("CreatePart(Crate) Failed to instantiate " + avPart.partPrefab.name); return null; } Part newPart = (Part)obj; newPart.gameObject.SetActive(true); newPart.gameObject.name = avPart.name; newPart.partInfo = avPart; newPart.highlightRecurse = true; newPart.SetMirror(Vector3.one); ShipConstruct newShip = new ShipConstruct(); newShip.Add(newPart); newShip.SaveShip(); newShip.shipName = avPart.title; newShip.shipType = 1; VesselCrewManifest vessCrewManifest = new VesselCrewManifest(); Vessel currentVessel = FlightGlobals.ActiveVessel; Vessel v = newShip.parts[0].localRoot.gameObject.AddComponent<Vessel>(); v.id = Guid.NewGuid(); v.vesselName = newShip.shipName; v.Initialize(false); v.Landed = true; v.rootPart.flightID = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState); v.rootPart.missionID = flagFromPart.missionID; v.rootPart.flagURL = flagFromPart.flagURL; //v.rootPart.collider.isTrigger = true; //v.landedAt = "somewhere"; Staging.beginFlight(); newShip.parts[0].vessel.ResumeStaging(); Staging.GenerateStagingSequence(newShip.parts[0].localRoot); Staging.RecalculateVesselStaging(newShip.parts[0].vessel); FlightGlobals.SetActiveVessel(currentVessel); v.SetPosition(position); v.SetRotation(rotation); // Solar panels from containers don't work otherwise for (int i = 0; i < newPart.Modules.Count; i++) { ConfigNode node = new ConfigNode(); node.AddValue("name", newPart.Modules[i].moduleName); newPart.LoadModule(node, ref i); } return newPart; }
public static Part CreatePart(AvailablePart avPart, Vector3 position, Quaternion rotation, Part flagFromPart) { UnityEngine.Object obj = UnityEngine.Object.Instantiate(avPart.partPrefab); if (!obj) { KAS_Shared.DebugError("CreatePart(Crate) Failed to instantiate " + avPart.partPrefab.name); return null; } Part newPart = (Part)obj; newPart.gameObject.SetActive(true); newPart.gameObject.name = "KASCreatedPart"; newPart.partInfo = avPart; newPart.highlightRecurse = true; ShipConstruct newShip = new ShipConstruct(); newShip.Add(newPart); newShip.SaveShip(); newShip.shipName = avPart.title; newShip.shipType = 1; VesselCrewManifest vessCrewManifest = new VesselCrewManifest(); Vessel currentVessel = FlightGlobals.ActiveVessel; Vessel v = newShip.parts[0].localRoot.gameObject.AddComponent<Vessel>(); v.id = Guid.NewGuid(); v.vesselName = newShip.shipName; v.Initialize(false); v.Landed = true; v.rootPart.flightID = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState); v.rootPart.missionID = (uint)Guid.NewGuid().GetHashCode(); v.rootPart.flagURL = flagFromPart.flagURL; //v.rootPart.collider.isTrigger = true; v.rootPart.FindModelTransform("model").localScale *= v.rootPart.rescaleFactor; //v.landedAt = "somewhere"; Staging.beginFlight(); newShip.parts[0].vessel.ResumeStaging(); Staging.GenerateStagingSequence(newShip.parts[0].localRoot); Staging.RecalculateVesselStaging(newShip.parts[0].vessel); FlightGlobals.SetActiveVessel(currentVessel); v.SetPosition(position); v.SetRotation(rotation); return newPart; }