static bool Prefix(MechLabPanel __instance, bool ___batchActionInProgress, MechLabItemSlotElement ___dragItem) { var hk = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl); if (!hk) { return(true); } if (!__instance.Initialized) { return(false); } if (___dragItem != null) { return(false); } ___batchActionInProgress = true; __instance.headWidget.AdvancedStripping(__instance); __instance.centerTorsoWidget.AdvancedStripping(__instance); __instance.leftTorsoWidget.AdvancedStripping(__instance); __instance.rightTorsoWidget.AdvancedStripping(__instance); __instance.leftArmWidget.AdvancedStripping(__instance); __instance.rightArmWidget.AdvancedStripping(__instance); __instance.leftLegWidget.AdvancedStripping(__instance); __instance.rightLegWidget.AdvancedStripping(__instance); __instance.FlagAsModified(); __instance.ValidateLoadout(false); ___batchActionInProgress = false; return(false); }
public static bool Prefix(MechLabPanel __instance) { if (!Core.Settings.RepairRearm) { return(true); } if (!__instance.Initialized || !__instance.IsSimGame) { return(false); } if (Traverse.Create(__instance).Field("dragItem").GetValue <MechLabItemSlotElement>() != null) { return(false); } __instance.headWidget.RepairAll(true, true); __instance.centerTorsoWidget.RepairAll(true, true); __instance.leftTorsoWidget.RepairAll(true, true); __instance.rightTorsoWidget.RepairAll(true, true); __instance.leftArmWidget.RepairAll(true, true); __instance.rightArmWidget.RepairAll(true, true); __instance.leftLegWidget.RepairAll(true, true); __instance.rightLegWidget.RepairAll(true, true); RepairArmor(__instance); __instance.ValidateLoadout(false); return(false); }
public static void Postfix(IMechLabDraggableItem item, ref bool __result, MechComponentRef __state, MechLabPanel ___mechLab, MechLabLocationWidget __instance) { if (!__result) { return; } foreach (var grab_handler in item.ComponentRef.Def.GetComponents <IOnItemGrabbed>()) { grab_handler.OnItemGrabbed(item, ___mechLab, __instance); } ___mechLab.ValidateLoadout(false); }
public void OnItemGrabbed(IMechLabDraggableItem item, MechLabPanel mechLab, MechLabLocationWidget widget) { Control.LogDebug(DType.ComponentInstall, $"- AutoReplace"); Control.LogDebug(DType.ComponentInstall, $"-- search replace for {item.ComponentRef.ComponentDefID}"); if (string.IsNullOrEmpty(ComponentDefId)) { Control.LogDebug(DType.ComponentInstall, $"-- no replacement, skipping"); return; } Control.LogDebug(DType.ComponentInstall, $"-- {widget}"); var location = Location == ChassisLocations.None ? widget.loadout.Location : Location; DefaultHelper.AddMechLab(ComponentDefId, Def.ComponentType, new MechLabHelper(mechLab), location); Control.LogDebug(DType.ComponentInstall, $"-- added {ComponentDefId} to {location}"); mechLab.ValidateLoadout(false); }
public void OnItemGrabbed(IMechLabDraggableItem item, MechLabPanel mechLab, MechLabLocationWidget widget) { Control.LogDebug(DType.ComponentInstall, $"- Category {CategoryID}"); Control.LogDebug(DType.ComponentInstall, $"-- search replace for {item.ComponentRef.ComponentDefID}"); var replace = DefaultFixer.Shared.GetReplaceFor(mechLab.activeMechDef, CategoryID, widget.loadout.Location, mechLab.sim); if (replace == null) { Control.LogDebug(DType.ComponentInstall, $"-- no replacement, skipping"); return; } DefaultHelper.AddMechLab(replace, new MechLabHelper(mechLab)); Control.LogDebug(DType.ComponentInstall, $"-- added {replace.ComponentDefID} to {replace.MountedLocation}"); mechLab.ValidateLoadout(false); }
internal static void OnStripArmor(MechLabPanel mechLabPanel) { if (!MechArmorState.Strip(mechLabPanel.activeMechDef, InputUtils.ControlModifierPressed, out var updates)) { return; } foreach (var update in updates) { var widget = mechLabPanel.GetLocationWidget(update.Location); widget.SetArmor(update.Location.IsRear(), update.Assigned); Control.Logger.Trace?.Log($"OnStripArmor.SetArmor update={update}"); } mechLabPanel.FlagAsModified(); mechLabPanel.ValidateLoadout(false); }
public static bool Prefix(MechLabPanel __instance) { if (!Core.Settings.RepairRearm) { return(true); } if (__instance.activeMechDef != null && __instance.activeMechDef.MechTags.Contains("XLRP_R&R")) { RepairArmor(__instance); __instance.ValidateLoadout(false); return(false); } else { return(true); } }
internal static void OnMaxArmor(MechLabPanel mechLabPanel, MechLabMechInfoWidget infoWidget) { if (!MechArmorState.Maximize(mechLabPanel.activeMechDef, InputUtils.ControlModifierPressed, ArmorStructureRatioFeature.ArmorPerStep, out var updates)) { return; } foreach (var update in updates) { var widget = mechLabPanel.GetLocationWidget(update.Location); widget.SetArmor(update.Location.IsRear(), update.Assigned); Control.Logger.Trace?.Log($"OnMaxArmor.SetArmor update={update}"); } infoWidget.RefreshInfo(); mechLabPanel.FlagAsModified(); mechLabPanel.ValidateLoadout(false); }
static bool Prefix(MechLabPanel __instance, MechLabMechInfoWidget ___mechInfoWidget, MechLabItemSlotElement ___dragItem) { var hk = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl); if (hk) { return(true); } if (!__instance.Initialized) { return(false); } if (___dragItem != null) { return(false); } if (__instance.headWidget.IsDestroyed || __instance.centerTorsoWidget.IsDestroyed || __instance.leftTorsoWidget.IsDestroyed || __instance.rightTorsoWidget.IsDestroyed || __instance.leftArmWidget.IsDestroyed || __instance.rightArmWidget.IsDestroyed || __instance.leftLegWidget.IsDestroyed || __instance.rightLegWidget.IsDestroyed) { __instance.modifiedDialogShowing = true; GenericPopupBuilder.Create("'Mech Location Destroyed", "You cannot auto-assign armor while a 'Mech location is Destroyed.").AddButton("Okay", null, true, null).CancelOnEscape().AddFader(new UIColorRef?(LazySingletonBehavior <UIManager> .Instance.UILookAndColorConstants.PopupBackfill), 0f, true).SetAlwaysOnTop().SetOnClose(delegate { __instance.modifiedDialogShowing = false; }).Render(); return(false); } __instance.headWidget.ModifyArmor(false, __instance.headWidget.maxArmor, true); __instance.centerTorsoWidget.ModifyArmor(false, __instance.centerTorsoWidget.maxArmor, true); __instance.centerTorsoWidget.ModifyArmor(true, __instance.centerTorsoWidget.maxRearArmor, true); __instance.leftTorsoWidget.ModifyArmor(false, __instance.leftTorsoWidget.maxArmor, true); __instance.leftTorsoWidget.ModifyArmor(true, __instance.leftTorsoWidget.maxRearArmor, true); __instance.rightTorsoWidget.ModifyArmor(false, __instance.rightTorsoWidget.maxArmor, true); __instance.rightTorsoWidget.ModifyArmor(true, __instance.rightTorsoWidget.maxRearArmor, true); __instance.leftArmWidget.ModifyArmor(false, __instance.leftArmWidget.maxArmor, true); __instance.rightArmWidget.ModifyArmor(false, __instance.rightArmWidget.maxArmor, true); __instance.leftLegWidget.ModifyArmor(false, __instance.leftLegWidget.maxArmor, true); __instance.rightLegWidget.ModifyArmor(false, __instance.rightLegWidget.maxArmor, true); ___mechInfoWidget.RefreshInfo(false); __instance.FlagAsModified(); __instance.ValidateLoadout(false); return(false); }
// Copied from OnMechLabDrop() but with inplace replacing of parts removed public static bool Prefix( MechLabLocationWidget __instance, MechLabPanel ___mechLab, Localize.Text ____dropErrorMessage, PointerEventData eventData, MechLabDropTargetType addToType) { return(_harmonyManager.PrefixLogExceptions(() => { if (!___mechLab.Initialized) { return; } if (___mechLab.DragItem == null) { return; } IMechLabDraggableItem dragItem = ___mechLab.DragItem; bool flag = __instance.ValidateAdd(dragItem.ComponentRef); if (!flag) { ___mechLab.ShowDropErrorMessage(____dropErrorMessage); ___mechLab.OnDrop(eventData); return; } bool clearOriginalItem = __instance.OnAddItem(dragItem, true); if (__instance.Sim != null) { WorkOrderEntry_InstallComponent subEntry = __instance.Sim.CreateComponentInstallWorkOrder(___mechLab.baseWorkOrder.MechID, dragItem.ComponentRef, __instance.loadout.Location, dragItem.MountedLocation); ___mechLab.baseWorkOrder.AddSubEntry(subEntry); } dragItem.MountedLocation = __instance.loadout.Location; ___mechLab.ClearDragItem(clearOriginalItem); __instance.RefreshHardpointData(); ___mechLab.ValidateLoadout(false); })); }
public static void Postfix(IMechLabDraggableItem item, ref bool __result, MechComponentRef __state, MechLabPanel ___mechLab, MechLabLocationWidget __instance) { try { if (!__result) { return; } var changes = new Queue <IChange>(); changes.Enqueue(new Change_Remove(item.ComponentRef, __instance.loadout.Location, true)); var state = new InventoryOperationState(changes, MechLabHelper.CurrentMechLab.ActiveMech); state.DoChanges(); state.ApplyMechlab(); ___mechLab.ValidateLoadout(false); } catch (Exception e) { Control.LogError(e); } }
// only allow one engine part per specific location internal static MechLabLocationWidgetOnMechLabDropPatch.Result DropCheck( MechLabLocationWidget widget, MechLabPanel mechLab, MechLabItemSlotElement dragItem, List <MechLabItemSlotElement> localInventory) { if (widget.loadout.Location != ChassisLocations.CenterTorso) { return(null); } var newComponentRef = dragItem.ComponentRef; var newComponentDef = newComponentRef.Def; var headSinkDef = newComponentDef as HeatSinkDef; if (headSinkDef == null) { return(null); } // check if we can work with it if (!headSinkDef.IsDHSKit() && !headSinkDef.IsSingle() && !headSinkDef.IsDouble()) { return(null); } var engineSlotElement = localInventory .FirstOrDefault(x => x != null && x.ComponentRef != null && x.ComponentRef.Def != null && x.ComponentRef.Def.IsEngineCore()); if (engineSlotElement == null) { if (headSinkDef.IsDHSKit()) { return(new MechLabLocationWidgetOnMechLabDropPatch.ErrorResult( string.Format("Cannot add {0}: No Engine found", newComponentDef.Description.Name) )); } else { return(null); } } var engineRef = localInventory.Where(c => c != null).Select(c => c.ComponentRef).GetEngineCoreRef(); if (mechLab.IsSimGame) { if (dragItem.OriginalDropParentType != MechLabDropTargetType.InventoryList) { return(new MechLabLocationWidgetOnMechLabDropPatch.ErrorResult( string.Format("Cannot add {0}: Item has to be from inventory", newComponentDef.Description.Name) )); } if (mechLab.originalMechDef.Inventory.Any(c => c.SimGameUID == engineRef.ComponentRef.SimGameUID)) { return(new MechLabLocationWidgetOnMechLabDropPatch.ErrorResult( string.Format("Cannot add {0}: Engine cannot be modified once installed, remove engine first", newComponentDef.Description.Name) )); } } if (headSinkDef.IsDHSKit()) { if (engineRef.IsDHS) { return(new MechLabLocationWidgetOnMechLabDropPatch.ErrorResult( string.Format("Cannot add {0}: Already a DHS engine", newComponentDef.Description.Name) )); } if (!Control.settings.AllowMixingDoubleAndSingleHeatSinks && engineRef.AdditionalSHSCount > 0) { return(new MechLabLocationWidgetOnMechLabDropPatch.ErrorResult( string.Format("Cannot add {0}: Reinstall engine to remove additional heat sinks before converting", newComponentDef.Description.Name) )); } engineRef.IsDHS = true; } else { int minHeatSinks, maxHeatSinks; Control.calc.CalcHeatSinks(engineRef.CoreDef, out minHeatSinks, out maxHeatSinks); if (engineRef.AdditionalHeatSinkCount >= maxHeatSinks - minHeatSinks) { return(null); //return new MechLabLocationWidgetOnMechLabDropPatch.ErrorResult( // string.Format("Cannot add {0}: Maximum additional heat sinks reached for engine", newComponentDef.Description.Name) //); } if (!Control.settings.AllowMixingDoubleAndSingleHeatSinks) { if (engineRef.IsDHS && headSinkDef.IsSingle() || engineRef.IsSHS && headSinkDef.IsDouble()) { return(new MechLabLocationWidgetOnMechLabDropPatch.ErrorResult( string.Format("Cannot add {0}: Mixing DHS and SHS is not allowed", newComponentDef.Description.Name) )); } } if (headSinkDef.IsDouble()) { engineRef.AdditionalDHSCount++; } else if (headSinkDef.IsSingle()) { engineRef.AdditionalSHSCount++; } } EnginePersistence.SaveEngineState(engineRef, mechLab); mechLab.ValidateLoadout(false); Traverse.Create(engineSlotElement).Method("RefreshInfo").GetValue(); return(new MechLabLocationWidgetOnMechLabDropPatch.RemoveItemResult()); }
public static bool Prefix(MechLabLocationWidget __instance, MechLabPanel ___mechLab, PointerEventData eventData) { try { var dragItem = ___mechLab.DragItem as MechLabItemSlotElement; var location = __instance.loadout.Location; if (!___mechLab.Initialized) { return(false); } var newComponentDef = dragItem?.ComponentRef?.Def; if (newComponentDef == null) { return(false); } Control.LogDebug(DType.ComponentInstall, $"OnMechLabDrop: Adding {newComponentDef.Description.Id}"); bool do_cancel(string error) { if (string.IsNullOrEmpty(error)) { return(false); } Control.LogDebug(DType.ComponentInstall, $"- Canceled: {error}"); ___mechLab.ForceItemDrop(dragItem); ___mechLab.OnDrop(eventData); ___mechLab.ShowDropErrorMessage(new Text(error)); return(true); } Control.LogDebug(DType.ComponentInstall, $"- pre validation"); foreach (var pre_validator in Validator.GetPre(newComponentDef)) { if (do_cancel(pre_validator(dragItem, location))) { return(false); } } Control.LogDebug(DType.ComponentInstall, $"- replace validation"); var changes = new Queue <IChange>(); changes.Enqueue(new Change_Add(dragItem, __instance.loadout.Location)); foreach (ReplaceValidateDropDelegate rep_validator in Validator.GetReplace(newComponentDef)) { if (do_cancel(rep_validator(dragItem, location, changes))) { return(false); } } #if CCDEBUG if (Control.Settings.DebugInfo.HasFlag(DType.ComponentInstall)) { if (changes.Count == 1) { Control.LogDebug(DType.ComponentInstall, $"-- no replace"); } else { foreach (var replace in changes) { if (replace is Change_Add add) { Control.LogDebug(DType.ComponentInstall, $"-- add {add.ItemID} to {add.Location}"); } else if (replace is Change_Remove remove) { Control.LogDebug(DType.ComponentInstall, $"-- remove {remove.ItemID} from {remove.Location}"); } } } } #endif Control.LogDebug(DType.ComponentInstall, $"- adjusting"); var state = new InventoryOperationState(changes, ___mechLab.activeMechDef); state.DoChanges(); var inv = state.Inventory; Control.LogDebug(DType.ComponentInstall, $"- post validation"); foreach (var pst_validator in Validator.GetPost(newComponentDef)) { int n = changes.Count; if (do_cancel(pst_validator(dragItem, state.Inventory))) { return(false); } } state.ApplyMechlab(); ___mechLab.ClearDragItem(true); __instance.RefreshHardpointData(); ___mechLab.ValidateLoadout(false); return(false); } catch (Exception e) { Control.LogError(e); } return(true); }
public static bool Prefix(MechLabLocationWidget __instance, ref string ___dropErrorMessage, List <MechLabItemSlotElement> ___localInventory, int ___usedSlots, int ___maxSlots, TextMeshProUGUI ___locationName, MechLabPanel ___mechLab) { Control.mod.Logger.Log("Drop on " + ___locationName.text); if (!___mechLab.Initialized) { Control.mod.Logger.Log("not Initialized"); return(false); } if (___mechLab.DragItem == null) { Control.mod.Logger.Log("Dragged item: NULL, exit"); return(false); } var drag_item = ___mechLab.DragItem; if (drag_item.ComponentRef == null) { Control.mod.Logger.Log("Dropped item: NULL, exit"); return(false); } Control.mod.Logger.Log("Dropped item: " + drag_item.ComponentRef.ComponentDefID); UniqueItem new_item_info; if (!drag_item.ComponentRef.Def.IsUnique(out new_item_info)) { Control.mod.Logger.Log("Item not Unique, exit"); return(true); } bool flag = __instance.ValidateAdd(drag_item.ComponentRef); Control.mod.Logger.Log(string.Format("Validation: {0} - {1}", flag, ___dropErrorMessage)); if (!flag && !___dropErrorMessage.EndsWith("Not enough free slots.")) { return(true); } var n = ___localInventory.FindUniqueItem(new_item_info); Control.mod.Logger.Log("index = " + n.ToString()); //if no - continue normal flow(add new or show "not enough slots" message if (n < 0) { return(true); } if (___usedSlots - ___localInventory[n].ComponentRef.Def.InventorySize + drag_item.ComponentRef.Def.InventorySize > ___maxSlots) { return(true); } var old_item = ___localInventory[n]; __instance.OnRemoveItem(old_item, true); ___mechLab.ForceItemDrop(old_item); var clear = __instance.OnAddItem(drag_item, true); if (__instance.Sim != null) { WorkOrderEntry_InstallComponent subEntry = __instance.Sim.CreateComponentInstallWorkOrder( ___mechLab.baseWorkOrder.MechID, drag_item.ComponentRef, __instance.loadout.Location, drag_item.MountedLocation); ___mechLab.baseWorkOrder.AddSubEntry(subEntry); } drag_item.MountedLocation = __instance.loadout.Location; ___mechLab.ClearDragItem(clear); __instance.RefreshHardpointData(); ___mechLab.ValidateLoadout(false); return(false); }
public static void ApplyLoadout(this MechLabPanel mechLabPanel, string mechDefId) { try { // Check first if (!mechLabPanel.Sim.DataManager.Exists(BattleTechResourceType.MechDef, mechDefId)) { GenericPopupBuilder .Create("Apply Loadout failed", "The requested MechDef " + mechDefId + " was not found") .AddButton("Confirm", null, true, null) .AddFader(new UIColorRef?(LazySingletonBehavior <UIManager> .Instance.UILookAndColorConstants.PopupBackfill), 0f, true) .SetAlwaysOnTop() .SetOnClose(delegate { // Nothing }) .Render(); // Abort! return; } MechDef activeMechDef = mechLabPanel.activeMechDef; MechDef requestedMechDef = new MechDef(mechLabPanel.Sim.DataManager.MechDefs.Get(mechDefId), null, true); // Check second List <string> errorDescriptions = new List <string>(); if (!mechLabPanel.CanApplyLoadout(requestedMechDef, out errorDescriptions)) { string popupTitle = "Apply Loadout failed"; //string popupBody = "The following problems were encountered:" + Environment.NewLine; string popupBody = ""; foreach (string errorDescription in errorDescriptions) { popupBody += errorDescription + Environment.NewLine; } GenericPopupBuilder .Create(popupTitle, popupBody) .AddButton("Confirm", null, true, null) .AddFader(new UIColorRef?(LazySingletonBehavior <UIManager> .Instance.UILookAndColorConstants.PopupBackfill), 0f, true) .SetAlwaysOnTop() .SetOnClose(delegate { // Nothing }) .Render(); // Abort! return; } // Checks done // Hard cleanup upfront mechLabPanel.OnRevertMech(); // Get data MechLabInventoryWidget inventoryWidget = (MechLabInventoryWidget)AccessTools.Field(typeof(MechLabPanel), "inventoryWidget").GetValue(mechLabPanel); MechLabDismountWidget dismountWidget = (MechLabDismountWidget)AccessTools.Field(typeof(MechLabPanel), "dismountWidget").GetValue(mechLabPanel); MechLabMechInfoWidget mechInfoWidget = (MechLabMechInfoWidget)AccessTools.Field(typeof(MechLabPanel), "mechInfoWidget").GetValue(mechLabPanel); HBS_InputField mechNickname = (HBS_InputField)AccessTools.Field(typeof(MechLabMechInfoWidget), "mechNickname").GetValue(mechInfoWidget); List <MechComponentRef> dropshipInventory = mechLabPanel.Sim.GetAllInventoryItemDefs(); List <MechComponentRef> storageInventory = mechLabPanel.storageInventory; List <MechComponentRef> activeMechInventory = mechLabPanel.activeMechInventory; MechComponentRef[] requestedMechComponentsArray = (MechComponentRef[])AccessTools.Field(typeof(MechDef), "inventory").GetValue(requestedMechDef); List <MechComponentRef> requestedMechComponents = requestedMechComponentsArray.ToList(); // Remove fixed equipment as it will be ignored from dismounting et all for (int i = requestedMechComponents.Count - 1; i >= 0; i--) { if (requestedMechComponents[i].IsFixed) { Logger.Debug("[Extensions.ResetToStock] FOUND AND WILL REMOVE FIXED EQUIPMENT: " + requestedMechComponents[i].ComponentDefID); requestedMechComponents.RemoveAt(i); } } // This puts the current equipment into dismountWidget and also clears the Mechs inventory // NOTE that fixed equipment will stay where it is -> must be removed from requestedComponents manually! mechLabPanel.OnStripEquipment(); // Collect items from dismountWidget and/or inventoryWidget List <MechComponentRef> requestedMechComponentsRequired = requestedMechComponents.ToList(); //List<MechLabItemSlotElement> activeMechDismountedItems = new List<MechLabItemSlotElement>(dismountWidget.localInventory); List <MechLabItemSlotElement> activeMechDismountedItems = dismountWidget.localInventory; //List<InventoryItemElement_NotListView> localInventoryItems = new List<InventoryItemElement_NotListView>(inventoryWidget.localInventory); List <InventoryItemElement_NotListView> localInventoryItems = inventoryWidget.localInventory; List <MechLabItemSlotElement> itemsCollectedFromDismount = new List <MechLabItemSlotElement>(); List <InventoryItemElement_NotListView> itemsCollectedFromInventory = new List <InventoryItemElement_NotListView>(); // CHECK foreach (MechComponentRef comp in requestedMechComponentsRequired) { Logger.Debug("[Extensions.ResetToStock] INIT requestedMechComponentsRequired: " + comp.ComponentDefID); } // Check for required items in dismountWidget first, remove/add from/to applicable Lists // @ToDo: Put in method for (int i = requestedMechComponentsRequired.Count - 1; i >= 0; i--) { bool found = false; for (int j = activeMechDismountedItems.Count - 1; j >= 0; j--) { if (requestedMechComponentsRequired[i].ComponentDefID == activeMechDismountedItems[j].ComponentRef.ComponentDefID) { Logger.Debug("[Extensions.ResetToStock] FOUND in activeMechDismountedItems: " + requestedMechComponentsRequired[i].ComponentDefID); found = true; requestedMechComponentsRequired.RemoveAt(i); itemsCollectedFromDismount.Add(activeMechDismountedItems[j]); // Remove visually // Do not forget to refresh the widget MechLabItemSlotElement mechLabItemSlotElement = activeMechDismountedItems[j]; mechLabItemSlotElement.gameObject.transform.SetParent(null, false); mechLabPanel.dataManager.PoolGameObject(MechLabPanel.MECHCOMPONENT_ITEM_PREFAB, mechLabItemSlotElement.gameObject); // Remove data AFTERWARDS too activeMechDismountedItems.RemoveAt(j); break; } } if (!found) { Logger.Debug("[Extensions.ResetToStock] NOT FOUND in activeMechDismountedItems: " + requestedMechComponentsRequired[i].ComponentDefID); } } // Refresh UI ReflectionHelper.InvokePrivateMethode(dismountWidget, "RefreshComponentCountText", null); // CHECK foreach (MechLabItemSlotElement item in itemsCollectedFromDismount) { Logger.Debug("[Extensions.ResetToStock] itemsCollectedFromDismount: " + item.ComponentRef.ComponentDefID + ", MountedLocation: " + item.MountedLocation + ", DropParent: " + item.DropParent); } // Check for REMAINING required items in inventoryWidget, remove/add from/to applicable Lists // NEEDS conversion of remaining components to inventory items via custom type List <InventoryItemElement_Simple> requestedMechItemsRequired = Utilities.ComponentsToInventoryItems(requestedMechComponentsRequired, true); List <InventoryItemElement_Simple> missingItems = new List <InventoryItemElement_Simple>(); bool itemsAvailableInInventory = mechLabPanel.ItemsAvailableInInventory(requestedMechItemsRequired, localInventoryItems, out missingItems); Logger.Debug("[Extensions.ResetToStock] itemsAvailableInInventory: " + itemsAvailableInInventory); if (itemsAvailableInInventory) { itemsCollectedFromInventory = mechLabPanel.PullItemsFromInventory(requestedMechItemsRequired, localInventoryItems); // Clear required components list requestedMechComponentsRequired.Clear(); } else { // Hard exit, SHOULD NEVER END UP HERE! Logger.Debug("[Extensions.ResetToStock] MISSING ITEMS. ABORTING. YOU SHOULD NEVER SEE THIS!"); mechLabPanel.OnRevertMech(); return; } // CHECK foreach (InventoryItemElement_NotListView item in itemsCollectedFromInventory) { Logger.Debug("[Extensions.ResetToStock] itemsCollectedFromInventory: " + item.ComponentRef.ComponentDefID + ", MountedLocation: " + item.MountedLocation + ", DropParent: " + item.DropParent); } // At this point inventoryWidget.localInventory AND dismountWidget.localInventory already have the potentially reusable components REMOVED // So, in "SetEquipment" they must be SPAWNED otherwise they are lost forever // Helper Dictionary Dictionary <ChassisLocations, MechLabLocationWidget> LocationHandler = new Dictionary <ChassisLocations, MechLabLocationWidget>(); LocationHandler.Add(ChassisLocations.Head, mechLabPanel.headWidget); LocationHandler.Add(ChassisLocations.CenterTorso, mechLabPanel.centerTorsoWidget); LocationHandler.Add(ChassisLocations.LeftTorso, mechLabPanel.leftTorsoWidget); LocationHandler.Add(ChassisLocations.RightTorso, mechLabPanel.rightTorsoWidget); LocationHandler.Add(ChassisLocations.LeftArm, mechLabPanel.leftArmWidget); LocationHandler.Add(ChassisLocations.RightArm, mechLabPanel.rightArmWidget); LocationHandler.Add(ChassisLocations.LeftLeg, mechLabPanel.leftLegWidget); LocationHandler.Add(ChassisLocations.RightLeg, mechLabPanel.rightLegWidget); // Prepare custom equipment with info about desired origin beforehand List <InventoryItemElement_Simple> requestedEquipment = new List <InventoryItemElement_Simple>(); List <MechLabItemSlotElement> dismountedItems = itemsCollectedFromDismount.ToList(); foreach (MechComponentRef requestedItem in requestedMechComponents) { InventoryItemElement_Simple requestedInventoryItem = new InventoryItemElement_Simple(); requestedInventoryItem.ComponentRef = requestedItem; requestedInventoryItem.Origin = MechLabDropTargetType.InventoryList; for (int i = dismountedItems.Count - 1; i >= 0; i--) { if (requestedItem.ComponentDefID == dismountedItems[i].ComponentRef.ComponentDefID) { requestedInventoryItem.Origin = MechLabDropTargetType.Dismount; dismountedItems.RemoveAt(i); break; } } requestedEquipment.Add(requestedInventoryItem); } // CHECK foreach (MechComponentRef item in requestedMechComponents) { Logger.Debug("[Extensions.ResetToStock] baseMechComponents: " + item.ComponentDefID); } foreach (InventoryItemElement_Simple item in requestedEquipment) { Logger.Debug("[Extensions.ResetToStock] requestedEquipment: " + item.ComponentRef.ComponentDefID + ", Origin: " + item.Origin); } // Set inventory including a hint to where the components were taken from // Example manual call: mechLabPanel.SetEquipment(requestedEquipment, mechLabPanel.centerTorsoWidget, requestedMechDef.GetLocationLoadoutDef(ChassisLocations.CenterTorso)); foreach (KeyValuePair <ChassisLocations, MechLabLocationWidget> LocationPair in LocationHandler) { mechLabPanel.SetEquipment(requestedEquipment, LocationPair.Value, requestedMechDef.GetLocationLoadoutDef(LocationPair.Key)); mechLabPanel.SetArmor(LocationPair.Value, requestedMechDef.GetLocationLoadoutDef(LocationPair.Key)); } // Refresh main inventory mechLabPanel.activeMechInventory = new List <MechComponentRef>(requestedMechDef.Inventory); //ReflectionHelper.InvokePrivateMethode(mechLabPanel.activeMechDef, "InsertFixedEquipmentIntoInventory", null); // Better as it calls RefreshInventory()? -> No, Tonnage is not adjusted... need to look into it somewhen //mechLabPanel.activeMechDef.SetInventory(requestedMechDef.Inventory); // Update dependent widgets (also calls CalculateCBillValue() -> CalculateSimGameWorkOrderCost() -> PruneWorkOrder()) mechInfoWidget.RefreshInfo(); // Mark as modified Traverse.Create(mechLabPanel).Field("Modified").SetValue(true); GameObject modifiedIcon = (GameObject)AccessTools.Field(typeof(MechLabPanel), "modifiedIcon").GetValue(mechLabPanel); modifiedIcon.SetActive(mechLabPanel.Modified); // Validate mechLabPanel.ValidateLoadout(true); ReflectionHelper.InvokePrivateMethode(mechLabPanel, "RefreshInventorySelectability", null); // Set Nickname mechNickname.SetText(requestedMechDef.Description.Name); // @ToDo: Inform user about what components were installed from where } catch (Exception e) { Logger.Error(e); } }
// only allow one engine part per specific location internal static MechLabLocationWidgetOnMechLabDropPatch.Result DropCheck( MechLabLocationWidget widget, MechLabPanel mechLab, MechLabItemSlotElement dragItem, List <MechLabItemSlotElement> localInventory) { if (widget.loadout.Location != ChassisLocations.CenterTorso) { return(null); } var newComponentRef = dragItem.ComponentRef; var newComponentDef = newComponentRef.Def; var headSinkDef = newComponentDef as HeatSinkDef; if (headSinkDef == null) { return(null); } // check if we can work with it if (!headSinkDef.IsDHSKit() && !headSinkDef.IsSingle() && !headSinkDef.IsDouble()) { return(null); } var existingEngine = localInventory .Where(x => x != null) .Select(x => x.ComponentRef) .FirstOrDefault(x => x != null && x.Def != null && x.Def.IsMainEngine()); if (existingEngine == null) { if (headSinkDef.IsDHSKit()) { return(new MechLabLocationWidgetOnMechLabDropPatch.ErrorResult( string.Format("Cannot add {0}: No Engine found", newComponentDef.Description.Name) )); } else { return(null); } } var engineRef = existingEngine.GetEngineRef(); if (headSinkDef.IsDHSKit()) { if (engineRef.IsDHS) { return(new MechLabLocationWidgetOnMechLabDropPatch.ErrorResult( string.Format("Cannot add {0}: Already a DHS engine", newComponentDef.Description.Name) )); } if (!Control.settings.AllowMixingDoubleAndSingleHeatSinks && engineRef.AdditionalSHSCount > 0) { return(null); //return new MechLabLocationWidgetOnMechLabDropPatch.ErrorResult( // string.Format("Cannot add {0}: Reinstall engine to remove additional heat sinks before converting", newComponentDef.Description.Name) //); } engineRef.IsDHS = true; } else { int minHeatSinks, maxHeatSinks; Control.calc.CalcHeatSinks(engineRef.engineDef, out minHeatSinks, out maxHeatSinks); if (engineRef.AdditionalHeatSinkCount >= maxHeatSinks - minHeatSinks) { return(null); //return new MechLabLocationWidgetOnMechLabDropPatch.ErrorResult( // string.Format("Cannot add {0}: Maximum additional heat sinks reached for engine", newComponentDef.Description.Name) //); } if (!Control.settings.AllowMixingDoubleAndSingleHeatSinks) { if (engineRef.IsDHS && headSinkDef.IsSingle() || engineRef.IsSHS && headSinkDef.IsDouble()) { return(new MechLabLocationWidgetOnMechLabDropPatch.ErrorResult( string.Format("Cannot add {0}: Mixing DHS and SHS is not allowed", newComponentDef.Description.Name) )); } } if (headSinkDef.IsDouble()) { engineRef.AdditionalDHSCount++; } else if (headSinkDef.IsSingle()) { engineRef.AdditionalSHSCount++; } } EnginePersistence.SaveEngineState(engineRef, mechLab); mechLab.ValidateLoadout(false); return(new MechLabLocationWidgetOnMechLabDropPatch.RemoveItemResult()); }
public static bool Prefix(MechLabLocationWidget __instance, MechLabPanel ___mechLab, PointerEventData eventData) { try { var dragItem = ___mechLab.DragItem as MechLabItemSlotElement; if (!___mechLab.Initialized) { return(false); } var newComponentDef = dragItem?.ComponentRef?.Def; if (newComponentDef == null) { return(false); } Control.LogDebug(DType.ComponentInstall, $"OnMechLabDrop: Adding {newComponentDef.Description.Id}"); var location_helper = new LocationHelper(__instance); var mechlab_helper = new MechLabHelper(___mechLab); bool do_cancel(string error, List <IChange> allchanges) { if (string.IsNullOrEmpty(error)) { return(false); } Control.LogDebug(DType.ComponentInstall, $"- Canceled: {error}"); if (allchanges != null) { foreach (var change in allchanges) { change.CancelChange(mechlab_helper, location_helper); } } ___mechLab.OnDrop(eventData); ___mechLab.ShowDropErrorMessage(new Text(error)); return(true); } Control.LogDebug(DType.ComponentInstall, $"- pre validation"); foreach (var pre_validator in Validator.GetPre(newComponentDef)) { if (do_cancel(pre_validator(dragItem, location_helper, mechlab_helper), null)) { return(false); } } Control.LogDebug(DType.ComponentInstall, $"- replace validation"); List <IChange> changes = new List <IChange>(); changes.Add(new AddFromInventoryChange(__instance.loadout.Location, dragItem)); foreach (var rep_validator in Validator.GetReplace(newComponentDef)) { if (do_cancel(rep_validator(dragItem, location_helper, changes), changes)) { return(false); } } #if CCDEBUG if (Control.Settings.DebugInfo.HasFlag(DType.ComponentInstall)) { if (changes.Count == 1) { Control.LogDebug(DType.ComponentInstall, $"-- no replace"); } else { foreach (var replace in changes) { if (replace is AddChange add) { Control.LogDebug(DType.ComponentInstall, $"-- add {add.item.ComponentRef.ComponentDefID}"); } else if (replace is RemoveChange remove) { Control.LogDebug(DType.ComponentInstall, $"-- remove {remove.item.ComponentRef.ComponentDefID}"); } } } } #endif Control.LogDebug(DType.ComponentInstall, $"- adjusting {changes.Count} changes"); int num = changes.Count; for (int i = 0; i < num; i++) { if (changes[i] is AddChange add) { Control.LogDebug(DType.ComponentInstall, $"-- add: {add.item.ComponentRef.ComponentDefID}"); foreach (var adj_validator in add.item.ComponentRef.GetComponents <IAdjustValidateDrop>()) { changes.AddRange(adj_validator.ValidateDropOnAdd(add.item, location_helper, mechlab_helper, changes)); } } else if (changes[i] is RemoveChange remove) { Control.LogDebug(DType.ComponentInstall, $"-- add: {remove.item.ComponentRef.ComponentDefID}"); foreach (var adj_validator in remove.item.ComponentRef.GetComponents <IAdjustValidateDrop>()) { changes.AddRange(adj_validator.ValidateDropOnRemove(remove.item, location_helper, mechlab_helper, changes)); } } } List <InvItem> new_inventory = ___mechLab.activeMechInventory .Select(i => new InvItem { item = i, location = i.MountedLocation }).ToList(); new_inventory.AddRange(changes.OfType <AddChange>() .Select(i => new InvItem { item = i.item.ComponentRef, location = i.location })); foreach (var remove in changes.OfType <RemoveChange>()) { new_inventory.RemoveAll(i => i.item == remove.item.ComponentRef); } Control.LogDebug(DType.ComponentInstall, $"- post validation"); foreach (var pst_validator in Validator.GetPost(newComponentDef)) { if (do_cancel(pst_validator(dragItem, ___mechLab.activeMechDef, new_inventory, changes), changes)) { return(false); } } Control.LogDebug(DType.ComponentInstall, $"- apply changes"); foreach (var change in changes) { change.DoChange(mechlab_helper, location_helper); } ___mechLab.ClearDragItem(true); __instance.RefreshHardpointData(); ___mechLab.ValidateLoadout(false); return(false); } catch (Exception e) { Control.LogError(e); } return(true); }