public static bool Prefix(
            Mech __instance,
            WeaponHitInfo hitInfo,
            ArmorLocation aLoc,
            ref float directStructureDamage,
            ref bool __result)
        {
            try
            {
                if (ComponentExplosionsFeature.IsInternalExplosionContained)
                {
                    __result = false;
                    Control.Logger.Warning.Log("prevented explosion pass through (you should never see this message)");
                    return(false);
                }

                if (ComponentExplosionsFeature.IsInternalExplosion)
                {
                    var location = MechStructureRules.GetChassisLocationFromArmorLocation(aLoc);
                    UpdateStructureDamage(__instance, location, hitInfo, ref directStructureDamage);
                }
            }
            catch (Exception e)
            {
                Control.Logger.Error.Log(e);
            }

            return(true);
        }
Пример #2
0
            public static void Prefix(Mech __instance, int originalHitLoc, ArmorLocation aLoc, Weapon weapon, ref float totalArmorDamage, ref float directStructureDamage)
            {
                var mechTags = __instance.GetTags();

                if (mechTags.Contains("BR_MQ_ArmourBaffleSystem") && ((ArmorLocation)originalHitLoc == ArmorLocation.LeftArm || (ArmorLocation)originalHitLoc == ArmorLocation.RightArm ||
                                                                      (ArmorLocation)originalHitLoc == ArmorLocation.LeftLeg || (ArmorLocation)originalHitLoc == ArmorLocation.RightLeg))
                {
                    totalArmorDamage      *= Core.Settings.ArmourBaffleFactor;
                    directStructureDamage *= Core.Settings.ArmourBaffleFactor;
                }
                if (mechTags.Contains("BR_MQ_CrabClaws") && ((ArmorLocation)originalHitLoc == ArmorLocation.LeftArm || (ArmorLocation)originalHitLoc == ArmorLocation.RightArm))
                {
                    totalArmorDamage      *= Core.Settings.CrabClawDamageFactor;
                    directStructureDamage *= Core.Settings.CrabClawDamageFactor;
                }
                if (__instance.GetPilot().pilotDef.PilotTags.Contains("PQ_pilot_elite") && __instance.weightClass == WeightClass.MEDIUM)
                {
                    var pips = __instance.EvasivePipsCurrent;
                    totalArmorDamage      *= 1 - pips * 0.05f;
                    directStructureDamage *= 1 - pips * 0.05f;
                }
                if (__instance.GetPilot().pilotDef.SkillGuts >= 5)
                {
                    float gutsBonus = (__instance.GetPilot().pilotDef.SkillGuts - 4) * 0.02f;
                    if (__instance.GetPilot().pilotDef.SkillGuts >= 10)
                    {
                        gutsBonus += 0.03f;
                    }
                    totalArmorDamage      *= 1 - gutsBonus;
                    directStructureDamage *= 1 - gutsBonus;
                }
            }
Пример #3
0
        static void Prefix(Mech __instance, ArmorLocation aLoc, Weapon weapon, float totalArmorDamage, float directStructureDamage)
        {
            Mod.Log.Trace?.Write("M:DL - entered");

            if (aLoc == ArmorLocation.Head)
            {
                Mod.Log.Info?.Write($"Head hit from weapon:{weapon?.UIName} for {totalArmorDamage} armor damage and {directStructureDamage} structure damage.");

                float currHeadArmor      = __instance.GetCurrentArmor(aLoc);
                int   damageMod          = (int)Math.Ceiling(totalArmorDamage);
                float damageThroughArmor = totalArmorDamage - currHeadArmor;
                Mod.Log.Debug?.Write($"TotalArmorDamage:{totalArmorDamage} - Head armor:{currHeadArmor} = throughArmor:{damageThroughArmor}");

                if (totalArmorDamage - currHeadArmor <= 0)
                {
                    damageMod = (int)Math.Floor(damageMod * Mod.Config.Combat.PainTolerance.HeadHitArmorOnlyResistPenaltyMulti);
                    Mod.Log.Info?.Write($"Head hit impacted armor only, reduced damage to:{damageMod}");
                }

                if (directStructureDamage != 0)
                {
                    Mod.Log.Debug?.Write($"Attack inflicted ${directStructureDamage}, adding to total resist damage.");
                    damageMod += (int)Math.Ceiling(directStructureDamage);
                }

                ModState.InjuryResistPenalty = damageMod * Mod.Config.Combat.PainTolerance.HeadDamageResistPenaltyPerArmorPoint;
                Mod.Log.Debug?.Write($"Headshot sets injury resist penalty to: {damageMod} x {Mod.Config.Combat.PainTolerance.HeadDamageResistPenaltyPerArmorPoint} = {ModState.InjuryResistPenalty}");
            }
        }
