private GUIStyle getGeeAccumStyle(KeepFitCrewMember crew, Period period, GeeLoadingAccumulator accum) { GameConfig gameConfig = scenarioModule.GetGameConfig(); GUIStyle style = new GUIStyle(GUI.skin.label); style.normal.textColor = Color.green; style.wordWrap = false; GeeToleranceConfig tolerance = gameConfig.GetGeeTolerance(period); if (tolerance == null) { return style; } float geeWarn = GeeLoadingCalculator.GetFitnessModifiedGeeTolerance(tolerance.warn, crew, gameConfig); float geeFatal = GeeLoadingCalculator.GetFitnessModifiedGeeTolerance(tolerance.fatal, crew, gameConfig); float gee = accum.GetLastGeeMeanPerSecond(); if (gee > geeFatal) { style.normal.textColor = Color.red; } else { if (gee > geeWarn) { style.normal.textColor = Color.yellow; } } return style; }
private GUIStyle getGeeAccumStyle(KeepFitCrewMember crew, Period period, GeeLoadingAccumulator accum) { GameConfig gameConfig = scenarioModule.GetGameConfig(); GUIStyle style = new GUIStyle(GUI.skin.label); style.normal.textColor = Color.green; style.wordWrap = false; GeeToleranceConfig tolerance = gameConfig.GetGeeTolerance(period); if (tolerance == null) { return(style); } float geeWarn = GeeLoadingCalculator.GetFitnessModifiedGeeTolerance(tolerance.warn, crew, gameConfig); float geeFatal = GeeLoadingCalculator.GetFitnessModifiedGeeTolerance(tolerance.fatal, crew, gameConfig); float gee = accum.GetLastGeeMeanPerSecond(); if (gee > geeFatal) { style.normal.textColor = Color.red; } else { if (gee > geeWarn) { style.normal.textColor = Color.yellow; } } return(style); }
public static void KillKerbal(System.Object source, KeepFitCrewMember crewMember) { Vessel vessel; Part part; ProtoCrewMember member; if (!getVesselCrewMember(crewMember.Name, out vessel, out part, out member)) { // very odd - we couldn't find the ProtoCrewMember for this KeepFitCrewMember source.Log_Release("KerbalKiller", "very odd - we couldn't find the ProtoCrewMember for this KeepFitCrewMember"); return; } if (CameraManager.Instance.currentCameraMode == CameraManager.CameraMode.IVA) { CameraManager.Instance.SetCameraFlight(); } ScreenMessages.PostScreenMessage(vessel.vesselName + ": Crewmember " + member.name + " died of G-force damage!", 30.0f, ScreenMessageStyle.UPPER_CENTER); FlightLogger.eventLog.Add("[" + FormatTime(vessel.missionTime) + "] " + member.name + " died of G-force damage."); source.Log_Release("KerbalKiller", "[{0}]: vessel[{1}] - {2} died of G-force damage.", Time.time, vessel.vesselName, member.name); if (!vessel.isEVA) { part.RemoveCrewmember(member); member.Die(); } }
private GeeLoadingOutCome handleGeeLoadingUpdate(KeepFitCrewMember crewMember, float geeLoading, float elapsedSeconds, GeeLoadingAccumulator accum, GeeToleranceConfig tolerance, float healthGeeToleranceModifier) { float meanG; if (accum.AccumulateGeeLoading(geeLoading, elapsedSeconds, out meanG)) { float geeWarn = GeeLoadingCalculator.GetFitnessModifiedGeeTolerance(tolerance.warn, crewMember, gameConfig); float geeFatal = GeeLoadingCalculator.GetFitnessModifiedGeeTolerance(tolerance.fatal, crewMember, gameConfig); if (meanG > geeFatal) { return(GeeLoadingOutCome.GeeFatal); } else if (meanG > geeWarn) { return(GeeLoadingOutCome.GeeWarn); } } return(GeeLoadingOutCome.Ok); }
public static float GetFitnessModifiedGeeTolerance(float tolerance, KeepFitCrewMember crew, GameConfig config) { float healthGeeToleranceModifier = crew.fitnessLevel / config.initialFitnessLevel; // tolerance goes down to 50% normal tolerance if you zero out on your fitness compared to baseline float result = (tolerance / 2) + tolerance * (healthGeeToleranceModifier / 2); return(result); }
public static float GetFitnessModifiedGeeTolerance(float tolerance, KeepFitCrewMember crew, GameConfig config) { float healthGeeToleranceModifier = crew.fitnessLevel / config.initialFitnessLevel; // tolerance goes down to 50% normal tolerance if you zero out on your fitness compared to baseline float result = (tolerance / 2) + tolerance * (healthGeeToleranceModifier / 2); return result; }
public float?getFitnessGeeToleranceModifier(string kerbalName) { if (gameConfig == null) { return(null); } KeepFitCrewMember crewMember = getCrewMember(kerbalName); return(crewMember != null ? (float?)GeeLoadingCalculator.GetFitnessModifiedGeeTolerance((float)1.0, crewMember, gameConfig) : null); }
private void onGeeFatal(KeepFitCrewMember crewMember) { if (!gameConfig.enabled || gameConfig.wimpMode) { string formatted = string.Format("KeepFit - Crewman {0} suffered momentary G-LOC!", crewMember.Name); ScreenMessages.PostScreenMessage(formatted, 3f, ScreenMessageStyle.UPPER_CENTER); } else { KerbalKiller.KillKerbal(this, crewMember); } }
internal void DrawExperienceTrait(KeepFitCrewMember crewMember) { ProtoCrewMember proto = HighLogic.CurrentGame.CrewRoster[crewMember.Name]; if (proto != null) { Texture2D texTrait = proto.experienceTrait.Config.IconImage; if (texTrait == null) { GUILayout.Label("(" + proto.experienceTrait.Title + ")"); } else { GUILayout.Label(new GUIContent(texTrait)); } } }
private void handleGeeLoadingUpdates(KeepFitCrewMember crew, float gee, float duration) { // modify the 'experienced' gee based on the crew member's fitness relative to the start state float healthGeeToleranceModifier = crew.fitnessLevel / gameConfig.initialFitnessLevel; GeeLoadingOutCome harshestOutcome = GeeLoadingOutCome.Ok; foreach (Period period in Enum.GetValues(typeof(Period))) { GeeToleranceConfig tolerance; GeeLoadingAccumulator accum; crew.geeAccums.TryGetValue(period, out accum); gameConfig.geeTolerances.TryGetValue(period, out tolerance); if (tolerance != null && accum != null) { if (!tryHandleWithGEffectsMod(crew, gee, duration, accum, tolerance, healthGeeToleranceModifier)) { GeeLoadingOutCome outcome = handleGeeLoadingUpdate(crew, gee, duration, accum, tolerance, healthGeeToleranceModifier); if (outcome > harshestOutcome) { harshestOutcome = outcome; } } } } switch (harshestOutcome) { case GeeLoadingOutCome.GeeFatal: onGeeFatal(crew); break; case GeeLoadingOutCome.GeeWarn: onGeeWarn(crew); break; } }
private KeepFitCrewMember updateRosters(Dictionary <string, KeepFitCrewMember> roster, KeepFitVesselRecord vessel, string name, ActivityLevel activityLevel, bool activityLevelReliable) { this.Log_DebugOnly("updateRosters", "updating crewMember[{0}] activityLevel[{1}]]", name, activityLevel); KeepFitCrewMember keepFitCrewMember = null; roster.TryGetValue(name, out keepFitCrewMember); if (keepFitCrewMember != null) { this.Log_DebugOnly("updateRosters", "crewMember[{0}] was in the old roster", name); } else { this.Log_DebugOnly("updateRosters", "crewMember[{0}] wasn't in the old roster", name); // not in the old roster - add him to the new one ... keepFitCrewMember = new KeepFitCrewMember(name, false); keepFitCrewMember.fitnessLevel = gameConfig.initialFitnessLevel; keepFitCrewMember.activityLevel = activityLevel; roster[name] = keepFitCrewMember; } if (activityLevelReliable) { keepFitCrewMember.activityLevel = activityLevel; } vessel.crew[name] = keepFitCrewMember; this.Log_DebugOnly("updateRosters", "crewMan[{0}] activityLevel[{1}]", name, activityLevel); return(keepFitCrewMember); }
private bool tryHandleWithGEffectsMod(KeepFitCrewMember crewMember, float geeLoading, float elapsedSeconds, GeeLoadingAccumulator accum, GeeToleranceConfig tolerance, float healthGeeToleranceModifier) { if (!gEffectsAPI.isInitialized()) { return(false); } double?downwardG = gEffectsAPI.getDownwardG(crewMember.Name); double?forwardG = gEffectsAPI.getForwardG(crewMember.Name); if ((downwardG == null) || (forwardG == null)) { return(false); } //The plain (medical) sum of longitudal and lateral G loads is used for G. Also the regular vector module Math.Sqrt(Math.Pow(downwardG, 2) + Math.Pow(upwardG, 2)) may be used. handleGeeLoadingUpdate(crewMember, Math.Abs((float)downwardG) + Math.Abs((float)forwardG), elapsedSeconds, accum, tolerance, healthGeeToleranceModifier); //The outcome is ignored for not displaying warning messages because G-Effects mod has enough visual warnings itself return(true); }
private GeeLoadingOutCome handleGeeLoadingUpdate(KeepFitCrewMember crewMember, float geeLoading, float elapsedSeconds, GeeLoadingAccumulator accum, GeeToleranceConfig tolerance, float healthGeeToleranceModifier) { float meanG; if (accum.AccumulateGeeLoading(geeLoading, elapsedSeconds, out meanG)) { float geeWarn = GeeLoadingCalculator.GetFitnessModifiedGeeTolerance(tolerance.warn, crewMember, gameConfig); float geeFatal = GeeLoadingCalculator.GetFitnessModifiedGeeTolerance(tolerance.fatal, crewMember, gameConfig); if (meanG > geeFatal) { return GeeLoadingOutCome.GeeFatal; } else if (meanG > geeWarn) { return GeeLoadingOutCome.GeeWarn; } } return GeeLoadingOutCome.Ok; }
private bool tryHandleWithGEffectsMod(KeepFitCrewMember crewMember, float geeLoading, float elapsedSeconds, GeeLoadingAccumulator accum, GeeToleranceConfig tolerance, float healthGeeToleranceModifier) { if (! gEffectsAPI.isInitialized()) { return false; } double? downwardG = gEffectsAPI.getDownwardG(crewMember.Name); double? forwardG = gEffectsAPI.getForwardG(crewMember.Name); if ((downwardG == null) || (forwardG == null)) { return false; } //The plain (medical) sum of longitudal and lateral G loads is used for G. Also the regular vector module Math.Sqrt(Math.Pow(downwardG, 2) + Math.Pow(upwardG, 2)) may be used. handleGeeLoadingUpdate(crewMember, Math.Abs((float)downwardG) + Math.Abs((float)forwardG), elapsedSeconds, accum, tolerance, healthGeeToleranceModifier); //The outcome is ignored for not displaying warning messages because G-Effects mod has enough visual warnings itself return true; }
private void handleGeeLoadingUpdates(KeepFitCrewMember crew, float gee, float duration) { // modify the 'experienced' gee based on the crew member's fitness relative to the start state float healthGeeToleranceModifier = crew.fitnessLevel / gameConfig.initialFitnessLevel; GeeLoadingOutCome harshestOutcome = GeeLoadingOutCome.Ok; foreach (Period period in Enum.GetValues(typeof(Period))) { GeeToleranceConfig tolerance; GeeLoadingAccumulator accum; crew.geeAccums.TryGetValue(period, out accum); gameConfig.geeTolerances.TryGetValue(period, out tolerance); if (tolerance != null && accum != null) { if (! tryHandleWithGEffectsMod(crew, gee, duration, accum, tolerance, healthGeeToleranceModifier)) { GeeLoadingOutCome outcome = handleGeeLoadingUpdate(crew, gee, duration, accum, tolerance, healthGeeToleranceModifier); if (outcome > harshestOutcome) { harshestOutcome = outcome; } } } } switch (harshestOutcome) { case GeeLoadingOutCome.GeeFatal: onGeeFatal(crew); break; case GeeLoadingOutCome.GeeWarn: onGeeWarn(crew); break; } }
private void onGeeWarn(KeepFitCrewMember crewMember) { string formatted = string.Format("KeepFit - Crewman {0} is reaching his G limits!", crewMember.Name); ScreenMessages.PostScreenMessage(formatted, 3f, ScreenMessageStyle.UPPER_CENTER); }
public Single?getFitnessLevel(string kerbalName) { KeepFitCrewMember crewMember = getCrewMember(kerbalName); return(crewMember != null ? (Single?)crewMember.fitnessLevel : null); }
private KeepFitCrewMember updateRosters(Dictionary<string, KeepFitCrewMember> roster, KeepFitVesselRecord vessel, string name, ActivityLevel activityLevel, bool activityLevelReliable) { this.Log_DebugOnly("updateRosters", "updating crewMember[{0}] activityLevel[{1}]]", name, activityLevel); KeepFitCrewMember keepFitCrewMember = null; roster.TryGetValue(name, out keepFitCrewMember); if (keepFitCrewMember != null) { this.Log_DebugOnly("updateRosters", "crewMember[{0}] was in the old roster", name); } else { this.Log_DebugOnly("updateRosters", "crewMember[{0}] wasn't in the old roster", name); // not in the old roster - add him to the new one ... keepFitCrewMember = new KeepFitCrewMember(name, false); keepFitCrewMember.fitnessLevel = gameConfig.initialFitnessLevel; keepFitCrewMember.activityLevel = activityLevel; roster[name] = keepFitCrewMember; } if (activityLevelReliable) { keepFitCrewMember.activityLevel = activityLevel; } vessel.crew[name] = keepFitCrewMember; this.Log_DebugOnly("updateRosters", "crewMan[{0}] activityLevel[{1}]", name, activityLevel); return keepFitCrewMember; }
public void FixedUpdate() { // too spammy //this.Log_DebugOnly("FixedUpdate", "."); if (gameConfig == null) { // too spammy //this.Log_DebugOnly("FixedUpdate", "No gameConfig - bailing"); return; } if (HighLogic.LoadedSceneIsEditor) { // too spammy this.Log_DebugOnly("FixedUpdate", "Not in flight scene - bailing"); return; } if (lastGeeLoadingUpdateUT == -1) { this.Log_DebugOnly("FixedUpdate", "No lastGeeLoadingUpdateUT - skipping this update"); // don't do anything this time this.lastGeeLoadingUpdateUT = Planetarium.GetUniversalTime(); return; } double currentUT = Planetarium.GetUniversalTime(); float elapsedSeconds = (float)(currentUT - lastGeeLoadingUpdateUT); lastGeeLoadingUpdateUT = currentUT; // too spammy //this.Log_DebugOnly("FixedUpdate", "[{0}] seconds since last fixed update", elapsedSeconds); // just check gee loading on active vessel for now Vessel vessel = FlightGlobals.ActiveVessel; if (vessel == null) { this.Log_DebugOnly("FixedUpdate", "No active vessel"); return; } // too spammy //this.Log_DebugOnly("FixedUpdate", "Checking gee loading for active vessel[{0}]", vessel.GetName()); float geeLoading; string invalidReason; bool valid = GeeLoadingCalculator.GetGeeLoading(vessel, out geeLoading, out invalidReason); if (!valid) { this.Log_DebugOnly("FixedUpdate", "Gee loading for active vessel[{0}] is not valid currently because[{1}]", vessel.GetName(), invalidReason); } else { // too spammy //this.Log_DebugOnly("FixedUpdate", "Gee loading for active vessel[{0}] is[{1}] letting the crew know", vessel.GetName(), geeLoading); foreach (ProtoCrewMember crewMember in vessel.GetVesselCrew()) { try { // too spammy //this.Log_DebugOnly("FixedUpdate", "Gee loading for active vessel[{0}] is[{1}] letting [{2}] know", vessel.GetName(), geeLoading, crewMember.name); KeepFitCrewMember keepFitCrewMember = gameConfig.roster.crew[crewMember.name]; handleGeeLoadingUpdates(keepFitCrewMember, geeLoading, elapsedSeconds); } catch (KeyNotFoundException) { // ignore, we'll pick them up later this.Log_Release("KeepFitGeeEffectsController:FixedUpdate", "Gee loading for active vessel[{0}] is[{1}] crewmember [{2}] not in the keepfit roster yet", vessel.GetName(), geeLoading, crewMember.name); } } } }
public void FixedUpdate() { // too spammy //this.Log_DebugOnly("FixedUpdate", "."); if (gameConfig == null) { // too spammy //this.Log_DebugOnly("FixedUpdate", "No gameConfig - bailing"); return; } if (HighLogic.LoadedSceneIsEditor) { // too spammy this.Log_DebugOnly("FixedUpdate", "Not in flight scene - bailing"); return; } // just check gee loading on active vessel for now Vessel vessel = FlightGlobals.ActiveVessel; if (vessel == null) { this.Log_DebugOnly("FixedUpdate", "No active vessel"); return; } if (lastGeeLoadingUpdateUT == -1) { this.Log_DebugOnly("FixedUpdate", "No lastGeeLoadingUpdateUT - skipping this update"); if (vessel.situation == Vessel.Situations.LANDED || vessel.situation == Vessel.Situations.SPLASHED || vessel.situation == Vessel.Situations.PRELAUNCH) { gStart = (float)vessel.mainBody.GeeASL; } else { gStart = 0; } gHistory = Enumerable.Repeat(gStart, 300).ToList(); gLoads[Period.Inst] = gStart; gLoads[Period.Short] = gStart; gLoads[Period.Medium] = gStart; gLoads[Period.Long] = gStart; // don't do anything this time this.lastGeeLoadingUpdateUT = Planetarium.GetUniversalTime(); return; } // too spammy //this.Log_DebugOnly("FixedUpdate", "[{0}] seconds since last fixed update", elapsedSeconds); // too spammy //this.Log_DebugOnly("FixedUpdate", "Checking gee loading for active vessel[{0}]", vessel.GetName()); float geeLoading; string invalidReason; bool valid = GeeLoadingCalculator.GetGeeLoading(vessel, out geeLoading, out invalidReason); if (!valid) { this.Log_DebugOnly("FixedUpdate", "Gee loading for active vessel[{0}] is not valid currently because[{1}]", vessel.GetName(), invalidReason); } else { // too spammy //this.Log_DebugOnly("FixedUpdate", "Gee loading for active vessel[{0}] is[{1}] letting the crew know", vessel.GetName(), geeLoading); double currentUT = Planetarium.GetUniversalTime(); float elapsedSeconds = (float)(currentUT - lastGeeLoadingUpdateUT); if (elapsedSeconds >= 1) { lastGeeLoadingUpdateUT = currentUT; gHistory.RemoveAt(299); gHistory.Insert(0, geeLoading); gLoads[Period.Inst] = geeLoading; gLoads[Period.Short] = gHistory.GetRange(0, 5).Average(); gLoads[Period.Medium] = gHistory.GetRange(0, 60).Average(); gLoads[Period.Long] = gHistory.Average(); } foreach (ProtoCrewMember crewMember in vessel.GetVesselCrew()) { try { // too spammy //this.Log_DebugOnly("FixedUpdate", "Gee loading for active vessel[{0}] is[{1}] letting [{2}] know", vessel.GetName(), geeLoading, crewMember.name); KeepFitCrewMember keepFitCrewMember = gameConfig.roster.crew[crewMember.name]; handleGeeLoadingUpdates(keepFitCrewMember, gLoads); } catch (KeyNotFoundException) { // ignore, we'll pick them up later this.Log_Release("KeepFitGeeEffectsController:FixedUpdate", "Gee loading for active vessel[{0}] is[{1}] crewmember [{2}] not in the keepfit roster yet", vessel.GetName(), geeLoading, crewMember.name); } } } }