Esempio n. 1
0
        public static void HUDMechArmorReadout_SetHoveredArmor_Postfix(HUDMechArmorReadout __instance, ArmorLocation location, Mech ___displayedMech)
        {
            if (__instance.UseForCalledShots && location == ArmorLocation.Head)
            {
                Mod.Log.Trace("HUDMAR:SHA entered");

                bool             canAlwaysCalledShot = false;
                List <Statistic> customStats         = ActorHelper.FindCustomStatistic(ModStats.CalledShowAlwaysAllow, __instance.HUD.SelectedActor);
                foreach (Statistic stat in customStats)
                {
                    if (stat.ValueType() == typeof(bool) && stat.Value <bool>())
                    {
                        canAlwaysCalledShot = true;
                    }
                }
                bool canBeTargeted = __instance.HUD.SelectedTarget.IsShutDown || __instance.HUD.SelectedTarget.IsProne || canAlwaysCalledShot;

                Mod.Log.Debug($"  Hover - target:({___displayedMech.DisplayName}_{___displayedMech.GetPilot()?.Name}) canBeTargeted:{canBeTargeted} by attacker:({__instance.HUD.SelectedActor.DisplayName})");
                Mod.Log.Debug($"      isShutdown:{___displayedMech.IsShutDown} isProne:{___displayedMech.IsProne} canAlwaysCalledShot:{canAlwaysCalledShot}");

                if (!canBeTargeted)
                {
                    Mod.Log.Debug("  preventing targeting of head.");
                    __instance.ClearHoveredArmor(ArmorLocation.Head);
                }
                else
                {
                    Mod.Log.Debug("  target head can be targeted.");
                }
            }
        }
Esempio n. 2
0
        static void Postfix(HUDMechArmorReadout __instance, ArmorLocation location, Mech ___displayedMech)
        {
            if (__instance == null || __instance.HUD == null ||
                __instance.HUD.SelectedActor == null || __instance.HUD.SelectedTarget == null)
            {
                return; // nothing to do
            }
            if (__instance.UseForCalledShots && location == ArmorLocation.Head)
            {
                Mod.Log.Trace?.Write("HUDMAR:SHA entered");

                bool attackerCanAlwaysMakeCalledShot = __instance.HUD.SelectedActor.CanAlwaysUseCalledShot();
                bool targetCanBeCalledShot           = __instance.HUD.SelectedTarget.IsShutDown || __instance.HUD.SelectedTarget.IsProne || attackerCanAlwaysMakeCalledShot;

                Mod.Log.Debug?.Write($"  Hover - target:({___displayedMech.DistinctId()}) canBeTargeted:{targetCanBeCalledShot} by attacker:({__instance.HUD.SelectedActor.DistinctId()})");
                Mod.Log.Debug?.Write($"      isShutdown:{___displayedMech.IsShutDown} isProne:{___displayedMech.IsProne} canAlwaysCalledShot:{attackerCanAlwaysMakeCalledShot}");

                if (!targetCanBeCalledShot)
                {
                    Mod.Log.Debug?.Write("  preventing targeting of head.");
                    __instance.ClearHoveredArmor(ArmorLocation.Head);
                }
                else
                {
                    Mod.Log.Debug?.Write("  target head can be targeted.");
                }
            }
        }
 public static void Postfix(HUDBuildingStructureReadout __instance)
 {
     if (__instance.DisplayedBuilding != null && __instance.HoverInfoTextStructure != null)
     {
         // TODO: Handle sensor lock
         int maxStructure = HUDMechArmorReadout.FormatForSummary(__instance.DisplayedBuilding.SummaryStructureMax);
         __instance.HoverInfoTextStructure.SetText($"? / {maxStructure}");
     }
 }
Esempio n. 4
0
        // Private method can't be patched by annotations, so use MethodInfo
        //public static MethodInfo TargetMethod() {
        //    return AccessTools.Method(typeof(HUDMechArmorReadout), "RefreshHoverInfo", new Type[] { });
        //}

        public static void Postfix(HUDMechArmorReadout __instance)
        {
            if (__instance != null && __instance.DisplayedMech != null && __instance.HoverInfoTextArmor != null && __instance.HoverInfoTextStructure != null)
            {
                if (!__instance.DisplayedMech.Combat.HostilityMatrix.IsLocalPlayerFriendly(__instance.DisplayedMech.TeamId))
                {
                    Mod.Log.Trace?.Write($"Hiding armor and structure on target: {CombatantUtils.Label(__instance.DisplayedMech)}");
                    ArmorAndStructHelper.ObfuscateArmorAndStructText(__instance.DisplayedMech, __instance.HoverInfoTextArmor, __instance.HoverInfoTextStructure);
                }
            }
        }
