/// <summary> /// This kills the Kerbal. /// </summary> /// <param name="module"></param> /// <param name="kerbal"></param> public static void KillKerbal(PartModule module, ProtoCrewMember kerbal) { List <ProtoCrewMember> part_crew = module.part.protoModuleCrew; Util.PostUpperMessage(kerbal.name + " ran out of LifeSupport and died!", 2); // Kerbal must be removed from part BEFORE calling Die() module.part.RemoveCrewmember(kerbal); // Necessary for "Valentina Kermal was killed" message in log. // Doesn't seem to have any other effect. kerbal.Die(); // Remove dead Kerbal's portrait - if not done, player will still be able // to control a ship with zero live Kerbals. // First two lines don't seem necessary, but may be more complete // if they update information used by other mods. module.vessel.CrewListSetDirty(); Vessel.CrewWasModified(module.vessel); KSP.UI.Screens.Flight.KerbalPortraitGallery.Instance.StartRefresh(module.vessel); // Put Kerbal in Missing queue if (HighLogic.CurrentGame.Parameters.Difficulty.MissingCrewsRespawn) { kerbal.StartRespawnPeriod(); } }
public static bool moveCrew(Vessel fromV, Vessel toV, bool spawn = true) { var all = true; var moved = false; foreach (var fromP in fromV.parts) { while (fromP.protoModuleCrew.Count > 0) { var toP = toV.parts.Find(p => p.CrewCapacity > p.protoModuleCrew.Count); if (toP == null) { break; } move_crew(fromP, toP, fromP.protoModuleCrew[0]); moved = true; } if (fromP.protoModuleCrew.Count > 0) { all = false; break; } } if (moved) { Vessel.CrewWasModified(fromV, toV); if (spawn) { respawnCrew(fromV, toV); } } return(all); }
public static bool moveCrew(Vessel fromV, Part toP, bool spawn = true) { if (toP.CrewCapacity <= toP.protoModuleCrew.Count) { return(false); } var all = true; var moved = false; foreach (var fromP in fromV.parts) { while (toP.protoModuleCrew.Count < toP.CrewCapacity && fromP.protoModuleCrew.Count > 0) { move_crew(fromP, toP, fromP.protoModuleCrew[0]); moved = true; } if (fromP.protoModuleCrew.Count > 0) { all = false; break; } } if (moved) { Vessel.CrewWasModified(fromV, toP.vessel); if (spawn) { respawnCrew(fromV, toP.vessel); } } return(all); }
public static bool moveCrew(Vessel toV, List <ProtoCrewMember> crew, bool spawn = true) { if (crew.Count == 0) { return(false); } var moved = new List <ProtoCrewMember>(crew.Capacity); foreach (var kerbal in crew) { var toP = toV.parts.Find(p => p.CrewCapacity > p.protoModuleCrew.Count); if (toP == null) { break; } move_crew(kerbal, toP); moved.Add(kerbal); } if (moved.Count > 0) { Vessel.CrewWasModified(toV); if (spawn) { respawnCrew(toV); } } return(moved.Count == crew.Count); }
public static bool moveCrew(Vessel fromV, Vessel toV, List <ProtoCrewMember> crew, bool spawn = true) { if (crew.Count == 0) { return(false); } var moved = new List <ProtoCrewMember>(crew.Capacity); foreach (var kerbal in crew) { Part fromP = null; ProtoCrewMember real_kerbal = null; foreach (var p in fromV.Parts) { real_kerbal = p.protoModuleCrew.Find(c => same_crew_member(c, kerbal)); if (real_kerbal != null) { fromP = p; break; } } if (real_kerbal == null) { continue; } var toP = toV.parts.Find(p => p.CrewCapacity > p.protoModuleCrew.Count); if (toP == null) { break; } move_crew(fromP, toP, real_kerbal); moved.Add(real_kerbal); } if (moved.Count > 0) { Vessel.CrewWasModified(fromV, toV); if (spawn) { respawnCrew(fromV, toV); } } return(moved.Count == crew.Count); }
public static bool moveCrew(Part fromP, Part toP, bool spawn = true) { if (fromP.protoModuleCrew.Count == 0 || toP.CrewCapacity <= toP.protoModuleCrew.Count) { return(false); } while (toP.protoModuleCrew.Count < toP.CrewCapacity && fromP.protoModuleCrew.Count > 0) { move_crew(fromP, toP, fromP.protoModuleCrew[0]); } var moved = fromP.protoModuleCrew.Count > 0; if (moved) { Vessel.CrewWasModified(fromP.vessel, toP.vessel); if (spawn) { respawnCrew(fromP.vessel, toP.vessel); } } return(moved); }
protected void retrainKerbals() { ProtoCrewMember trainee; foreach (string kerbalName in newProfessions.Keys) { trainee = trainees[kerbalName]; //If the kerbal is currently a tourist, then unregister the kerbal from any tourism contracts. if (trainee.trait == "Tourist") { WBIContractScenario.Instance.unregisterKerbal(kerbalName); } //Set the new trait KerbalPortraitGallery.Instance.UnregisterActiveCrew(trainee.KerbalRef); trainee.UnregisterExperienceTraits(trainee.KerbalRef.InPart); trainee.KerbalRef.InVessel.CrewListSetDirty(); KerbalRoster.SetExperienceTrait(trainee, newProfessions[kerbalName]); trainee.RegisterExperienceTraits(trainee.KerbalRef.InPart); trainee.KerbalRef.InVessel.CrewListSetDirty(); KerbalPortraitGallery.Instance.RegisterActiveCrew(trainee.KerbalRef); KerbalPortraitGallery.Instance.UpdatePortrait(trainee.KerbalRef); KerbalPortraitGallery.Instance.StartReset(this.part.vessel); //Reset experience if (resetExperience) { KerbalRoster.SetExperienceLevel(trainee, 0); } Vessel.CrewWasModified(trainee.KerbalRef.InVessel); FlightInputHandler.ResumeVesselCtrlState(trainee.KerbalRef.InVessel); } }
internal void CrewTransferProcesses() { try { if (!CrewXferActive) { return; } if (CameraManager.Instance.currentCameraMode == CameraManager.CameraMode.IVA) { ScreenMessages.PostScreenMessage("<color=orange>Cannot go IVA. An SM Crew Xfer is in progress</color>", 4f); CameraManager.Instance.SetCameraMode(CameraManager.CameraMode.Flight); } switch (CrewXferState) { case XferState.Off: // We're just starting loop, so set some evnironment stuff. // We want to run the start sound no matter what the realism settings are // to give an audio indication to the player that the process is active Timestamp = DateTime.Now; SMSound.SourceCrewStart.Play(); CrewXferState = XferState.Start; break; case XferState.Start: SMAddon.Elapsed += (DateTime.Now - Timestamp).TotalSeconds; if (SMSettings.RealXfers) { // Play run sound when start sound is nearly done. (repeats) if (SMAddon.Elapsed >= SMSound.ClipPumpStart.length - 0.25) { SMSound.SourceCrewStart.Stop(); SMSound.SourceCrewRun.Play(); SMAddon.Elapsed = 0; CrewXferState = XferState.Transfer; } } else { CrewXferState = XferState.Transfer; } break; case XferState.Transfer: SMAddon.Elapsed += (DateTime.Now - Timestamp).TotalSeconds; if (SMSettings.RealXfers) { // wait for movement to end... if (SMAddon.Elapsed >= CrewXferDelaySec || (IsSeat2SeatXfer && SMAddon.Elapsed > Seat2SeatXferDelaySec)) { CrewXferState = XferState.Stop; CrewTransferStartAction(); } } else { if (SMAddon.Elapsed > 1) { CrewXferState = XferState.Stop; } } break; case XferState.Stop: // Spawn crew in parts and in vessel. if (SMSettings.RealXfers) { // play crew sit. SMSound.SourceCrewRun.Stop(); SMSound.SourceCrewStop.Play(); } CrewTransferStartAction(); CrewTransferStopAction(); Vessel.CrewWasModified(SMAddon.SmVessel.Vessel); SMAddon.SmVessel.Vessel.DespawnCrew(); SMAddon.Elapsed = 0; CrewXferState = XferState.Portraits; IvaDelayActive = true; break; case XferState.Portraits: // Account for crew move callbacks by adding a frame delay for portrait updates after crew move... SMAddon.SmVessel.Vessel.SpawnCrew(); if (IvaDelayActive && IvaPortraitDelay < SMSettings.IvaUpdateFrameDelay) { IvaPortraitDelay += 1; } else if ((IvaDelayActive && IvaPortraitDelay >= SMSettings.IvaUpdateFrameDelay) || !IvaDelayActive) { if (IsStockXfer) { ScreenMessages.PostScreenMessage( $"<color=yellow>{FromCrewMember.name} moved (by SM) to {ToPart.partInfo.title}.</color>", 5f); } ResetXferProcess(); } break; } if (CrewXferState != XferState.Off) { Timestamp = DateTime.Now; } } catch (Exception ex) { if (!SMAddon.FrameErrTripped) { SmUtils.LogMessage($"Transfer State: {CrewXferState}...", SmUtils.LogType.Error, true); SmUtils.LogMessage( $" in CrewTransferProcess (repeating error). Error: {ex.Message} \r\n\r\n{ex.StackTrace}", SmUtils.LogType.Error, true); SMAddon.FrameErrTripped = true; ResetXferProcess(); } } }
public static void respawnCrew(Vessel fromV, Vessel toV) { Vessel.CrewWasModified(fromV, toV); FlightGlobals.ActiveVessel.DespawnCrew(); toV.StartCoroutine(CallbackUtil.DelayedCallback(1, FlightGlobals.ActiveVessel.SpawnCrew)); }