// true implies injury occurs static bool Prefix(Pilot __instance, InjuryReason reason) { try { if (reason != InjuryReason.SideTorsoDestroyed && reason == InjuryReason.HeadHit && IgnoreNextHeadHit.Contains(__instance)) { //var sim = UnityGameInstance.BattleTechGame.Simulation; //if (sim.CompanyTags.Contains("FewerHeadInjuriesDisabled")) // return true; UnityGameInstance.BattleTechGame.Combat.MessageCenter.PublishMessage( new AddSequenceToStackMessage( new ShowActorInfoSequence( __instance.ParentActor, "INJURY AVOIDED", FloatieMessage.MessageNature.Inspiration, false) ) ); IgnoreNextHeadHit.Remove(__instance); return(false); } } catch (Exception ex) { Log(ex.ToString()); } return(true); }
public static void LogAmmoExplosionOnPilot(InjuryReason reason) { if (reason != InjuryReason.AmmoExplosion) { return; } ammoExploded = true; }
static bool Prefix(Pilot __instance, InjuryReason reason) { if (reason == InjuryReason.HeadHit && LessHeadInjuries.IgnoreNextHeadHit.Contains(__instance)) { LessHeadInjuries.IgnoreNextHeadHit.Remove(__instance); return(false); } return(true); }
public static void Postfix(Pilot __instance, InjuryReason reason, bool __state, ref bool ___needsInjury, ref InjuryReason ___injuryReason) { // Check for ReceiveHeatDamageInjury if (__instance?.ParentActor?.GetType() == typeof(Mech)) { Mech mech = (Mech)__instance.ParentActor; Statistic receiveHeatDamageInjuryStat = mech.StatCollection.GetStatistic("ReceiveHeatDamageInjury"); Mod.Log.Debug($"Checking actor with injuryReason:{reason} and receiveHeatDamageInjury:{receiveHeatDamageInjuryStat}"); // If the below is true, we likely are coming from a ME patch - // see https://github.com/BattletechModders/MechEngineer/blob/master/source/Features/ShutdownInjuryProtection/Patches/Mech_CheckForHeatDamage_Patch.cs if (reason == InjuryReason.NotSet && mech.IsOverheated && mech.StatCollection.GetStatistic("ReceiveHeatDamageInjury") != null) { Mod.Log.Debug($"Actor received a heatDamage injury, computing overheat ratio."); float overheatRatio = PainHelper.CalculateOverheatRatio(mech); int overheatPenalty = (int)Math.Floor(overheatRatio * Mod.Config.Combat.PainTolerance.PenaltyPerHeatDamageInjuryRatio); Mod.Log.Debug($"overheatPenalty:{overheatPenalty} = " + $"Floor( overheatRatio:{overheatRatio} * penaltyPerOverheatDamage{Mod.Config.Combat.PainTolerance.PenaltyPerHeatDamageInjuryRatio} )"); ModState.InjuryResistPenalty = overheatPenalty; } // Set explicit damage values for known damage types if (reason == InjuryReason.Knockdown) { ModState.InjuryResistPenalty = Mod.Config.Combat.PainTolerance.KnockdownDamage; } else if (reason == InjuryReason.SideTorsoDestroyed) { ModState.InjuryResistPenalty = Mod.Config.Combat.PainTolerance.TorsoDestroyedDamage; } } if (ModState.InjuryResistPenalty != -1) { bool success = PainHelper.MakeResistCheck(__instance); if (success) { // If the state value is true, then there was already an injury set on the pilot. Do nothign. if (__state) { Mod.Log.Info($"Pilot has an outstanding injury, not ignoring!"); } else { ___needsInjury = false; ___injuryReason = InjuryReason.NotSet; } } // Reset our mod state ModState.InjuryResistPenalty = -1; } }
static bool Prefix(Pilot __instance, DamageType damageType, ref bool ___needsInjury, ref InjuryReason ___injuryReason) { Mod.Log.Trace?.Write("P:SNI - entered"); // DEBUG Line here: Someone is emitting an injuryReason of 101. Try to identify them by emitting a stack trace when this happens. if ((int)___injuryReason > 6) { Mod.Log.Warn?.Write($"PainTolerance intercepted injuryReason with value of: {(int)___injuryReason} and desc: {___injuryReason}"); Mod.Log.Info?.Write($" -- injured actor was: {__instance.ParentActor.DistinctId()}"); System.Diagnostics.StackTrace t = new System.Diagnostics.StackTrace(); Mod.Log.Info?.Write($" -- PainTolerance:InjurePilot intercepted call stack:"); Mod.Log.Info?.Write($" --\n\n{t}"); Mod.Log.Info?.Write($" -- Skipping pain tolerance check!"); return(true); } if (__instance.ParentActor == null) { return(true); } Mod.Log.Info?.Write($"Checking pilot: {__instance.ParentActor.DistinctId()} to resist injury of type: {___injuryReason}"); // Compute the resist penalty for each damage type that we support if (damageType == DamageType.HeadShot) { Mod.Log.Info?.Write($" Actor suffered a headshot, injury resist was set to: {ModState.InjuryResistPenalty}"); } else if (damageType == DamageType.AmmoExplosion) { Mod.Log.Info?.Write($" Actor suffered an ammo explosion, injury resist was set to: {ModState.InjuryResistPenalty}"); } else if (damageType == DamageType.Knockdown || damageType == DamageType.KnockdownSelf) { ModState.InjuryResistPenalty = Mod.Config.Combat.PainTolerance.KnockdownResistPenalty; Mod.Log.Info?.Write($" Actor was knocked down, setting injury resist to: {ModState.InjuryResistPenalty}"); } else if (damageType == DamageType.SideTorso) { ModState.InjuryResistPenalty = Mod.Config.Combat.PainTolerance.SideLocationDestroyedResistPenalty; Mod.Log.Info?.Write($" Actor torso/side destroyed, setting injury resist to: {ModState.InjuryResistPenalty}"); } else if (damageType == DamageType.Overheat || damageType == DamageType.OverheatSelf || "OVERHEATED".Equals(__instance.InjuryReasonDescription, StringComparison.InvariantCultureIgnoreCase)) { // comparison string must match label in https://github.com/BattletechModders/MechEngineer/blob/master/source/Features/ShutdownInjuryProtection/Patches/Pilot_InjuryReasonDescription_Patch.cs Mod.Log.Debug?.Write($" Actor damage from overheating or ME heatDamage injury, computing overheat ratio."); float overheatRatio = PainHelper.CalculateOverheatRatio(__instance.ParentActor as Mech); int overheatPenalty = (int)Math.Floor(overheatRatio * Mod.Config.Combat.PainTolerance.OverheatResistPenaltyPerHeatPercentile); Mod.Log.Debug?.Write($" overheatPenalty:{overheatPenalty} = " + $"Floor( overheatRatio:{overheatRatio} * penaltyPerOverheatDamage{Mod.Config.Combat.PainTolerance.OverheatResistPenaltyPerHeatPercentile} )"); ModState.InjuryResistPenalty = overheatPenalty; Mod.Log.Info?.Write($" Actor overheated, setting injury resist to: {ModState.InjuryResistPenalty}"); } // Check head injury if (__instance.ParentActor.ImmuneToHeadInjuries()) { Mod.Log.Info?.Write($"Ignoring head injury on actor: {__instance.ParentActor.DistinctId()} due to stat"); return(false); } // Need default resistance? if (ModState.InjuryResistPenalty != -1) { bool success = PainHelper.MakeResistCheck(__instance); if (success) { Mod.Log.Info?.Write($"Ignoring {___injuryReason} injury on pilot."); // Publish a floatie string localText = new Text(Mod.LocalizedText.Floaties[ModText.FT_InjuryResist], new object[] { }).ToString(); IStackSequence stackSequence = new ShowActorInfoSequence(__instance.ParentActor, localText, FloatieMessage.MessageNature.PilotInjury, useCamera: false); SharedState.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(stackSequence)); return(false); } else { Mod.Log.Info?.Write($"Pilot will suffer injury type: {___injuryReason}."); } ModState.InjuryResistPenalty = -1; } return(true); }
internal static void SetInjury(this AbstractActor actor, string sourceID, int stackItemUID, InjuryReason reason, DamageType damageType) { var pilot = actor.GetPilot(); if (pilot == null) { return; } // check if we might override an existing injury if (pilot.NeedsInjury) { Control.Logger.Warning?.Log($"Can't apply injury as another injury is already queued, conflicting res={pilot.injuryReason} desc={pilot.InjuryReasonDescription}"); return; } // attack sequences still going on will call CheckPilotStatusFromAttack at the end var hasAnyAttackSequence = actor.Combat.AttackDirector.GetAllAttackSequencesThatAffectCombatant(actor).Any(); if (ForceInjuryImmediatelyIfOutsideAttackSequence || AllowDelayedInjuryUntilNextTurn || hasAnyAttackSequence) { pilot.SetNeedsInjury(reason); } if (ForceInjuryImmediatelyIfOutsideAttackSequence && !hasAnyAttackSequence) { CheckPilotStatusForInjuries(actor, sourceID, stackItemUID, damageType); } }