private IEnumerator CaptureCraft(Vessel craftVessel) { FlightGlobals.overrideOrbit = true; while (true) { Debug.Log($"[EL] Waiting to capture {craftVessel.vesselName}"); bool partsInitialized = true; foreach (Part p in craftVessel.parts) { if (!p.started) { partsInitialized = false; break; } } builder.RepositionShip(craftVessel); SetCraftOrbit(craftVessel, OrbitDriver.UpdateMode.UPDATE); if (partsInitialized) { break; } OrbitPhysicsManager.HoldVesselUnpack(2); yield return(null); } FlightGlobals.overrideOrbit = false; SetCraftOrbit(craftVessel, OrbitDriver.UpdateMode.UPDATE); craftVessel.GoOffRails(); builder.SetCraftMass(0); CoupleWithCraft(craftVessel); state = State.Transfer; PostCapture(); }
private IEnumerator CaptureCraft() { Vector3 pos; while (true) { bool partsInitialized = true; foreach (Part p in craftVessel.parts) { if (!p.started) { partsInitialized = false; break; } } pos = launchTransform.TransformPoint(craftOffset); craftVessel.SetPosition(pos, true); if (partsInitialized) { break; } OrbitPhysicsManager.HoldVesselUnpack(2); yield return(null); } FlightGlobals.overrideOrbit = false; SetCraftOrbit(); craftVessel.GoOffRails(); builder.SetCraftMass(0); CoupleWithCraft(); state = State.Transfer; PostCapture(); }
public static void SetOrbit(Vessel vessel, Orbit newOrbit) { var destinationMagnitude = newOrbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()).magnitude; try { OrbitPhysicsManager.HoldVesselUnpack(60); } catch (NullReferenceException) { logTM($"{vessel} OrbitPhysicsManager.HoldVesselUnpack threw NullReferenceException"); } var allVessels = FlightGlobals.fetch?.vessels ?? (IEnumerable <Vessel>) new[] { vessel }; foreach (var v in allVessels) { v.GoOnRails(); } var oldBody = vessel.orbitDriver.orbit.referenceBody; HardsetOrbit(vessel.orbitDriver, newOrbit); vessel.orbitDriver.pos = vessel.orbit.pos.xzy; vessel.orbitDriver.vel = vessel.orbit.vel; var newBody = vessel.orbitDriver.orbit.referenceBody; if (newBody != oldBody) { var evnt = new GameEvents.HostedFromToAction <Vessel, CelestialBody>(vessel, oldBody, newBody); GameEvents.onVesselSOIChanged.Fire(evnt); } }
/// <summary> /// Call this method to set a new time using the planetarium /// </summary> public static void StepClock(double targetTick) { if (HighLogic.LoadedScene == GameScenes.LOADING) { LunaLog.Log("[LMP] Skipping StepClock in loading screen"); return; } if (HighLogic.LoadedSceneIsFlight) { if (FlightGlobals.fetch.activeVessel == null || !FlightGlobals.ready) { LunaLog.Log("[LMP] Skipping StepClock (active vessel is null or not ready)"); return; } try { OrbitPhysicsManager.HoldVesselUnpack(5); } catch { LunaLog.LogError("[LMP] Failed to hold vessel unpack"); return; } PutVesselsInPhysicsRangeOnRails(targetTick); } Planetarium.SetUniversalTime(targetTick); }
private static void SetOrbit(this Vessel vessel, Orbit newOrbit) { if (newOrbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()).magnitude > newOrbit.referenceBody.sphereOfInfluence) { LogsManager.ErrorLog("Destination position was above the sphere of influence"); return; } try { OrbitPhysicsManager.HoldVesselUnpack(60); } catch (NullReferenceException) { LogsManager.ErrorLog("OrbitPhysicsManager.HoldVesselUnpack threw NullReferenceException"); } vessel.GoOnRails(); var oldBody = vessel.orbitDriver.orbit.referenceBody; vessel.orbitDriver.UpdateOrbit(newOrbit); vessel.orbitDriver.pos = vessel.orbit.pos.xzy; vessel.orbitDriver.vel = vessel.orbit.vel; var newBody = vessel.orbitDriver.orbit.referenceBody; if (newBody != oldBody) { var evnt = new GameEvents.HostedFromToAction <Vessel, CelestialBody>(vessel, oldBody, newBody); GameEvents.onVesselSOIChanged.Fire(evnt); } }
public static void SetOrbit(this Vessel vessel, Orbit newOrbit) { var destinationMagnitude = newOrbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()).magnitude; if (destinationMagnitude > newOrbit.referenceBody.sphereOfInfluence) { Extensions.ErrorPopup("Destination position was above the sphere of influence"); return; } if (destinationMagnitude < newOrbit.referenceBody.Radius) { Extensions.ErrorPopup("Destination position was below the surface"); return; } vessel.Landed = false; vessel.Splashed = false; vessel.landedAt = string.Empty; var parts = vessel.parts; if (parts != null) { var clamps = parts.Where(p => p.Modules != null && p.Modules.OfType <LaunchClamp>().Any()).ToList(); foreach (var clamp in clamps) { clamp.Die(); } } try { OrbitPhysicsManager.HoldVesselUnpack(60); } catch (NullReferenceException) { Extensions.Log("OrbitPhysicsManager.HoldVesselUnpack threw NullReferenceException"); } var allVessels = FlightGlobals.fetch == null ? (IEnumerable <Vessel>) new[] { vessel } : FlightGlobals.Vessels; foreach (var v in allVessels.Where(v => v.packed == false)) { v.GoOnRails(); } var oldBody = vessel.orbitDriver.orbit.referenceBody; HardsetOrbit(vessel.orbitDriver, newOrbit); vessel.orbitDriver.pos = vessel.orbit.pos.xzy; vessel.orbitDriver.vel = vessel.orbit.vel; var newBody = vessel.orbitDriver.orbit.referenceBody; if (newBody != oldBody) { var evnt = new GameEvents.HostedFromToAction <Vessel, CelestialBody>(vessel, oldBody, newBody); GameEvents.onVesselSOIChanged.Fire(evnt); } }
public static void SetOrbit(this Vessel vessel, Orbit newOrbit) { //var originalUp = FlightGlobals.getUpAxis (); //Log.Info ("originalUp: " + originalUp.ToString ()); var destinationMagnitude = newOrbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()).magnitude; if (destinationMagnitude > newOrbit.referenceBody.sphereOfInfluence) { Extensions.ErrorPopup("Destination position was above the sphere of influence"); return; } if (destinationMagnitude < newOrbit.referenceBody.Radius) { Extensions.ErrorPopup("Destination position was below the surface"); return; } FlightGlobals.fetch.SetShipOrbit(newOrbit.referenceBody.flightGlobalsIndex, newOrbit.eccentricity, newOrbit.semiMajorAxis, newOrbit.inclination, newOrbit.LAN, newOrbit.meanAnomalyAtEpoch, newOrbit.argumentOfPeriapsis, newOrbit.ObT); FloatingOrigin.ResetTerrainShaderOffset(); try { OrbitPhysicsManager.HoldVesselUnpack(60); } catch (NullReferenceException) { Log.Info("OrbitPhysicsManager.HoldVesselUnpack threw NullReferenceException"); } }
/// <summary> /// Switch to the vessel /// </summary> private static IEnumerator SwitchToVessel() { if (VesselToSwitchTo != null) { var tries = 0; var zoom = FlightCamera.fetch.Distance; OrbitPhysicsManager.HoldVesselUnpack(); while (!VesselToSwitchTo.loaded && tries < 100) { tries++; yield return(new WaitForFixedUpdate()); } LunaLog.Log($"Tries: {tries} Loaded: {VesselToSwitchTo.loaded}"); if (!VesselToSwitchTo.loaded) { tries = 0; //Vessels still didn't loaded after 100 fixued update frames, let's wait for 1 more second... while (!VesselToSwitchTo.loaded && tries < 10) { tries++; yield return(new WaitForSeconds(0.1f)); } } FlightGlobals.ForceSetActiveVessel(VesselToSwitchTo); FlightCamera.fetch.SetDistance(zoom); VesselToSwitchTo = null; } }
private IEnumerator EaseSimulationUT_Coroutine(double startUT, double targetUT) { const double dayInSeconds = 86_400; if (targetUT <= Planetarium.GetUniversalTime()) { yield break; } KCTDebug.Log($"Easing jump to simulation UT in {dayInSeconds}s steps"); int currentFrame = Time.frameCount; double nextUT = startUT; while (targetUT - nextUT > dayInSeconds) { nextUT += dayInSeconds; FlightDriver.fetch.framesBeforeInitialSave += Time.frameCount - currentFrame; currentFrame = Time.frameCount; OrbitPhysicsManager.HoldVesselUnpack(); Planetarium.SetUniversalTime(nextUT); yield return(new WaitForFixedUpdate()); } OrbitPhysicsManager.HoldVesselUnpack(); Planetarium.SetUniversalTime(targetUT); }
public static void SetOrbit(this Vessel vessel, Orbit newOrbit) { vessel.PrepVesselTeleport(); try { OrbitPhysicsManager.HoldVesselUnpack(60); } catch (NullReferenceException) { Extensions.Log("OrbitPhysicsManager.HoldVesselUnpack threw NullReferenceException"); } var allVessels = FlightGlobals.fetch?.vessels ?? (IEnumerable <Vessel>) new[] { vessel }; foreach (var v in allVessels) { v.GoOnRails(); } var oldBody = vessel.orbitDriver.orbit.referenceBody; HardsetOrbit(vessel.orbitDriver, newOrbit); vessel.orbitDriver.pos = vessel.orbit.pos.xzy; vessel.orbitDriver.vel = vessel.orbit.vel; var newBody = vessel.orbitDriver.orbit.referenceBody; if (newBody != oldBody) { var evnt = new GameEvents.HostedFromToAction <Vessel, CelestialBody>(vessel, oldBody, newBody); GameEvents.onVesselSOIChanged.Fire(evnt); } }
private void StepClock(double targetTick) { if (HighLogic.LoadedScene == GameScenes.LOADING) { DarkLog.Debug("Skipping StepClock in loading screen"); return; } if (HighLogic.LoadedSceneIsFlight) { if (FlightGlobals.fetch.activeVessel == null || !FlightGlobals.ready) { DarkLog.Debug("Skipping StepClock (active vessel is null or not ready)"); return; } try { OrbitPhysicsManager.HoldVesselUnpack(5); } catch { DarkLog.Debug("Failed to hold vessel unpack"); return; } foreach (Vessel v in FlightGlobals.fetch.vessels) { if (!v.packed) { if (v != FlightGlobals.fetch.activeVessel) { try { v.GoOnRails(); } catch { DarkLog.Debug("Error packing vessel " + v.id.ToString()); } } if (v == FlightGlobals.fetch.activeVessel) { if (SafeToStepClock(v, targetTick)) { try { v.GoOnRails(); } catch { DarkLog.Debug("Error packing active vessel " + v.id.ToString()); } } } } } } Planetarium.SetUniversalTime(targetTick); }
public static void SetOrbit(this Vessel vessel, Orbit newOrbit) { var destinationMagnitude = newOrbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()).magnitude; if (destinationMagnitude > newOrbit.referenceBody.sphereOfInfluence) { UiHelper.WindowHelper.Error("Destination position was above the sphere of influence"); return; } if (destinationMagnitude < newOrbit.referenceBody.Radius) { UiHelper.WindowHelper.Error("Destination position was below the surface"); return; } vessel.PrepVesselTeleport(); try { OrbitPhysicsManager.HoldVesselUnpack(60); } catch (NullReferenceException) { Utils.Log("OrbitPhysicsManager.HoldVesselUnpack threw NullReferenceException"); } var allVessels = FlightGlobals.fetch?.vessels ?? (IEnumerable <Vessel>) new[] { vessel }; foreach (var v in allVessels) { v.GoOnRails(); } var oldBody = vessel.orbitDriver.orbit.referenceBody; HardsetOrbit(vessel.orbitDriver, newOrbit); vessel.orbitDriver.pos = vessel.orbit.pos.xzy; vessel.orbitDriver.vel = vessel.orbit.vel; var newBody = vessel.orbitDriver.orbit.referenceBody; if (newBody != oldBody) { var evnt = new GameEvents.HostedFromToAction <Vessel, CelestialBody>(vessel, oldBody, newBody); GameEvents.onVesselSOIChanged.Fire(evnt); } //vessel.situation = ORBITING if (vessel.situation == Vessel.Situations.ORBITING) { } else { vessel.situation = Vessel.Situations.ORBITING; } }
public static void SetOrbit(this Vessel vessel, Orbit newOrbit) { //var originalUp = FlightGlobals.getUpAxis (); //Log.Info ("originalUp: " + originalUp.ToString ()); var destinationMagnitude = newOrbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()).magnitude; if (destinationMagnitude > newOrbit.referenceBody.sphereOfInfluence) { Extensions.ErrorPopup("Destination position was above the sphere of influence"); return; } if (destinationMagnitude < newOrbit.referenceBody.Radius) { Extensions.ErrorPopup("Destination position was below the surface"); return; } vessel.PrepVesselTeleport(); try { OrbitPhysicsManager.HoldVesselUnpack(60); } catch (NullReferenceException) { Log.Info("OrbitPhysicsManager.HoldVesselUnpack threw NullReferenceException"); } var allVessels = FlightGlobals.fetch == null ? (IEnumerable <Vessel>) new[] { vessel } : FlightGlobals.Vessels; foreach (var v in allVessels.Where(v => v.packed == false)) { v.GoOnRails(); } var oldBody = vessel.orbitDriver.orbit.referenceBody; Log.Info("oldBody: " + oldBody.ToString()); HardsetOrbit(vessel.orbitDriver, newOrbit); vessel.orbitDriver.pos = vessel.orbit.pos.xzy; vessel.orbitDriver.vel = vessel.orbit.vel; var newBody = vessel.orbitDriver.orbit.referenceBody; Log.Info("newBody: " + newBody.ToString()); if (newBody != oldBody) { var evnt = new GameEvents.HostedFromToAction <Vessel, CelestialBody>(vessel, oldBody, newBody); GameEvents.onVesselSOIChanged.Fire(evnt); } }
/// <summary> /// Reloads an existing vessel into the game. Try to avoid this method as possible. It has really bad performance and /// works really bad if you are reloading your own current vessel... /// </summary> public static bool ReloadVessel(ProtoVessel vesselProto) { if (vesselProto == null) { return(false); } LunaLog.Log($"Reloading vessel {vesselProto.vesselID}"); ReloadingVesselId = vesselProto.vesselID; try { //Are we realoading our current active vessel? var reloadingCurrentVessel = FlightGlobals.ActiveVessel?.id == vesselProto.vesselID; //Load the existing target, if any. We will use this to reset the target to the newly loaded vessel, if the vessel we're reloading is the one that is targeted. var currentTargetId = FlightGlobals.fetch.VesselTarget?.GetVessel()?.id; //If targeted, unloading the vessel will cause the target to be lost. We'll have to reset it later. //Bear in mind that UnloadVessel will trigger VesselRemoveEvents.OnVesselWillDestroy!! So be sure to set ReloadingVesselId correctly VesselRemoveSystem.Singleton.KillVessel(vesselProto.vesselID, "Reloading vessel", false, false); if (LoadVesselImpl(vesselProto)) { //Case when the target is the vessel we are changing if (currentTargetId == vesselProto.vesselID) { //Record the time immediately before calling SetVesselTarget to remove it's message var currentTime = Time.realtimeSinceStartup; FlightGlobals.fetch.SetVesselTarget(vesselProto.vesselRef, true); RemoveSetTargetMessages(currentTime); } if (reloadingCurrentVessel) { OrbitPhysicsManager.HoldVesselUnpack(); FlightGlobals.fetch.activeVessel.GoOnRails(); VesselSwitcherSystem.Singleton.SwitchToVessel(vesselProto.vesselID); } return(true); } return(false); } catch (Exception e) { LunaLog.LogError($"[LMP]: Error reloading vessel: {e}"); return(false); } finally { ReloadingVesselId = Guid.Empty; } }
public static void LowTechWarp(CelestialBody TargetBody, float TimeFactor) { Debug.Log(Utils.Log("BMSHyperdrive.WarpDriver.LowTechWarp is Triggered. Beginning jump drive action.")); System.Random days = new System.Random(); int orbdays = days.Next(1, 10); Orbit orbit = Orbit.CreateRandomOrbitFlyBy(TargetBody, (orbdays / 10)); //Create random orbit parameters ///These warp drives blow raspberries at reality in a way that has some issues- ///one of them being going forward in time 20000 seconds- and even more for Kerbin warping ///Remember kids, DON'T BLOW RASPBERRIES AT REALITY!!! //Time warp - Set new UT var OldUT = Planetarium.GetUniversalTime(); var UTChange = TimeFactor * 1.667; var NewUT = (OldUT + UTChange); Planetarium.SetUniversalTime(NewUT); print(Utils.Log("UT updated. New UT: " + NewUT + ". Jumping.")); if (FlightGlobals.ActiveVessel != null) //If you have a vessel { print(Utils.Log("Activating WarpDrive, property FlightGlobals.ActiveVessel has a value.")); OrbitPhysicsManager.HoldVesselUnpack(60); FlightGlobals.ActiveVessel.GoOnRails(); //Make vessel controllable by code //Set vessel orbit params to those generated earlier FlightGlobals.ActiveVessel.orbit.referenceBody = orbit.referenceBody; FlightGlobals.ActiveVessel.orbit.LAN = orbit.LAN; FlightGlobals.ActiveVessel.orbit.semiMajorAxis = orbit.semiMajorAxis; FlightGlobals.ActiveVessel.orbit.eccentricity = orbit.eccentricity; FlightGlobals.ActiveVessel.orbit.inclination = orbit.inclination; FlightGlobals.ActiveVessel.orbit.argumentOfPeriapsis = orbit.argumentOfPeriapsis; FlightGlobals.ActiveVessel.orbit.meanAnomalyAtEpoch = orbit.meanAnomalyAtEpoch; FlightGlobals.ActiveVessel.orbit.epoch = orbit.epoch; FlightGlobals.ActiveVessel.orbitDriver.orbit = orbit; //Activate OPS-201 PRO - Inotialize orbit FlightGlobals.ActiveVessel.orbitDriver.orbit.Init(); FlightGlobals.ActiveVessel.orbitDriver.orbit.UpdateFromUT(Planetarium.GetUniversalTime()); } else { print(Utils.Log("Error. Could not initiate Jump Drive. Property FlightGlobals.ActiveVessel is null.")); print(Utils.Log(String.Format("How on ", FlightGlobals.GetHomeBodyDisplayName(), "did you even call this if there is no active vessel?"))); return; } }
private void MakeOrbit(OrbitDriver driver, CelestialBody reference) { Debug.Log("Jumping to " + partnerBody); CelestialBody oldBody = driver.referenceBody; FlightGlobals.overrideOrbit = true; FlightGlobals.fetch.Invoke("disableOverride", 2f); driver.vessel.Landed = false; driver.vessel.Splashed = false; driver.vessel.SetLandedAt(""); driver.vessel.KillPermanentGroundContact(); driver.vessel.ResetGroundContact(); FlightGlobals.currentMainBody = reference; OrbitPhysicsManager.SetDominantBody(reference); // Pack vessels foreach (Vessel vessel in FlightGlobals.Vessels) { if (!vessel.packed) { vessel.GoOnRails(); } } // Disable inverse rotation foreach (CelestialBody body in PSystemManager.Instance.localBodies) { body.inverseRotation = false; } driver.orbit.referenceBody = reference; driver.updateFromParameters(); // Finalize Vessel Movement CollisionEnhancer.bypass = true; FloatingOrigin.SetOffset(driver.vessel.transform.position); OrbitPhysicsManager.CheckReferenceFrame(); OrbitPhysicsManager.HoldVesselUnpack(10); if (reference != oldBody) { GameEvents.onVesselSOIChanged.Fire( new GameEvents.HostedFromToAction <Vessel, CelestialBody>(driver.vessel, oldBody, reference)); } driver.vessel.IgnoreGForces(20); }
/// <summary> /// Call this method to set a new time /// </summary> public static void StepClock(double targetTick) { if (HighLogic.LoadedScene == GameScenes.LOADING) { LunaLog.Log("[LMP] Skipping StepClock in loading screen"); return; } if (HighLogic.LoadedSceneIsFlight) { if (FlightGlobals.fetch.activeVessel == null || !FlightGlobals.ready) { LunaLog.Log("[LMP] Skipping StepClock (active vessel is null or not ready)"); return; } try { OrbitPhysicsManager.HoldVesselUnpack(5); } catch { LunaLog.LogError("[LMP] Failed to hold vessel unpack"); return; } foreach (var vessel in FlightGlobals.VesselsLoaded.Where(v => !v.packed)) { if (vessel.isActiveVessel && SafeToStepClock(vessel, targetTick) || !vessel.isActiveVessel && vessel.situation != Vessel.Situations.PRELAUNCH) { try { //For prelaunch vessels, we should not go on rails as this will reset the throttles and such vessel.GoOnRails(); } catch { LunaLog.LogError(vessel.isActiveVessel ? $"[LMP] Error packing active vessel {vessel.id}" : $"[LMP] Error packing vessel {vessel.id}"); } } } } Planetarium.SetUniversalTime(targetTick); }
private static void WarpShip(Vessel vessel, Orbit newOrbit) { if (newOrbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()).magnitude > newOrbit.referenceBody.sphereOfInfluence) { return; } vessel.Landed = false; vessel.Splashed = false; vessel.landedAt = string.Empty; var parts = vessel.parts; if (parts != null) { var clamps = parts.Where(p => p.Modules != null && p.Modules.OfType <LaunchClamp>().Any()).ToList(); foreach (var clamp in clamps) { clamp.Die(); } } try { OrbitPhysicsManager.HoldVesselUnpack(60); } catch (NullReferenceException) { } foreach (var v in (FlightGlobals.fetch == null ? (IEnumerable <Vessel>) new[] { vessel } : FlightGlobals.Vessels).Where(v => v.packed == false)) { v.GoOnRails(); } HardsetOrbit(vessel.orbit, newOrbit); vessel.orbitDriver.pos = vessel.orbit.pos.xzy; vessel.orbitDriver.vel = vessel.orbit.vel; }
/// <summary> /// Advance the orbit epoch to the specified time sent as parameter /// </summary> public static void AdvanceShipPosition(this Vessel vessel, double time) { //If we advance the orbit when flying, we risk going inside the terrain as the orbit goes deep down the planet! if (vessel.situation <= Vessel.Situations.FLYING) { return; } var obtPos = vessel.orbit.getRelativePositionAtUT(time); var obtVel = vessel.orbit.getOrbitalVelocityAtUT(time); if (!vessel.packed) { vessel.GoOnRails(); } vessel.orbit.UpdateFromStateVectors(obtPos, obtVel, vessel.mainBody, time); vessel.orbitDriver.updateFromParameters(); OrbitPhysicsManager.CheckReferenceFrame(); OrbitPhysicsManager.HoldVesselUnpack(10); vessel.IgnoreGForces(20); }
IEnumerator SpawnCoRoutine() { if ((vessel.Parts[0] != null) && (vessel.Parts[0].Rigidbody != null)) { vessel.Parts[0].Rigidbody.isKinematic = true; } //vessel.GoOnRails(); while ((vessel.packed) && (vessel.acceleration.magnitude == 0)) { vessel.SetPosition(launchPoint); yield return(null); } while (true) { bool partsInitialized = true; foreach (Part p in vessel.parts) { if (!p.started) { partsInitialized = false; break; } } vessel.SetPosition(launchPoint, true); //vessel.SetWorldVelocity(Vector3d.up * 0); if (partsInitialized) { break; } OrbitPhysicsManager.HoldVesselUnpack(2); yield return(null); } vessel.GoOffRails(); //flare.IgnoreGForces(250); Log.Info("Final Latitude: " + vessel.latitude + ", Longitude: " + vessel.longitude); }
public static void MedTechWarp(CelestialBody TargetBody, float UTChange) { print("MrcarrotBMSHyperdrive.WarpDriver.MedTechWarp is Triggered. Beginning jump drive action."); //Ccreate orbital params and change UT var orbit = Orbit.CreateRandomOrbitAround(TargetBody, TargetBody.Radius + (TargetBody.sphereOfInfluence - 120000), TargetBody.Radius + (TargetBody.sphereOfInfluence - 100000)); var OldUT = Planetarium.GetUniversalTime(); var NewUT = (OldUT + UTChange); Planetarium.SetUniversalTime(NewUT); print(Utils.Log("UT updated. Jumping.")); if (FlightGlobals.ActiveVessel != null) { print(Utils.Log("Activating WarpDrive, property FlightGlobals.ActiveVessel has a value.")); OrbitPhysicsManager.HoldVesselUnpack(60); FlightGlobals.ActiveVessel.GoOnRails(); FlightGlobals.ActiveVessel.orbit.referenceBody = orbit.referenceBody; FlightGlobals.ActiveVessel.orbit.LAN = orbit.LAN; FlightGlobals.ActiveVessel.orbit.semiMajorAxis = orbit.semiMajorAxis; FlightGlobals.ActiveVessel.orbit.eccentricity = orbit.eccentricity; FlightGlobals.ActiveVessel.orbit.inclination = orbit.inclination; FlightGlobals.ActiveVessel.orbit.argumentOfPeriapsis = orbit.argumentOfPeriapsis; FlightGlobals.ActiveVessel.orbit.meanAnomalyAtEpoch = orbit.meanAnomalyAtEpoch; FlightGlobals.ActiveVessel.orbit.epoch = orbit.epoch; FlightGlobals.ActiveVessel.orbitDriver.orbit = orbit; FlightGlobals.ActiveVessel.orbitDriver.orbit.Init(); FlightGlobals.ActiveVessel.orbitDriver.orbit.UpdateFromUT(Planetarium.GetUniversalTime()); } else { Debug.LogError(Utils.Log("BMSHyperdrive.WarpDriver.MedTechWarp has encountered an 'anomaly'. Jump canceled.")); print("How on Kerbin did you even call this if there is no active vessel?"); return; } }
private void ConfirmInterface(int GuiID) // Second beacon interface window. { GUIStyle buttonNeutral = new GUIStyle(GUI.skin.button); buttonNeutral.padding = new RectOffset(8, 8, 8, 8); buttonNeutral.normal.textColor = buttonNeutral.focused.textColor = Color.white; buttonNeutral.hover.textColor = buttonNeutral.active.textColor = Color.white; GUIStyle labelHasFuel = new GUIStyle(GUI.skin.label); labelHasFuel.normal.textColor = Color.green; GUIStyle labelNoFuel = new GUIStyle(GUI.skin.label); labelNoFuel.normal.textColor = Color.red; GUILayout.BeginVertical(HighLogic.Skin.scrollView); if (nearBeacon != null) { double tripdist = Vector3d.Distance(nearBeacon.vessel.GetWorldPos3D(), farBeacon.GetWorldPos3D()); double tonnage = vessel.GetTotalMass(); Vessel nbparent = nearBeacon.vessel; string nbModel = nearBeacon.beaconModel; double tripcost = getTripBaseCost(tripdist, tonnage, nbModel); double driftpenalty = Math.Pow(Math.Floor(nearBeaconDistance / 200), 2) + Math.Floor(Math.Pow(nearBeaconRelVel, 1.5)); if (driftpenalty > 0) { GUILayout.Label("+" + driftpenalty + "% due to Drift."); } Dictionary <Part, string> HCUParts = getHCUParts(vessel); if (!nearBeacon.hasHCU) { if (vessel.GetCrewCount() > 0 || HCUParts.Count > 0) { GUILayout.Label("WARNING: This beacon has no active Heisenkerb Compensator.", labelNoFuel); } if (vessel.GetCrewCount() > 0) { GUILayout.Label("Transfer will kill crew.", labelNoFuel); } if (HCUParts.Count > 0) { GUILayout.Label("These resources will destabilize in transit:", labelNoFuel); foreach (KeyValuePair <Part, string> hcuresource in HCUParts) { GUILayout.Label(hcuresource.Key.name + " - " + hcuresource.Value, labelNoFuel); } } } GUILayout.Label("Confirm Warp:"); var basecost = Math.Round(tripcost * 100) / 100; GUILayout.Label("Base Cost: " + basecost + " Karborundum."); double sciBonus = nearBeacon.getCrewBonuses(nbparent, "Scientist", 0.5, 5); if (nearBeacon.hasSCU) { if (driftpenalty == 0 && sciBonus >= 0.9) { GUILayout.Label("Superconducting Coil Array reduces cost by 10%."); tripcost *= 0.9; } if (sciBonus < 0.9 || (sciBonus < 1 && driftpenalty > 0)) { double dispBonus = Math.Round((1 - sciBonus) * 100); GUILayout.Label("Scientists on beacon vessel reduce cost by " + dispBonus + "%."); tripcost *= sciBonus; } } if (driftpenalty > 0) { GUILayout.Label("Relative speed and distance to beacon adds " + driftpenalty + "%."); } tripcost += tripcost * (driftpenalty * .01); tripcost = Math.Round(tripcost * 100) / 100; if (nearBeacon.hasAMU) { double AMUCost = getAMUCost(vessel, farBeacon, tonnage, nearBeacon.beaconModel); GUILayout.Label("AMU Compensation adds " + AMUCost + " Karborundum."); tripcost += AMUCost; } if (nearBeacon.hasHCU) { double adjHCUCost = HCUCost; if (nearBeacon.beaconModel == "IB1") { adjHCUCost = Math.Round((HCUCost - (tripcost * 0.02)) * 100) / 100; } GUILayout.Label("HCU Shielding adds " + adjHCUCost + " Karborundum."); tripcost += adjHCUCost; } GUILayout.Label("Total Cost: " + tripcost + " Karborundum."); GUILayout.Label("Destination: " + farBeacon.mainBody.name + " at " + Math.Round(farBeacon.altitude / 1000) + "km."); precision = getTripSpread(tripdist, farBeaconModel); GUILayout.Label("Transfer will emerge within " + precision + "m of destination beacon."); if (farBeacon.altitude - precision <= farBeacon.mainBody.Radius * 0.1f || farBeacon.altitude - precision <= farBeacon.mainBody.atmosphereDepth) { GUILayout.Label("Arrival area is very close to " + farBeacon.mainBody.name + ".", labelNoFuel); } if (!nearBeacon.hasAMU) { Vector3d transferVelOffset = getJumpOffset(vessel, farBeacon, nearBeacon.beaconModel) - farBeacon.orbit.vel; GUILayout.Label("Velocity relative to exit beacon will be " + Math.Round(transferVelOffset.magnitude) + "m/s."); } double retTripCost = 0; double checkfuel = 0; bool fuelcheck = false; foreach (ProtoPartSnapshot ppart in farBeacon.protoVessel.protoPartSnapshots) { foreach (ProtoPartModuleSnapshot pmod in ppart.modules) { if (pmod.moduleName == "ESLDBeacon" && pmod.moduleValues.GetValue("beaconStatus") == "Active.") { string pmodel = pmod.moduleValues.GetValue("beaconModel"); fuelcheck = double.TryParse(pmod.moduleValues.GetValue("fuelOnBoard"), out checkfuel); if (retTripCost < getTripBaseCost(tripdist, tonnage, pmodel)) { retTripCost = getTripBaseCost(tripdist, tonnage, pmodel); } } } } string fuelmessage = "Destination beacon's fuel could not be checked."; if (fuelcheck) { fuelmessage = "Destination beacon has " + checkfuel + " Karborundum."; } GUILayout.Label(fuelmessage); retTripCost = Math.Round(retTripCost * 100) / 100; if (retTripCost <= checkfuel) { GUILayout.Label("Destination beacon can make return trip using " + retTripCost + " (base cost) Karborundum.", labelHasFuel); } else { GUILayout.Label("Destination beacon would need " + retTripCost + " (base cost) Karborundum for return trip using active beacons.", labelNoFuel); } if (oPredict != null) { updateExitOrbit(vessel, farBeacon, nearBeacon.beaconModel); } if (GUILayout.Button("Confirm and Warp", buttonNeutral)) { RenderingManager.RemoveFromPostDrawQueue(4, new Callback(drawConfirm)); HailerGUIClose(); if (oPredict != null) { hideExitOrbit(oPredict); } // Check transfer path one last time. KeyValuePair <string, CelestialBody> checkpath = masterClass.HasTransferPath(nbparent, farBeacon, nearBeacon.gLimit); // One more check for a clear path in case they left the window open too long. bool finalPathCheck = false; if (checkpath.Key == "OK") { finalPathCheck = true; } // Check fuel one last time. fuelcheck = false; fuelcheck = nearBeacon.requireResource(nbparent, "Karborundum", tripcost, true); if (fuelcheck && finalPathCheck) // Fuel is paid for and path is clear. { // Buckle up! if (!nearBeacon.hasHCU) // Penalize for HCU not being present/online. { List <ProtoCrewMember> crewList = new List <ProtoCrewMember>(); List <Part> crewParts = new List <Part>(); foreach (Part vpart in vessel.Parts) { foreach (ProtoCrewMember crew in vpart.protoModuleCrew) { crewParts.Add(vpart); crewList.Add(crew); } } for (int i = crewList.Count - 1; i >= 0; i--) { if (i >= crewList.Count) { if (crewList.Count == 0) { break; } i = crewList.Count - 1; } ProtoCrewMember tempCrew = crewList[i]; crewList.RemoveAt(i); ScreenMessages.PostScreenMessage(tempCrew.name + " was killed in transit!", 5.0f, ScreenMessageStyle.UPPER_CENTER); crewParts[i].RemoveCrewmember(tempCrew); crewParts.RemoveAt(i); tempCrew.Die(); } HCUParts = getHCUParts(vessel); List <Part> HCUList = new List <Part>(); foreach (KeyValuePair <Part, string> HCUPart in HCUParts) { HCUList.Add(HCUPart.Key); } HCUParts.Clear(); for (int i = HCUList.Count - 1; i >= 0; i--) { if (i >= HCUList.Count) { if (HCUList.Count == 0) { break; } i = HCUList.Count - 1; } Part tempPart = HCUList[i]; HCUList.RemoveAt(i); tempPart.explosionPotential = 1; tempPart.explode(); tempPart.Die(); } } masterClass.dazzle(); Vector3d transferVelOffset = getJumpOffset(vessel, farBeacon, nearBeacon.beaconModel); if (nearBeacon.hasAMU) { transferVelOffset = farBeacon.orbit.vel; } Vector3d spread = ((UnityEngine.Random.onUnitSphere + UnityEngine.Random.insideUnitSphere) / 2) * (float)precision; vessel.Landed = false; vessel.Splashed = false; vessel.landedAt = string.Empty; OrbitPhysicsManager.HoldVesselUnpack(180); nbparent.GoOnRails(); vessel.GoOnRails(); vessel.situation = Vessel.Situations.ORBITING; vessel.orbit.UpdateFromStateVectors(farBeacon.orbit.pos + spread, transferVelOffset, farBeacon.mainBody, Planetarium.GetUniversalTime()); vessel.orbit.Init(); vessel.orbit.UpdateFromUT(Planetarium.GetUniversalTime()); vessel.orbitDriver.pos = vessel.orbit.pos.xzy; vessel.orbitDriver.vel = vessel.orbit.vel; } else if (!fuelcheck && finalPathCheck) { ScreenMessages.PostScreenMessage("Jump failed! Origin beacon did not have enough fuel to execute transfer.", 5.0f, ScreenMessageStyle.UPPER_CENTER); } else if (!finalPathCheck) { ScreenMessages.PostScreenMessage("Jump Failed! Transfer path has become obstructed.", 5.0f, ScreenMessageStyle.UPPER_CENTER); } else { ScreenMessages.PostScreenMessage("Jump Failed! Origin beacon cannot complete transfer.", 5.0f, ScreenMessageStyle.UPPER_CENTER); } } } else { if (oPredict != null) { hideExitOrbit(oPredict); } } if (!vessel.isActiveVessel) { RenderingManager.RemoveFromPostDrawQueue(4, new Callback(drawConfirm)); if (oPredict != null) { hideExitOrbit(oPredict); } } if (GUILayout.Button("Back", buttonNeutral)) { RenderingManager.RemoveFromPostDrawQueue(4, new Callback(drawConfirm)); HailerGUIOpen(); if (oPredict != null) { hideExitOrbit(oPredict); } } GUILayout.EndVertical(); GUI.DragWindow(new Rect(0, 0, 10000, 20)); }
private void StepClock(double targetTick) { if (HighLogic.LoadedScene == GameScenes.LOADING) { DarkLog.Debug("Skipping StepClock in loading screen"); return; } if (HighLogic.LoadedSceneIsFlight) { if (FlightGlobals.fetch.activeVessel != null) { if (FlightGlobals.fetch.activeVessel.patchedConicRenderer == null || FlightGlobals.fetch.activeVessel.patchedConicRenderer.solver == null || FlightGlobals.fetch.activeVessel.patchedConicRenderer.solver.maneuverNodes == null) { DarkLog.Debug("Skipping StepClock (standalone map viewer workaround)"); return; } } else { DarkLog.Debug("Skipping StepClock (active vessel is null)"); return; } try { OrbitPhysicsManager.HoldVesselUnpack(5); } catch { DarkLog.Debug("Failed to hold vessel unpack"); return; } foreach (Vessel v in FlightGlobals.fetch.vessels) { if (!v.packed) { if (v != FlightGlobals.fetch.activeVessel) { try { v.GoOnRails(); } catch { DarkLog.Debug("Error packing vessel " + v.id.ToString()); } } if (v == FlightGlobals.fetch.activeVessel) { if (SafeToStepClock(v, targetTick)) { try { v.GoOnRails(); } catch { DarkLog.Debug("Error packing active vessel " + v.id.ToString()); } } } } } } Planetarium.SetUniversalTime(targetTick); }
public SpacefoldState setOrbit(CelestialBody targetBody) { // Current orbit Orbit currentOrbit = vessel.orbit; // Tech Efficiency int techEfficiency = core.dataControl.GetHoltzmanTechEfficiency(); System.Random rand = new System.Random(); Orbit newOrbit = new Orbit(); // New values newOrbit.inclination = Convert.ToDouble(rand.Next((int)currentOrbit.inclination, (int)20)); newOrbit.eccentricity = Convert.ToDouble(rand.Next((int)currentOrbit.eccentricity, (int)10)); newOrbit.semiMajorAxis = targetBody.Radius + (targetBody.sphereOfInfluence / techEfficiency); newOrbit.LAN = 90; newOrbit.argumentOfPeriapsis = 90; newOrbit.meanAnomalyAtEpoch = 0; newOrbit.epoch = 0; newOrbit.referenceBody = targetBody; Debug.Log("inclination: " + newOrbit.inclination); Debug.Log("eccentricity: " + newOrbit.eccentricity); Debug.Log("semiMajorAxis: " + newOrbit.semiMajorAxis); if (newOrbit.getRelativePositionAtUT(Planetarium.GetUniversalTime()).magnitude > newOrbit.referenceBody.sphereOfInfluence) { Debug.LogError("Destination position was above the sphere of influence"); return(SpacefoldState.ABOVE_SOI); } vessel.Landed = false; vessel.Splashed = false; vessel.landedAt = string.Empty; try { OrbitPhysicsManager.HoldVesselUnpack(60); } catch (Exception e) { Debug.LogError("[Dune] NavigatorControl setOrbit() exception on physicsManager: " + e); } foreach (var v in (FlightGlobals.fetch == null ? (IEnumerable <Vessel>) new[] { vessel } : FlightGlobals.Vessels).Where(v => v.packed == false)) { v.GoOnRails(); } // Set new values. vessel.orbit.inclination = newOrbit.inclination; vessel.orbit.eccentricity = newOrbit.eccentricity; vessel.orbit.semiMajorAxis = newOrbit.semiMajorAxis; vessel.orbit.LAN = newOrbit.LAN; vessel.orbit.argumentOfPeriapsis = newOrbit.argumentOfPeriapsis; vessel.orbit.meanAnomalyAtEpoch = newOrbit.meanAnomalyAtEpoch; vessel.orbit.epoch = newOrbit.epoch; vessel.orbit.referenceBody = newOrbit.referenceBody; vessel.orbit.Init(); vessel.orbit.UpdateFromUT(Planetarium.GetUniversalTime()); vessel.orbitDriver.pos = vessel.orbit.pos.xzy; vessel.orbitDriver.vel = vessel.orbit.vel; spacefoldInProgress = false; return(SpacefoldState.SUCCESS); }
public static WaitForFixedUpdate ForFixedUpdate() { OrbitPhysicsManager.HoldVesselUnpack(2); return(new WaitForFixedUpdate()); }
public static void DelayPhysicsForSeconds(float dt) { OrbitPhysicsManager.HoldVesselUnpack(Mathf.CeilToInt(dt / TimeWarp.fixedDeltaTime) + 1); }
public void Develocitize() { // This code is inspired quite heavily by HyperEdit's OrbitEditor.cs if (recharge <= 0.0f) { double ut = Planetarium.GetUniversalTime(); Orbit curo = vessel.orbitDriver.orbit; Vector3d currentVelocity = curo.getOrbitalVelocityAtUT(ut); Vector3d prograde = currentVelocity.normalized; bool nomoon = false; Vector3d vlocal = new Vector3d(0.0, 0.0, 0.0); Vector3d vplanetary = new Vector3d(0.0, 0.0, 0.0); if (vessel.mainBody && vessel.mainBody.orbitDriver) { vlocal = vessel.mainBody.orbitDriver.orbit.getOrbitalVelocityAtUT(ut); CelestialBody rb = vessel.mainBody.referenceBody; if (rb != null && rb != vessel.mainBody && rb.orbitDriver) { vplanetary = rb.orbitDriver.orbit.getOrbitalVelocityAtUT(ut); } else { vplanetary = vlocal; vlocal = new Vector3d(0.0, 0.0, 0.0); nomoon = true; } } // Do not call GetObtVelocity and expect it to work with this code // It switches around Y and Z Vector3d velocityToCancel = new Vector3d(0.0, 0.0, 0.0); if (rFrameVal > 0) { velocityToCancel += vlocal; } if (rFrameVal > 1) { velocityToCancel += vplanetary; } Vector3d exVelocityToCancel = velocityToCancel; velocityToCancel += currentVelocity; double speedToCancel = velocityToCancel.magnitude; double powerCost = (int)speedToCancel * powerMultiplier; double powerGot = WSXStuff.ThingAvailable(vessel, resourceUsed); if (powerGot < powerCost) { rechargeNotice = "Partial Devlocitize"; this.recharge = 5.0f; powerCost = powerGot; } powerDrain = (float)powerCost; maxPowerDrain = powerDrain; part.Effect(engageEffectName, 1.0f); // Extremely small velocities cause the game to mess up very badly, so try something small and increase... float mult = 0.0f; if (rFrameVal == 0 || nomoon) { mult = 2.0f; } Orbit newo; do { Vector3d retro = prograde * -mult; newo = new Orbit(curo.inclination, curo.eccentricity, curo.semiMajorAxis, curo.LAN, curo.argumentOfPeriapsis, curo.meanAnomalyAtEpoch, curo.epoch, curo.referenceBody); newo.UpdateFromStateVectors(curo.pos, retro - exVelocityToCancel, curo.referenceBody, ut); mult += 1.0f; } while (double.IsNaN(newo.getOrbitalVelocityAtUT(ut).magnitude)); mult -= 1.0f; print("[WSXDV] Needed Multiplier " + mult.ToString()); vessel.Landed = false; vessel.Splashed = false; vessel.landedAt = string.Empty; // I'm actually not sure what this is for... but HyperEdit does it. // I had weird problems when I took it out, anyway. try { OrbitPhysicsManager.HoldVesselUnpack(60); } catch (NullReferenceException) { print("[WSXDV] NullReferenceException"); } var allVessels = FlightGlobals.fetch == null ? (IEnumerable <Vessel>) new[] { vessel } : FlightGlobals.Vessels; foreach (var v in allVessels.Where(v => v.packed == false)) { v.GoOnRails(); } // End HyperEdit code I don't really understand curo.inclination = newo.inclination; curo.eccentricity = newo.eccentricity; curo.semiMajorAxis = newo.semiMajorAxis; curo.LAN = newo.LAN; curo.argumentOfPeriapsis = newo.argumentOfPeriapsis; curo.meanAnomalyAtEpoch = newo.meanAnomalyAtEpoch; curo.epoch = newo.epoch; curo.Init(); curo.UpdateFromUT(ut); vessel.orbitDriver.pos = vessel.orbit.pos.xzy; vessel.orbitDriver.vel = vessel.orbit.vel; Events ["Develocitize"].active = false; this.recharge = 5.0f; } }
public void Warp(Vessel target, Vessel destination, float precision, List <Part> unsafeParts = null) { float tripdist = Vector3.Distance(base.vessel.GetWorldPos3D(), destination.GetWorldPos3D()); float totalMass = target.GetTotalMass(); float cost = GetTripFinalCost(GetTripBaseCost(tripdist, totalMass), target, destination, totalMass, unsafeParts); HailerGUI.PathCheck pathCheck = new HailerGUI.PathCheck(base.vessel, destination, gLimitEff); if (pathCheck.clear) { if (jumpResources.All(res => RequireResource(res.resID, (double)(res.ratio * cost), false))) { jumpResources.All(res => RequireResource(res.resID, (double)(res.ratio * cost), true)); HailerButton.Instance.Dazzle(); Vector3d transferVelOffset = GetJumpVelOffset(target, destination); if (hasAMU) { transferVelOffset = destination.orbit.vel; } Vector3d vector3d = (UnityEngine.Random.onUnitSphere + UnityEngine.Random.insideUnitSphere) / 2f * precision; // Making the spread less likely to throw you outside the SoI of the body. if ((destination.orbit.pos + vector3d).magnitude > destination.mainBody.sphereOfInfluence) { vector3d = -vector3d; // Negative random is equally random. } OrbitDriver orbitDriver = target.orbitDriver; Orbit orbit = orbitDriver.orbit; Orbit orbit2 = new Orbit(orbit.inclination, orbit.eccentricity, orbit.semiMajorAxis, orbit.LAN, orbit.argumentOfPeriapsis, orbit.meanAnomalyAtEpoch, orbit.epoch, orbit.referenceBody); orbit2.UpdateFromStateVectors(destination.orbit.pos + vector3d, transferVelOffset, destination.mainBody, Planetarium.GetUniversalTime()); target.Landed = false; target.Splashed = false; target.landedAt = string.Empty; OrbitPhysicsManager.HoldVesselUnpack(60); List <Vessel> vessels = FlightGlobals.Vessels; foreach (Vessel item in vessels.AsEnumerable()) { if (!item.packed) { item.GoOnRails(); } } CelestialBody referenceBody = target.orbitDriver.orbit.referenceBody; orbit.inclination = orbit2.inclination; orbit.eccentricity = orbit2.eccentricity; orbit.semiMajorAxis = orbit2.semiMajorAxis; orbit.LAN = orbit2.LAN; orbit.argumentOfPeriapsis = orbit2.argumentOfPeriapsis; orbit.meanAnomalyAtEpoch = orbit2.meanAnomalyAtEpoch; orbit.epoch = orbit2.epoch; orbit.referenceBody = orbit2.referenceBody; orbit.Init(); orbit.UpdateFromUT(Planetarium.GetUniversalTime()); if ((UnityEngine.Object)orbit.referenceBody != (UnityEngine.Object)orbit2.referenceBody) { orbitDriver.OnReferenceBodyChange?.Invoke(orbit2.referenceBody); } target.orbitDriver.pos = target.orbit.pos.xzy; target.orbitDriver.vel = target.orbit.vel; if ((UnityEngine.Object)target.orbitDriver.orbit.referenceBody != (UnityEngine.Object)referenceBody) { GameEvents.onVesselSOIChanged.Fire(new GameEvents.HostedFromToAction <Vessel, CelestialBody>(target, referenceBody, target.orbitDriver.orbit.referenceBody)); } if (UnsafeTransfer) { if (unsafeParts == null) { unsafeParts = HailerGUI.GetHCUParts(target).Keys.ToList(); } for (int i = unsafeParts.Count - 1; i >= 0; i--) { unsafeParts[i].explosionPotential = Mathf.Max(1f, unsafeParts[i].explosionPotential); unsafeParts[i].explode(); } for (int i = base.vessel.parts.Count - 1; i >= 0; i--) { Part part = base.vessel.parts[i]; for (int j = part.protoModuleCrew.Count - 1; j >= 0; j--) { ProtoCrewMember protoCrewMember = part.protoModuleCrew[j]; ScreenMessages.PostScreenMessage(protoCrewMember.name + " was killed in transit!", 5f, ScreenMessageStyle.UPPER_CENTER); base.vessel.parts[i].RemoveCrewmember(protoCrewMember); protoCrewMember.Die(); } } } } else { ScreenMessages.PostScreenMessage("Jump failed! Origin beacon did not have enough fuel to execute transfer.", 5f, ScreenMessageStyle.UPPER_CENTER); } } }