public MechComponentRef GetReplaceFor(MechDef mech, string categoryId, ChassisLocations location, SimGameState state) { bool check_def(IDefault def) { return(def.CategoryID == categoryId && (def.AnyLocation || location == def.Location)); } foreach (var def in mech.Chassis.GetComponents <ChassisDefaults>()) { if (check_def(def)) { return(def.GetReplace(mech, state)); } } if (TaggedDefaults != null) { foreach (var def in TaggedDefaults.Where(check_def)) { if (mech.MechTags.Contains(def.Tag) || mech.Chassis.ChassisTags.Contains(def.Tag)) { return(def.GetReplace(mech, state)); } } } return(Defaults != null?Defaults.Where(check_def).Select(def => def.GetReplace(mech, state)).FirstOrDefault() : null); }
public object GetDefId(MechDef mech, string categoryId, ChassisLocations location) { bool check_def(IDefault def) { return(def.CategoryID == categoryId && (def.AnyLocation || location == def.Location)); } foreach (var def in mech.Chassis.GetComponents <ChassisDefaults>()) { if (check_def(def)) { return(def.DefID); } } foreach (var def in TaggedDefaults.Where(check_def)) { if (mech.MechTags.Contains(def.Tag) || mech.Chassis.ChassisTags.Contains(def.Tag)) { return(def.DefID); } } return(Defaults.Where(check_def).Select(def => def.DefID).FirstOrDefault()); }
internal static void OverrideApplyStructureStatDamage( this Mech mech, ChassisLocations location, float damage, WeaponHitInfo hitInfo ) { try { if (IsInternalExplosion) { var properties = ComponentExplosionHandler.Shared.GetCASEProperties(currentMech, (int)location); if (properties.MaximumDamage.HasValue) { var directDamage = Mathf.Min(damage, properties.MaximumDamage.Value); var backDamage = damage - directDamage; //Control.mod.Logger.LogDebug($"reducing structure damage from {damage} to {directDamage} in {Mech.GetAbbreviatedChassisLocation(location)}"); damage = directDamage; if (backDamage > 0) { currentMech.PublishFloatieMessage("EXPLOSION REDIRECTED"); if ((location & ChassisLocations.Torso) > 0) { ArmorLocation armorLocation; switch (location) { case ChassisLocations.LeftTorso: armorLocation = ArmorLocation.LeftTorsoRear; break; case ChassisLocations.RightTorso: armorLocation = ArmorLocation.RightTorsoRear; break; default: armorLocation = ArmorLocation.CenterTorsoRear; break; } var armor = mech.GetCurrentArmor(armorLocation); if (armor > 0) { var armorDamage = Mathf.Min(backDamage, armor); //Control.mod.Logger.LogDebug($"added blowout armor damage {armorDamage} to {Mech.GetLongArmorLocation(armorLocation)}"); mech.ApplyArmorStatDamage(armorLocation, armorDamage, hitInfo); } } } } } } catch (Exception e) { Control.mod.Logger.LogError(e); } mech.ApplyStructureStatDamage(location, damage, hitInfo); }
private static string ValidateECM(MechLabItemSlotElement item, ChassisLocations locations) { var def = item.ComponentRef.Def; if (def.ComponentSubType < MechComponentType.Prototype_Generic && def.ComponentSubType != MechComponentType.ElectronicWarfare) { return(string.Empty); } int count = MechLabHelper.CurrentMechLab.ActiveMech.Inventory.Count(cref => cref.Def.ComponentSubType == def.ComponentSubType); if (count > 0) { if (def.ComponentSubType == MechComponentType.ElectronicWarfare || def.ComponentSubType == MechComponentType.Prototype_ElectronicWarfare) { return ("ELECTRONIC WARFARE COMPONENT LIMIT: You can only equip one Electronic Warfare component on this 'Mech."); } else { return ($"PROTOTYPE COMPONENT LIMIT: You can only equip one {def.ComponentSubType} component on this 'Mech"); } } return(string.Empty); }
public static string GetDefaultActuator(MechDef mech, ChassisLocations location, ArmActuatorSlot slot) { if (location != ChassisLocations.RightArm && location != ChassisLocations.LeftArm) { return(null); } if (mech == null || !mech.Chassis.Is <ArmActuatorSupport>(out var support)) { return(GetComponentIdForSlot(slot)); } switch (slot) { case ArmActuatorSlot.PartShoulder: return(support.GetShoulder(location)); case ArmActuatorSlot.PartUpper: return(support.GetUpper(location)); case ArmActuatorSlot.PartLower: return(support.GetLower(location)); case ArmActuatorSlot.PartHand: return(support.GetHand(location)); default: return(null); } }
public Change_Add(MechLabItemSlotElement slot, ChassisLocations location) { this.slot = slot; ItemID = slot.ComponentRef.ComponentDefID; Type = slot.ComponentRef.ComponentDefType; Location = location; }
public void ModifyMech(MechDef mDef, SimGameState s, UpgradeList ulist, ref float canFreeTonns, List <string[]> changedAmmoTypes, MechDef fromData) { BTRandomMechComponentUpgrader_Init.Log.Log("checking addition sublists"); List <MechComponentRef> inv = mDef.Inventory.ToList(); foreach (UpgradeList.UpgradeEntry[] l in ulist.Additions) { if (s.NetworkRandom.Float(0f, 1f) < ulist.UpgradePerComponentChance) { string log = ""; UpgradeList.UpgradeEntry ue = ulist.RollEntryFromSubList(l, s.NetworkRandom, -1, s.CurrentDate, ref log, ulist.UpgradePerComponentChance); if (ue != null && !ue.ID.Equals("")) { MechComponentDef d = s.GetComponentDefFromID(ue.ID); ChassisLocations loc = mDef.SearchLocationToAddComponent(d, canFreeTonns, inv, null, ChassisLocations.None); if (loc == ChassisLocations.None) { BTRandomMechComponentUpgrader_Init.Log.Log("cannot add " + log); continue; } BTRandomMechComponentUpgrader_Init.Log.Log($"adding {log} into {loc}"); MechComponentRef r = new MechComponentRef(ue.ID, null, d.ComponentType, loc, -1, ComponentDamageLevel.Functional, false); r.SetComponentDef(d); inv.Add(r); canFreeTonns -= d.Tonnage; } else { BTRandomMechComponentUpgrader_Init.Log.Log("cannot add, nothing rolled " + log); } } } mDef.SetInventory(inv.ToArray()); }
private HardpointDataDef._WeaponHardpointData GetWeaponData(ChassisLocations location) { var locationString = location.ToString().ToLower(); var weaponsData = chassisDef.HardpointDataDef.HardpointData.FirstOrDefault(x => x.location == locationString); return(weaponsData); }
internal LocationHelper GetLocationHelper(ChassisLocations location) { switch (location) { case ChassisLocations.Head: return(LHelper_HD); case ChassisLocations.LeftArm: return(LHelper_LA); case ChassisLocations.LeftTorso: return(LHelper_LT); case ChassisLocations.CenterTorso: return(LHelper_CT); case ChassisLocations.RightTorso: return(LHelper_RT); case ChassisLocations.RightArm: return(LHelper_RA); case ChassisLocations.LeftLeg: return(LHelper_LL); case ChassisLocations.RightLeg: return(LHelper_RL); } return(null); }
internal HardpointDataDef._WeaponHardpointData GetWeaponData(ChassisLocations location) { var locationString = VHLUtils.GetStringFromLocation(location); var weaponsData = chassisDef.HardpointDataDef.HardpointData.FirstOrDefault(x => x.location == locationString); return(weaponsData); }
private void CalculateBlanksForLocation(ChassisLocations location) { var weaponData = GetWeaponData(location); if (weaponData.weapons == null || weaponData.blanks == null) { return; } var usedMappings = weaponMappings .Where(x => x.Key.MountedLocation == location) .Select(x => x.Value) .Distinct() .ToList(); var usedSlots = weaponData.weapons .Where(x => x.Any(y => usedMappings.Contains(y))) // find all mappings in the same groups .SelectMany(x => x) .Select(PrefabHardpoint) // we only care about the last part of the id .Distinct() .ToList(); var requiredBlanks = weaponData.blanks .Where(x => !usedSlots.Contains(PrefabHardpoint(x))) .ToList(); Control.Logger.Debug?.Log($"Blank mappings for chassis {chassisDef.Description.Id} at {location} [{requiredBlanks.JoinAsString()}]"); blanks[location] = requiredBlanks; }
public MechLabLocationWidget GetLocationWidget(ChassisLocations location) { switch (location) { case ChassisLocations.Head: return(MechLab.headWidget); case ChassisLocations.LeftArm: return(MechLab.leftArmWidget); case ChassisLocations.LeftTorso: return(MechLab.leftTorsoWidget); case ChassisLocations.CenterTorso: return(MechLab.centerTorsoWidget); case ChassisLocations.RightTorso: return(MechLab.rightTorsoWidget); case ChassisLocations.RightArm: return(MechLab.rightArmWidget); case ChassisLocations.LeftLeg: return(MechLab.leftLegWidget); case ChassisLocations.RightLeg: return(MechLab.rightLegWidget); } return(null); }
public void ComponentInstallWorkOrder(MechComponentRef mechComponent, ChassisLocations newLocation, WorkOrderEntry_InstallComponent result) { var workOrderCosts = mechComponent.Def.GetComponent <WorkOrderCosts>(); if (workOrderCosts == null) { return; } if (newLocation == ChassisLocations.None) // remove { if (mechComponent.DamageLevel == ComponentDamageLevel.Destroyed) { ApplyCosts(result, workOrderCosts.RemoveDestroyed); } else { ApplyCosts(result, workOrderCosts.Remove); } } else // install { ApplyCosts(result, workOrderCosts.Install); } }
internal bool Add(MechComponentDef def, ChassisLocations location = ChassisLocations.None, bool force = false) { // find location if (location == ChassisLocations.None || LocationCount(location) > 1) { location = FindSpaceAtLocations(def.InventorySize, def.AllowedLocations); if (location == ChassisLocations.None) { return(false); } } var newLocationUsage = GetUsedSlots(location) + def.InventorySize; if (!force && newLocationUsage > GetMaxSlots(location)) { return(false); } TotalUsage += def.InventorySize; LocationUsage[location] = newLocationUsage; if (def.Is <DynamicSlots>(out var ds)) { DynamicSlots.Add(ds); } var componentRef = new MechComponentRef(def.Description.Id, null, def.ComponentType, location); componentRef.DataManager = DataManager; componentRef.RefreshComponentDef(); Inventory.Add(componentRef); return(true); }
internal static float AccuracyForLocation(StatCollection statCollection, ChassisLocations location) { var naming = new MechLocationNaming(location); var key = naming.LocationalStatisticName("Accuracy"); return(AccuracyForKey(statCollection, key)); }
public void OnRemove(ChassisLocations location, InventoryOperationState state) { if (!Def.IsDefault() && state.Mech.HasWeaponDefaults(location)) { state.AddChange(new Change_WeaponAdjust(location)); } }
public static AddFromInventoryChange FoundInInventory(ChassisLocations location, MechLabHelper mechlab, Predicate <MechComponentDef> SearchTerms) { Control.LogDebug(DType.ComponentInstall, $"AddFromInventoryChange.Create() one search"); var item = search_item(mechlab, SearchTerms); return(item == null ? null : new AddFromInventoryChange(location, item)); }
public static void AddInventory(string defaultID, MechDef mech, ChassisLocations location, ComponentType type, SimGameState state) { var r = CreateRef(defaultID, type, mech.DataManager, state); if (r != null) { r.SetData(location, -1, ComponentDamageLevel.Functional, true); var inv = mech.Inventory.ToList(); inv.Add(r); mech.SetInventory(inv.ToArray()); #if CCDEBUG if (Control.Settings.DebugInfo.HasFlag(DType.FixedCheck)) { var flag = r.GetComponent <Flags>(); Control.LogDebug(DType.FixedCheck, $"AddInventory: {r.Def.Description.Id} isdefult:{r.Def.IsDefault()} isfixed:{r.IsFixed} isFlag:{flag == null}"); if (flag == null) { Control.LogDebug(DType.FixedCheck, $"-- NO FLAGS!"); } else { Control.LogDebug(DType.FixedCheck, $"-- default: {flag.IsSet("default")} isdefault:{flag.Default}"); } foreach (var simpleCustomComponent in r.GetComponents <SimpleCustomComponent>()) { Control.LogDebug(DType.FixedCheck, $"-- {simpleCustomComponent}"); } } #endif } }
public static void LogOverheat(Mech __instance, ChassisLocations location, float damageAmount) { try { string line = thisSequence; if (DebugLog) { Verbo("Overheat damage {1} to {0}", location, damageAmount); } if (LogLocation) { line += FillBlanks(11) + Separator + "--"; if (LogDamage) { line += Separator + damageAmount + Separator + location // stops at + FillBlanks(2) // armours + Separator + beforeStruct + Separator + __instance.GetCurrentStructure(location); if (LogCritical) { line += CritDummy; } } } log.Add(line); } catch (Exception ex) { Error(ex); } }
private static float WeakestArmour(Mech mech, ChassisLocations location) { // For side torsos, report 0 if rear armour is breached. if (location == ChassisLocations.LeftTorso) { if (mech.GetCurrentArmor(LeftTorsoRear) <= 0) { return(0); } } else if (location == ChassisLocations.RightTorso) { if (mech.GetCurrentArmor(RightTorsoRear) <= 0) { return(0); } } float armour = mech.GetCurrentArmor((ArmorLocation)location); // Arms are at most as strong as the side torsos if (location == ChassisLocations.LeftArm) { return(Math.Min(armour, WeakestArmour(mech, ChassisLocations.LeftTorso))); } else if (location == ChassisLocations.RightArm) { return(Math.Min(armour, WeakestArmour(mech, ChassisLocations.RightTorso))); } return(armour); }
public static void LogBaseCritChance(float __result, Mech target, ChassisLocations hitLocation) { try { thisBaseCritChance = __result; thisLocationMaxHP = target.GetMaxStructure(hitLocation); } catch (Exception ex) { Error(ex); } }
public string PreValidateDrop(MechLabItemSlotElement item, ChassisLocations location) { if (!Valid) { return(string.Empty); } var hardpoints = MechLabHelper.CurrentMechLab.ActiveMech.GetAllHardpoints(location); int n = 0; foreach (var hardpoint in hardpoints) { if (hardpoint.hpInfo.Visible) { n += 1; if (hardpoint.hpInfo.WeaponCategory.ID == WeaponCategory.ID) { return(string.Empty); } } } if (n >= 4) { return(Control.Settings.Message.Hardpoints_TooManyHardpoints); } return(string.Empty); }
private PrefabSets GetAvailablePrefabSetsForLocation(ChassisLocations location) { var locationString = VHLUtils.GetStringFromLocation(location); var weaponsData = chassisDef.HardpointDataDef.HardpointData.FirstOrDefault(x => x.location == locationString); var sets = new PrefabSets(); if (weaponsData.weapons == null) { //Control.mod.Logger.LogDebug($"no hardpoint data found for {chassisDef.Description.Id} at {location}"); } else { foreach (var weapons in weaponsData.weapons) { var index = sets.Count; try { var set = new PrefabSet(index, weapons); sets.Add(set); } catch (Exception e) { Control.mod.Logger.LogDebug($"error processing hardpoint data for {chassisDef.Description.Id} at {location}: index={index} weapons=[{weapons?.JoinAsString()}]", e); throw; } } } return(sets); }
private static void ModifyInventorySlots(ref LocationDef locationDef, ChassisLocations location, ValueChange <int> change) { if (locationDef.Location != location) { return; } var newValue = change.Change(locationDef.InventorySlots); if (!newValue.HasValue) { return; } if (location == ChassisLocations.CenterTorso) { newValue += MechLabSlotsFeature.settings.TopLeftWidget.Slots + MechLabSlotsFeature.settings.TopRightWidget.Slots; } var info = typeof(LocationDef).GetField("InventorySlots"); var value = Convert.ChangeType(newValue, info.FieldType); var box = (object)locationDef; info.SetValue(box, value); locationDef = (LocationDef)box; Control.Logger.Debug?.Log($"set InventorySlots={locationDef.InventorySlots} on location={location}"); }
// Evaluates whether a given mech needs any structure repaired public static bool CheckStructureDamage(MechDef mech) { // Default to not requesting any structure repair bool mechNeedsRepair = false; // Using the repair priority for loop here as it is faster and simpler than foreach'ing over ChassisLocations and filtering out ones that don't have armor for (int index = 0; index < Globals.repairPriorities.Count; index++) { // Set current ChassisLocation ChassisLocations thisLoc = Globals.repairPriorities.ElementAt(index).Value; // Get current mech location loadout from the looped chassis definitions LocationLoadoutDef thisLocLoadout = mech.GetLocationLoadoutDef(thisLoc); // Friendly name for this location string thisLocName = thisLoc.ToString(); // Work out difference of armor lost for each location - default to 0 int structureDifference = 0; float currentStructure = thisLocLoadout.CurrentInternalStructure; float definedStructure = mech.GetChassisLocationDef(thisLoc).InternalStructure; structureDifference = (int)Mathf.Abs(currentStructure - definedStructure); // If any difference betwen the location's current and assigned armor is detected, flag this mech for armor repair if (structureDifference > 0) { Logger.LogDebug(mech.Name + " requires structure repair based on damage to: " + thisLocName); mechNeedsRepair = true; break; // Stop evaluating other locations once a repair requirement is determined } } return(mechNeedsRepair); }
public static void FixCost( SimGameState __instance, MechComponentRef mechComponent, ChassisLocations newLocation, ChassisLocations previousLocation, string mechSimGameUID, WorkOrderEntry_InstallComponent __result) { try { Control.LogDebug(DType.InstallCost, $"SimGameState_CreateComponentInstallWorkOrder: for {mechComponent.ComponentDefID}"); Control.LogDebug(DType.InstallCost, $"-- from {previousLocation} to {newLocation}"); Control.LogDebug(DType.InstallCost, $"-- order {__result?.GetType().ToString() ?? "null"}"); if (__result == null) { Control.LogDebug(DType.InstallCost, "-- No order"); return; } if (__result.DesiredLocation == ChassisLocations.None) { var tr = Traverse.Create(__result); tr.Field <int>("Cost").Value = 0; } else { var tr = Traverse.Create(__result).Field <int>("Cost"); if (tr == null) { Control.LogDebug(DType.InstallCost, "SimGameState_CreateComponentInstallWorkOrder: traverce not created!"); return; } MechDef mechByID = __instance.GetMechByID(mechSimGameUID); #if CCDEBUG if (mechByID == null) { Control.LogDebug(DType.InstallCost, "-- no mech found!"); } #endif if (mechByID != null && mechByID.Chassis.ChassisTags.Contains(Control.Settings.OmniTechFlag)) { Control.LogDebug(DType.InstallCost, "-- mech is omni!"); tr.Value = (Control.Settings.OmniTechCostBySize ? mechComponent.Def.InventorySize / 2 : 1) * Control.Settings.OmniTechInstallCost; } if (tr.Value == 0) { tr.Value = 1; } } } catch (Exception e) { Control.LogError(e); } }
private List <PrefabSet> GetAvailablePrefabSetsForLocation(ChassisLocations location) { var weaponsData = GetWeaponData(location); var sets = new List <PrefabSet>(); if (weaponsData.weapons == null) { Control.Logger.Debug?.Log($"no hardpoint data found for {chassisDef.Description.Id} at {location}"); } else { foreach (var weapons in weaponsData.weapons) { var index = sets.Count; try { var set = new PrefabSet(index, weapons.Where(x => !preMappedPrefabNames.Contains(x))); sets.Add(set); } catch (Exception e) { Control.Logger.Warning?.Log($"error processing hardpoint data for {chassisDef.Description.Id} at {location}: index={index} weapons=[{weapons?.JoinAsString()}]", e); //throw; } } } return(sets); }
private string[] RemoveUnwantedHardpoints(ChassisLocations location, string[] hardpointSet) { var counter = new HardpointCounter(chassisDef, location); IEnumerable <string> hardpoints = hardpointSet; if (counter.numBallistic == 0) { hardpoints = hardpoints.Where(hp => !hp.Contains("_bh")); } if (counter.numEnergy == 0 && counter.numSmall == 0) { hardpoints = hardpoints.Where(hp => !hp.Contains("_eh")); } if (counter.numMissile == 0) { hardpoints = hardpoints.Where(hp => !hp.Contains("_mh")); } if (counter.numSmall == 0) { hardpoints = hardpoints.Where(hp => !hp.Contains("_ah")); } return(hardpoints.ToArray()); }
private inv_change(bool add, string id, ChassisLocations location, ComponentType type = ComponentType.NotSet) { this.add = add; this.Location = location; this.Id = id; this.Type = type; }
private void CalculateMappingForLocation(ChassisLocations location, List <MechComponentRef> sortedComponentRefs) { var bestSelection = new PrefabSelectionCandidate(GetAvailablePrefabSetsForLocation(location), new List <PrefabMapping>()); var currentCandidates = new List <PrefabSelectionCandidate> { bestSelection }; foreach (var componentRef in sortedComponentRefs) { var newCandidates = new List <PrefabSelectionCandidate>(); foreach (var candidate in currentCandidates) { var hasNew = false; foreach (var set in candidate.Sets) { var prefabName = set.GetCompatiblePrefab(componentRef.Def.PrefabIdentifier); if (prefabName == null) { //Control.mod.Logger.LogDebug("could not find prefabName for " + componentRef?.Def?.PrefabIdentifier); continue; } var newMapping = new PrefabMapping(prefabName, componentRef); var newCandidate = candidate.CreateWithoutSet(set, newMapping); newCandidates.Add(newCandidate); hasNew = true; } if (!hasNew) // we didn't find anything better, so re-add the old one { newCandidates.Add(candidate); } } currentCandidates = newCandidates; } foreach (var candidate in currentCandidates) { if (candidate.CompareTo(bestSelection) > 0) { bestSelection = candidate; } } if (bestSelection.Mappings.Count < 1) { return; } var text = $"Mappings for chassis {chassisDef.Description.Id} at {location}"; foreach (var mapping in bestSelection.Mappings) { text += $"\n{mapping.MechComponentRef.Def.Description.Id} {mapping.PrefabName}"; cacheMappings[mapping.MechComponentRef] = mapping.PrefabName; } Control.mod.Logger.LogDebug(text); }