Пример #4
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.");
                }
            }
        }
Пример #5
0
        static void Prefix(Mech __instance, ArmorLocation aLoc, float totalArmorDamage, float directStructureDamage)
        {
            if (aLoc == ArmorLocation.Head)
            {
                //var sim = UnityGameInstance.BattleTechGame.Simulation;
                //if (sim.CompanyTags.Contains("FewerHeadInjuriesDisabled"))
                //    return;

                var currentArmor = __instance.GetCurrentArmor(aLoc);
                var maxArmor     = __instance.GetMaxArmor(aLoc);
                if (Math.Abs(__instance.GetCurrentArmor(aLoc)) < float.Epsilon)
                {
                    return;
                }

                if (currentArmor - totalArmorDamage + directStructureDamage <= 0)
                {
                    return;
                }

                var Modifier =
                    UnityGameInstance.BattleTechGame.Simulation.GetCareerModeOverallDifficultyMod();
                var rng = new Random().Next(1, 101);
                if (rng <= currentArmor / maxArmor * 100 * Modifier)
                {
                    IgnoreNextHeadHit.Add(__instance.pilot);
                }
            }
        }
        internal static ArmorLocation GetPassthroughLocation(
            ArmorLocation location,
            AttackDirection attackDirection
            )
        {
            try
            {
                if (ComponentExplosionsFeature.IsInternalExplosion && currentMech != null)
                {
                    var chassisLocation = MechStructureRules.GetChassisLocationFromArmorLocation(location);
                    var properties      = ComponentExplosionsFeature.Shared.GetCASEProperties(currentMech, (int)chassisLocation);
                    if (properties != null)
                    {
                        currentMech.PublishFloatieMessage("EXPLOSION CONTAINED");

                        //Control.mod.Logger.LogDebug($"prevented explosion pass through from {Mech.GetAbbreviatedChassisLocation(chassisLocation)}");

                        return(ArmorLocation.None); // CASE redirects damage, so lets redirect it to none
                    }
                }
            }
            catch (Exception e)
            {
                Control.mod.Logger.LogError(e);
            }

            return(MechStructureRules.GetPassthroughLocation(location, attackDirection));
        }
        public static void Prefix(MechFallSequence __instance)
        {
            Mod.Log.Trace("MFS:OnComplete - entered.");
            int damagePointsTT = (int)Math.Ceiling(__instance.OwningMech.tonnage / 10f);

            Mod.Log.Debug($"Actor: {CombatantUtils.Label(__instance.OwningMech)} will suffer {damagePointsTT} TT damage points.");

            // Check for any pilot skill damage reduction
            float damageReduction = 1.0f - __instance.OwningMech.PilotCheckMod(Mod.Config.Piloting.DFAReductionMulti);
            float reducedDamage   = (float)Math.Max(0f, Math.Floor(damageReduction * damagePointsTT));

            Mod.Log.Debug($" Reducing TT fall damage from: {damagePointsTT} by {damageReduction:P1} to {reducedDamage}");

            List <int> locationDamage = new List <int>();

            while (damagePointsTT >= 5)
            {
                locationDamage.Add(5 * Mod.Config.Piloting.FallingDamagePerTenTons);
                damagePointsTT -= 5;
            }
            if (damagePointsTT > 0)
            {
                locationDamage.Add(damagePointsTT * Mod.Config.Piloting.FallingDamagePerTenTons);
            }

            Mod.Log.Debug($"Applying falling damage to actor: {CombatantUtils.Label(__instance.OwningMech)}");
            foreach (int damage in locationDamage)
            {
                ArmorLocation location = FallingDamageLocations[__instance.OwningMech.Combat.NetworkRandom.Int(0, FallingDamageLocations.Length)];
                Mod.Log.Debug($"  {damage} damage to location: {location}");
                __instance.OwningMech.DEBUG_DamageLocation(location, damage, __instance.OwningMech, DamageType.KnockdownSelf);
            }
        }
