Example #1
0
        public static bool CheckForCrit(AIMCritInfo info, int hitLocation, bool logCrit)
        {
            try {
                if (info?.weapon == null)
                {
                    return(true);
                }
                info.SetHitLocation(hitLocation);
                AbstractActor target = info.target;
                if (SkipCritingDeadMech && IsBeatingDeadMech(target))
                {
                    return(false);
                }
                float chance = info.GetCritChance();
                for (int i = 1; chance > 0; i++)
                {
                    float critRoll = Combat.NetworkRandom.Float(); // If use original code AttackDirector.GetRandomFromCache( info.hitInfo, 2 ), may run out of rolls
                    if (DebugLog)
                    {
                        Verbo("Crit {3} roll {0} <= chance {1}? {2}", critRoll, chance, critRoll <= chance, i);
                    }
                    if (i == 1)
                    {
                        AttackLog.LogAIMCritRoll(critRoll);
                    }
                    if (critRoll > chance)
                    {
                        break;
                    }
                    float slotRoll = Combat.NetworkRandom.Float();
                    if (AttackLog.thisCritComp == null)
                    {
                        AttackLog.LogAIMSlotRoll(slotRoll);
                    }
                    MechComponent component = FindAndCritComponent(info, slotRoll);
                    if (i > 1)
                    {
                        Verbo("Crit x{0} on location {1} of {2} by {3}. Roll {4} <= Chance {5}. Crit'ed {6}",
                              i, component?.Location ?? hitLocation, info.target, info.weapon, critRoll, chance, component?.UIName.ToString() ?? "(None)");
                    }
                    if (logCrit)
                    {
                        AttackLog.LogCritResult(target, info.weapon);
                        logCrit = false;
                    }
                    if (!Settings.MultipleCrits)
                    {
                        break;
                    }
                    chance -= critRoll;
                }
                PostCheckForCrit(info, logCrit);
            }                 catch (Exception ex) { Error(ex); }

            return(false);
        }
Example #2
0
 private static void ConsolidateCrit(AIMCritInfo info)
 {
     try {
         damaged.Clear();
         allowConsolidateOnce = true;
         damages = info.hitInfo.ConsolidateCriticalHitInfo(GetWeaponDamage(info));
         damages.Remove(0);
         damages.Remove(65536);
         if (DebugLog)
         {
             Verbo("SplitCriticalHitInfo found {0} hit locations by {1} on {2}.", damages.Count, info.weapon, info.target);
         }
         foreach (var damage in damages)
         {
             info.SetHitLocation(damage.Key);
             if (!info.CanBeCrit())
             {
                 continue;
             }
             if (info.IsArmourBreached)
             {
                 if (DebugLog)
                 {
                     Verbo("Struct damage {0} = {1}", damage.Key, damage.Value);
                 }
                 damaged.Add(damage.Key, damage.Value);
                 continue;
             }
             if (!ThroughArmorCritEnabled)
             {
                 continue;
             }
             if (DebugLog)
             {
                 Verbo("Armour damage {0} = {1}", damage.Key, damage.Value);
             }
             if ((TAC_Threshold == 0 && TAC_ThresholdPerc == 0) || // No threshold
                 /*const*/ (TAC_Threshold > 0 && damage.Value >= TAC_Threshold) ||
                 /*abs% */ (TAC_ThresholdPerc > 0 && damage.Value >= TAC_ThresholdPerc * info.maxArmour) ||
                 /*curr%*/ (TAC_ThresholdPerc < 0 && damage.Value >= TAC_ThresholdPerc * (info.currentArmour + damage.Value)))
             {
                 damaged.Add(damage.Key, damage.Value);
             }
             else if (DebugLog)
             {
                 Verbo("Damage not reach threshold {0} / {1}% (Armour {2}/{3})", TAC_Threshold, TAC_ThresholdPerc * 100, info.currentArmour, info.maxArmour);
             }
         }
         damages.Clear();
     }                 catch (Exception ex) { Error(ex); }
 }