예제 #1
0
        // 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);
        }
예제 #2
0
 public static void LogAmmoExplosionOnPilot(InjuryReason reason)
 {
     if (reason != InjuryReason.AmmoExplosion)
     {
         return;
     }
     ammoExploded = true;
 }
예제 #3
0
        static bool Prefix(Pilot __instance, InjuryReason reason)
        {
            if (reason == InjuryReason.HeadHit && LessHeadInjuries.IgnoreNextHeadHit.Contains(__instance))
            {
                LessHeadInjuries.IgnoreNextHeadHit.Remove(__instance);
                return(false);
            }

            return(true);
        }
예제 #4
0
        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;
            }
        }
예제 #5
0
        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);
        }
예제 #6
0
    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);
        }
    }