diff --git a/source/Components/AutoReplace.cs b/source/Components/AutoReplace.cs index 016b980..a29ae75 100644 --- a/source/Components/AutoReplace.cs +++ b/source/Components/AutoReplace.cs @@ -7,6 +7,7 @@ namespace CustomComponents public class AutoReplace : SimpleCustomComponent, IOnItemGrabbed, IOnInstalled { public string ComponentDefId { get; set; } + public ChassisLocations Location { get; set; } public void OnItemGrabbed(IMechLabDraggableItem item, MechLabPanel mechLab, MechLabLocationWidget widget) { @@ -18,8 +19,10 @@ public void OnItemGrabbed(IMechLabDraggableItem item, MechLabPanel mechLab, Mech return; } Control.Logger.LogDebug($"-- {widget}"); - DefaultHelper.AddMechLab(ComponentDefId, Def.ComponentType, new MechLabHelper(mechLab), widget.loadout.Location); - Control.Logger.LogDebug($"-- added {ComponentDefId}"); + var location = Location == ChassisLocations.None ? widget.loadout.Location : Location; + + DefaultHelper.AddMechLab(ComponentDefId, Def.ComponentType, new MechLabHelper(mechLab),location); + Control.Logger.LogDebug($"-- added {ComponentDefId} to {location}"); mechLab.ValidateLoadout(false); } @@ -29,8 +32,9 @@ public void OnInstalled(WorkOrderEntry_InstallComponent order, SimGameState stat Control.Logger.LogDebug($"-- search replace for {order.MechComponentRef.ComponentDefID}"); if (order.PreviousLocation != ChassisLocations.None) { - Control.Logger.LogDebug($"-- found, adding {ComponentDefId} to {order.PreviousLocation}"); - DefaultHelper.AddInventory(ComponentDefId, mech, order.PreviousLocation, order.MechComponentRef.ComponentDefType, state); + var location = Location == ChassisLocations.None ? order.PreviousLocation : Location; + Control.Logger.LogDebug($"-- found, adding {ComponentDefId} to {location}"); + DefaultHelper.AddInventory(ComponentDefId, mech, location, order.MechComponentRef.ComponentDefType, state); } else { diff --git a/source/Components/Category.cs b/source/Components/Category.cs index 9c47334..7a05528 100644 --- a/source/Components/Category.cs +++ b/source/Components/Category.cs @@ -90,7 +90,7 @@ public void OnInstalled(WorkOrderEntry_InstallComponent order, SimGameState stat Control.Logger.LogDebug($"-- total {n1}/{CategoryDescriptor.MaxEquiped} location: {n2}/{CategoryDescriptor.MaxEquipedPerLocation}"); - var replace = mech.Inventory.FirstOrDefault(i => i.MountedLocation == order.DesiredLocation && i.IsCategory(CategoryID) && i.IsDefault()); + var replace = mech.Inventory.FirstOrDefault(i => (i.MountedLocation == order.DesiredLocation || CategoryDescriptor.ReplaceAnyLocation) && i.IsCategory(CategoryID) && i.IsDefault()); Control.Logger.LogDebug($"-- possible replace: {(replace == null ? "not found" : replace.ComponentDefID)}"); @@ -103,7 +103,7 @@ public void OnInstalled(WorkOrderEntry_InstallComponent order, SimGameState stat Control.Logger.LogDebug($"-- need_repalce: {need_replace}"); if (need_replace) - DefaultHelper.RemoveInventory(replace.ComponentDefID, mech, order.DesiredLocation, replace.ComponentDefType); + DefaultHelper.RemoveInventory(replace.ComponentDefID, mech, replace.MountedLocation, replace.ComponentDefType); } @@ -117,7 +117,7 @@ public string ReplaceValidateDrop(MechLabItemSlotElement drop_item, LocationHelp CategoryDescriptor.MaxEquiped <= 0 && CategoryDescriptor.MaxEquipedPerLocation <= 0) { #if CCDEBUG - Control.Logger.LogDebug($"--- no replace needed"); + Control.Logger.LogDebug($"--- no replace needed"); #endif return String.Empty; } @@ -159,8 +159,25 @@ public string ReplaceValidateDrop(MechLabItemSlotElement drop_item, LocationHelp if (n >= CategoryDescriptor.MaxEquiped) { - var replace = location.LocalInventory + var + replace = location.LocalInventory .FirstOrDefault(i => i.ComponentRef.Def.IsCategory(CategoryID)); + if (CategoryDescriptor.ReplaceAnyLocation && replace == null) + { + var mechlab = new MechLabHelper(location.mechLab); + foreach (var widget in mechlab.GetWidgets()) + { + if(widget.loadout.Location == location.widget.loadout.Location) + continue; + + var loc_helper = new LocationHelper(widget); + replace = loc_helper.LocalInventory + .FirstOrDefault(i => i.ComponentRef.Def.IsCategory(CategoryID)); + if(replace != null) + break; + } + } + #if CCDEBUG Control.Logger.LogDebug($"--- replace: {(replace == null ? "none" : replace.ComponentRef.ComponentDefID)}"); #endif diff --git a/source/Components/RequieredCategory.cs b/source/Components/RequieredCategory.cs index 1598433..8af9e12 100644 --- a/source/Components/RequieredCategory.cs +++ b/source/Components/RequieredCategory.cs @@ -19,7 +19,7 @@ public void ValidateMech(Dictionary> errors, Me if (mechDef.Inventory.Any(i => i.IsCategory(CategoryID))) return; errors[MechValidationType.InvalidInventorySlots].Add(string.IsNullOrEmpty(ErrorMessage) ? - $"{Def.Description.Name} require {category.displayName} installed" : + $"{Def.Description.Name} requires {category.displayName} installed" : ErrorMessage); } diff --git a/source/Control.cs b/source/Control.cs index 9dcb2bf..aeb2225 100644 --- a/source/Control.cs +++ b/source/Control.cs @@ -48,7 +48,7 @@ public static void Init(string directory, string settingsJSON) Validator.RegisterMechValidator(CategoryController.ValidateMech, CategoryController.ValidateMechCanBeFielded); - Logger.Log("Loaded CustomComponents v0.6.2.1.0"); + Logger.Log("Loaded CustomComponents v0.6.3.0.3"); #if CCDEBUG Logger.LogDebug("Loading Categories"); #endif diff --git a/source/Helpers/CategoryDescriptor.cs b/source/Helpers/CategoryDescriptor.cs index 8ce8999..f98c25c 100644 --- a/source/Helpers/CategoryDescriptor.cs +++ b/source/Helpers/CategoryDescriptor.cs @@ -42,6 +42,10 @@ public string DisplayName [DefaultValue(false), JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool AutoReplace = false; + + [DefaultValue(false), JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool ReplaceAnyLocation = false; + /// /// max of items per mech /// diff --git a/source/Helpers/DefaultHelper.cs b/source/Helpers/DefaultHelper.cs index d4a91f8..fa6d9a9 100644 --- a/source/Helpers/DefaultHelper.cs +++ b/source/Helpers/DefaultHelper.cs @@ -85,6 +85,7 @@ public static void AddMechLab(string id, ComponentType type, MechLabHelper mechL } var slot = CreateSlot(id, type, mechLab.MechLab); + slot.MountedLocation = location; target.OnAddItem(slot, false); } @@ -246,7 +247,11 @@ internal static MechComponentRef[] ClearInventory(MechDef source, SimGameState s if (list[i].Is(out var replace)) { var ref_item = CreateRef(replace.ComponentDefId, list[i].ComponentDefType, list[i].DataManager, state); - ref_item.SetData(list[i].MountedLocation, list[i].HardpointSlot, list[i].DamageLevel); + var location = replace.Location == ChassisLocations.None + ? list[i].MountedLocation + : replace.Location; + + ref_item.SetData(location, list[i].HardpointSlot, list[i].DamageLevel); ref_item.SetSimGameUID(state.GenerateSimGameUID()); result_list.Add(ref_item); Control.Logger.LogDebug($"-- Replace with {ref_item.ComponentDefID} - {ref_item.SimGameUID}"); diff --git a/source/Helpers/MechLabHelper.cs b/source/Helpers/MechLabHelper.cs index b85b80d..efe6612 100644 --- a/source/Helpers/MechLabHelper.cs +++ b/source/Helpers/MechLabHelper.cs @@ -1,4 +1,5 @@ -using BattleTech; +using System.Collections.Generic; +using BattleTech; using BattleTech.UI; using Harmony; @@ -12,6 +13,19 @@ public class MechLabHelper private Traverse main; private Traverse drag_item; + public IEnumerable GetWidgets() + { + yield return MechLab.headWidget; + yield return MechLab.leftArmWidget; + yield return MechLab.leftTorsoWidget; + yield return MechLab.centerTorsoWidget; + yield return MechLab.rightTorsoWidget; + yield return MechLab.rightArmWidget; + yield return MechLab.leftLegWidget; + yield return MechLab.rightLegWidget; + } + + public MechLabLocationWidget GetLocationWidget(ChassisLocations location) { switch (location) diff --git a/source/Validators/MechLabLocationWidget_OnMechLabDrop_Patch.cs b/source/Validators/MechLabLocationWidget_OnMechLabDrop_Patch.cs index 035f2fe..a34889e 100644 --- a/source/Validators/MechLabLocationWidget_OnMechLabDrop_Patch.cs +++ b/source/Validators/MechLabLocationWidget_OnMechLabDrop_Patch.cs @@ -73,7 +73,7 @@ bool do_cancel(string error) List changes = new List(); changes.Add(new AddChange(__instance.loadout.Location, dragItem)); if (replaceItem != null) - changes.Add(new RemoveChange(__instance.loadout.Location, replaceItem)); + changes.Add(new RemoveChange(replaceItem.MountedLocation, replaceItem)); diff --git a/source/Validators/Validator.cs b/source/Validators/Validator.cs index 5a8342b..74f7a18 100644 --- a/source/Validators/Validator.cs +++ b/source/Validators/Validator.cs @@ -206,6 +206,19 @@ internal static void ValidateMech(Dictionary> e { validator(errors, validationLevel, mechDef); } + + var sizes = mechDef.Inventory.Select(cref => + new { location = cref.MountedLocation, size = cref.Def.InventorySize }) + .GroupBy(i => i.location) + .Select(i => new { location = i.Key, size = i.Sum(a => a.size) }).ToList(); + + foreach (var size in sizes) + { + if (mechDef.GetChassisLocationDef(size.location).InventorySlots < size.size) + { + errors[MechValidationType.InvalidInventorySlots].Add($"{size.location} no space left, remove excess equipment"); + } + } } internal static bool ValidateMechCanBeFielded(MechDef mechDef) @@ -216,6 +229,17 @@ internal static bool ValidateMechCanBeFielded(MechDef mechDef) return false; } + var sizes = mechDef.Inventory.Select(cref => + new {location = cref.MountedLocation, size = cref.Def.InventorySize}) + .GroupBy(i => i.location) + .Select(i => new {location = i.Key, size = i.Sum(a => a.size)}).ToList(); + + foreach (var size in sizes) + { + if (mechDef.GetChassisLocationDef(size.location).InventorySlots < size.size) + return false; + } + return true; } }