internal void AmmoPull() // In Thread { try { foreach (var weapon in WeaponToPullAmmo) { using (weapon.Comp.Ai?.MyGrid.Pin()) using (weapon.Comp.MyCube.Pin()) { if (weapon.Comp.MyCube.MarkedForClose || weapon.Comp.Ai == null || weapon.Comp.Ai.MarkedForClose || weapon.Comp.Ai.MyGrid.MarkedForClose || !weapon.Comp.InventoryInited || weapon.Comp.Platform.State != MyWeaponPlatform.PlatformState.Ready) { InvPullClean.Add(weapon); continue; } var defId = weapon.ActiveAmmoDef.AmmoDefinitionId; var freeSpace = weapon.System.MaxAmmoVolume - weapon.Comp.CurrentInventoryVolume; var spotsFree = (int)(freeSpace / weapon.ActiveAmmoDef.AmmoDef.Const.MagVolume); var magsNeeded = (int)((weapon.System.FullAmmoVolume - weapon.CurrentAmmoVolume) / weapon.ActiveAmmoDef.AmmoDef.Const.MagVolume); magsNeeded = magsNeeded > spotsFree ? spotsFree : magsNeeded; var ammoPullRequests = InventoryMoveRequestPool.Get(); ammoPullRequests.Weapon = weapon; var magsAdded = 0; var logged = 0; foreach (var inventory in weapon.Comp.Ai.InventoryMonitor.Values) { MyConcurrentList <BetterInventoryItem> items; if (AmmoThreadItemList.TryGetValue(inventory, out items)) { for (int l = items.Count - 1; l >= 0; l--) { var item = items[l]; if (!item.DefId.Equals(defId)) { continue; } var magsAvailable = item.Amount; if (magsAvailable > 0 && magsNeeded > 0 && ((IMyInventory)inventory).CanTransferItemTo(weapon.Comp.BlockInventory, defId)) { if (magsAvailable >= magsNeeded) { ammoPullRequests.Inventories.Add(new InventoryMags { Inventory = inventory, Item = item, Amount = magsNeeded }); magsAdded += magsNeeded; item.Amount -= magsNeeded; magsNeeded = 0; } else { ammoPullRequests.Inventories.Add(new InventoryMags { Inventory = inventory, Item = item, Amount = magsAvailable }); magsNeeded -= magsAvailable; magsAdded += magsAvailable; item.Amount -= magsAvailable; items.RemoveAtFast(l); BetterInventoryItems.Return(item); } weapon.CurrentAmmoVolume = magsAdded * weapon.ActiveAmmoDef.AmmoDef.Const.MagVolume; } if (magsNeeded <= 0) { break; } } } else if (logged++ == 0) { Log.Line($"[Inventory invalid in AmmoPull] Weapon:{weapon.Comp.MyCube.BlockDefinition.Id.SubtypeName} - blockMarked:{weapon.Comp.MyCube.MarkedForClose} - aiMarked:{weapon.Comp.Ai.MarkedForClose} - cTick:{Tick - weapon.Comp.Ai.AiCloseTick} - mTick:{Tick - weapon.Comp.Ai.AiMarkedTick} - sTick:{Tick - weapon.Comp.Ai.CreatedTick}"); } } if (ammoPullRequests.Inventories.Count > 0) { AmmoToPullQueue.Add(ammoPullRequests); } else { InventoryMoveRequestPool.Return(ammoPullRequests); } } InvPullClean.Add(weapon); } } catch (Exception e) { Log.Line($"Error in AmmoPull: {e}"); } }
internal void AmmoPull() // In Thread { Weapon weapon = null; try { for (int i = WeaponToPullAmmo.Count - 1; i >= 0; i--) { weapon = WeaponToPullAmmo[i]; using (weapon.Comp.Ai?.MyGrid.Pin()) using (weapon.Comp.MyCube.Pin()) { if (weapon.Comp.MyCube.MarkedForClose || weapon.Comp.Ai == null || weapon.Comp.Ai.MarkedForClose || weapon.Comp.Ai.MyGrid.MarkedForClose || !weapon.Comp.InventoryInited || weapon.Comp.Platform.State != MyWeaponPlatform.PlatformState.Ready) { InvPullClean.Add(weapon); continue; } var defId = weapon.ActiveAmmoDef.AmmoDefinitionId; var freeSpace = weapon.System.MaxAmmoVolume - weapon.Comp.CurrentInventoryVolume; var spotsFree = (int)(freeSpace / weapon.ActiveAmmoDef.AmmoDef.Const.MagVolume); var magsNeeded = (int)((weapon.System.FullAmmoVolume - weapon.CurrentAmmoVolume) / weapon.ActiveAmmoDef.AmmoDef.Const.MagVolume); magsNeeded = magsNeeded > spotsFree ? spotsFree : magsNeeded; var ammoPullRequests = InventoryMoveRequestPool.Get(); ammoPullRequests.Weapon = weapon; var magsAdded = 0; for (int j = 0; j < weapon.Comp.Ai.Inventories.Count; j++) { var inventory = weapon.Comp.Ai.Inventories[j]; var items = AmmoThreadItemList[inventory]; for (int l = items.Count - 1; l >= 0; l--) { var item = items[l]; if (!item.DefId.Equals(defId)) { continue; } var magsAvailable = item.Amount; if (magsAvailable > 0 && magsNeeded > 0 && ((IMyInventory)inventory).CanTransferItemTo(weapon.Comp.BlockInventory, defId)) { if (magsAvailable >= magsNeeded) { ammoPullRequests.Inventories.Add(new InventoryMags { Inventory = inventory, Item = item, Amount = magsNeeded }); magsAdded += magsNeeded; item.Amount -= magsNeeded; magsNeeded = 0; } else { ammoPullRequests.Inventories.Add(new InventoryMags { Inventory = inventory, Item = item, Amount = magsAvailable }); magsNeeded -= magsAvailable; magsAdded += magsAvailable; item.Amount -= magsAvailable; items.RemoveAtFast(l); BetterInventoryItems.Return(item); } weapon.CurrentAmmoVolume = magsAdded * weapon.ActiveAmmoDef.AmmoDef.Const.MagVolume; } if (magsNeeded <= 0) { break; } } } if (ammoPullRequests.Inventories.Count > 0) { AmmoToPullQueue.Add(ammoPullRequests); } else { InventoryMoveRequestPool.Return(ammoPullRequests); } } InvPullClean.Add(weapon); } } catch (Exception e) { Log.Line($"Error in AmmoPull: {e}"); if (weapon != null) { UniqueListRemove(weapon, WeaponToPullAmmoIndexer, WeaponToPullAmmo); } } }