internal static void OverrideChassisSettings(ChassisDef chassisDef) { if (AutoFixerFeature.settings.ChassisDefSkip == null) { return; } if (AutoFixerFeature.settings.ChassisDefSkip.Contains(chassisDef.Description.Id)) { return; } if (AutoFixUtils.IsIgnoredByTags(chassisDef.ChassisTags, AutoFixerFeature.settings.ChassisDefTagsSkip)) { return; } Control.mod.Logger.Log($"Auto fixing chassisDef={chassisDef.Description.Id}"); AutoFixChassisDef(chassisDef); AutoFixSlots(chassisDef); }
public void AutoFixMechDef(MechDef mechDef) { if (!AutoFixerFeature.settings.MechDefEngine) { return; } if (AutoFixerFeature.settings.MechDefSkip.Contains(mechDef.Description.Id) || AutoFixerFeature.settings.MechDefSkip.Contains(mechDef.Chassis.Description.Id)) { return; } if (AutoFixUtils.IsIgnoredByTags(mechDef.Chassis.ChassisTags, AutoFixerFeature.settings.ChassisDefTagsSkip) || AutoFixUtils.IsIgnoredByTags(mechDef.MechTags, AutoFixerFeature.settings.MechDefTagsSkip)) { return; } //DumpAllAsTable(); if (mechDef.Inventory.Any(c => c.Def.GetComponent <EngineCoreDef>() != null)) { return; } Control.mod.Logger.Log($"Auto fixing mechDef={mechDef.Description.Id} chassisDef={mechDef.Chassis.Description.Id}"); ArmorStructureRatioFeature.Shared.AutoFixMechDef(mechDef); var builder = new MechDefBuilder(mechDef.Chassis, mechDef.Inventory.ToList()); var standardHeatSinkDef = mechDef.DataManager.GetDefaultEngineHeatSinkDef(); var engineHeatSinkDef = builder.Inventory .Select(r => r.Def.GetComponent <CoolingDef>()) .Where(d => d != null) .Select(d => mechDef.DataManager.HeatSinkDefs.Get(d.HeatSinkDefId)) .Where(d => d != null) .Select(d => d.GetComponent <EngineHeatSinkDef>()) .FirstOrDefault() ?? standardHeatSinkDef; float freeTonnage; { float currentTotalTonnage = 0, maxValue = 0; MechStatisticsRules.CalculateTonnage(mechDef, ref currentTotalTonnage, ref maxValue); var maxFreeTonnage = mechDef.Chassis.Tonnage - currentTotalTonnage; freeTonnage = maxFreeTonnage; Control.mod.Logger.LogDebug($" currentTotalTonnage={currentTotalTonnage}" + $" freeTonnage={freeTonnage}" + $" maxFreeTonnage={maxFreeTonnage}"); } //Control.mod.Logger.LogDebug("C maxEngineTonnage=" + maxEngineTonnage); var standardWeights = new Weights(); // use default gyro and weights var standardHeatBlock = mechDef.DataManager.HeatSinkDefs.Get(AutoFixerFeature.settings.MechDefHeatBlockDef).GetComponent <EngineHeatBlockDef>(); var standardCooling = mechDef.DataManager.HeatSinkDefs.Get(AutoFixerFeature.settings.MechDefCoolingDef).GetComponent <CoolingDef>(); var engineCoreDefs = mechDef.DataManager.HeatSinkDefs .Select(hs => hs.Value) .Select(hs => hs.GetComponent <EngineCoreDef>()) .Where(c => c != null) .OrderByDescending(x => x.Rating); Engine maxEngine = null; { //var heatSinks = builder.Inventory.Where(x => x.ComponentDefType == ComponentType.HeatSink && x.Def.Is<EngineHeatSinkDef>()).ToList(); var jumpJetList = builder.Inventory.Where(x => x.ComponentDefType == ComponentType.JumpJet).ToList(); var engines = new LinkedList <Engine>(); foreach (var coreDef in engineCoreDefs) { { var engine = new Engine(standardCooling, standardHeatBlock, coreDef, standardWeights, new List <MechComponentRef>()); engines.AddFirst(engine); } { // remove superfluous jump jets var maxJetCount = coreDef.GetMovement(mechDef.Chassis.Tonnage).JumpJetCount; //Control.mod.Logger.LogDebug($"before Inventory.Count={builder.Inventory.Count} jumpJetList.Count={jumpJetList.Count} maxJetCount={maxJetCount}"); while (jumpJetList.Count > maxJetCount) { var lastIndex = jumpJetList.Count - 1; var jumpJet = jumpJetList[lastIndex]; freeTonnage += jumpJet.Def.Tonnage; builder.Remove(jumpJet); jumpJetList.Remove(jumpJet); } //Control.mod.Logger.LogDebug($"after Inventory.Count={builder.Inventory.Count} jumpJetList.Count={jumpJetList.Count} maxJetCount={maxJetCount}"); } foreach (var engine in engines) { // Control.mod.Logger.LogDebug($"D engine={engine.CoreDef} engine.TotalTonnage={engine.TotalTonnage} freeTonnage={freeTonnage}"); if (engine.TotalTonnage <= freeTonnage) { maxEngine = engine; } else { break; } } if (maxEngine != null) { break; } } } if (maxEngine == null) { return; } Control.mod.Logger.LogDebug($" maxEngine={maxEngine.CoreDef} freeTonnage={freeTonnage}"); { var dummyCore = builder.Inventory.FirstOrDefault(r => r.ComponentDefID == AutoFixerFeature.settings.MechDefCoreDummy); if (dummyCore != null) { builder.Remove(dummyCore); } } // add engine builder.Add(maxEngine.CoreDef.Def, ChassisLocations.CenterTorso, true); if (!EngineFeature.settings.AllowMixingHeatSinkTypes) { // remove incompatible heat sinks var incompatibleHeatSinks = builder.Inventory .Where(r => r.Def.Is <EngineHeatSinkDef>(out var hs) && hs.HSCategory != engineHeatSinkDef.HSCategory) .ToList(); foreach (var incompatibleHeatSink in incompatibleHeatSinks) { builder.Remove(incompatibleHeatSink); } //Control.mod.Logger.LogDebug($"Inventory.Count={builder.Inventory.Count} incompatibleHeatSinks.Count={incompatibleHeatSinks.Count}"); // add same amount of compatible heat sinks foreach (var unused in incompatibleHeatSinks) { builder.Add(engineHeatSinkDef.Def); } //Control.mod.Logger.LogDebug($"Inventory.Count={builder.Inventory.Count}"); } // add free heatsinks { //var maxFree = maxEngine.CoreDef.ExternalHeatSinksFreeMaxCount; //var current = maxEngine.ExternalHeatSinkCount; var maxFree = maxEngine.HeatSinkExternalFreeMaxCount; var current = 0; //we assume exiting heatsinks on the mech are additional and not free for (var i = current; i < maxFree; i++) { if (!builder.Add(engineHeatSinkDef.Def)) { break; } } //Control.mod.Logger.LogDebug($"Inventory.Count={builder.Inventory.Count} maxFree={maxFree}"); } // find any overused location if (builder.HasOveruseAtAnyLocation()) { // heatsinks, upgrades var itemsToBeReordered = builder.Inventory .Where(IsReorderable) .OrderBy(c => MechDefBuilder.LocationCount(c.Def.AllowedLocations)) .ThenByDescending(c => c.Def.InventorySize) .ThenByDescending(c => { switch (c.ComponentDefType) { case ComponentType.Upgrade: return(2); case ComponentType.AmmunitionBox: return(1); default: return(0); } }) .ToList(); // remove all items that can be reordered: heatsinks, upgrades foreach (var item in itemsToBeReordered) { builder.Remove(item); } // then add most restricting, and then largest items first (probably double head sinks) foreach (var item in itemsToBeReordered) { // couldn't add everything if (!builder.Add(item.Def)) { return; } } } mechDef.SetInventory(builder.Inventory.OrderBy(element => element, new OrderComparer()).ToArray()); //{ // float currentTotalTonnage = 0, maxValue = 0; // MechStatisticsRules.CalculateTonnage(mechDef, ref currentTotalTonnage, ref maxValue); // Control.mod.Logger.LogDebug($" end currentTotalTonnage={currentTotalTonnage} mechDef.Chassis.Tonnage={mechDef.Chassis.Tonnage}"); //} }