Пример #8
0
        public static void Prefix(Mech __instance, WeaponHitInfo hitInfo, ArmorLocation aLoc, Weapon weapon, float totalArmorDamage, float directStructureDamage,
                                  int hitIndex, AttackImpactQuality impactQuality, DamageType damageType)
        {
            if (aLoc == ArmorLocation.Head)
            {
                Mod.Log.Info($"Head hit from weapon:{weapon?.UIName} for {totalArmorDamage} armor damage and {directStructureDamage} structure damage. " +
                             $"Quality was:{impactQuality} with type:{damageType}");

                float currHeadArmor      = __instance.GetCurrentArmor(aLoc);
                int   damageMod          = (int)Math.Ceiling(totalArmorDamage);
                float damageThroughArmor = totalArmorDamage - currHeadArmor;
                Mod.Log.Debug($"TotalArmorDamage:{totalArmorDamage} - Head armor:{currHeadArmor} = throughArmor:{damageThroughArmor}");

                if (totalArmorDamage - currHeadArmor <= 0)
                {
                    damageMod = (int)Math.Floor(damageMod * Mod.Config.Combat.PainTolerance.HeadHitArmorOnlyMulti);
                    Mod.Log.Info($"Head hit impacted armor only, reduced damage to:{damageMod}");
                }

                if (directStructureDamage != 0)
                {
                    Mod.Log.Debug($"Attack inflicted ${directStructureDamage}, adding to total resist damage.");
                    damageMod += (int)Math.Ceiling(directStructureDamage);
                }

                ModState.InjuryResistPenalty = damageMod * Mod.Config.Combat.PainTolerance.PenaltyPerHeadDamage;
                Mod.Log.Info($"Setting resist penalty to:{damageMod} x {Mod.Config.Combat.PainTolerance.PenaltyPerHeadDamage} = {ModState.InjuryResistPenalty}");
            }
        }
Пример #9
0
 public Armor(string armorName, string armorType, int price, float weight, ArmorLocation location,
             int defenseValue, int defenseModifier, params string[] allowableClasses)
     : base(armorName, armorType, price, weight, allowableClasses)
 {
     Location = location;
     DefenseValue = defenseValue;
     DefenseModifier = defenseModifier;
 }
Пример #10
0
 public static void RecordMechDamage(Mech __instance, ArmorLocation aLoc, float totalDamage)
 {
     if (aLoc == ArmorLocation.None || aLoc == ArmorLocation.Invalid)
     {
         return;
     }
     RecordUnitDamage(aLoc.ToString(), totalDamage,
                      __instance.GetCurrentArmor(aLoc), __instance.GetCurrentStructure(MechStructureRules.GetChassisLocationFromArmorLocation(aLoc)));
 }
 public static bool Prefix(ArmorLocation location, ref ArmorLocation __result)
 {
     if (location == ArmorLocation.Head)
     {
         __result = ArmorLocation.CenterTorso;
         return(false);
     }
     return(true);
 }
        public void AddArmorDamage(float damage, ArmorLocation loc)
        {
            float existingDamage = 0.0f;

            if (armorLocationDictionary.ContainsKey(loc))
            {
                existingDamage = armorLocationDictionary[loc];
            }
            armorLocationDictionary[loc] = existingDamage + damage;
        }
Пример #13
0
        public static float GetRemainingHealth(this Mech mech, ArmorLocation aLocation)
        {
            ChassisLocations cLocation = MechStructureRules.GetChassisLocationFromArmorLocation(aLocation);

            float armorCurrent     = mech.GetCurrentArmor(aLocation);
            float structureCurrent = mech.GetCurrentStructure(cLocation);

            Logger.Info($"[MechExtensions_GetRemainingHealth] ({aLocation}) H:{structureCurrent + armorCurrent}(S:{structureCurrent}, A:{armorCurrent})");

            return(armorCurrent + structureCurrent);
        }
