Ejemplo n.º 1
0
        public void CheckChutes()
        {
            Vessel vessel = FlightGlobals.ActiveVessel;

            //Get the vessel cache
            bool createdNewRecord = false;
            LoadedQualitySummary qualitySummary = BARISScenario.Instance.GetLoadedQualitySummary(vessel, out createdNewRecord);

            if (qualitySummary == null)
            {
                return;
            }

            //Get failure candidates
            ModuleQualityControl[]          failureCandidates = qualitySummary.GetStagingFailureCandidates(stagingID);
            List <ModuleBreakableParachute> parachutes;
            int count;

            for (int index = 0; index < failureCandidates.Length; index++)
            {
                parachutes = failureCandidates[index].part.FindModulesImplementing <ModuleBreakableParachute>();
                count      = parachutes.Count;
                for (int chuteIndex = 0; chuteIndex < count; chuteIndex++)
                {
                    parachutes[chuteIndex].isStaged = true;
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// This method performs the staging reliability check. If successful, then all parts in the stage may contribute to their type of part's flight experience.
        /// If it fails, then one or more parts in the stage may fail regardless of their MTBF rating. If it critically fails, the vessel blows up.
        /// </summary>
        public void CheckYoStaging()
        {
            debugLog("CheckYoStaging!");
            Vessel vessel                       = FlightGlobals.ActiveVessel;
            bool   isCascadeFailure             = false;
            bool   isSuccessfulStaging          = false;
            bool   astronautAverted             = false;
            bool   isFailure                    = false;
            ModuleQualityControl qualityControl = null;
            int    totalBreakables              = 0;
            string message;
            bool   updateEditorBays = false;

            //Stage check flag
            stageCheckInProgress = true;

            disableTestModeIfNeeded();

            //Debug stuff
            if (BARISScenario.showDebug)
            {
                isCascadeFailure            = NextStagingIsCascadeFailure;
                NextStagingIsCascadeFailure = false;

                isSuccessfulStaging     = NextStagingIsSuccessful;
                NextStagingIsSuccessful = false;

                astronautAverted           = NextStagingAstonautAverted;
                NextStagingAstonautAverted = false;

                isFailure        = NextStagingFails;
                NextStagingFails = false;
            }

            //Get the vessel cache
            bool createdNewRecord = false;
            LoadedQualitySummary qualitySummary = BARISScenario.Instance.GetLoadedQualitySummary(vessel, out createdNewRecord);

            if (qualitySummary == null)
            {
                return;
            }

            //Get failure candidates
            ModuleQualityControl[] failureCandidates = qualitySummary.GetStagingFailureCandidates(stagingID);

            //Make a vessel reliability check
            QualityCheckResult result = BARISScenario.Instance.PerformQualityCheck(qualitySummary.reliability, qualitySummary.highestRank, 0, false);

            //Debug checks
            if (BARISScenario.showDebug)
            {
                if (isSuccessfulStaging)
                {
                    result.statusResult = QualityCheckStatus.success;
                }
                else if (astronautAverted)
                {
                    result.statusResult = QualityCheckStatus.astronautAverted;
                }
                else if (isFailure)
                {
                    result.statusResult = QualityCheckStatus.fail;
                }
                else if (isCascadeFailure)
                {
                    result.statusResult = QualityCheckStatus.criticalFail;
                }

                debugLog("DEBUG: New reliability check result: " + result.statusResult);
            }

            switch (result.statusResult)
            {
            //All the failure candidates explode!
            case QualityCheckStatus.criticalFail:
                if (failureCandidates != null)
                {
                    //Fire the catastrophic failure event to give others a chance to avert disaster somehow.
                    onStagingCriticalFailure?.Invoke();
                    if (criticalFailureAverted)
                    {
                        //Reset the flag
                        criticalFailureAverted = false;
                        break;
                    }

                    //Ok we're go for vessel destruction!

                    //Cause stress. Lots of it.
                    snacksWrapper.AddStressToCrew(vessel, BARISStressCategories.stressCategoryHigh);

                    //Inform player of cascade failure
                    message = vessel.vesselName + Localizer.Format(BARISScenario.CascadeFailureMsg);
                    BARISScenario.Instance.LogPlayerMessage(message);

                    //Mark a quality module for death. This will blow up the vessel it is attached to.
                    //It cannot be a module that is marked as an escape pod. This part will initiate vessel destruction.
                    //Vessel might or might not be the active vessel depending upon how the abort sequence is set up.
                    ModuleEscapePod escapePod = null;
                    for (int index = failureCandidates.Length - 1; index >= 0; index--)
                    {
                        escapePod = failureCandidates[index].part.FindModuleImplementing <ModuleEscapePod>();
                        if (escapePod == null || escapePod.escapePodEnabled == false)
                        {
                            failureCandidates[index].SetMarkedForDeath(true);
                            break;
                        }
                        escapePod = null;
                    }

                    //Make an escape check to see if we can trigger an abort sequence.
                    launchEscapeBase = getHighestStupidity();
                    QualityCheckResult escapeResult = BARISScenario.Instance.PerformQualityCheck(vessel, launchEscapeBase, escapeCheckSkill, false);

                    //Go for abort sequence!
                    if (escapeResult.statusResult != QualityCheckStatus.fail && escapeResult.statusResult != QualityCheckStatus.criticalFail)
                    {
                        //Give crew a chance to get to the escape pods.
                        abandonShip(vessel);

                        //If there is an astronaut aboard with the escape skill then assume the astronaut hit the launch abort.
                        if (escapeResult.astronaut != null)
                        {
                            message = escapeResult.astronaut.name + Localizer.Format(BARISScenario.LASActivatedMsg);
                            BARISScenario.Instance.LogPlayerMessage(message);
                        }

                        //Hit the abort button
                        vessel.ActionGroups.SetGroup(KSPActionGroup.Abort, true);
                    }
                }
                else
                {
                    debugLog("No failure candidates to blow up! Picking a random part to explode...");
                    int failedPartIndex = UnityEngine.Random.Range(0, qualitySummary.qualityModules.Length - 1);
                    qualitySummary.qualityModules[failedPartIndex].part.explode();
                }
                break;

            //Log successful flight experience
            case QualityCheckStatus.success:
                totalBreakables = qualitySummary.qualityModules.Length;
                for (int index = 0; index < totalBreakables; index++)
                {
                    qualitySummary.qualityModules[index].UpdateFlightLog();
                }
                updateEditorBays = true;
                break;

            //Any number of the failure candidates can fail.
            case QualityCheckStatus.fail:
                if (failureCandidates != null)
                {
                    int expGainTarget = BARISSettingsLaunch.StagingFailExpTarget;
                    debugLog("Target number to gain flight experience: " + expGainTarget);

                    //Crew gets stressed from parts failing
                    snacksWrapper.AddStressToCrew(vessel, BARISStressCategories.stressCategoryMedium);

                    int failedModules = UnityEngine.Random.Range(1, failureCandidates.Length);
                    for (int index = 0; index < failedModules; index++)
                    {
                        qualityControl = failureCandidates[index];
                        if (!qualityControl.IsBroken)
                        {
                            qualityControl.DeclarePartBroken();
                        }
                        else
                        {
                            qualityControl.BreakAPartModule();
                        }

                        //There's a chance that the part will also gain flight experience
                        if (UnityEngine.Random.Range(1, 100) >= expGainTarget)
                        {
                            debugLog(qualityControl.part.partInfo.title + " has gained flight experience during part failure.");
                            qualityControl.UpdateFlightLog();
                            updateEditorBays = true;
                        }

                        //There's a chance that the part will explode!
                        if (BARISBridge.FailuresCanExplode)
                        {
                            if (UnityEngine.Random.Range(1, 100) >= BARISBridge.ExplosivePotentialLaunches)
                            {
                                message = qualityControl.part.partInfo.title + Localizer.Format(BARISScenario.CatastrophicFailure);
                                BARISScenario.Instance.LogPlayerMessage(message);
                                qualityControl.part.explosionPotential = 0.01f;
                                qualityControl.part.explode();
                            }
                        }
                    }
                }
                else
                {
                    debugLog("No failureCandidates have MTBF = 0");
                }
                break;

            //Add a failure averted event card
            case QualityCheckStatus.criticalSuccess:
                totalBreakables = qualitySummary.qualityModules.Length;
                for (int index = 0; index < totalBreakables; index++)
                {
                    qualitySummary.qualityModules[index].UpdateFlightLog();
                }
                break;

            //Show event card result
            case QualityCheckStatus.eventCardAverted:
                break;

            //Shout out to the astronaut that saved the day
            case QualityCheckStatus.astronautAverted:
                if (qualitySummary.rankingAstronaut != null)
                {
                    //Astronaut gets a small amount of stress
                    snacksWrapper.AddStressToCrew(vessel, BARISStressCategories.stressCategoryLow);

                    message = qualitySummary.rankingAstronaut.name + Localizer.Format(BARISScenario.QualityCheckFailAvertedAstronaut3);
                    if (BARISSettings.LogAstronautAvertMsg)
                    {
                        BARISScenario.Instance.LogPlayerMessage(message);
                    }
                    else
                    {
                        FlightLogger.fetch.LogEvent(message);
                    }
                }
                break;

            default:
                break;
            }

            //Cleanup
            if (updateEditorBays)
            {
                BARISScenario.Instance.UpdateEditorBayFlightBonuses();
            }

            BARISAppButton.flightAppView.UpdateCachedData();
            stageCheckInProgress = false;
        }