private void checkApproachingGeeLimit() { if (FlightGlobals.ActiveVessel != null && FlightGlobals.ActiveVessel.geeForce < 4.0) // Can there be any tourist with Gee force tolerance below that? { if (highGee) { reinitVessel(FlightGlobals.ActiveVessel); highGee = false; ScreenMessages.PostScreenMessage("EVA prohibition cleared"); } return; } if (tourists == null) { return; } foreach (ProtoCrewMember crew in FlightGlobals.ActiveVessel.GetVesselCrew()) { if (!tourists.ContainsKey(crew.name) || // not among tourists !Tourist.isTourist(crew) || // not really a tourist crew.type != ProtoCrewMember.KerbalType.Crew) { // was probably unpromoted continue; } if (crew.gExperienced / ProtoCrewMember.GToleranceMult(crew) > 50000) // Magic number. At 60000 kerbal passes out { printDebug(String.Format("Unpromoting {0} due to high gee", crew.name)); crew.type = ProtoCrewMember.KerbalType.Tourist; ScreenMessages.PostScreenMessage(String.Format( "{0} temporary prohibited from EVA due to experienced high Gee forces", crew.name)); highGee = true; } } }
protected void FixedUpdate() { int pC; if (HighLogic.LoadedSceneIsFlight && part.CrewCapacity > 0 && (pC = part.protoModuleCrew.Count) > 0) { double UT = Planetarium.GetUniversalTime(); if (nextCheck < 0d) { nextCheck = UT + checkInterval; } else if (UT > nextCheck) { if (pressureAtKillAltitude == default) { pressureAtKillAltitude = FlightGlobals.GetHomeBody().GetPressureAtm(crewDeathAltitude); _origDoStockGCalcs = ProtoCrewMember.doStockGCalcs; } nextCheck = UT + checkInterval; if (part.staticPressureAtm < pressureAtKillAltitude) { ScreenMessages.PostScreenMessage($"Cockpit is above the safe altitude which will lead to crew incapacitation and eventually to death", 1f, ScreenMessageStyle.UPPER_CENTER, XKCDColors.Red); if (!_origDoStockGCalcs.HasValue) { _origDoStockGCalcs = ProtoCrewMember.doStockGCalcs; } ProtoCrewMember.doStockGCalcs = false; bool killed = false; for (int i = pC; i-- > 0;) { ProtoCrewMember pcm = part.protoModuleCrew[i]; double highGPenalty = vessel.geeForce > 3 ? vessel.geeForce : 1; pcm.gExperienced += (0.5d + rnd.NextDouble()) * gDamageAdder * highGPenalty; double gMult = ProtoCrewMember.GToleranceMult(pcm) * HighLogic.CurrentGame.Parameters.CustomParams <GameParameters.AdvancedParams>().KerbalGToleranceMult; _anyCrewAboveWarnThreshold = pcm.gExperienced > PhysicsGlobals.KerbalGThresholdWarn * gMult; double locThreshold = PhysicsGlobals.KerbalGThresholdLOC * gMult; if (!pcm.outDueToG && pcm.gExperienced > locThreshold) { // Just passed out ScreenMessages.PostScreenMessage($"<color=red>{pcm.name} has lost consciousness due to hypoxia!</color>", 5.5f, ScreenMessageStyle.UPPER_CENTER); } // There's at least one cycle of delay after passing out before the death chance rolls start if (pcm.outDueToG && rnd.NextDouble() < crewDeathChance) { killed = true; ScreenMessages.PostScreenMessage($"{vessel.vesselName}: Crewmember {pcm.name} has died from exposure to near-vacuum.", 30.0f, ScreenMessageStyle.UPPER_CENTER, XKCDColors.Red); FlightLogger.fetch.LogEvent($"[{KSPUtil.PrintTime(vessel.missionTime, 3, false)}] {pcm.name} died from exposure to near-vacuum."); part.RemoveCrewmember(pcm); pcm.Die(); } } if (killed && CameraManager.Instance.currentCameraMode == CameraManager.CameraMode.IVA) { CameraManager.Instance.SetCameraFlight(); } } else { if (_origDoStockGCalcs.HasValue) { ProtoCrewMember.doStockGCalcs = _origDoStockGCalcs.Value; _origDoStockGCalcs = null; } } } } }
protected void FixedUpdate() { int pC; if (HighLogic.LoadedSceneIsFlight && part.CrewCapacity > 0 && (pC = part.protoModuleCrew.Count) > 0) { double UT = KSPUtils.GetUT(); if (lastCheck < 0d) { lastCheck = UT; } double deltaTime = UT - lastCheck; if (deltaTime > checkInterval) { if (!_origDoStockGCalcs.HasValue) { _origDoStockGCalcs = ProtoCrewMember.doStockGCalcs; } lastCheck = UT; double curAltitute = part.vessel.altitude; if (curAltitute > crewDeathAltitude) { // Assume the standard atmosphere if (referenceDensity < 0d) { referenceDensity = Planetarium.fetch.Home.GetDensity(Planetarium.fetch.Home.GetPressure(crewDeathAltitude), Planetarium.fetch.Home.GetTemperature(crewDeathAltitude)); referenceDensityMin = referenceDensity * 0.02d; } timeSinceHypoxiaStarted += deltaTime; ScreenMessages.PostScreenMessage($"Cockpit is above the safe altitude which will lead to crew incapacitation and eventually to death", 1f, ScreenMessageStyle.UPPER_CENTER, XKCDColors.Red); if (!_origDoStockGCalcs.HasValue) { _origDoStockGCalcs = ProtoCrewMember.doStockGCalcs; } ProtoCrewMember.doStockGCalcs = false; bool killed = false; for (int i = pC; i-- > 0;) { ProtoCrewMember pcm = part.protoModuleCrew[i]; double highGPenalty = vessel.geeForce > 3d ? System.Math.Pow(vessel.geeForce - 2d, 2d) : 1; double curDensity = part.atmDensity; if (curDensity < referenceDensityMin) { curDensity = referenceDensityMin; } double altitudeMult = (curAltitute - crewDeathAltitude) / crewDeathAltitude * 10d + referenceDensity / curDensity - 1d; double timeMult = System.Math.Pow(timeSinceHypoxiaStarted, 1.5d) * 0.01d; pcm.gExperienced += (0.5d + rnd.NextDouble()) * gDamageAdder * highGPenalty * altitudeMult * timeMult; double gMult = ProtoCrewMember.GToleranceMult(pcm) * HighLogic.CurrentGame.Parameters.CustomParams <GameParameters.AdvancedParams>().KerbalGToleranceMult; _anyCrewAboveWarnThreshold = pcm.gExperienced > PhysicsGlobals.KerbalGThresholdWarn * gMult; double locThreshold = PhysicsGlobals.KerbalGThresholdLOC * gMult; if (!pcm.outDueToG && pcm.gExperienced > locThreshold) { // Just passed out ScreenMessages.PostScreenMessage($"<color=red>{pcm.name} has lost consciousness due to hypoxia!</color>", 5.5f, ScreenMessageStyle.UPPER_CENTER); } // There's at least one cycle of delay after passing out before the death chance rolls start if (pcm.outDueToG && rnd.NextDouble() < crewDeathChance * altitudeMult * timeMult) { killed = true; ScreenMessages.PostScreenMessage($"{vessel.vesselName}: Crewmember {pcm.name} has died from exposure to near-vacuum.", 30.0f, ScreenMessageStyle.UPPER_CENTER, XKCDColors.Red); FlightLogger.fetch.LogEvent($"[{KSPUtil.PrintTime(vessel.missionTime, 3, false)}] {pcm.name} died from exposure to near-vacuum."); part.RemoveCrewmember(pcm); pcm.Die(); } } if (killed && CameraManager.Instance.currentCameraMode == CameraManager.CameraMode.IVA) { CameraManager.Instance.SetCameraFlight(); } } else { timeSinceHypoxiaStarted = 0d; if (_origDoStockGCalcs.HasValue) { ProtoCrewMember.doStockGCalcs = _origDoStockGCalcs.Value; _origDoStockGCalcs = null; } } } } }