Пример #14
0
 public ArmorItem(string _name, string _description, ItemType _itemType, int _value, bool _usedInCombat, int _AC, ArmorLocation _armorLocation)
 {
     name          = _name;
     Id            = SingleTon.GetItemManager().AllItems.Count;
     describtion   = _description;
     itemType      = _itemType;
     Value         = _value;
     UseInCombat   = _usedInCombat;
     AC            = _AC;
     ArmorLocation = _armorLocation;
     Effect        = "Def +" + AC;
 }
Пример #15
0
 public static void LogMechHit(ArmorLocation __result, Dictionary <ArmorLocation, int> hitTable, float randomRoll, ArmorLocation bonusLocation, float bonusLocationMultiplier)
 {
     LogHitSequence(MechStructureRules.GetChassisLocationFromArmorLocation(__result), randomRoll, bonusLocation, bonusLocationMultiplier,
                    TryGet(hitTable, ArmorLocation.Head) + Separator +
                    (TryGet(hitTable, ArmorLocation.CenterTorso) + TryGet(hitTable, ArmorLocation.CenterTorsoRear)) + Separator +
                    (TryGet(hitTable, ArmorLocation.LeftTorso) + TryGet(hitTable, ArmorLocation.LeftTorsoRear)) + Separator +
                    (TryGet(hitTable, ArmorLocation.RightTorso) + TryGet(hitTable, ArmorLocation.RightTorsoRear)) + Separator +
                    TryGet(hitTable, ArmorLocation.LeftArm) + Separator +
                    TryGet(hitTable, ArmorLocation.RightArm) + Separator +
                    TryGet(hitTable, ArmorLocation.LeftLeg) + Separator +
                    TryGet(hitTable, ArmorLocation.RightLeg));
 }
Пример #16
0
 public RepairRecord()
 {
     InnerStructure          = 0f;
     Armor                   = 0f;
     Components              = 0;
     TurnsSinceDamage        = 1;
     MechStructureLocations  = new ChassisLocations[0];
     MechArmorLocations      = new ArmorLocation[0];
     VehicleLocations        = new VehicleChassisLocations[0];
     AffectInstalledLocation = false;
     repairTrigger           = new RepairTrigger();
 }
Пример #17
0
        public static float GetRemainingHealthRatio(this Mech mech, ArmorLocation aLocation)
        {
            ChassisLocations cLocation = MechStructureRules.GetChassisLocationFromArmorLocation(aLocation);

            float armorCurrent     = mech.GetCurrentArmor(aLocation);
            float structureCurrent = mech.GetCurrentStructure(cLocation);
            float armorMax         = mech.GetMaxArmor(aLocation);
            float structureMax     = mech.GetMaxStructure(cLocation);

            Logger.Info($"[MechExtensions_GetRemainingHealthRatio] ({aLocation}) S:{structureCurrent}/{structureMax}, A:{armorCurrent}/{armorMax}");

            return((armorCurrent + structureCurrent) / (armorMax + structureMax));
        }
Пример #18
0
 public Armor(
      string armorName,
      string armorType,
      int price,
      float weight,
      ArmorLocation location,
      int defenseValue,
      int defenseModifier)
     : base(armorName, armorType, price, weight)
 {
     this.location = location;
     this.defenseValue = defenseValue;
     this.defenseModifier = defenseModifier;
 }
Пример #19
0
 public Armor(
     string armorName,
     string armorType,
     int price,
     float weight,
     ArmorLocation location,
     int defenseValue,
     int defenseModifier)
     : base(armorName, armorType, price, weight)
 {
     this.location        = location;
     this.defenseValue    = defenseValue;
     this.defenseModifier = defenseModifier;
 }
Пример #20
0
 public Armor(
     string armorName,
     string armorType,
     int price,
     float weight,
     ArmorLocation locaion,
     int defenseValue,
     int defenseModifier,
     params Type[] allowableClasses)
     : base(armorName, armorType, price, weight, allowableClasses)
 {
     Location        = location;
     DefenseValue    = defenseValue;
     DefenseModifier = defenseModifier;
 }
Пример #21
0
        public Armor(
				string name,
				string type,
				int price,
				float weight,
				ArmorLocation location,
				int defenseValue = 0,
				int defenseModifier = 0,
				params string[] allowedClasses)
            : base(name, type, price, weight, allowedClasses)
        {
            Location = location;
            DefenseValue = defenseValue;
            DefenseModifier = defenseModifier;
        }
