Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
            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);
            }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
    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);
    }
Ejemplo n.º 7
0
            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);
                }
            }
Ejemplo n.º 8
0
    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);
    }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
0
            // 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);
                }));
            }
Ejemplo n.º 11
0
        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);
            }
        }
Ejemplo n.º 12
0
        // 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());
        }
Ejemplo n.º 13
0
        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);
        }
Ejemplo n.º 14
0
        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);
        }
Ejemplo n.º 15
0
        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);
            }
        }
Ejemplo n.º 16
0
        // 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());
        }
Ejemplo n.º 17
0
        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);
        }