Esempio n. 5
0
        public static void Postfix(CombatHUDMechTrayArmorHover __instance)
        {
            HUDMechArmorReadout          ___Readout = (HUDMechArmorReadout)Traverse.Create(__instance).Property("Readout").GetValue();
            CombatHUDTooltipHoverElement ___ToolTip = (CombatHUDTooltipHoverElement)Traverse.Create(__instance).Property("ToolTip").GetValue();

            if (___Readout != null && ___Readout.DisplayedMech != null && ___Readout.DisplayedMech.Combat != null && ___ToolTip != null)
            {
                Mech target = ___Readout.DisplayedMech;
                if (!target.Combat.HostilityMatrix.IsLocalPlayerFriendly(target.TeamId))
                {
                    SensorScanType scanType = SensorLockHelper.CalculateSharedLock(target, ModState.LastPlayerActorActivated);
                    if (scanType < SensorScanType.AllInformation)
                    {
                        ___ToolTip.BuffStrings.Clear();
                        ___ToolTip.DebuffStrings.Clear();
                    }
                }
            }
        }
        public static void FixRearStructureDisplay(HUDMechArmorReadout __instance, AttackDirection shownAttackDirection)
        {
            try {
                HUDMechArmorReadout me = __instance;
                float[]             timeSinceStructureDamaged = (float[])timeSinceStructureDamagedProp.GetValue(me, null);
                Color[]             structureRear             = (Color[])structureRearProp.GetValue(me, null);

                float flashPeriod = 0f;
                Color flashColour = Color.black;
                if (LookAndColor == null)
                {
                    TryRun(() => LookAndColor = HBS.LazySingletonBehavior <UIManager> .Instance.UILookAndColorConstants);
                }
                if (LookAndColor != null)
                {
                    flashPeriod = LookAndColor.FlashArmorTime;
                    flashColour = LookAndColor.ArmorFlash.color;
                }
                Dictionary <ArmorLocation, int> dictionary = null;
                bool mayDisableParts = shownAttackDirection != AttackDirection.None && me.UseForCalledShots;
                if (mayDisableParts)
                {
                    dictionary = HUD.Combat.HitLocation.GetMechHitTable(shownAttackDirection, false);
                }

                for (int i = 0; i < 8; i++)
                {
                    float structureFlash = Mathf.Clamp01(1f - timeSinceStructureDamaged[i] / flashPeriod);
                    Color structureColor = structureRear[i]; // The first line that has typo in original code
                    if (mayDisableParts)
                    {
                        ArmorLocation rearLocation = HUDMechArmorReadout.GetArmorLocationFromIndex(i, true, me.flipRearDisplay);
                        bool          isIntact     = dictionary.ContainsKey(rearLocation) && dictionary[rearLocation] != 0;
                        if (!isIntact)                 // And the second typo line
                        {
                            structureColor = Color.Lerp(structureColor, Color.black, me.hiddenColorLerp);
                        }
                    }
                    UIHelpers.SetImageColor(me.StructureRear[i], Color.Lerp(structureColor, flashColour, structureFlash));
                }
            }                 catch (Exception ex) { Error(ex); }
        }
Esempio n. 7
0
        public static string GetLocationHealthString(ICombatant combatant, ArmorLocation location)
        {
            string result = "";

            if (combatant.UnitType != UnitType.Mech)
            {
                return("NO MECH");
            }

            Mech m = combatant as Mech;

            Color  g             = LazySingletonBehavior <UIManager> .Instance.UIColorRefs.gold;
            Color  w             = LazySingletonBehavior <UIManager> .Instance.UIColorRefs.whiteHalf;
            string colorTagG     = $"<color=#{ColorUtility.ToHtmlStringRGBA(g)}>";
            string colorTagW     = $"<color=#{ColorUtility.ToHtmlStringRGBA(w)}>";
            string closeColorTag = "</color>";

            int currentArmor     = (int)m.GetCurrentArmor(location);
            int maxArmor         = (int)HUDMechArmorReadout.GetInitialArmorForLocation(m.MechDef, location);
            int currentStructure = Math.Max(1, ((int)m.GetCurrentStructure(MechStructureRules.GetChassisLocationFromArmorLocation(location))));
            int maxStructure     = (int)m.GetMaxStructure(MechStructureRules.GetChassisLocationFromArmorLocation(location));
            int totalCurrent     = currentArmor + currentStructure;
            int totalMax         = maxArmor + maxStructure;

            // Simple
            if (currentStructure < maxStructure || currentArmor <= 0)
            {
                result = $"{colorTagG}LOCATION HEALTH: {totalCurrent} / {totalMax}{closeColorTag}";
            }
            else
            {
                result = $"{colorTagW}LOCATION HEALTH: {totalCurrent} / {totalMax}{closeColorTag}";
            }

            // Differentiated
            //result = $"{colorTagG}STRUCTURE: {currentStructure} / {maxStructure}{closeColorTag}      {colorTagW}ARMOR: {currentArmor} / {maxArmor}{closeColorTag}";

            return(result);
        }
