// FIXME to be part of an update loop (maybe) // void EjectOnImpendingDoom() // { // if (!ejected && ejectOnImpendingDoom * (float)vessel.srfSpeed > ai.terrainAlertDistance) // { // KerbalSafety.Instance.Eject(vessel, this); // Abandon ship! // ai.avoidingTerrain = false; // } // } #region Ejection /// <summary> /// Eject from a vessel. /// </summary> public void Eject() { if (ejected) { return; // We've already ejected. } if (kerbalEVA != null) { if (kerbalEVA.isActiveAndEnabled) // Otherwise, they've been killed already and are being cleaned up by KSP. { if (seat != null && kerbalEVA.IsSeated()) // Leave the seat. { Debug.Log("[KerbalSafety]: " + kerbalName + " is leaving their seat on " + seat.part.vessel.vesselName + "."); seat.LeaveSeat(new KSPActionParam(KSPActionGroup.Abort, KSPActionType.Activate)); } else { Debug.Log("[KerbalSafety]: " + kerbalName + " has already left their seat."); } StartCoroutine(PostEjection()); StartCoroutine(DelayedChuteDeployment()); StartCoroutine(RecoverWhenPossible()); } } else if (crew != null) // Eject from a cockpit. { Debug.Log("[KerbalSafety]: DEBUG skipping ejection for " + kerbalName + " in cockpit " + part + " for now."); return; // kerbalEVA = FlightEVA.fetch.spawnEVA(kerbalPCM, part, part.airlock, true); // if (kerbalEVA) // { // Debug.Log("[KerbalSafety]: " + kerbalPCM.displayName + " ejected from " + part.vessel.vesselName + " at " + part.vessel.radarAltitude.ToString("0.0") + "m."); // kerbalEVA.autoGrabLadderOnStart = false; // Don't grab the vessel. // chute = kerbalEVA.vessel.FindPartModuleImplementing<ModuleEvaChute>(); // if (chute != null) // chute.deploymentState = ModuleEvaChute.deploymentStates.STOWED; // Make sure the chute is stowed. // // DeactivatePilot(); // StartCoroutine(PostEjection()); // } // else // { // // All exits were blocked by something. FIXME Try adjusting the fromAirlock Transform in spawnEVA. // // BDACompetitionMode.Instance.competitionStatus.Add(kerbalPCM.displayName + " failed to eject from " + part.vessel.vesselName + ", all exits were blocked. RIP."); // Debug.Log("[KerbalSafety]: " + kerbalPCM.displayName + " failed to eject from " + part.vessel.vesselName + ", all exits were blocked. RIP."); // part.vessel.RemoveCrew(kerbalPCM); // Save their ghost. // // StartCoroutine(ExplodeStuffThenEject()); // // ExplodeStuffThenEject(); // } } else { Debug.LogError("[KerbalSafety]: Ejection called without a kerbal present."); } ejected = true; }
// FIXME to be part of an update loop (maybe) // void EjectOnImpendingDoom() // { // if (!ejected && ejectOnImpendingDoom * (float)vessel.srfSpeed > ai.terrainAlertDistance) // { // KerbalSafety.Instance.Eject(vessel, this); // Abandon ship! // ai.avoidingTerrain = false; // } // } #region Ejection /// <summary> /// Eject from a vessel. /// </summary> public void Eject() { if (ejected) { return; // We've already ejected. } if (part == null || part.vessel == null) { return; // The vessel is gone, don't try to do anything. } if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDArmory.KerbalSafety]: Ejection triggered for " + kerbalName + " in " + part); } if (kerbalEVA != null) { if (kerbalEVA.isActiveAndEnabled) // Otherwise, they've been killed already and are being cleaned up by KSP. { if (seat != null && kerbalEVA.IsSeated()) // Leave the seat. { Debug.Log("[BDArmory.KerbalSafety]: " + kerbalName + " is leaving their seat on " + seat.part.vessel.vesselName + "."); seat.LeaveSeat(new KSPActionParam(KSPActionGroup.Abort, KSPActionType.Activate)); } else { Debug.Log("[BDArmory.KerbalSafety]: " + kerbalName + " has already left their seat."); } StartCoroutine(DelayedChuteDeployment()); StartCoroutine(RecoverWhenPossible()); } } else if (crew != null && part.protoModuleCrew.Contains(crew) && !FlightEVA.hatchInsideFairing(part)) // Eject from a cockpit. { if (BDArmorySettings.KERBAL_SAFETY < 2) { return; } if (!ProcessEjection(part)) // All exits were blocked by something. { if (!EjectFromOtherPart()) // Look for other airlocks to spawn from. { message = kerbalName + " failed to eject from " + part.vessel.vesselName + ", all exits were blocked. R.I.P."; BDACompetitionMode.Instance.competitionStatus.Add(message); Debug.Log("[BDArmory.KerbalSafety]: " + message); } } } else { Debug.LogWarning("[BDArmory.KerbalSafety]: Ejection called without a kerbal present."); } ejected = true; }
public bool leavingSeat = false; // Whether the kerbal is about to leave their seat. #endregion #region Field definitions // [KSPField(isPersistant = true, guiActive = true, guiActiveEditor = true, guiName = "#LOC_BDArmory_EjectOnImpendingDoom", // Eject if doomed // groupName = "pilotAI_Ejection", groupDisplayName = "#LOC_BDArmory_PilotAI_Ejection", groupStartCollapsed = true), // UI_FloatRange(minValue = 0f, maxValue = 1f, stepIncrement = 0.02f, scene = UI_Scene.All)] // public float ejectOnImpendingDoom = 0.2f; // Time to impact at which to eject. #endregion /// <summary> /// Begin managing a crew member in a part. /// </summary> /// <param name="crew">The proto crew member.</param> /// <param name="part">The part.</param> public IEnumerator Configure(ProtoCrewMember crew, Part part) { if (crew == null) { Debug.LogError("[KerbalSafety]: Cannot manage null crew."); Destroy(this); yield break; } if (part == null) { Debug.LogError("[KerbalSafety]: Crew cannot exist outside of a part."); Destroy(this); yield break; } while (!part.vessel.loaded) { yield return(new WaitForFixedUpdate()); // Wait for the vessel to be loaded. (Avoids kerbals not being registered in seats.) } kerbalName = crew.displayName; this.crew = crew; this.crew.ResetInventory(); // Reset the inventory to a chute and a jetpack. this.part = part; if (part.IsKerbalEVA()) { this.kerbalEVA = part.GetComponent <KerbalEVA>(); if (kerbalEVA.IsSeated()) { var seats = part.vessel.FindPartModulesImplementing <KerbalSeat>(); bool found = false; foreach (var s in seats) { if (s.Occupant == part) { seat = s; found = true; break; } } if (!found) { Debug.LogError("[KerbalSafety]: Failed to find the kerbal seat that " + kerbalName + " occupies."); yield break; } } else // Free-falling EVA kerbal. { ejected = true; } chute = kerbalEVA.vessel.FindPartModuleImplementing <ModuleEvaChute>(); if (chute != null) { chute.deploymentState = ModuleEvaChute.deploymentStates.STOWED; // Make sure the chute is stowed. } } AddHandlers(); KerbalSafetyManager.Instance.kerbals.Add(crew, this); Debug.Log("[KerbalSafety]: Managing the safety of " + kerbalName + " in " + part.vessel.vesselName + "."); }
// [KSPField(isPersistant = true, guiActive = true, guiActiveEditor = true, guiName = "#LOC_BDArmory_EjectOnImpendingDoom", // Eject if doomed // groupName = "pilotAI_Ejection", groupDisplayName = "#LOC_BDArmory_PilotAI_Ejection", groupStartCollapsed = true), // UI_FloatRange(minValue = 0f, maxValue = 1f, stepIncrement = 0.02f, scene = UI_Scene.All)] // public float ejectOnImpendingDoom = 0.2f; // Time to impact at which to eject. #endregion /// <summary> /// Begin managing a crew member in a part. /// </summary> /// <param name="crew">The proto crew member.</param> /// <param name="part">The part.</param> public IEnumerator Configure(ProtoCrewMember crew, Part part, bool quiet = false) { if (crew == null) { Debug.LogError("[BDArmory.KerbalSafety]: Cannot manage null crew."); Destroy(this); yield break; } if (part == null) { Debug.LogError("[BDArmory.KerbalSafety]: Crew cannot exist outside of a part."); Destroy(this); yield break; } while (!part.vessel.loaded) { yield return(new WaitForFixedUpdate()); // Wait for the vessel to be loaded. (Avoids kerbals not being registered in seats.) } kerbalName = crew.displayName; this.crew = crew; switch (BDArmorySettings.KERBAL_SAFETY_INVENTORY) { case 1: this.crew.ResetInventory(true); // Reset the inventory to the default of a chute and a jetpack. break; case 2: this.crew.ResetInventory(false); // Reset the inventory to just a chute. break; } this.part = part; if (part.IsKerbalEVA()) { this.kerbalEVA = part.GetComponent <KerbalEVA>(); if (kerbalEVA.IsSeated()) { var seats = part.vessel.FindPartModulesImplementing <KerbalSeat>(); bool found = false; foreach (var s in seats) { if (s.Occupant == part) { seat = s; found = true; break; } } if (!found) { Debug.LogError("[BDArmory.KerbalSafety]: Failed to find the kerbal seat that " + kerbalName + " occupies."); yield break; } } else // Free-falling EVA kerbal. { ejected = true; StartCoroutine(DelayedChuteDeployment()); StartCoroutine(RecoverWhenPossible()); } ConfigureKerbalEVA(kerbalEVA); } AddHandlers(); KerbalSafetyManager.Instance.kerbals.Add(crew, this); if (!quiet) { Debug.Log("[BDArmory.KerbalSafety]: Managing the safety of " + kerbalName + (ejected ? " on EVA" : " in " + part.vessel.vesselName) + "."); } OnVesselModified(part.vessel); // Immediately check the vessel. }