예제 #1
0
        // 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;
        }
예제 #2
0
        // 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;
        }
예제 #3
0
        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 + ".");
        }
예제 #4
0
        // [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.
        }