Пример #22
0
 internal ArmorLocationState(
     ArmorLocation location,
     int allocationPriority, // used to calculate priority, priority is reduced linearly by assigned points
     int max,                // actual max to calculate IsFull
     int assigned,
     ChassisLocationState?linkedChassisLocationState
     // used for torso armor locations that have shared limits
     )
 {
     Location           = location;
     AllocationPriority = allocationPriority;
     Max      = max;
     Assigned = assigned;
     LinkedChassisLocationState = linkedChassisLocationState;
 }
Пример #23
0
        // ============ Zombie ============

        public static void FixZombieMech(Mech __instance, ref float totalDamage, ArmorLocation aLoc)
        {
            try {
                if (aLoc == ArmorLocation.None || aLoc == ArmorLocation.Invalid)
                {
                    return;
                }
                float armour = __instance.GetCurrentArmor(aLoc);
                if (armour >= totalDamage)
                {
                    return;
                }
                KillZombie("mech", __instance.DisplayName, armour + __instance.GetCurrentStructure(MechStructureRules.GetChassisLocationFromArmorLocation(aLoc)), ref totalDamage);
            }                 catch (Exception ex) { Error(ex); }
        }
Пример #24
0
            public static void Postfix(CombatHUD __instance)
            {
                try
                {
                    // Only relevant for Precision Strike
                    if (__instance.SelectionHandler.ActiveState == null || __instance.SelectionHandler.ActiveState.SelectionType != SelectionType.FireMorale)
                    {
                        return;
                    }
                    // No headshots from behind
                    if (__instance.CalledShotPopUp.ShownAttackDirection == AttackDirection.FromBack)
                    {
                        return;
                    }

                    Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] Clear confirmed called headshot if enabled weapons change to an invalid amount...");

                    bool isCalledShotPopupVisible = __instance.CalledShotPopUp.Visible;
                    Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] isCalledShotPopupVisible: " + isCalledShotPopupVisible);

                    int   enabledWeaponCount = Utilities.GetReadiedWeaponCount(__instance.SelectedActor.Weapons, __instance.SelectedTarget, true);
                    Pilot selectedPilot      = __instance.SelectedActor.GetPilot();
                    int   maxAllowedWeapons  = Utilities.GetMaxAllowedWeaponCountForHeadshots(selectedPilot);
                    bool  validWeaponCountForPrecisionStrike = enabledWeaponCount <= maxAllowedWeapons ? true : false;
                    Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] enabledWeaponCount: " + enabledWeaponCount);
                    Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] validWeaponCountForPrecisionStrike: " + validWeaponCountForPrecisionStrike);

                    ArmorLocation baseCalledShotLocation = (ArmorLocation)typeof(SelectionStateFire).GetField("calledShotLocation", AccessTools.all).GetValue(__instance.SelectionHandler.ActiveState);
                    bool          headIsTargeted         = baseCalledShotLocation == ArmorLocation.Head;
                    Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] headIsTargeted: " + headIsTargeted);

                    //bool isMoraleAttack = __instance.SelectionHandler.ActiveState is SelectionStateMoraleAttack;
                    //Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] isMoraleAttack: " + isMoraleAttack);

                    bool shouldBackOut = headIsTargeted && !isCalledShotPopupVisible && !validWeaponCountForPrecisionStrike;
                    Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] shouldBackOut: " + shouldBackOut);

                    if (shouldBackOut)
                    {
                        Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] " + __instance.SelectionHandler.ActiveState.ToString() + ".BackOut()");
                        __instance.SelectionHandler.ActiveState.BackOut();
                    }
                }
                catch (Exception e)
                {
                    Logger.Error(e);
                }
            }
        public float GetArmorDamageForLocation(ArmorLocation loc)
        {
            float dmg = 0.0f;

            if (armorLocationDictionary.ContainsKey(loc))
            {
                dmg = armorLocationDictionary[loc];
            }

            for (int childIndex = 0; childIndex < children.Count; ++childIndex)
            {
                ChildWithProbability c = children[childIndex];
                dmg += c.DamageExpectationRecord.GetArmorDamageForLocation(loc) * c.Probability;
            }
            return(dmg);
        }