Esempio n. 8
0
            public static void Postfix(HUDMechArmorReadout __instance, ArmorLocation location, Mech ___displayedMech)
            {
                try
                {
                    if (__instance.UseForCalledShots && location == ArmorLocation.Head)
                    {
                        Logger.Debug("[HUDMechArmorReadout_SetHoveredArmor_POSTFIX] Clear head selection if too many weapons are enabled...");

                        int   enabledWeaponCount = Utilities.GetReadiedWeaponCount(__instance.HUD.SelectedActor.Weapons, __instance.HUD.SelectedTarget);
                        Pilot selectedPilot      = __instance.HUD.SelectedActor.GetPilot();
                        int   maxAllowedWeapons  = Utilities.GetMaxAllowedWeaponCountForHeadshots(selectedPilot);
                        bool  validWeaponCountForPrecisionStrike = enabledWeaponCount <= maxAllowedWeapons ? true : false;

                        bool headCanBeTargeted = __instance.HUD.SelectedTarget.IsShutDown || __instance.HUD.SelectedTarget.IsProne || validWeaponCountForPrecisionStrike;

                        Logger.Debug("[HUDMechArmorReadout_SetHoveredArmor_POSTFIX] __instance.HUD.SelectedActor: " + __instance.HUD.SelectedActor.DisplayName);
                        Logger.Debug("[HUDMechArmorReadout_SetHoveredArmor_POSTFIX] enabledWeaponCount: " + enabledWeaponCount);
                        Logger.Debug("[HUDMechArmorReadout_SetHoveredArmor_POSTFIX] validWeaponCountForPrecisionStrike: " + validWeaponCountForPrecisionStrike);

                        Logger.Debug("[HUDMechArmorReadout_SetHoveredArmor_POSTFIX] ___displayedMech: " + ___displayedMech.DisplayName);
                        Logger.Debug("[HUDMechArmorReadout_SetHoveredArmor_POSTFIX] ___displayedMech.IsShutDown: " + ___displayedMech.IsShutDown);
                        Logger.Debug("[HUDMechArmorReadout_SetHoveredArmor_POSTFIX] ___displayedMech.IsProne: " + ___displayedMech.IsProne);
                        Logger.Debug("[HUDMechArmorReadout_SetHoveredArmor_POSTFIX] headCanBeTargeted: " + headCanBeTargeted);

                        if (!headCanBeTargeted)
                        {
                            Logger.Debug("[HUDMechArmorReadout_SetHoveredArmor_POSTFIX] Prevent targeting of head...");
                            __instance.ClearHoveredArmor(ArmorLocation.Head);
                        }
                    }
                }
                catch (Exception e)
                {
                    Logger.Error(e);
                }
            }
        public static void ShowStructureDamageThroughArmour(HUDMechArmorReadout __instance)
        {
            try {
                HUDMechArmorReadout me = __instance;
                Mech    mech           = me.DisplayedMech;
                MechDef mechDef        = mech?.MechDef ?? me.DisplayedMechDef;
                if (mech == null && mechDef == null)
                {
                    return;
                }
                ChassisLocations[] location = me.flipFrontDisplay ? Flipped : Normal;
                int[]   back      = me.flipFrontDisplay != me.flipRearDisplay ? new int[] { 0, 0, 4, 3, 2 } : new int[] { 0, 0, 2, 3, 4 };
                Color   clear     = Color.clear;
                Color[] armor     = (Color[])armorProp.GetValue(me, null);
                Color[] armorRear = (Color[])armorRearProp.GetValue(me, null);
                Color[] outline   = null, outlineRear = null, structure = null, structureRear = null;

                for (int i = 0; i < 8; i++)
                {
                    float percent = float.NaN;
                    // Front
                    if (armor[i] != clear) // Skip check on armour-less locations
                    {
                        if (IsStructureDamaged(ref percent, mech, mechDef, location[i]))
                        {
                            if (structure == null) // Lazy reflection access
                            {
                                structure = (Color[])structureProp.GetValue(me, null);
                                outline   = (Color[])outlineProp.GetValue(me, null);
                            }
                            outline[i] = structure[i] = armor[i];
                            if (me.UseForCalledShots)
                            {
                                armor[i] = clear;
                            }
                            else
                            {
                                armor[i].a *= 0.5f; // Front has structure over armor, but structure has more blank to fill.
                            }
                        }
                    }
                    // Back
                    if (i < 2 || i > 4)
                    {
                        continue;
                    }
                    int j = back[i];
                    if (armorRear[j] != clear)
                    {
                        if (IsStructureDamaged(ref percent, mech, mechDef, location[i])) // i is not typo. We want to check same chassis location as front.
                        {
                            if (structureRear == null)
                            {
                                structureRear = (Color[])structureRearProp.GetValue(me, null);
                                outlineRear   = (Color[])outlineRearProp.GetValue(me, null);
                            }
                            outlineRear[j] = structureRear[j] = armorRear[j];
                            armorRear[j]   = clear;
                        }
                    }
                }
            }                 catch (Exception ex) { Error(ex); }
        }
Esempio n. 10
0
 public static void Postfix(HUDMechArmorReadout __instance)
 {
     __instance.flipFrontDisplay = false;
     __instance.flipRearDisplay  = false;
 }