private static void Prefix(Mech __instance, string sourceID, int stackItemID) { ILog heatLogger = HBS.Logging.Logger.GetLogger("CombatLog.Heat", LogLevel.Warning); if (heatLogger.IsLogEnabled) { heatLogger.Log(string.Format("[CBTHeat] Is Overheated: {0}", __instance.IsOverheated)); } if (__instance.IsOverheated) { CBTPilotingRules rules = new CBTPilotingRules(__instance.Combat); float gutsTestChance = rules.GetGutsModifier(__instance); float skillRoll = __instance.Combat.NetworkRandom.Float(); float ammoRoll = __instance.Combat.NetworkRandom.Float(); int turnsOverheated = __instance.StatCollection.GetValue <int>("TurnsOverheated"); float shutdownPercentage = CBTHeat.GetShutdownPercentageForTurn(turnsOverheated); float ammoExplosionPercentage = CBTHeat.GetAmmoExplosionPercentageForTurn(turnsOverheated); if (heatLogger.IsLogEnabled) { heatLogger.Log(string.Format("[CBTHeat] Turns Overheated: {0}", turnsOverheated)); heatLogger.Log(string.Format("[CBTHeat] Intiating Shutdown Override Check")); heatLogger.Log(string.Format("[CBTHeat] Guts Skill: {0}", (float)__instance.SkillGuts)); heatLogger.Log(string.Format("[CBTHeat] Guts Divisor: {0}", CBTHeat.Settings.GutsDivisor)); heatLogger.Log(string.Format("[CBTHeat] Guts Bonus: {0}", gutsTestChance)); heatLogger.Log(string.Format("[CBTHeat] Skill Roll: {0}", skillRoll)); heatLogger.Log(string.Format("[CBTHeat] Skill + Guts Roll: {0}", skillRoll + gutsTestChance)); heatLogger.Log(string.Format("[CBTHeat] Ammo Roll: {0}", ammoRoll)); heatLogger.Log(string.Format("[CBTHeat] Ammo + Guts Roll: {0}", ammoRoll + gutsTestChance)); heatLogger.Log(string.Format("[CBTHeat] Skill Target: {0}", shutdownPercentage)); heatLogger.Log(string.Format("[CBTHeat] Ammo Roll Target: {0}", ammoExplosionPercentage)); } if (CBTHeat.Settings.UseGuts) { ammoRoll = ammoRoll + gutsTestChance; skillRoll = skillRoll + gutsTestChance; } MultiSequence sequence = new MultiSequence(__instance.Combat); sequence.SetCamera(CameraControl.Instance.ShowDeathCam(__instance, false, -1f), 0); if (CBTHeat.CanAmmoExplode(__instance)) { if (ammoRoll < ammoExplosionPercentage) { __instance.Combat.MessageCenter.PublishMessage(new FloatieMessage(__instance.GUID, __instance.GUID, "Ammo Overheated!", FloatieMessage.MessageNature.CriticalHit)); var ammoBox = __instance.ammoBoxes.Where(box => box.CurrentAmmo > 0).OrderByDescending(box => box.CurrentAmmo / box.AmmoCapacity).FirstOrDefault(); if (ammoBox != null) { var fakeHit = new WeaponHitInfo(stackItemID, -1, -1, -1, string.Empty, string.Empty, -1, null, null, null, null, null, null, null, AttackDirection.None, Vector2.zero, null); ammoBox.DamageComponent(fakeHit, ComponentDamageLevel.Destroyed, true); } return; } sequence.AddChildSequence(new ShowActorInfoSequence(__instance, "Ammo Explosion Avoided!", FloatieMessage.MessageNature.Debuff, true), sequence.ChildSequenceCount - 1); } if (!__instance.IsPastMaxHeat) { if (skillRoll < shutdownPercentage) { if (heatLogger.IsLogEnabled) { heatLogger.Log(string.Format("[CBTHeat] Skill Check Failed! Initiating Shutdown")); } MechEmergencyShutdownSequence mechShutdownSequence = new MechEmergencyShutdownSequence(__instance); sequence.AddChildSequence(mechShutdownSequence, sequence.ChildSequenceCount - 1); __instance.StatCollection.Set <int>("TurnsOverheated", 0); } else { if (heatLogger.IsLogEnabled) { heatLogger.Log(string.Format("[CBTHeat] Skill Check Succeeded!")); } sequence.AddChildSequence(new ShowActorInfoSequence(__instance, "Shutdown Override Successful!", FloatieMessage.MessageNature.Buff, true), sequence.ChildSequenceCount - 1); turnsOverheated += 1; __instance.StatCollection.Set <int>("TurnsOverheated", turnsOverheated); } } sequence.AddChildSequence(new DelaySequence(__instance.Combat, 2f), sequence.ChildSequenceCount - 1); __instance.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(sequence)); } else { int turnsOverheated = __instance.StatCollection.GetValue <int>("TurnsOverheated"); if (turnsOverheated > 0) { __instance.StatCollection.Set <int>("TurnsOverheated", 0); } } }
static void Prefix(Mech __instance) { Mod.HeatLog.Info?.Write($"AT END OF TURN: ACTOR: {__instance.DistinctId()} has currentHeat: {__instance.CurrentHeat}" + $" tempHeat: {__instance.TempHeat} maxHeat: {__instance.MaxHeat} heatsinkCapacity: {__instance.AdjustedHeatsinkCapacity}"); // Invalidate any melee state the actor may have set ModState.InvalidateState(__instance); // Make the checks for ammo explosions, etc float heatCheck = __instance.HeatCheckMod(Mod.Config.SkillChecks.ModPerPointOfGuts); float pilotCheck = __instance.PilotCheckMod(Mod.Config.SkillChecks.ModPerPointOfPiloting); Mod.HeatLog.Debug?.Write($" Actor: {__instance.DistinctId()} has heatCheckMod: {heatCheck} pilotingCheckMod: {pilotCheck}"); MultiSequence sequence = new MultiSequence(__instance.Combat); bool failedInjuryCheck = CheckHelper.ResolvePilotInjuryCheck(__instance, __instance.CurrentHeat, sequence.RootSequenceGUID, sequence.SequenceGUID, heatCheck); bool failedSystemFailureCheck = CheckHelper.ResolveSystemFailureCheck(__instance, __instance.CurrentHeat, sequence.SequenceGUID, heatCheck); bool failedAmmoCheck = CheckHelper.ResolveRegularAmmoCheck(__instance, __instance.CurrentHeat, sequence.SequenceGUID, heatCheck); bool failedVolatileAmmoCheck = CheckHelper.ResolveVolatileAmmoCheck(__instance, __instance.CurrentHeat, sequence.SequenceGUID, heatCheck); Mod.HeatLog.Info?.Write($" failedInjuryCheck: {failedInjuryCheck} failedSystemFailureCheck: {failedSystemFailureCheck} " + $"failedAmmoCheck: {failedAmmoCheck} failedVolatileAmmoCheck: {failedVolatileAmmoCheck}"); bool failedShutdownCheck = false; if (!__instance.IsShutDown) { // Resolve Shutdown + Fall failedShutdownCheck = !CheckHelper.DidCheckPassThreshold(Mod.Config.Heat.Shutdown, __instance.CurrentHeat, __instance, heatCheck, ModText.FT_Check_Shutdown); Mod.HeatLog.Info?.Write($" failedShutdownCheck: {failedShutdownCheck}"); if (failedShutdownCheck) { Mod.HeatLog.Info?.Write($"-- Shutdown check failed for unit {CombatantUtils.Label(__instance)}, forcing unit to shutdown"); string debuffText = new Text(Mod.LocalizedText.Floaties[ModText.FT_Shutdown_Failed_Overide]).ToString(); sequence.AddChildSequence(new ShowActorInfoSequence(__instance, debuffText, FloatieMessage.MessageNature.Debuff, true), sequence.ChildSequenceCount - 1); MechEmergencyShutdownSequence mechShutdownSequence = new MechEmergencyShutdownSequence(__instance); //{ // RootSequenceGUID = __instance.SequenceGUID //}; sequence.AddChildSequence(mechShutdownSequence, sequence.ChildSequenceCount - 1); if (__instance.IsOrWillBeProne) { bool failedFallingCheck = !CheckHelper.DidCheckPassThreshold(Mod.Config.Heat.ShutdownFallThreshold, __instance, pilotCheck, ModText.FT_Check_Fall); Mod.HeatLog.Debug?.Write($" failedFallingCheck: {failedFallingCheck}"); if (failedFallingCheck) { Mod.HeatLog.Info?.Write(" Pilot check from shutdown failed! Forcing a fall!"); string fallDebuffText = new Text(Mod.LocalizedText.Floaties[ModText.FT_Shutdown_Fall]).ToString(); sequence.AddChildSequence(new ShowActorInfoSequence(__instance, fallDebuffText, FloatieMessage.MessageNature.Debuff, true), sequence.ChildSequenceCount - 1); MechFallSequence mfs = new MechFallSequence(__instance, "Overheat", new Vector2(0f, -1f)); //{ // RootSequenceGUID = __instance.SequenceGUID //}; sequence.AddChildSequence(mfs, sequence.ChildSequenceCount - 1); } else { Mod.HeatLog.Info?.Write($"Pilot check to avoid falling passed. Applying unstead to unit."); __instance.ApplyUnsteady(); } } else { Mod.HeatLog.Debug?.Write("Unit is already prone, skipping."); } } } else { Mod.HeatLog.Debug?.Write("Unit is already shutdown, skipping."); } if (failedInjuryCheck || failedSystemFailureCheck || failedAmmoCheck || failedVolatileAmmoCheck || failedShutdownCheck) { __instance.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(sequence)); } }