Пример #26
0
        // ============ UTILS ============

        internal static float FixMultiplier(ArmorLocation location, float multiplier)
        {
            if (location == None)
            {
                return(0);
            }
            if (MechCalledShotMultiplier != 1)
            {
                multiplier *= MechCalledShotMultiplier;
            }
            if (location == Head && CallShotClustered && ClusterChanceNeverMultiplyHead)
            {
                return(multiplier * ClusterChanceOriginalLocationMultiplier);
            }
            return(multiplier);
        }
Пример #27
0
        private static void ShowDamageFloatie(Mech mech, ArmorLocation location, float damage,
                                              string sourceGUID)
        {
            if (mech != null && mech.GameRep != null)
            {
                Vector3 vector = mech.GameRep.GetHitPosition((int)location) + UnityEngine.Random.insideUnitSphere * 5f;
                FloatieMessage.MessageNature nature = mech.GetCurrentArmor(location) > 0f ?
                                                      FloatieMessage.MessageNature.ArmorDamage : FloatieMessage.MessageNature.StructureDamage;

                FloatieMessage message = new FloatieMessage(sourceGUID, mech.GUID, $"{damage}",
                                                            SharedState.Combat.Constants.CombatUIConstants.floatieSizeMedium, nature,
                                                            vector.x, vector.y, vector.z);

                SharedState.Combat.MessageCenter.PublishMessage(message);
            }
        }
Пример #28
0
        public static void ShowCalledLocationHP(CombatHUDCalledShotPopUp __instance)
        {
            try {
                if (title == null)
                {
                    title = UnityEngine.GameObject.Find("calledShot_Title")?.GetComponent <TMPro.TextMeshProUGUI>();
                    title.enableAutoSizing = false;
                    if (title == null)
                    {
                        return;
                    }
                }

                /*
                 * public void SetText(StringBuilder text);
                 * public void SetText(string text, float arg0, float arg1, float arg2);
                 * public void SetText(string text, float arg0, float arg1);
                 * public void SetText(string text, float arg0);
                 * public void SetText(string text, bool syncTextInputBox);
                 * public void SetText(string text);*/

                CombatHUDCalledShotPopUp me           = __instance;
                ArmorLocation            hoveredArmor = me.MechArmorDisplay.HoveredArmor;
                if (me.locationNameText.text.StartsWith("-"))
                {
                    title.SetText("Called Shot");
                }
                else if (me.DisplayedActor is Mech mech)
                {
                    float hp = mech.GetCurrentStructure(MechStructureRules.GetChassisLocationFromArmorLocation(hoveredArmor));
                    if (hp <= 0)
                    {
                        title.SetText("Called Shot");
                        me.locationNameText.SetText("-choose target-", ZeroObjects);
                    }
                    else
                    {
                        float mhp = mech.GetMaxStructure(MechStructureRules.GetChassisLocationFromArmorLocation(hoveredArmor)),
                              armour = mech.GetCurrentArmor(hoveredArmor), marmour = mech.GetMaxArmor(hoveredArmor);
                        title.text = me.locationNameText.text;
                        me.locationNameText.text = string.Format("{0:0}/{1:0} <#FFFFFF>{2:0}/{3:0}", hp, mhp, armour, marmour);
                    }
                }
            }                 catch (Exception ex) { Error(ex); }
        }
 internal static float GetCurrentArmor(
     this Mech mech,
     ArmorLocation location
     )
 {
     try
     {
         if (ComponentExplosionsFeature.IsInternalExplosion)
         {
             return(0);
         }
     }
     catch (Exception e)
     {
         Control.mod.Logger.LogError(e);
     }
     return(mech.GetCurrentArmor(location));
 }
Пример #30
0
 public static void LogMechDamage(Mech __instance, ArmorLocation aLoc, Weapon weapon, DamageType damageType)
 {
     try {
         if (aLoc == ArmorLocation.None || aLoc == ArmorLocation.Invalid || !IsLoggedDamage(damageType))
         {
             return;
         }
         int line = LogActorDamage(__instance.GetCurrentArmor(aLoc), __instance.GetCurrentStructure(MechStructureRules.GetChassisLocationFromArmorLocation(aLoc)));
         if (line >= 0 && Settings.CritFollowDamageTransfer && hitMap != null)
         {
             string newKey = GetHitKey(weapon.uid, aLoc, __instance.GUID);
             if (DebugLog)
             {
                 Verbo("Log damage transfer {0} = {1}", newKey, line);
             }
             hitMap[newKey] = line;
         }
     }                 catch (Exception ex) { Error(ex); }
 }
