예제 #1
0
        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));
            }
        }