public override void CombatStartsOnce()
        {
            instance         = this;
            NameplateColours = ParseColours(Settings.NameplateColourPlayer, Settings.NameplateColourEnemy, Settings.NameplateColourAlly);
            if (Settings.ShowEnemyWounds != null || Settings.ShowAllyHealth != null || Settings.ShowPlayerHealth != null)
            {
                Patch(typeof(CombatHUDActorNameDisplay), "RefreshInfo", typeof(VisibilityLevel), null, "ShowPilotWounds");
                Patch(typeof(Pilot), "InjurePilot", null, "RefreshPilotNames");
            }
            if (NameplateColours != null)
            {
                Info("Nameplate colours: {0}", NameplateColours);
                Patch(typeof(CombatHUDNumFlagHex), "OnActorChanged", null, "SetNameplateColor");
            }
            FloatingArmorColours = ParseColours(Settings.FloatingArmorColourPlayer, Settings.FloatingArmorColourEnemy, Settings.FloatingArmorColourAlly);
            if (FloatingArmorColours != null)
            {
                Info("Armor colours: {0}", FloatingArmorColours);
                BarOwners = new Dictionary <CombatHUDPipBar, ICombatant>();
                Patch(typeof(CombatHUDPipBar), "ShowValue", new Type[] { typeof(float), typeof(Color), typeof(Color), typeof(Color), typeof(bool) }, "SetArmorBarColour", null);
                Patch(typeof(CombatHUDNumFlagHex), "OnActorChanged", "SetArmorBarOwner", null);
            }

            if (Settings.ShowDangerousTerrain)
            {
                SidePanelProp = typeof(MoveStatusPreview).GetProperty("sidePanel", NonPublic | Instance);
                if (SidePanelProp == null)
                {
                    Warn("MoveStatusPreview.sidePanel not found, ShowDangerousTerrain not patched.");
                }
                else
                {
                    Patch(typeof(MoveStatusPreview), "DisplayPreviewStatus", null, "AppendDangerousTerrainText");
                }
            }
            if (Settings.ShowMeleeTerrain)  // Considered transpiler but we'll only save one method call. Not worth trouble?
            {
                UpdateStatusMethod = typeof(CombatMovementReticle).GetMethod("UpdateStatusPreview", NonPublic | Instance);
                StatusPreviewProp  = typeof(CombatMovementReticle).GetProperty("StatusPreview", NonPublic | Instance);
                if (AnyNull <object>(UpdateStatusMethod, StatusPreviewProp))
                {
                    Warn("CombatMovementReticle.UpdateStatusPreview or StatusPreview not found, ShowMeleeTerrain not patched.");
                }
                else
                {
                    Patch(typeof(CombatMovementReticle), "DrawPath", null, "ShowMeleeTerrainText");
                    Patch(typeof(CombatMovementReticle), "drawJumpPath", null, "ShowDFATerrainText");
                }
            }
            if (Settings.SpecialTerrainDotSize != 1 || Settings.NormalTerrainDotSize != 1)
            {
                Patch(typeof(MovementDotMgr.MovementDot).GetConstructors()[0], null, "ScaleMovementDot");
            }
            if (Settings.BoostTerrainDotColor)
            {
                Patch(typeof(CombatMovementReticle), "Awake", null, "ColourMovementDot");
            }
        }
        public override void CombatStartsOnce()
        {
            Type SlotType = typeof(CombatHUDWeaponSlot), PanelType = typeof(CombatHUDWeaponPanel);

            if (Settings.SaturationOfLoadout != 0 || Settings.ShowDamageInLoadout || Settings.ShowMeleeDamageInLoadout || Settings.ShowAlphaDamageInLoadout != null)
            {
                Patch(typeof(CombatHUDTargetingComputer), "RefreshWeaponList", null, "EnhanceWeaponLoadout");
            }

            if (Settings.ShowBaseHitchance)
            {
                Patch(SlotType, "UpdateToolTipsFiring", typeof(ICombatant), "ShowBaseHitChance", null);
                Patch(SlotType, "UpdateToolTipsMelee", typeof(ICombatant), "ShowBaseMeleeChance", null);
            }
            if (Settings.ShowNeutralRangeInBreakdown)
            {
                rangedPenalty = ModifierList.GetRangedModifierFactor("range");
                Patch(SlotType, "UpdateToolTipsFiring", typeof(ICombatant), "ShowNeutralRange", null);
            }
            if (Settings.ShowWeaponProp || Settings.WeaponRangeFormat != null)
            {
                Patch(SlotType, "GenerateToolTipStrings", null, "UpdateWeaponTooltip");
            }

            if (Settings.ShowReducedWeaponDamage || Settings.CalloutWeaponStability)
            {
                Patch(SlotType, "RefreshDisplayedWeapon", null, "UpdateWeaponDamage");
            }
            if (Settings.ShowTotalWeaponDamage)
            {
                Patch(PanelType, "ShowWeaponsUpTo", null, "ShowTotalDamageSlot");
                Patch(PanelType, "RefreshDisplayedWeapons", "ResetTotalWeaponDamage", "ShowTotalWeaponDamage");
                Patch(SlotType, "RefreshHighlighted", "BypassTotalSlotHighlight", null);
            }
            if (Settings.ShowReducedWeaponDamage || Settings.ShowTotalWeaponDamage)
            {
                // Update damage numbers (and multi-target highlights) _after_ all slots are in a correct state.
                Patch(typeof(SelectionStateFireMulti), "SetTargetedCombatant", null, "RefreshTotalDamage");
                Patch(SlotType, "OnPointerUp", null, "RefreshTotalDamage");
            }
            if (Settings.CalloutWeaponStability)
            {
                HeadsUpDisplay.HookCalloutToggle(ToggleStabilityDamage);
            }

            if (HasMod("com.joelmeador.WeaponRealizer", "WeaponRealizer.Core"))
            {
                TryRun(ModLog, InitWeaponRealizerBridge);
            }
        }
        public override void CombatStartsOnce()
        {
            if (Settings.ShowNumericInfo)
            {
                Patch(typeof(CombatHUDActorDetailsDisplay), "RefreshInfo", null, "ShowNumericInfo");
                Patch(typeof(CombatHUDActorInfo), "RefreshAllInfo", "RecordTarget", "ShowBuildingInfo");
                Patch(typeof(CombatHUDActorInfo), "RefreshPredictedHeatInfo", null, "RecordRefresh");
                Patch(typeof(CombatHUDActorInfo), "RefreshPredictedStabilityInfo", null, "RecordRefresh");
                // Force heat/stab number refresh
                Patch(typeof(CombatHUDMechTray), "Update", null, "RefreshActorInfo");
                // Force move/distance number refresh
                Patch(typeof(SelectionStateMove), "ProcessMousePos", null, "RefreshMoveAndDist");
                Patch(typeof(SelectionStateJump), "ProcessMousePos", null, "RefreshMoveAndDist");
                HeadsUpDisplay.HookCalloutToggle(RefreshTargetInfo);
            }
            if (Settings.FixHeatPreview)
            {
                Patch(typeof(Mech), "get_AdjustedHeatsinkCapacity", null, "CorrectProjectedHeat");
            }

            if (Settings.ShowAmmoInTooltip || Settings.ShowEnemyAmmoInTooltip)
            {
                MechTrayArmorHoverToolTipProp = typeof(CombatHUDMechTrayArmorHover).GetProperty("ToolTip", NonPublic | Instance);
                if (MechTrayArmorHoverToolTipProp == null)
                {
                    Warn("Cannot access CombatHUDMechTrayArmorHover.ToolTip, ammo not displayed in paperdoll tooltip.");
                }
                else
                {
                    Patch(typeof(CombatHUDMechTrayArmorHover), "setToolTipInfo", new Type[] { typeof(Mech), typeof(ArmorLocation) }, "OverridePaperDollTooltip", null);
                }
            }

            if (Settings.ShortPilotHint != null)
            {
                PilotStatus = new Dictionary <CombatHUDMWStatus, Pilot>(4);
                Patch(typeof(CombatHUDMWStatus), "OnPortraitRightClicked", null, "RefreshPilotHint");
                Patch(typeof(CombatHUDMWStatus), "ForceUnexpand", null, "RefreshPilotHint");
                Patch(typeof(CombatHUDMWStatus), "RefreshPilot", null, "ReplacePilotHint");
            }

            if (Settings.MechTrayGreyActedPilot)
            {
                Patch(typeof(CombatHUDPortrait), "RefreshDisplayedActor", null, "ColourPilotNames");
            }
        }