Пример #31
0
        // CLONE OF HBS CODE - LIKELY BRITTLE!
        public static float CalcCalledShotLocationTargetChance(Mech targetMech, ArmorLocation armorLoc, ChassisLocations chassisLoc)
        {
            LocationDamageLevel locationDamageLevel = targetMech.GetLocationDamageLevel(chassisLoc);

            if (locationDamageLevel == LocationDamageLevel.Destroyed)
            {
                return(0f);
            }
            float num;

            if (armorLoc != ArmorLocation.Head)
            {
                if (armorLoc != ArmorLocation.CenterTorso)
                {
                    num = AIHelper.GetBehaviorVariableValue(targetMech.BehaviorTree, BehaviorVariableName.Float_CalledShotOtherBaseChance).FloatVal;
                }
                else
                {
                    num = AIHelper.GetBehaviorVariableValue(targetMech.BehaviorTree, BehaviorVariableName.Float_CalledShotCenterTorsoBaseChance).FloatVal;
                }
            }
            else
            {
                num = AIHelper.GetBehaviorVariableValue(targetMech.BehaviorTree, BehaviorVariableName.Float_CalledShotHeadBaseChance).FloatVal;
            }
            if (locationDamageLevel == LocationDamageLevel.Penalized || locationDamageLevel == LocationDamageLevel.NonFunctional)
            {
                num *= AIHelper.GetBehaviorVariableValue(targetMech.BehaviorTree, BehaviorVariableName.Float_CalledShotDamagedChanceMultiplier).FloatVal;
            }
            List <MechComponent> componentsForLocation = targetMech.GetComponentsForLocation(chassisLoc, ComponentType.Weapon);
            float num2 = 0f;

            for (int i = 0; i < componentsForLocation.Count; i++)
            {
                Weapon weapon = componentsForLocation[i] as Weapon;
                if (weapon != null && weapon.CanFire)
                {
                    float num3 = (float)weapon.ShotsWhenFired * weapon.DamagePerShot;
                    num2 += num3;
                }
            }
            return(num + AIHelper.GetBehaviorVariableValue(targetMech.BehaviorTree, BehaviorVariableName.Float_CalledShotWeaponDamageChance).FloatVal *num2);
        }
Пример #32
0
        // 0-1   == 1-2 = head -> 2
        // 2-21  == 3-22 = center torso -> 20
        // 22-37 == 23-38 = left torso -> 16
        // 38-53 == 39-54 = right torso -> 16
        // 54-63 == 55-64 = left arm -> 10
        // 64-73 == 65-74 = right arm -> 10
        // 74-86 == 75-87 = left leg -> 13
        // 87-99 == 88-100 = right leg -> 13

        public static ArmorLocation GetRandomMechArmorLocation()
        {
            ArmorLocation location = ArmorLocation.CenterTorso;

            bool isFront     = Mod.Random.Next(0, 100) < 80;
            int  locationIdx = Mod.Random.Next(0, 100);

            if (locationIdx <= 1)
            {
                location = ArmorLocation.Head;
            }
            else if (locationIdx <= 21)
            {
                location = isFront ? ArmorLocation.CenterTorso : ArmorLocation.CenterTorsoRear;
            }
            else if (locationIdx <= 37)
            {
                location = isFront ? ArmorLocation.LeftTorso : ArmorLocation.LeftTorsoRear;
            }
            else if (locationIdx <= 53)
            {
                location = isFront ? ArmorLocation.RightTorso : ArmorLocation.RightTorsoRear;
            }
            else if (locationIdx <= 63)
            {
                location = ArmorLocation.LeftArm;
            }
            else if (locationIdx <= 73)
            {
                location = ArmorLocation.RightArm;
            }
            else if (locationIdx <= 86)
            {
                location = ArmorLocation.LeftLeg;
            }
            else if (locationIdx <= 99)
            {
                location = ArmorLocation.RightLeg;
            }

            Mod.Log.Trace?.Write($" - Returning random location: {location}");
            return(location);
        }
        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); }
        }