public static void Prefix(MechFallSequence __instance) { Mod.Log.Trace("MFS:OnComplete - entered."); int damagePointsTT = (int)Math.Ceiling(__instance.OwningMech.tonnage / 10f); Mod.Log.Debug($"Actor: {CombatantUtils.Label(__instance.OwningMech)} will suffer {damagePointsTT} TT damage points."); // Check for any pilot skill damage reduction float damageReduction = 1.0f - __instance.OwningMech.PilotCheckMod(Mod.Config.Piloting.DFAReductionMulti); float reducedDamage = (float)Math.Max(0f, Math.Floor(damageReduction * damagePointsTT)); Mod.Log.Debug($" Reducing TT fall damage from: {damagePointsTT} by {damageReduction:P1} to {reducedDamage}"); List <int> locationDamage = new List <int>(); while (damagePointsTT >= 5) { locationDamage.Add(5 * Mod.Config.Piloting.FallingDamagePerTenTons); damagePointsTT -= 5; } if (damagePointsTT > 0) { locationDamage.Add(damagePointsTT * Mod.Config.Piloting.FallingDamagePerTenTons); } Mod.Log.Debug($"Applying falling damage to actor: {CombatantUtils.Label(__instance.OwningMech)}"); foreach (int damage in locationDamage) { ArmorLocation location = FallingDamageLocations[__instance.OwningMech.Combat.NetworkRandom.Int(0, FallingDamageLocations.Length)]; Mod.Log.Debug($" {damage} damage to location: {location}"); __instance.OwningMech.DEBUG_DamageLocation(location, damage, __instance.OwningMech, DamageType.KnockdownSelf); } }
// Create a falling sequence, publish a floatie with the error public static void AddFallingSequence(Mech mech, MultiSequence parentSequence, string floatieText) { MechFallSequence mechFallSequence = new MechFallSequence(mech, floatieText, new Vector2(0f, -1f)); string fallDebuffText = new Text(Mod.Config.LocalizedFloaties[floatieText]).ToString(); MultiSequence showInfoSequence = new ShowActorInfoSequence(mech, fallDebuffText, FloatieMessage.MessageNature.Debuff, false) { RootSequenceGUID = mechFallSequence.SequenceGUID }; mechFallSequence.AddChildSequence(showInfoSequence, mechFallSequence.MessageIndex); mech.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(mechFallSequence)); }
// Create a falling sequence, publish a floatie with the error public static void AddFallingSequence(Mech mech, MultiSequence parentSequence, string floatieText) { Mod.Log.Info?.Write($"Adding falling sequence for mech: {mech.DistinctId()}"); MechFallSequence mechFallSequence = new MechFallSequence(mech, floatieText, new Vector2(0f, -1f)); string fallDebuffText = new Text(Mod.LocalizedText.Floaties[floatieText]).ToString(); MultiSequence showInfoSequence = new ShowActorInfoSequence(mech, fallDebuffText, FloatieMessage.MessageNature.Debuff, false) { RootSequenceGUID = mechFallSequence.SequenceGUID }; mechFallSequence.AddChildSequence(showInfoSequence, mechFallSequence.MessageIndex); mech.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(mechFallSequence)); Mod.Log.Info?.Write(" -- published fall sequence."); IStackSequence doneWithActorSequence = mech.DoneWithActor(); mech.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(doneWithActorSequence)); Mod.Log.Info?.Write(" -- published doneWithActor sequence."); }
public static void Prefix(MechFallSequence __instance) { Mod.Log.Trace?.Write("MFS:OnComplete - entered."); int damagePointsTT = (int)Math.Ceiling(__instance.OwningMech.tonnage / 10f); Mod.Log.Debug?.Write($"Actor: {CombatantUtils.Label(__instance.OwningMech)} will suffer {damagePointsTT} TT damage points."); // Check for any pilot skill damage reduction float damageReduction = 1.0f - __instance.OwningMech.PilotCheckMod(Mod.Config.Piloting.DFAReductionMulti); float reducedDamage = (float)Math.Max(0f, Math.Floor(damageReduction * damagePointsTT)); Mod.Log.Debug?.Write($" Reducing TT fall damage from: {damagePointsTT} by {damageReduction:P1} to {reducedDamage}"); List <float> locationDamage = new List <float>(); while (damagePointsTT >= 5) { locationDamage.Add(5 * Mod.Config.Piloting.FallingDamagePerTenTons); damagePointsTT -= 5; } if (damagePointsTT > 0) { locationDamage.Add(damagePointsTT * Mod.Config.Piloting.FallingDamagePerTenTons); } Mod.Log.Info?.Write($"FALLING DAMAGE: TT damage: {damagePointsTT} => {damagePointsTT * Mod.Config.Piloting.FallingDamagePerTenTons} falling damage to actor: {CombatantUtils.Label(__instance.OwningMech)}"); try { (Weapon melee, Weapon dfa)fakeWeapons = ModState.GetFakedWeapons(__instance.OwningMech); AttackHelper.CreateImaginaryAttack(__instance.OwningMech, fakeWeapons.melee, __instance.OwningMech, __instance.SequenceGUID, locationDamage.ToArray(), DamageType.KnockdownSelf, MeleeAttackType.NotSet); } catch (Exception e) { Mod.Log.Error?.Write(e, "FAILED TO APPLY FALL DAMAGE"); } }
static void ApplyFallingDamage(MechFallSequence sequence, int oldState, int newState) { if (newState != FinishedState) { return; } var mech = sequence.OwningMech; if (mech.IsFlaggedForDeath || mech.IsDead) { return; // TODO: maybe even the dead should take damage? } var locationTakingDamage = possibleLocations[UnityEngine.Random.Range(0, possibleLocations.Length)]; Logger.Debug($"falling happened!\nlocation taking damage: {locationTakingDamage}"); var rawFallingDamage = Core.ModSettings.FallingAmountDamagePerTon * mech.tonnage; var fallingDamageValue = rawFallingDamage; if (Core.ModSettings.PilotingSkillFallingDamageMitigation) { var mitigation = Calculator.PilotingMitigation(mech); var mitigationPercent = Mathf.RoundToInt(mitigation * 100); fallingDamageValue = rawFallingDamage - (mitigation * rawFallingDamage); Logger.Debug($"falling damage numbers\n" + $"pilotSkill: {mech.SkillPiloting}\n" + $"mitigation: {mitigation}\n" + $"rawFallingDamage: {rawFallingDamage}\n" + $"mitigationPercent: {mitigationPercent}\n" + $"fallingDamageValue: {fallingDamageValue}"); mech.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(new ShowActorInfoSequence(mech, $"Pilot Check: Avoided {mitigationPercent}% Falling Damage!", FloatieMessage.MessageNature.Neutral, true))); } mech.DEBUG_DamageLocation(locationTakingDamage, fallingDamageValue, mech); if (AttackDirector.damageLogger.IsLogEnabled) { AttackDirector.damageLogger.Log($"@@@@@@@@ {mech.DisplayName} takes {fallingDamageValue} damage to its {Mech.GetLongArmorLocation(locationTakingDamage)} from falling!"); } }
public static bool Prefix(MechHeatSequence __instance, HeatSequenceState newState) { if (newState != HeatSequenceState.Finished) { return(true); } Traverse stateT = Traverse.Create(__instance).Field("state"); HeatSequenceState currentState = (HeatSequenceState)stateT.GetValue <int>(); if (currentState == newState) { return(true); } Mod.Log.Info($"MHS - executing updated logic for state: {newState} on actor:{__instance.OwningMech.DisplayName}_{__instance.OwningMech.GetPilot().Name}."); stateT.SetValue((int)newState); Traverse timeInCurrentStateT = Traverse.Create(__instance).Field("timeInCurrentState"); timeInCurrentStateT.SetValue(0f); /* Finished Can be invoked from a rising state (heat being added): * Attack Sequence, artillery sequence, actor burning effect, (heatSinkStep=false, applyStartupHeatSinks=false) * On End of turn sequence - (heatSinkStep=true, applyStartupHeatSinks=false) * On Mech Startup sequence - (heatSinkStep=true, applyStartupHeatSinks=true) */ if (!__instance.PerformHeatSinkStep) { Mod.Log.Debug($"Reconciling heat for actor: {CombatantUtils.Label(__instance.OwningMech)}"); Mod.Log.Debug($" Before - currentHeat: {__instance.OwningMech.CurrentHeat} tempHeat: {__instance.OwningMech.TempHeat} " + $"isPastMaxHeat: {__instance.OwningMech.IsPastMaxHeat} hasAppliedHeatSinks: {__instance.OwningMech.HasAppliedHeatSinks}"); // Checks for heat damage, clamps heat to max and min __instance.OwningMech.ReconcileHeat(__instance.RootSequenceGUID, __instance.InstigatorID); Mod.Log.Debug($" After - currentHeat: {__instance.OwningMech.CurrentHeat} tempHeat: {__instance.OwningMech.TempHeat} " + $"isPastMaxHeat: {__instance.OwningMech.IsPastMaxHeat} hasAppliedHeatSinks: {__instance.OwningMech.HasAppliedHeatSinks}"); } //if (__instance.OwningMech.IsPastMaxHeat && !__instance.OwningMech.IsShutDown) { // __instance.OwningMech.GenerateOverheatedSequence(__instance); // return; //} if (__instance.PerformHeatSinkStep && !__instance.ApplyStartupHeatSinks) { // We are at the end of the turn - force an overheat Mod.Log.Info("AT END OF TURN - CHECKING EFFECTS"); MultiSequence sequence = new MultiSequence(__instance.OwningMech.Combat); // Possible sequences // Shutdown // Fall from shutdown // Ammo Explosion // System damage // Pilot injury // Pilot death float heatCheck = __instance.OwningMech.HeatCheckMod(Mod.Config.Piloting.SkillMulti); float pilotCheck = __instance.OwningMech.PilotCheckMod(Mod.Config.Piloting.SkillMulti); Mod.Log.Debug($" Actor: {CombatantUtils.Label(__instance.OwningMech)} has gutsMulti: {heatCheck} pilotingMulti: {pilotCheck}"); // Resolve Pilot Injury bool failedInjuryCheck = !CheckHelper.DidCheckPassThreshold(Mod.Config.Heat.PilotInjury, __instance.OwningMech.CurrentHeat, __instance.OwningMech, heatCheck, ModConfig.FT_Check_Injury); Mod.Log.Debug($" failedInjuryCheck: {failedInjuryCheck}"); if (failedInjuryCheck) { Mod.Log.Debug("-- Pilot Injury check failed, forcing injury from heat"); __instance.OwningMech.pilot.InjurePilot(__instance.SequenceGUID.ToString(), __instance.RootSequenceGUID, 1, DamageType.OverheatSelf, null, __instance.OwningMech); if (!__instance.OwningMech.pilot.IsIncapacitated) { AudioEventManager.SetPilotVOSwitch <AudioSwitch_dialog_dark_light>(AudioSwitch_dialog_dark_light.dark, __instance.OwningMech); AudioEventManager.PlayPilotVO(VOEvents.Pilot_TakeDamage, __instance.OwningMech, null, null, true); if (__instance.OwningMech.team.LocalPlayerControlsTeam) { AudioEventManager.PlayAudioEvent("audioeventdef_musictriggers_combat", "friendly_warrior_injured", null, null); } } } // Resolve System Damage bool failedSystemFailureCheck = !CheckHelper.DidCheckPassThreshold(Mod.Config.Heat.SystemFailures, __instance.OwningMech.CurrentHeat, __instance.OwningMech, heatCheck, ModConfig.FT_Check_System_Failure); Mod.Log.Debug($" failedSystemFailureCheck: {failedSystemFailureCheck}"); if (failedSystemFailureCheck) { Mod.Log.Debug("-- System Failure check failed, forcing system damage"); List <MechComponent> functionalComponents = __instance.OwningMech.allComponents.Where(mc => mc.IsFunctional).ToList(); MechComponent componentToDamage = functionalComponents.GetRandomElement(); Mod.Log.Debug($" Destroying component: {componentToDamage.UIName} from heat damage."); WeaponHitInfo fakeHit = new WeaponHitInfo(__instance.RootSequenceGUID, -1, -1, -1, string.Empty, string.Empty, -1, null, null, null, null, null, null, null, new AttackDirection[] { AttackDirection.None }, null, null, null); componentToDamage.DamageComponent(fakeHit, ComponentDamageLevel.Destroyed, true); } // Resolve Ammo Explosion - regular ammo bool failedAmmoCheck = false; AmmunitionBox mostDamaging = HeatHelper.FindMostDamagingAmmoBox(__instance.OwningMech, false); if (mostDamaging != null) { failedAmmoCheck = !CheckHelper.DidCheckPassThreshold(Mod.Config.Heat.Explosion, __instance.OwningMech.CurrentHeat, __instance.OwningMech, heatCheck, ModConfig.FT_Check_Explosion); Mod.Log.Debug($" failedAmmoCheck: {failedAmmoCheck}"); if (failedAmmoCheck) { Mod.Log.Debug("-- Ammo Explosion check failed, forcing ammo explosion"); if (mostDamaging != null) { Mod.Log.Debug($" Exploding ammo: {mostDamaging.UIName}"); WeaponHitInfo fakeHit = new WeaponHitInfo(__instance.RootSequenceGUID, -1, -1, -1, string.Empty, string.Empty, -1, null, null, null, null, null, null, null, new AttackDirection[] { AttackDirection.None }, null, null, null); mostDamaging.DamageComponent(fakeHit, ComponentDamageLevel.Destroyed, true); } else { Mod.Log.Debug(" Unit has no ammo boxes, skipping."); } } } // Resolve Ammo Explosion - inferno ammo bool failedVolatileAmmoCheck = false; AmmunitionBox mostDamagingVolatile = HeatHelper.FindMostDamagingAmmoBox(__instance.OwningMech, true); if (mostDamagingVolatile != null) { failedVolatileAmmoCheck = !CheckHelper.DidCheckPassThreshold(Mod.Config.Heat.Explosion, __instance.OwningMech.CurrentHeat, __instance.OwningMech, heatCheck, ModConfig.FT_Check_Explosion); Mod.Log.Debug($" failedVolatileAmmoCheck: {failedVolatileAmmoCheck}"); if (failedVolatileAmmoCheck) { Mod.Log.Debug("-- Volatile Ammo Explosion check failed, forcing volatile ammo explosion"); if (mostDamaging != null) { Mod.Log.Debug($" Exploding inferno ammo: {mostDamagingVolatile.UIName}"); WeaponHitInfo fakeHit = new WeaponHitInfo(__instance.RootSequenceGUID, -1, -1, -1, string.Empty, string.Empty, -1, null, null, null, null, null, null, null, new AttackDirection[] { AttackDirection.None }, null, null, null); mostDamagingVolatile.DamageComponent(fakeHit, ComponentDamageLevel.Destroyed, true); } else { Mod.Log.Debug(" Unit has no inferno ammo boxes, skipping."); } } } bool failedShutdownCheck = false; if (!__instance.OwningMech.IsShutDown) { // Resolve Shutdown + Fall failedShutdownCheck = !CheckHelper.DidCheckPassThreshold(Mod.Config.Heat.Shutdown, __instance.OwningMech.CurrentHeat, __instance.OwningMech, heatCheck, ModConfig.FT_Check_Shutdown); Mod.Log.Debug($" failedShutdownCheck: {failedShutdownCheck}"); if (failedShutdownCheck) { Mod.Log.Debug("-- Shutdown check failed, forcing unit to shutdown"); string debuffText = new Text(Mod.Config.LocalizedFloaties[ModConfig.FT_Shutdown_Failed_Overide]).ToString(); sequence.AddChildSequence(new ShowActorInfoSequence(__instance.OwningMech, debuffText, FloatieMessage.MessageNature.Debuff, true), sequence.ChildSequenceCount - 1); MechEmergencyShutdownSequence mechShutdownSequence = new MechEmergencyShutdownSequence(__instance.OwningMech) { RootSequenceGUID = __instance.SequenceGUID }; sequence.AddChildSequence(mechShutdownSequence, sequence.ChildSequenceCount - 1); if (__instance.OwningMech.IsOrWillBeProne) { bool failedFallingCheck = !CheckHelper.DidCheckPassThreshold(Mod.Config.Heat.ShutdownFallThreshold, __instance.OwningMech, pilotCheck, ModConfig.FT_Check_Fall); Mod.Log.Debug($" failedFallingCheck: {failedFallingCheck}"); if (failedFallingCheck) { Mod.Log.Info("Pilot check from shutdown failed! Forcing a fall!"); string fallDebuffText = new Text(Mod.Config.LocalizedFloaties[ModConfig.FT_Shutdown_Fall]).ToString(); sequence.AddChildSequence(new ShowActorInfoSequence(__instance.OwningMech, fallDebuffText, FloatieMessage.MessageNature.Debuff, true), sequence.ChildSequenceCount - 1); MechFallSequence mfs = new MechFallSequence(__instance.OwningMech, "Overheat", new Vector2(0f, -1f)) { RootSequenceGUID = __instance.SequenceGUID }; sequence.AddChildSequence(mfs, sequence.ChildSequenceCount - 1); } else { Mod.Log.Info($"Pilot check to avoid falling passed."); } } else { Mod.Log.Debug("Unit is already prone, skipping."); } } } else { Mod.Log.Debug("Unit is already shutdown, skipping."); } if (failedInjuryCheck || failedSystemFailureCheck || failedAmmoCheck || failedShutdownCheck) { __instance.OwningMech.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(sequence)); } return(false); } if (__instance.OwningMech.GameRep != null) { if (__instance.OwningMech.team.LocalPlayerControlsTeam) { if (__instance.OwningMech.CurrentHeat > __instance.OwningMech.OverheatLevel) { string text = string.Format("MechHeatSequence_{0}_{1}", __instance.RootSequenceGUID, __instance.SequenceGUID); AudioEventManager.CreateVOQueue(text, -1f, null, null); AudioEventManager.QueueVOEvent(text, VOEvents.Mech_Overheat_Warning, __instance.OwningMech); AudioEventManager.StartVOQueue(1f); } if ((float)__instance.OwningMech.CurrentHeat > (float)__instance.OwningMech.MaxHeat - (float)(__instance.OwningMech.MaxHeat - __instance.OwningMech.OverheatLevel) * 0.333f) { WwiseManager.PostEvent <AudioEventList_ui>(AudioEventList_ui.ui_overheat_alarm_3, WwiseManager.GlobalAudioObject, null, null); } else if ((float)__instance.OwningMech.CurrentHeat > (float)__instance.OwningMech.MaxHeat - (float)(__instance.OwningMech.MaxHeat - __instance.OwningMech.OverheatLevel) * 0.666f) { WwiseManager.PostEvent <AudioEventList_ui>(AudioEventList_ui.ui_overheat_alarm_2, WwiseManager.GlobalAudioObject, null, null); } else if (__instance.OwningMech.CurrentHeat > __instance.OwningMech.OverheatLevel) { WwiseManager.PostEvent <AudioEventList_ui>(AudioEventList_ui.ui_overheat_alarm_1, WwiseManager.GlobalAudioObject, null, null); } } if (__instance.OwningMech.CurrentHeat > Mod.Config.Heat.ShowLowOverheatAnim) { __instance.OwningMech.GameRep.StopManualPersistentVFX(__instance.OwningMech.Combat.Constants.VFXNames.heat_midHeat_persistent); __instance.OwningMech.GameRep.PlayVFX(8, __instance.OwningMech.Combat.Constants.VFXNames.heat_highHeat_persistent, true, Vector3.zero, false, -1f); return(false); } if ((float)__instance.OwningMech.CurrentHeat > Mod.Config.Heat.ShowExtremeOverheatAnim) { __instance.OwningMech.GameRep.StopManualPersistentVFX(__instance.OwningMech.Combat.Constants.VFXNames.heat_highHeat_persistent); __instance.OwningMech.GameRep.PlayVFX(8, __instance.OwningMech.Combat.Constants.VFXNames.heat_midHeat_persistent, true, Vector3.zero, false, -1f); return(false); } __instance.OwningMech.GameRep.StopManualPersistentVFX(__instance.OwningMech.Combat.Constants.VFXNames.heat_highHeat_persistent); __instance.OwningMech.GameRep.StopManualPersistentVFX(__instance.OwningMech.Combat.Constants.VFXNames.heat_midHeat_persistent); } return(false); }
public static void Postfix(MechFallSequence __instance) { Mod.Log.Trace?.Write("MFS:OnAdded - entered."); QuipHelper.PublishQuip(__instance.OwningMech, Mod.LocalizedText.Quips.Knockdown); }
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)); } }