public static float GetRecoveryValueForChuteLanding(ProtoVessel pv) { bool probeCoreAttached = false; foreach (ProtoPartSnapshot pps in pv.protoPartSnapshots) { if (pps.modules.Find(module => (module.moduleName == "ModuleCommand" && ((ModuleCommand)module.moduleRef).minimumCrew == 0)) != null) { KCTDebug.Log("Probe Core found!"); probeCoreAttached = true; } } float RecoveryMod = probeCoreAttached ? 1.0f : KCT_GameStates.settings.RecoveryModifier; double distanceFromKSC = SpaceCenter.Instance.GreatCircleDistance(SpaceCenter.Instance.cb.GetRelSurfaceNVector(pv.latitude, pv.longitude)); double maxDist = SpaceCenter.Instance.cb.Radius * Math.PI; float recoveryPercent = RecoveryMod * Mathf.Lerp(0.98f, 0.1f, (float)(distanceFromKSC / maxDist)); float totalReturn = 0; foreach (ProtoPartSnapshot pps in pv.protoPartSnapshots) { float dryCost, fuelCost; totalReturn += ShipConstruction.GetPartCosts(pps, pps.partInfo, out dryCost, out fuelCost); } float totalBeforeReturn = (float)Math.Round(totalReturn, 2); totalReturn *= recoveryPercent; totalReturn = (float)Math.Round(totalReturn, 2); KCTDebug.Log("Vessel being recovered by KCT. Percent returned: " + 100 * recoveryPercent + "%. Distance from KSC: " + Math.Round(distanceFromKSC / 1000, 2) + " km"); KCTDebug.Log("Funds being returned: " + totalReturn + "/" + totalBeforeReturn); return(totalReturn); }
public LaunchConfig(string craftDirectory, string name, string launchSite, bool recover) { LaunchSite = launchSite; Recover = recover; // Load the vessel and its default crew if (craftDirectory == "VAB") { EditorDriver.editorFacility = EditorFacility.VAB; } else if (craftDirectory == "SPH") { EditorDriver.editorFacility = EditorFacility.SPH; } else { throw new ArgumentException("Invalid craftDirectory, should be VAB or SPH"); } Path = ShipConstruction.GetSavePath(name); template = ShipConstruction.LoadTemplate(Path); if (template == null) { throw new InvalidOperationException("Failed to load template for vessel"); } manifest = HighLogic.CurrentGame.CrewRoster.DefaultCrewForVessel( template.config, VesselCrewManifest.FromConfigNode(template.config)); facility = (craftDirectory == "SPH") ? SpaceCenterFacility.SpaceplaneHangar : SpaceCenterFacility.VehicleAssemblyBuilding; facilityLevel = ScenarioUpgradeableFacilities.GetFacilityLevel(facility); site = (launchSite == "Runway") ? SpaceCenterFacility.Runway : SpaceCenterFacility.LaunchPad; siteLevel = ScenarioUpgradeableFacilities.GetFacilityLevel(site); isPad = (site == SpaceCenterFacility.LaunchPad); }
private ShipConstruct shipConstruct = null; // Only needed to get more info about the template-ship, like its crew-capacity. public int GetCrewCapacity() { int crewCapacity = 0; if (HighLogic.LoadedScene == GameScenes.FLIGHT) { throw new Exception("ShipConstruction.LoadShip cannot be run while in flight"); // This would create a new, non-functioning vessel near the current vessel } try { if (this.shipConstruct == null) { shipConstruct = ShipConstruction.LoadShip(template.filename); } foreach (Part part in shipConstruct.parts) { crewCapacity += part.CrewCapacity; } } catch (Exception e) { Debug.LogError("[KSTS] CachedShipTemplate::GetCrewCapacity(): " + e.ToString()); } return(crewCapacity); }
public static CraftTemplate GetTemplateByName(string name, string facility) { if (string.IsNullOrEmpty(facility)) { facility = "<empty>"; } if (!string.IsNullOrEmpty(name)) { switch (facility.ToLower()) { case ("vab"): EditorDriver.editorFacility = EditorFacility.VAB; break; case ("sph"): EditorDriver.editorFacility = EditorFacility.SPH; break; default: throw new KOSException("Failed to load craft. Facility " + facility + " not recognized, expected \"VAB\" or \"SPH\""); } var path = ShipConstruction.GetSavePath(name); var template = ShipConstruction.LoadTemplate(path); if (template == null) { throw new KOSException("Failed to load craft named \"" + name + "\" from given path:\n " + path); } return(new CraftTemplate(path, template)); } throw new KOSException("Failed to load craft named " + name + " from facility " + facility); }
private static ProtoVessel GetVesselFromShipConstruct(ShipConstruct shipConstruct, ProtoVessel oldVessel, Game game) { foreach (var p in shipConstruct.parts) { p.flightID = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState); p.missionID = oldVessel.protoPartSnapshots[0].missionID; p.launchID = oldVessel.protoPartSnapshots[0].launchID; p.flagURL = oldVessel.protoPartSnapshots[0].flagURL ?? HighLogic.CurrentGame.flagURL; p.temperature = 1.0; // LITARLY NO CLUE WHY NO CODE IN SQUAD IS EXECUTING THIS (this little piece of shit took me 2 days) p.UpdateOrgPosAndRot(shipConstruct.parts[0]); } var empty = new ConfigNode(); var dummyProto = new ProtoVessel(empty, null); var dummyVessel = new Vessel(); dummyVessel.parts = shipConstruct.parts; dummyProto.vesselRef = dummyVessel; // ReSharper disable once SuggestVarOrType_SimpleTypes foreach (Part p in shipConstruct.parts) { dummyProto.protoPartSnapshots.Add(new ProtoPartSnapshot(p, dummyProto)); } // ReSharper disable once SuggestVarOrType_SimpleTypes foreach (ProtoPartSnapshot p in dummyProto.protoPartSnapshots) { p.storePartRefs(); } return(dummyProto); }
private void GenerateStrandedKerbal(int bodyID, string kerbalName) { //Add kerbal to crew roster. DarkLog.Debug("Spawning missing kerbal, name: " + kerbalName); ProtoCrewMember pcm = HighLogic.CurrentGame.CrewRoster.GetNewKerbal(ProtoCrewMember.KerbalType.Unowned); pcm.name = kerbalName; pcm.rosterStatus = ProtoCrewMember.RosterStatus.Assigned; //Create protovessel uint newPartID = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState); CelestialBody contractBody = FlightGlobals.Bodies[bodyID]; //Atmo: 10km above atmo, to half the planets radius out. //Non-atmo: 30km above ground, to half the planets radius out. double minAltitude = FinePrint.Utilities.CelestialUtilities.GetMinimumOrbitalAltitude(contractBody, 1.1f); double maxAltitude = minAltitude + contractBody.Radius * 0.5; Orbit strandedOrbit = Orbit.CreateRandomOrbitAround(FlightGlobals.Bodies[bodyID], minAltitude, maxAltitude); ConfigNode[] kerbalPartNode = new ConfigNode[1]; ProtoCrewMember[] partCrew = new ProtoCrewMember[1]; partCrew[0] = pcm; kerbalPartNode[0] = ProtoVessel.CreatePartNode("kerbalEVA", newPartID, partCrew); ConfigNode protoVesselNode = ProtoVessel.CreateVesselNode(kerbalName, VesselType.EVA, strandedOrbit, 0, kerbalPartNode); ConfigNode discoveryNode = ProtoVessel.CreateDiscoveryNode(DiscoveryLevels.Unowned, UntrackedObjectClass.A, double.PositiveInfinity, double.PositiveInfinity); ProtoVessel protoVessel = new ProtoVessel(protoVesselNode, HighLogic.CurrentGame); protoVessel.discoveryInfo = discoveryNode; //It's not supposed to be infinite, but you're crazy if you think I'm going to decipher the values field of the rescue node. HighLogic.CurrentGame.flightState.protoVessels.Add(protoVessel); }
void Update() { if (FlightGlobals.fetch == null) { return; } Vessel activeVessel = FlightGlobals.ActiveVessel; if (activeVessel == null) { return; } vesselPartValue = 0.0f; vesselResourceValue = 0.0f; foreach (Part part in FlightGlobals.ActiveVessel.Parts) { float dryCost, fuelCost; ShipConstruction.GetPartCosts(part.protoPartSnapshot, part.partInfo, out dryCost, out fuelCost); vesselPartValue += dryCost; foreach (PartResource resource in part.Resources) { vesselResourceValue += (float)resource.amount * resource.info.unitCost; } } vesselValue = vesselPartValue + vesselResourceValue; }
/// <summary> /// Create an InventoryPart from an origin ConfigNode, extracting the name, dry cost, and relevant MODULEs /// </summary> /// <param name="originPartConfigNode">The <see cref="ConfigNode"/> to use as the basis of the <see cref="InventoryPart"/>.</param> public InventoryPart(ConfigNode originPartConfigNode) { _name = ConfigNodeUtils.PartNameFromNode(originPartConfigNode); float fuelCost; AvailablePart availablePartForNode = ConfigNodeUtils.AvailablePartFromNode(originPartConfigNode); if (availablePartForNode != null) { float dryMass, fuelMass; ShipConstruction.GetPartCostsAndMass(originPartConfigNode, availablePartForNode, out _dryCost, out fuelCost, out dryMass, out fuelMass); } if (originPartConfigNode.HasNode("MODULE")) { foreach (ConfigNode module in originPartConfigNode.GetNodes("MODULE")) { foreach (string trackedModuleName in ScrapYard.Instance.Settings.TrackedModules) { if (module.GetValue("name").ToUpper().Contains(trackedModuleName)) { savedModules.Add(module); } } } } }
public void SpawnVessel() { //var allowedSituations = Vessel.Situations.LANDED | Vessel.Situations.PRELAUNCH | Vessel.Situations.SPLASHED; //if (allowedSituations != (allowedSituations & FlightGlobals.ActiveVessel.situation)) //{ // throw new Exception(_notLandedErrorText); //} if (string.IsNullOrEmpty(_selectedCraftFilePath)) { throw new Exception(_noVesselSelectedErrorText); } PartUtilities.ConsumeResources(_cachedCostData); // Backup the ship config from the VAB/SPH, load the selected .craft file // and restore the cached config from the VAB/SPH var constructBak = ShipConstruction.ShipConfig; var construct = ShipConstruction.LoadShip(_selectedCraftFilePath); ShipConstruction.ShipConfig = constructBak; ShipConstruction.PutShipToGround(construct, transform); ShipConstruction.AssembleForLaunch( construct, vessel.landedAt, vessel.displaylandedAt, construct.missionFlag, HighLogic.CurrentGame, new VesselCrewManifest()); _window.CloseWindow(); }
/// <summary> /// Recover the kerbal when possible (has landed and isn't the active vessel). /// </summary> /// <param name="asap">Don't wait until the kerbal has landed.</param> public IEnumerator RecoverWhenPossible(bool asap = false) { if (asap) { if (KerbalSafetyManager.Instance.kerbals.ContainsKey(crew)) { KerbalSafetyManager.Instance.kerbals.Remove(crew); // Stop managing this kerbal. } } if (recovering) { yield break; } recovering = true; if (!asap) { yield return(new WaitUntil(() => kerbalEVA == null || kerbalEVA.vessel.LandedOrSplashed)); yield return(new WaitForSeconds(5)); // Give it around 5s after landing, then recover the kerbal } yield return(new WaitUntil(() => kerbalEVA == null || FlightGlobals.ActiveVessel != kerbalEVA.vessel)); if (kerbalEVA == null) { Debug.LogError("[BDArmory.KerbalSafety]: " + kerbalName + " on EVA is MIA."); yield break; } Debug.Log("[BDArmory.KerbalSafety]: Recovering " + kerbalName + "."); recovered = true; ShipConstruction.RecoverVesselFromFlight(kerbalEVA.vessel.protoVessel, HighLogic.CurrentGame.flightState, true); }
private void CreateLode(LodeData lodeData) { lodeData.altitude = TerrainHeight(lodeData.latitude, lodeData.longitude, lodeData.body); Vector3d pos = lodeData.body.GetWorldSurfacePosition(lodeData.latitude, lodeData.longitude, lodeData.altitude.Value); lodeData.orbit = new Orbit(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, lodeData.body); lodeData.orbit.UpdateFromStateVectors(pos, lodeData.body.getRFrmVel(pos), lodeData.body, Planetarium.GetUniversalTime()); ConfigNode[] partNodes; ShipConstruct shipConstruct = null; uint flightId = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState); partNodes = new ConfigNode[1]; partNodes[0] = ProtoVessel.CreatePartNode(lodeData.craftPart.name, flightId); DiscoveryLevels discoveryLevel = DiscoveryLevels.Owned; ConfigNode protoVesselNode = ProtoVessel.CreateVesselNode(lodeData.name, lodeData.vesselType, lodeData.orbit, 0, partNodes); Vector3d norm = lodeData.body.GetRelSurfaceNVector(lodeData.latitude, lodeData.longitude); double terrainHeight = 0.0; if (lodeData.body.pqsController != null) { terrainHeight = lodeData.body.pqsController.GetSurfaceHeight(norm) - lodeData.body.pqsController.radius; } bool splashed = true && terrainHeight < 0.001; protoVesselNode.SetValue("sit", (splashed ? Vessel.Situations.SPLASHED : Vessel.Situations.LANDED).ToString()); protoVesselNode.SetValue("landed", (!splashed).ToString()); protoVesselNode.SetValue("splashed", splashed.ToString()); protoVesselNode.SetValue("lat", lodeData.latitude.ToString()); protoVesselNode.SetValue("lon", lodeData.longitude.ToString()); protoVesselNode.SetValue("alt", lodeData.altitude.ToString()); protoVesselNode.SetValue("landedAt", lodeData.body.name); float lowest = float.MaxValue; foreach (Collider collider in lodeData.craftPart.partPrefab.GetComponentsInChildren <Collider>()) { if (collider.gameObject.layer != 21 && collider.enabled) { lowest = Mathf.Min(lowest, collider.bounds.min.y); } } if (Mathf.Approximately(lowest, float.MaxValue)) { lowest = 0; } Quaternion normal = Quaternion.LookRotation(new Vector3((float)norm.x, (float)norm.y, (float)norm.z)); Quaternion rotation = Quaternion.identity; rotation = rotation * Quaternion.FromToRotation(Vector3.up, Vector3.back); float hgt = (shipConstruct != null ? shipConstruct.parts[0] : lodeData.craftPart.partPrefab).localRoot.attPos0.y - lowest; protoVesselNode.SetValue("hgt", hgt.ToString()); protoVesselNode.SetValue("rot", KSPUtil.WriteQuaternion(rotation * normal)); Vector3 nrm = (rotation * Vector3.forward); protoVesselNode.SetValue("nrm", nrm.x + "," + nrm.y + "," + nrm.z); protoVesselNode.SetValue("prst", false.ToString()); ProtoVessel protoVessel = new ProtoVessel(protoVesselNode, HighLogic.CurrentGame); protoVessel.Load(HighLogic.CurrentGame.flightState); }
private ConfigNode FromInFlightVessel(Vessel VesselToSave, ListType listType) { //This code is taken from InflightShipSave by Claw, using the CC-BY-NC-SA license. //This code thus is licensed under the same license, despite the GPLv3 license covering original KCT code //See https://github.com/ClawKSP/InflightShipSave string ShipName = VesselToSave.vesselName; ShipConstruct ConstructToSave = new ShipConstruct(ShipName, "", VesselToSave.parts[0]); Quaternion OriginalRotation = VesselToSave.vesselTransform.rotation; Vector3 OriginalPosition = VesselToSave.vesselTransform.position; if (listType == ListType.SPH) { VesselToSave.SetRotation(new Quaternion((float)Math.Sqrt(0.5), 0, 0, (float)Math.Sqrt(0.5))); } else { VesselToSave.SetRotation(new Quaternion(0, 0, 0, 1)); } Vector3 ShipSize = ShipConstruction.CalculateCraftSize(ConstructToSave); VesselToSave.SetPosition(new Vector3(0, Math.Min(ShipSize.y + 2, 15), 0)); //Try to limit the max height we put the ship at ConfigNode cn = ConstructToSave.SaveShip(); SanitizeShipNode(cn); // override KSP sizing of the ship construct cn.SetValue("size", KSPUtil.WriteVector(Utilities.GetShipSize(ConstructToSave, true))); // These are actually needed, do not comment them out VesselToSave.SetRotation(OriginalRotation); VesselToSave.SetPosition(OriginalPosition); //End of Claw's code. Thanks Claw! return(cn); }
public float getPartRawPrice(ProtoPartSnapshot P) { float dryCost, fuelCost; ShipConstruction.GetPartCosts(P, P.partInfo, out dryCost, out fuelCost); return(dryCost); }
public void RefreshSubassemblies() { subs.Clear(); buttons.Clear(); var path = KSPUtil.ApplicationRootPath + "saves/" + HighLogic.SaveFolder + "/Subassemblies/"; Directory.CreateDirectory(path); var directoryInfo = new DirectoryInfo(path); FileInfo[] files = directoryInfo.GetFiles("*.craft"); for (int i = 0, len = files.Length; i < len; i++) { var sub = ShipConstruction.LoadTemplate(files[i].FullName); if (sub == null || sub.partCount == 0 || !sub.shipPartsUnlocked) { continue; } var label = string.Format("<color=yellow><b>{0}</b></color>\n" + "<color=silver>mass:</color> {1:F1}t " + "<color=silver>cost:</color> {2:F0} " + "<color=silver>size:</color> {3}", sub.shipName, sub.totalMass, sub.totalCost, Utils.formatDimensions(sub.GetShipSize())); var button = string.IsNullOrEmpty(sub.shipDescription)? new GUIContent(label) : new GUIContent(label, sub.shipDescription); buttons.Add(button); subs.Add(sub); } }
public void Load(ConfigNode node) { if (node.name == "CONTENT" && node.HasValue("qty")) { pristine_count += int.Parse(node.GetValue("qty")); } else if (node.name == "CONTENT_PART" && node.HasValue("kas_total_mass")) { ConfigNode nodeD = new ConfigNode(); node.CopyTo(nodeD); // Backward compatibility: compute the cost and save it if (!nodeD.HasValue("kas_total_cost")) { var snapshot = KAS_Shared.LoadProtoPartSnapshot(nodeD); float dry_cost, fuel_cost; float total_cost = ShipConstruction.GetPartCosts(snapshot, part, out dry_cost, out fuel_cost); nodeD.AddValue("kas_total_cost", total_cost); } instance_mass += float.Parse(nodeD.GetValue("kas_total_mass")); instance_cost += float.Parse(nodeD.GetValue("kas_total_cost")); instances.Add(nodeD); } }
public bool CanLaunchVessel(KCT_BuildListVessel vessel, out string reason) { if (vessel == null) { reason = "No vessel"; return(false); } double mass = vessel.GetTotalMass(); if (mass > MaxMass) { reason = $"mass ({mass:0.#}t) is higher than the allowed {MaxMass:0.#}"; return(false); } ShipTemplate template = new ShipTemplate(); template.LoadShip(vessel.shipNode); Vector3 dimensions = ShipConstruction.CalculateCraftSize(template); if (dimensions.x > MaxSize.x | dimensions.y > MaxSize.y | dimensions.z > MaxSize.z) { reason = $"size ({dimensions.x:0.#} x {dimensions.y:0.#} x {dimensions.z:0.#} m) is more than the allowed {MaxSize.x:0.#} x {MaxSize.y:0.#} x {MaxSize.z:0.#} m"; return(false); } reason = null; return(true); }
public static string TemporarySaveVessel(Vessel VesselToSave) { string ShipName = VesselToSave.vesselName; ShipConstruct ConstructToSave = new ShipConstruct(ShipName, "", VesselToSave.parts[0]); Quaternion OriginalRotation = VesselToSave.vesselTransform.rotation; Vector3 OriginalPosition = VesselToSave.vesselTransform.position; VesselToSave.SetRotation(new Quaternion(0, 0, 0, 1)); Vector3 ShipSize = ShipConstruction.CalculateCraftSize(ConstructToSave); VesselToSave.SetPosition(new Vector3(0, ShipSize.y + 2, 0)); ConfigNode CN = new ConfigNode("ShipConstruct"); CN = ConstructToSave.SaveShip(); VesselToSave.SetRotation(OriginalRotation); VesselToSave.SetPosition(OriginalPosition); string filename = UrlDir.ApplicationRootPath + "GameData/FlightEdit/temp.craft"; CN.Save(filename); return(filename); }
private ConfigNode FromInFlightVessel(Vessel VesselToSave) { //This code is taken from InflightShipSave by Claw, using the CC-BY-NC-SA license. //This code thus is licensed under the same license, despite the GPLv3 license covering original KCT code //See https://github.com/ClawKSP/InflightShipSave string ShipName = VesselToSave.vesselName; // Debug.LogWarning("Saving: " + ShipName); ShipConstruct ConstructToSave = new ShipConstruct(ShipName, "", VesselToSave.parts[0]); Quaternion OriginalRotation = VesselToSave.vesselTransform.rotation; Vector3 OriginalPosition = VesselToSave.vesselTransform.position; VesselToSave.SetRotation(new Quaternion(0, 0, 0, 1)); Vector3 ShipSize = ShipConstruction.CalculateCraftSize(ConstructToSave); VesselToSave.SetPosition(new Vector3(0, ShipSize.y + 2, 0)); ConfigNode CN = new ConfigNode("ShipConstruct"); CN = ConstructToSave.SaveShip(); SanitizeShipNode(CN); VesselToSave.SetRotation(OriginalRotation); VesselToSave.SetPosition(OriginalPosition); //End of Claw's code. Thanks Claw! return(CN); }
public double GetDryMass() { double dryMass = 0; if (HighLogic.LoadedScene == GameScenes.FLIGHT) { throw new Exception("ShipConstruction.LoadShip cannot be run while in flight"); // This would create a new, non-functioning vessel near the current vessel } try { if (this.shipConstruct == null) { shipConstruct = ShipConstruction.LoadShip(template.filename); } foreach (Part part in shipConstruct.parts) { dryMass += part.mass - part.resourceMass; } } catch (Exception e) { Debug.LogError("[KSTS] CachedShipTemplate::GetDryMass(): " + e.ToString()); } return(dryMass); }
/*************************************************************************************************************************/ private float vessels_cost(ProtoVessel temp_vessel) { float partcost, float_dummy, vesselcost = 0; PartResourceDefinition resc_def; #if DEBUG // if (Debug_Level_1_Active) Log.PushStackInfo("FMRS_Core.vessels_cost", "enter float vessels_cost(ProtoVessel temp_vessel) " + temp_vessel.vesselID.ToString()); if (Debug_Active) { Log.Info("Calculate cost from: " + temp_vessel.vesselName); } #endif foreach (ProtoPartSnapshot part in temp_vessel.protoPartSnapshots) { ShipConstruction.GetPartCosts(part, part.partInfo, out partcost, out float_dummy); foreach (ProtoPartResourceSnapshot resc in part.resources) { resc_def = PartResourceLibrary.Instance.resourceDefinitions[resc.resourceName]; partcost += (float)resc.amount * resc_def.unitCost; } vesselcost += partcost; } #if DEBUG if (Debug_Active) { Log.Info("FMRS cost: " + vesselcost.ToString()); } // if (Debug_Level_1_Active) Log.PopStackInfo("leave float vessels_cost(ProtoVessel temp_vessel)"); #endif return(vesselcost); }
/// <summary> /// Create an InventoryPart from an origin ProtoPartSnapshot, extracting the name, dry cost, and relevant MODULEs /// </summary> /// <param name="originPartSnapshot">The <see cref="ProtoPartSnapshot"/> to use as the basis of the <see cref="InventoryPart"/>.</param> public InventoryPart(ProtoPartSnapshot originPartSnapshot) { _name = originPartSnapshot.partInfo.name; if (ScrapYard.Instance.Settings.PartBlacklist.Contains(Name)) { DoNotStore = true; } float fuelCost; ShipConstruction.GetPartCosts(originPartSnapshot, originPartSnapshot.partInfo, out _dryCost, out fuelCost); //Save modules if (originPartSnapshot.modules != null) { foreach (ProtoPartModuleSnapshot module in originPartSnapshot.modules) { string name = module.moduleName; bool isTracker = name.Equals("ModuleSYPartTracker"); if (isTracker || moduleNameMatchesAnything(name)) //only save if there is a potential match { ConfigNode saved = module.moduleValues; _allModules.Add(saved); if (isTracker) { TrackerModule = new TrackerModuleWrapper(saved); } } } } ID = originPartSnapshot.persistentId; }
/// <summary> /// Wait until pre-flight checks for new vessel are complete. /// </summary> /// <param name="config">Config.</param> static void WaitForVesselPreFlightChecks(LaunchConfig config) { if (config.error != null) { throw new InvalidOperationException(config.error); } if (!config.preFlightChecksComplete) { throw new YieldException(new ParameterizedContinuationVoid <LaunchConfig>(WaitForVesselPreFlightChecks, config)); } // Check launch site clear var vesselsToRecover = ShipConstruction.FindVesselsLandedAt(HighLogic.CurrentGame.flightState, config.LaunchSite); if (vesselsToRecover.Any()) { // Recover existing vessels if the launch site is not clear if (!config.Recover) { throw new InvalidOperationException("Launch site not clear"); } foreach (var vessel in vesselsToRecover) { ShipConstruction.RecoverVesselFromFlight(vessel, HighLogic.CurrentGame.flightState, true); } } // Do the actual launch - passed pre-flight checks, and launch site is clear. FlightDriver.StartWithNewLaunch(config.Path, EditorLogic.FlagURL, config.LaunchSite, config.manifest); throw new YieldException(new ParameterizedContinuationVoid <int>(WaitForVesselSwitch, 0)); }
public static float GetPartCostFromNode(ConfigNode part) { string name = PartNameFromNode(part); float dry, wet; float total = ShipConstruction.GetPartCosts(part, GetAvailablePartByName(name), out dry, out wet); return(total); }
private void SpawnShipConstruction(ShipConstructor constructor, ShipConstruction shipConstruction) { Player player = PlayerDatabase.Instance.GetObjectPlayer(constructor.gameObject); Vector3 thisPosition = constructor.gameObject.transform.position; Vector3 spawnPosition = new Vector3(thisPosition.x + constructor.relativeConstructionSpawn.x, thisPosition.y + constructor.relativeConstructionSpawn.y, thisPosition.z + constructor.relativeConstructionSpawn.z); Spawner.Instance.SpawnShip(shipConstruction.shipType, player, spawnPosition, Quaternion.identity, true); }
internal void BuildAndLaunchCraft() { // build craft ShipConstruct nship = new ShipConstruct(); nship.LoadShip(craftConfig); 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, 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.LogFormat("[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; } }
public void SaveAsSubmodule(string launchVehicleName) { string description = string.Format("{0}: Launched vehicle as submodule", launchVehicleName); ShipConstruct shipConstruct = new ShipConstruct(launchVehicleName, description, separator); ShipConstruction.SaveSubassembly(shipConstruct, launchVehicleName); Debug.Log("[BeenThereDoneThat]: Saved launched vehicle as submodule"); }
protected override void VesselSelected(string filePath, CraftBrowserDialog.LoadType loadType) { if (filePath == _selectedCraftFilePath) { return; } // Clear out previously selected vessel _cachedCostData = null; _cachedResources = null; _window.ShipSelected(null); _selectedCraftFilePath = filePath; _craftConfigNode = ConfigNode.Load(filePath); if (_craftConfigNode == null || _craftConfigNode.CountNodes < 1) { _window.ShowAlert(_invalidVesselErrorText); return; } var error = string.Empty; if (!ShipConstruction.AllPartsFound(_craftConfigNode, ref error)) { Debug.LogError($"[KONSTRUCTION] Failed to load vessel at {_selectedCraftFilePath}"); Debug.LogError($"[KONSTRUCTION] {error}"); _window.ShowAlert(_unavailablePartsErrorText); return; } var protoVessel = CreateProtoVessel(); if (protoVessel == null) { _window.ShowAlert(_invalidVesselErrorText); return; } else if (_hasLaunchClamp) { _window.ShowAlert(_launchClampErrorText); return; } _cachedProtoVessel = protoVessel; var partResources = GetResourceCosts(); var konstructorMetadata = new KonstructorMetadata(partResources); var shipName = Localizer.Format(_craftConfigNode.GetValue("ship")); var shipMetadata = new ShipMetadata( shipName, $"{_dryMassText}: {_cachedDryMass:N1} t", $"{_dryCostText}: {_cachedFundsCost:N0}", konstructorMetadata, _cachedThumbnail); _window.ShipSelected(shipMetadata); }
public static Part LoadPartSnapshot(Vessel vessel, ConfigNode node, Vector3 position, Quaternion rotation) { ProtoPartSnapshot snapshot = KAS_Shared.LoadProtoPartSnapshot(node); if (HighLogic.CurrentGame.flightState.ContainsFlightID(snapshot.flightID)) { snapshot.flightID = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState); } snapshot.parentIdx = 0; snapshot.position = position; snapshot.rotation = rotation; snapshot.stageIndex = 0; snapshot.defaultInverseStage = 0; snapshot.seqOverride = -1; snapshot.inStageIndex = -1; snapshot.attachMode = (int)AttachModes.SRF_ATTACH; snapshot.attached = true; snapshot.flagURL = vessel.rootPart.flagURL; // Save properties that may be messed up by new colliders RigidbodyInertia rb_backup = new RigidbodyInertia(vessel.rootPart.rb); Part new_part = snapshot.Load(vessel, false); vessel.Parts.Add(new_part); if (vessel.packed) { GameEvents.onVesselWasModified.Fire(vessel); } else { // Request initialization as nonphysical to prevent explosions new_part.physicalSignificance = Part.PhysicalSignificance.NONE; // Disable all sub-objects with colliders List <Collider> re_enable = new List <Collider>(); foreach (var collider in new_part.GetComponentsInChildren <Collider>()) { if (collider.gameObject.activeSelf) { re_enable.Add(collider); collider.gameObject.SetActive(false); } } new_part.StartCoroutine(WaitAndUnpack(new_part, re_enable)); } rb_backup.Restore(vessel.rootPart.rb); return(new_part); }
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.ty = 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; }
static void Postfix(ShipConstruction __instance, string shipType, int team, ïçîìäîóäìïæ.åéðñðçîîïêç info) { try { Instance.StartCoroutine("doStuff", team); }catch (Exception e) { debugLog(e.Message); } }