internal void RegisterEvents(bool register = true) { if (register) { if (Registered) { Log.Line($"Comp RegisterEvents error"); } //TODO change this Registered = true; TerminalBlock.AppendingCustomInfo += AppendingCustomInfo; MyCube.IsWorkingChanged += IsWorkingChanged; MyCube.OnMarkForClose += OnMarkForClose; IsWorkingChanged(MyCube); if (BlockInventory == null) { Log.Line($"BlockInventory is null"); } else { BlockInventory.InventoryContentChanged += OnContentsChanged; Session.BlockInventoryItems[BlockInventory] = new ConcurrentDictionary <uint, BetterInventoryItem>(); Session.AmmoThreadItemList[BlockInventory] = Session.BetterItemsListPool.Get(); var items = BlockInventory.GetItems(); for (int i = 0; i < items.Count; i++) { var bItem = Session.BetterInventoryItems.Get(); var item = items[i]; bItem.Amount = (int)item.Amount; bItem.Item = item; bItem.Content = item.Content; Session.BlockInventoryItems[BlockInventory][items[i].ItemId] = bItem; } } } else { if (!Registered) { Log.Line($"Comp UnRegisterEvents error"); } if (Registered) { //TODO change this Registered = false; TerminalBlock.AppendingCustomInfo -= AppendingCustomInfo; MyCube.IsWorkingChanged -= IsWorkingChanged; MyCube.OnMarkForClose -= OnMarkForClose; if (BlockInventory == null) { Log.Line($"BlockInventory is null"); } else { BlockInventory.InventoryContentChanged -= OnContentsChanged; ConcurrentDictionary <uint, BetterInventoryItem> removedItems; MyConcurrentList <BetterInventoryItem> removedList; if (Session.BlockInventoryItems.TryRemove(BlockInventory, out removedItems)) { foreach (var inventoryItems in removedItems) { Session.BetterInventoryItems.Return(inventoryItems.Value); } removedItems.Clear(); } if (Session.AmmoThreadItemList.TryRemove(BlockInventory, out removedList)) { Session.BetterItemsListPool.Return(removedList); } } } } }
public Dictionary <string, int> PullIn(IMyTerminalBlock Puller, Dictionary <string, int> ComponentList, string TypeConstraint) { lock (InventoryLock) { // If you are wondering why I'm using Ingame interfaces in ModAPI, the Ingame inventory functions are more error-proof Dictionary <string, int> PulledList = new Dictionary <string, int>(); var AccessibleInventoryOwners = GetAccessibleInventories(Puller); VRage.Game.ModAPI.Ingame.IMyInventory PullingInventory = (Puller as Sandbox.ModAPI.Ingame.IMyTerminalBlock).GetInventory(); if (PullingInventory == null) { return(null); } foreach (var Block in AccessibleInventoryOwners) { VRage.Game.ModAPI.Ingame.IMyInventory BlockInventory; if (Block.InventoryCount > 1) { BlockInventory = (Block as Sandbox.ModAPI.Ingame.IMyTerminalBlock).GetInventory(1); } else { BlockInventory = (Block as Sandbox.ModAPI.Ingame.IMyTerminalBlock).GetInventory(0); } var InventoryList = BlockInventory.GetItems(); foreach (VRage.Game.ModAPI.Ingame.IMyInventoryItem Item in InventoryList) { if (Item.Amount <= 0 || (TypeConstraint.Contains("Component") && Item.Amount < 1)) { continue; // KSWH and their code... } if (!Item.Content.TypeId.ToString().Contains(TypeConstraint)) { continue; } if (!ComponentList.ContainsKey(Item.Content.SubtypeName)) { continue; } int NecessaryAmount = ComponentList[Item.Content.SubtypeName]; if (NecessaryAmount <= 0) { continue; //This means we've pulled everything we need } int PullableAmount = Item.Amount > NecessaryAmount ? NecessaryAmount : (int)Item.Amount; PullableAmount = (int)PullingInventory.ComputeAmountThatFits(Item, PullableAmount); if (PullableAmount == 0) { continue; } int ItemIndex = InventoryList.IndexOf(Item); int ItemAmount = (int)Item.Amount; PullingInventory.TransferItemFrom(BlockInventory, ItemIndex, null, true, PullableAmount); ComponentList[Item.Content.SubtypeName] -= PullableAmount; if (PulledList.ContainsKey(Item.Content.SubtypeName)) { PulledList[Item.Content.SubtypeName] += ItemAmount; } else { PulledList.Add(Item.Content.SubtypeName, ItemAmount); } } } return(PulledList); } }