// AI Helper functions below // Return of MaxHeat means no limit from this effect public static int AcceptableHeatForAIFromVolatileAmmo(this Mech mech, float heatCheckMod, float bhvarAcceptableHeatFraction) { int acceptableHeat = Mod.Config.Heat.MaxHeat; Mod.AILog.Info?.Write($"-- Checking volatile ammo "); AmmunitionBox mostDamagingVolatile = HeatHelper.FindMostDamagingAmmoBox(mech, true); if (mostDamagingVolatile != null) { // We have volatile ammo, success chances will be lower because of the greater chance of an ammo explosion foreach (KeyValuePair <int, float> kvp in Mod.Config.Heat.Explosion) { if (kvp.Value == -1f) { // Guaranteed explosion, return one less than this value acceptableHeat = kvp.Key - 1; break; } float rawExplosionChance = Math.Max(0f, kvp.Value - heatCheckMod); Mod.AILog.Info?.Write($" heat: {kvp.Key} has rawChance: {kvp.Value} - pilotMod: {heatCheckMod} => raw explosionChance: {rawExplosionChance}"); float successChance = 1.0f - rawExplosionChance; float compoundChance = successChance * successChance; float finalExplosionChance = 1.0f - compoundChance; Mod.AILog.Info?.Write($" 1.0f - compoundChance: {compoundChance} => finalExplosionChance: {finalExplosionChance}"); if (finalExplosionChance <= bhvarAcceptableHeatFraction) { acceptableHeat = kvp.Key; } else { break; } } } else { Mod.AILog.Info?.Write($" No volatile ammo, skipping"); } Mod.AILog.Info?.Write($"Unit: {mech.DistinctId()} has acceptableHeat: {acceptableHeat} from volatile ammo due to behVar: {bhvarAcceptableHeatFraction}."); return(acceptableHeat); }
public static void Postfix(CombatHUDStatusPanel __instance, Mech mech) { Mod.UILog.Trace?.Write("CHUBSP:SSDI:POST entered."); var type = __instance.GetType(); MethodInfo methodInfo = type.GetMethod("ShowDebuff", (BindingFlags.NonPublic | BindingFlags.Instance), null, new Type[] { typeof(SVGAsset), typeof(Text), typeof(Text), typeof(Vector3), typeof(bool) }, new ParameterModifier[5]); Traverse HUDT = Traverse.Create(__instance).Property("HUD"); CombatHUD HUD = HUDT.GetValue <CombatHUD>(); CalculatedHeat calculatedHeat = HeatHelper.CalculateHeat(mech, HUD.SelectionHandler.ProjectedHeatForState); Mod.UILog.Debug?.Write($"In ShutdownIndicator, projectedHeat {HUD.SelectionHandler.ProjectedHeatForState} => calculatedHeat: {calculatedHeat.ThresholdHeat} vs {Mod.Config.Heat.WarnAtHeat}"); Mod.UILog.Debug?.Write($" current: {calculatedHeat.CurrentHeat} projected: {calculatedHeat.ProjectedHeat} temp: {calculatedHeat.TempHeat} " + $"sinkable: {calculatedHeat.SinkableHeat} sinkCapacity: {calculatedHeat.OverallSinkCapacity} future: {calculatedHeat.FutureHeat} threshold: {calculatedHeat.ThresholdHeat}"); Mod.UILog.Debug?.Write($" CACTerrainHeat{ calculatedHeat.CACTerrainHeat} CurrentPathNodes: {calculatedHeat.CurrentPathNodes} isProjectedHeat: {calculatedHeat.IsProjectedHeat}"); if (mech.IsShutDown) { Mod.UILog.Info?.Write($" Mech {CombatantUtils.Label(mech)} is shutdown, displaying the shutdown warning"); methodInfo.Invoke(__instance, new object[] { LazySingletonBehavior <UIManager> .Instance.UILookAndColorConstants.StatusShutDownIcon, new Text(Mod.LocalizedText.Tooltips[ModText.CHUDSP_TT_WARN_SHUTDOWN_TITLE]), new Text(Mod.LocalizedText.Tooltips[ModText.CHUDSP_TT_WARN_SHUTDOWN_TEXT]), __instance.defaultIconScale, false }); } else if (calculatedHeat.ThresholdHeat >= Mod.Config.Heat.WarnAtHeat) { Mod.UILog.Info?.Write($"Mech {mech.DistinctId()} has thresholdHeat {calculatedHeat.ThresholdHeat} >= warningHeat: {Mod.Config.Heat.WarnAtHeat}. Displaying heat warning."); methodInfo.Invoke(__instance, new object[] { LazySingletonBehavior <UIManager> .Instance.UILookAndColorConstants.StatusOverheatingIcon, new Text(Mod.LocalizedText.Tooltips[ModText.CHUDSP_TT_WARN_OVERHEAT_TITLE]), new Text(Mod.LocalizedText.Tooltips[ModText.CHUDSP_TT_WARN_OVERHEAT_TEXT]), __instance.defaultIconScale, false }); } }
// Return of MaxHeat means no limit from this effect public static int AcceptableHeatForAIFromRegularAmmo(this Mech mech, float heatCheckMod, float bhvarAcceptableHeatFraction) { int acceptableHeat = Mod.Config.Heat.MaxHeat; Mod.AILog.Info?.Write($"-- Checking regular ammo "); AmmunitionBox mostDamaging = HeatHelper.FindMostDamagingAmmoBox(mech, false); if (mostDamaging != null) { // We have regular ammo, so success chances are as on tin foreach (KeyValuePair <int, float> kvp in Mod.Config.Heat.Explosion) { if (kvp.Value == -1f) { // Guaranteed explosion, return one less than this value acceptableHeat = kvp.Key - 1; break; } float explosionChance = Math.Max(0f, kvp.Value - heatCheckMod); Mod.AILog.Info?.Write($" heat: {kvp.Key} has rawChance: {kvp.Value} - pilotMod: {heatCheckMod} => explosionChance: {explosionChance}"); if (explosionChance <= bhvarAcceptableHeatFraction) { acceptableHeat = kvp.Key; } else { break; } } } else { Mod.AILog.Info?.Write($" No regular ammo, skipping"); } Mod.AILog.Info?.Write($"Unit: {mech.DistinctId()} has acceptableHeat: {acceptableHeat} from regular ammo due to behVar: {bhvarAcceptableHeatFraction}."); return(acceptableHeat); }
public static void Postfix(CombatHUDAttackModeSelector __instance) { Mod.UILog.Trace?.Write("CHUDAMS:U - entered."); Traverse HUDT = Traverse.Create(__instance).Property("HUD"); CombatHUD HUD = HUDT.GetValue <CombatHUD>(); if (HUD != null && HUD.SelectedActor != null && HUD.SelectedActor is Mech) { Traverse showHeatWarningsT = Traverse.Create(__instance).Field("showHeatWarnings"); bool showHeatWarnings = showHeatWarningsT.GetValue <bool>(); if (showHeatWarnings) { CalculatedHeat calculatedHeat = HeatHelper.CalculateHeat(HUD.SelectedActor as Mech, HUD.SelectionHandler.ProjectedHeatForState); //Mod.UILog.Debug?.Write($" In CombatHUDAttackModeSelector, projectedHeat: {calculatedHeat.ThresholdHeat} vs {Mod.Config.Heat.WarnAtHeat}"); bool isOverheated = calculatedHeat.ThresholdHeat >= Mod.Config.Heat.WarnAtHeat; bool isShutdown = calculatedHeat.ThresholdHeat >= Mod.Config.Heat.MaxHeat; Traverse updateOverheatWarningsT = Traverse.Create(__instance).Method("UpdateOverheatWarnings", new object[] { isOverheated, isShutdown }); updateOverheatWarningsT.GetValue(); } } }
public ActionResult <IEnumerable <SensorDataExDTO> > Get(string id, [FromQuery] string from, [FromQuery] string to) { List <SensorDataExDTO> retData = new List <SensorDataExDTO>(); List <AggregateDataEx> sensorDataList = _repository.LoadSensorDataEx(id, from, to); foreach (var item in sensorDataList) { var tmp = new SensorDataExDTO(); tmp.MAC = item.SenderMAC; tmp.Name = item.SenderName; tmp.Temp = item.Temperature; tmp.Humidity = item.Humidity; tmp.IngestionTimestamp = item.IngestionTimestamp; tmp.TValve = item.TValve; tmp.TScheduledTarget = item.TScheduledTarget; tmp.BatteryLevel = item.BatteryLevel; tmp.HeatIndex = HeatHelper.GetHeatIndexCelsius(item.Temperature, item.Humidity); tmp.SetTempSended = item.SetTempSended; tmp.TCurrentTarget = item.TCurrentTarget; retData.Add(tmp); } return(retData); }
public void UpdateText(Mech displayedMech) { CalculatedHeat calculatedHeat = HeatHelper.CalculateHeat(displayedMech, CombatHUD.SelectionHandler.ProjectedHeatForState); // If everything has changed, skip and avoid the update if (calculatedHeat.CurrentHeat == CurrentHeat && calculatedHeat.TempHeat == TempHeat && calculatedHeat.ProjectedHeat == ProjectedHeat && calculatedHeat.CACTerrainHeat == this.CACTerrainHeat && calculatedHeat.CurrentPathNodes == CurrentPathNodes) { return; } Mod.HeatLog.Debug?.Write($"Updating heat dialog for actor: {CombatantUtils.Label(displayedMech)}"); Mod.HeatLog.Debug?.Write($" previous values: CurrentHeat: {CurrentHeat} ProjectedHeat: {ProjectedHeat} TempHeat: {TempHeat} CACTerrainHeat: {CACTerrainHeat} currentPathNodes: {CurrentPathNodes}"); this.CurrentHeat = calculatedHeat.CurrentHeat; this.ProjectedHeat = calculatedHeat.ProjectedHeat; this.TempHeat = calculatedHeat.TempHeat; this.CACTerrainHeat = calculatedHeat.CACTerrainHeat; this.CurrentPathNodes = calculatedHeat.CurrentPathNodes; Mod.HeatLog.Debug?.Write($" current values: CurrentHeat: {CurrentHeat} ProjectedHeat: {ProjectedHeat} TempHeat: {TempHeat} CACTerrainHeat: {CACTerrainHeat} currentPathNodes: {CurrentPathNodes}"); StringBuilder descSB = new StringBuilder(""); StringBuilder warningSB = new StringBuilder(""); // Future heat descSB.Append(new Localize.Text( Mod.LocalizedText.Tooltips[ModText.CHUD_TT_End_Heat], new object[] { calculatedHeat.ThresholdHeat, Mod.Config.Heat.MaxHeat } )); // Heat line float heatCheck = displayedMech.HeatCheckMod(Mod.Config.SkillChecks.ModPerPointOfGuts); // Force a recalculation of the overheat warning if (calculatedHeat.FutureHeat > Mod.Config.Heat.WarnAtHeat) { Traverse statusPanelT = Traverse.Create(HUD.MechTray).Field("StatusPanel"); CombatHUDStatusPanel combatHUDStatusPanel = statusPanelT.GetValue <CombatHUDStatusPanel>(); Traverse showShutdownIndicator = Traverse.Create(combatHUDStatusPanel).Method("ShowShutDownIndicator", new object[] { displayedMech }); showShutdownIndicator.GetValue(); } float sinkCapMulti = displayedMech.DesignMaskHeatMulti(calculatedHeat.IsProjectedHeat); string sinkCapMultiColor = sinkCapMulti >= 1f ? "00FF00" : "FF0000"; descSB.Append(new Localize.Text( Mod.LocalizedText.Tooltips[ModText.CHUD_TT_Heat], new object[] { calculatedHeat.FutureHeat, Mod.Config.Heat.MaxHeat, calculatedHeat.SinkableHeat, calculatedHeat.OverallSinkCapacity, sinkCapMultiColor, sinkCapMulti } )); float threshold = 0f; // Check Ammo foreach (KeyValuePair <int, float> kvp in Mod.Config.Heat.Explosion) { if (calculatedHeat.ThresholdHeat >= kvp.Key) { threshold = kvp.Value; } } if (threshold != 0f && threshold != -1f) { Mod.HeatLog.Debug?.Write($"Ammo Explosion Threshold: {threshold} vs. d100+{heatCheck * 100f}"); descSB.Append(new Localize.Text( Mod.LocalizedText.Tooltips[ModText.CHUD_TT_Explosion], new object[] { heatCheck * 100f, threshold * 100f } )); } else if (threshold == -1f) { Mod.HeatLog.Debug?.Write($"Ammo Explosion Guaranteed!"); warningSB.Append(new Localize.Text(Mod.LocalizedText.Tooltips[ModText.CHUD_TT_Explosion_Warning])); } // Check Injury threshold = 0f; foreach (KeyValuePair <int, float> kvp in Mod.Config.Heat.PilotInjury) { if (calculatedHeat.ThresholdHeat >= kvp.Key) { threshold = kvp.Value; } } if (threshold != 0f) { Mod.HeatLog.Debug?.Write($"Injury Threshold: {threshold} vs. d100+{heatCheck * 100f}"); descSB.Append(new Localize.Text( Mod.LocalizedText.Tooltips[ModText.CHUD_TT_Injury], new object[] { heatCheck * 100f, threshold * 100f } )); } // Check System Failure threshold = 0f; foreach (KeyValuePair <int, float> kvp in Mod.Config.Heat.SystemFailures) { if (calculatedHeat.ThresholdHeat >= kvp.Key) { threshold = kvp.Value; } } if (threshold != 0f) { Mod.HeatLog.Debug?.Write($"System Failure Threshold: {threshold} vs. d100+{heatCheck * 100f}"); descSB.Append(new Localize.Text( Mod.LocalizedText.Tooltips[ModText.CHUD_TT_Sys_Failure], new object[] { heatCheck * 100f, threshold * 100f } )); } // Check Shutdown threshold = 0f; foreach (KeyValuePair <int, float> kvp in Mod.Config.Heat.Shutdown) { if (calculatedHeat.ThresholdHeat >= kvp.Key) { threshold = kvp.Value; } } if (threshold != 0f && threshold != -1f) { Mod.HeatLog.Debug?.Write($"Shutdown Threshold: {threshold} vs. d100+{heatCheck * 100f}"); descSB.Append(new Localize.Text( Mod.LocalizedText.Tooltips[ModText.CHUD_TT_Shutdown], new object[] { heatCheck * 100f, threshold * 100f } )); } else if (threshold == -1f) { Mod.HeatLog.Debug?.Write($"Shutdown Guaranteed!"); warningSB.Append(new Localize.Text(Mod.LocalizedText.Tooltips[ModText.CHUD_TT_Shutdown_Warning])); } // Attack modifiers int modifier = 0; foreach (KeyValuePair <int, int> kvp in Mod.Config.Heat.Firing) { if (calculatedHeat.ThresholdHeat >= kvp.Key) { modifier = kvp.Value; } } if (modifier != 0) { Mod.HeatLog.Debug?.Write($"Attack Modifier: +{modifier}"); descSB.Append(new Localize.Text(Mod.LocalizedText.Tooltips[ModText.CHUD_TT_Attack], new object[] { modifier })); } modifier = 0; // Movement modifier foreach (KeyValuePair <int, int> kvp in Mod.Config.Heat.Firing) { if (calculatedHeat.ThresholdHeat >= kvp.Key) { modifier = kvp.Value; } } if (modifier != 0) { Mod.HeatLog.Debug?.Write($"Movement Modifier: -{modifier * 30}m"); descSB.Append(new Localize.Text(Mod.LocalizedText.Tooltips[ModText.CHUD_TT_Move], new object[] { modifier * 30f })); } base.SetTitleDescAndWarning("Heat", descSB.ToString(), warningSB.ToString()); }