private bool EjectFromOtherPart() { Part fromPart = part; foreach (var toPart in part.vessel.parts) { if (toPart == part) { continue; } if (toPart.CrewCapacity > 0 && !FlightEVA.hatchInsideFairing(toPart) && !FlightEVA.HatchIsObstructed(toPart, toPart.airlock)) { var crewTransfer = CrewTransfer.Create(fromPart, crew, OnDialogDismiss); if (crewTransfer.validParts.Contains(toPart)) { Debug.Log("[BDArmory.KerbalSafety]: Transferring " + kerbalName + " from " + fromPart + " to " + toPart + " then ejecting."); crewTransfer.MoveCrewTo(toPart); if (ProcessEjection(toPart)) { return(true); } fromPart = toPart; } } } return(false); }
// 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 override void OnUpdate() { Log.Info("OnUpdate 1"); if (HighLogic.LoadedSceneIsFlight) // && vessel.HoldPhysics == true) { // Make sure controls are unlocked (workaround for compatibility issue with Kerbal Joint Reinforcement) if (InputLockManager.GetControlLock("KJRLoadLock") != ControlTypes.ALL_SHIP_CONTROLS) { if (this.part.protoModuleCrew.Count > 0 && allCommandSeats.Count == 0) { print("[TakeCommand] populating seat list"); foreach (Part p in vessel.parts) { if (p.Modules.OfType <TakeCommand>().Any()) { if (p.protoModuleCrew.Count > 0) { allCommandSeats.Add(p); } } } print("[TakeCommand] found " + allCommandSeats.Count + " occupied seats"); } Log.Info("this.part.protoModuleCrew.Count: " + this.part.protoModuleCrew.Count()); #if true if (!error) { Log.Info("OnUpdate 2"); if (FlightEVA.hatchInsideFairing(this.part)) { ScreenMessages.PostScreenMessage(part.partInfo.title + " is inside a fairing (not allowed)", 15.0f, ScreenMessageStyle.UPPER_CENTER); ScreenMessages.PostScreenMessage("Revert and try again", 15.0f, ScreenMessageStyle.UPPER_CENTER); error = true; } else { Log.Info("OnUpdate 3"); if (boardKerbal == false) { Log.Info("OnUpdate 4"); Log.Info("boardKerbal"); if (this.part.protoModuleCrew.Count > 0 && allCommandSeats.First().GetInstanceID() == this.part.GetInstanceID()) { // Time to eject this crew member ProtoCrewMember kerbal; while (this.part.protoModuleCrew.Count() > 0) { kerbal = this.part.protoModuleCrew[0]; //ProtoCrewMember kerbal = this.part.protoModuleCrew.First(); print("[TakeCommand] ejecting " + kerbal.name + " from " + this.part.GetInstanceID()); escapeHatch.GetComponent <Collider>().enabled = true; if (FlightEVA.fetch.spawnEVA(kerbal, this.part, escapeHatch.transform)) { myKerbal = "kerbalEVA (" + kerbal.name + ")"; myFemaleKerbal = "kerbalEVAfemale (" + kerbal.name + ")"; boardKerbal = true; escapeHatch.GetComponent <Collider>().enabled = false; } else { print("[TakeCommand] error ejecting " + kerbal.name); ScreenMessages.PostScreenMessage("Unable to put kerbal: " + kerbal.name + " into the external seat", 5.0f, ScreenMessageStyle.UPPER_CENTER); ScreenMessages.PostScreenMessage("Revert and try again", 5.0f, ScreenMessageStyle.UPPER_CENTER); error = true; Log.Info("Error set true"); break; // this.part.protoModuleCrew.Remove(kerbal); } } } } else { Log.Info("OnUpdate 5"); // Check and wait until the ejected Kerbal is the active vessel before proceeding Log.Info("this.vessel.name: " + this.vessel.name); Log.Info("FlightGlobals.ActiveVessel.name: " + FlightGlobals.ActiveVessel.name); if (this.vessel == FlightGlobals.ActiveVessel) { Log.Info("this.vessel is activevessel, myKerbal: " + myKerbal); } if (FlightGlobals.ActiveVessel.name == myKerbal || FlightGlobals.ActiveVessel.name == myFemaleKerbal) { KerbalEVA kerbal = FlightGlobals.ActiveVessel.GetComponent <KerbalEVA>(); Log.Info("kerbal.fsm.currentStateName: " + kerbal.fsm.currentStateName); if (kerbal.fsm.Started == true) { allCommandSeats.Remove(allCommandSeats.First()); //allCommandSeats.Remove(this.part); boardKerbal = false; if (kerbal.flagItems == 0) { kerbal.AddFlag(); } print("[TakeCommand] seating " + kerbal.name + " in " + this.part.GetInstanceID()); // Board in first unoccupied seat var freeModule = this.part.Modules.OfType <KerbalSeat>().First(t => t.Occupant == null); freeModule.BoardSeat(); } } } } } else { Log.Info("error is true"); } #endif } } base.OnUpdate(); }