Esempio n. 1
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);
            }
        }