public static MechComponent GetComponentFromRoll(AbstractActor me, int location, float random) { List <MechComponent> list = ListComponentsAtLocation(me, location); if (me is Mech mech) { if ((list.IsNullOrEmpty() || list.All(e => e.DamageLevel >= ComponentDamageLevel.Destroyed)) && Settings.CritLocationTransfer) { ArmorLocation newLocation = MechStructureRules.GetPassthroughLocation(MechStructureRules.GetArmorFromChassisLocation((ChassisLocations)location) & FrontArmours, AttackDirection.FromFront); if (newLocation != ArmorLocation.None) { Verbo("Crit list empty at {0} of {1}, transferring crit to {2}", (ChassisLocations)location, me, newLocation); ChassisLocations chassis = MechStructureRules.GetChassisLocationFromArmorLocation(newLocation); return(GetComponentFromRoll(me, (int)chassis, random)); } } else if (!Settings.CritIgnoreEmptySlots) { int MinSlots = mech.MechDef.GetChassisLocationDef((ChassisLocations)location).InventorySlots; if (DebugLog && MinSlots > list.Count) { Verbo("Padding list to {0} with empty slots", MinSlots); } for (int i = list.Count; i < MinSlots; i++) { list.Add(null); } } } int slot = (int)(list.Count * random); MechComponent result = slot < list.Count ? list[slot] : null; if (DebugLog) { Verbo("Slot roll {0}, slot count {1}, slot {2}, component {3} status {4}", random, list.Count, slot, result, result?.DamageLevel); } AttackLog.LogCritComp(result, slot); return(result); }
internal static ArmorLocation ToArmorLocation(this ChassisLocations chassisLocation, bool isRearArmor) { var armorLocation = MechStructureRules.GetArmorFromChassisLocation(chassisLocation); return(armorLocation & (isRearArmor ? ArmorLocationRear : ~ArmorLocationRear)); }