예제 #1
0
        internal void MoveAmmo()
        {
            for (int i = 0; i < AmmoToPullQueue.Count; i++)
            {
                var weaponAmmoToPull  = AmmoToPullQueue[i];
                var weapon            = weaponAmmoToPull.Weapon;
                var inventoriesToPull = weaponAmmoToPull.Inventories;

                if (!weapon.Comp.InventoryInited || weapon.Comp.Platform.State != MyWeaponPlatform.PlatformState.Ready)
                {
                    InventoryMoveRequestPool.Return(weaponAmmoToPull);
                    continue;
                }

                for (int j = 0; j < inventoriesToPull.Count; j++)
                {
                    var mag  = inventoriesToPull[j];
                    var amt  = mag.Amount;
                    var item = mag.Item;

                    if (weapon.Comp.BlockInventory.ItemsCanBeAdded(amt, weapon.ActiveAmmoDef.AmmoDef.Const.AmmoItem) && mag.Inventory.ItemsCanBeRemoved(amt, item.Item))
                    {
                        mag.Inventory.RemoveItems(item.Item.ItemId, amt);
                        weapon.Comp.BlockInventory.Add(weapon.ActiveAmmoDef.AmmoDef.Const.AmmoItem, amt);
                    }
                }

                weapon.Ammo.CurrentMags = weapon.Comp.BlockInventory.GetItemAmount(weapon.ActiveAmmoDef.AmmoDefinitionId).ToIntSafe();

                InventoryMoveRequestPool.Return(weaponAmmoToPull);
            }
            AmmoToPullQueue.Clear();
        }
예제 #2
0
        internal void MoveAmmo()
        {
            MyTuple <Weapon, MyTuple <MyInventory, int>[]> weaponAmmoToPull;

            while (AmmoToPullQueue.TryDequeue(out weaponAmmoToPull))
            {
                var weapon = weaponAmmoToPull.Item1;
                if (!weapon.Comp.InventoryInited)
                {
                    continue;
                }
                var inventoriesToPull = weaponAmmoToPull.Item2;
                var def     = weapon.ActiveAmmoDef.AmmoDefinitionId;
                var magItem = weapon.ActiveAmmoDef.AmmoDef.Const.AmmoItem;

                weapon.Comp.IgnoreInvChange = true;

                for (int i = 0; i < inventoriesToPull.Length; i++)
                {
                    var amt = inventoriesToPull[i].Item2;
                    inventoriesToPull[i].Item1.RemoveItemsOfType(amt, def);
                    weapon.Comp.BlockInventory.Add(magItem, amt);
                }

                if (inventoriesToPull.Length > 0)
                {
                    weapon.State.Sync.CurrentMags = weapon.Comp.BlockInventory.GetItemAmount(weapon.ActiveAmmoDef.AmmoDefinitionId);
                    if (weapon.CanReload)
                    {
                        weapon.StartReload();
                    }
                }

                weapon.Comp.IgnoreInvChange = false;
            }
        }
        internal void PurgeAll()
        {
            FutureEvents.Purge((int)Tick);
            PurgeTerminalSystem();

            foreach (var reports in Reporter.ReportData.Values)
            {
                foreach (var report in reports)
                {
                    report.Clean();
                    Reporter.ReportPool.Return(report);
                }
                reports.Clear();
            }
            Reporter.ReportData.Clear();
            Reporter.ReportPool.Clean();

            PacketsToClient.Clear();
            PacketsToServer.Clear();

            foreach (var suit in (PacketType[])Enum.GetValues(typeof(PacketType)))
            {
                foreach (var pool in PacketPools.Values)
                {
                    pool.Clean();
                }
                PacketPools.Clear();
            }

            foreach (var item in _effectedCubes)
            {
                var cubeid     = item.Key;
                var blockInfo  = item.Value;
                var functBlock = blockInfo.FunctBlock;
                var cube       = blockInfo.CubeBlock;

                if (cube == null || cube.MarkedForClose)
                {
                    _effectPurge.Enqueue(cubeid);
                    continue;
                }

                functBlock.EnabledChanged -= ForceDisable;
                functBlock.Enabled         = blockInfo.FirstState;
                cube.SetDamageEffect(false);
                _effectPurge.Enqueue(cubeid);
            }

            while (_effectPurge.Count != 0)
            {
                _effectedCubes.Remove(_effectPurge.Dequeue());
            }

            Av.Glows.Clear();
            Av.AvShotPool.Clean();

            DeferedUpBlockTypeCleanUp(true);
            BlockTypeCleanUp.Clear();

            foreach (var map in GridToFatMap.Keys)
            {
                RemoveGridFromMap(map);
            }

            GridToFatMap.Clear();
            FatMapPool.Clean();

            DirtyGridsTmp.Clear();

            foreach (var structure in WeaponPlatforms.Values)
            {
                foreach (var system in structure.WeaponSystems)
                {
                    foreach (var ammo in system.Value.WeaponAmmoTypes)
                    {
                        ammo.AmmoDef.Const.PrimeEntityPool?.Clean();
                    }
                }

                structure.WeaponSystems.Clear();
            }
            WeaponPlatforms.Clear();

            foreach (var gridToMap in GridToBlockTypeMap)
            {
                foreach (var map in gridToMap.Value)
                {
                    map.Value.ClearImmediate();
                    ConcurrentListPool.Return(map.Value);
                }
                gridToMap.Value.Clear();
                BlockTypePool.Return(gridToMap.Value);
            }
            GridToBlockTypeMap.Clear();

            foreach (var playerGrids in PlayerEntityIdInRange)
            {
                playerGrids.Value.Clear();
            }

            PlayerEntityIdInRange.Clear();

            DirtyGrids.Clear();

            DsUtil.Purge();
            DsUtil2.Purge();

            _effectActive = false;
            ShootingWeapons.Clear();
            AcquireTargets.Clear();
            RemoveEffectsFromGrid.Clear();
            WeaponAmmoPullQueue.Clear();
            AmmoToPullQueue.Clear();
            Hits.Clear();
            AllArmorBaseDefinitions.Clear();
            HeavyArmorBaseDefinitions.Clear();
            AllArmorBaseDefinitions.Clear();
            AcquireTargets.Clear();
            ChargingWeapons.Clear();
            LargeBlockSphereDb.Clear();
            SmallBlockSphereDb.Clear();
            AnimationsToProcess.Clear();
            _subTypeIdToWeaponDefs.Clear();
            WeaponDefinitions.Clear();
            SlimsSortedList.Clear();
            _destroyedSlims.Clear();
            _destroyedSlimsClient.Clear();
            _slimHealthClient.Clear();
            _slimsSet.Clear();
            _turretDefinitions.Clear();

            foreach (var comp in CompsToStart)
            {
                PlatFormPool.Return(comp.Platform);
                comp.Platform = null;
            }

            foreach (var readd in CompReAdds)
            {
                PlatFormPool.Return(readd.Comp.Platform);
                readd.Comp.Platform = null;
            }
            foreach (var comp in CompsDelayed)
            {
                PlatFormPool.Return(comp.Platform);
                comp.Platform = null;
            }
            PlatFormPool.Clean();
            CompsToStart.ClearImmediate();

            CompsDelayed.Clear();
            CompReAdds.Clear();
            GridAiPool.Clean();

            Av.RipMap.Clear();
            foreach (var mess in Av.KeensBrokenParticles)
            {
                Av.KeenMessPool.Return(mess);
            }

            Av.KeensBrokenParticles.Clear();

            foreach (var av in Av.AvShots)
            {
                av.GlowSteps.Clear();
                Av.AvShotPool.Return(av);
            }
            Av.AvShotPool.Clean();
            Av.AvBarrels1.Clear();
            Av.AvBarrels2.Clear();
            Av.AvShots.Clear();
            Av.HitSounds.Clear();

            foreach (var errorpkt in ClientSideErrorPktList)
            {
                errorpkt.Packet.CleanUp();
            }
            ClientSideErrorPktList.Clear();

            GridEffectPool.Clean();
            GridEffectsPool.Clean();
            BlockTypePool.Clean();
            ConcurrentListPool.Clean();

            GroupInfoPool.Clean();
            TargetInfoPool.Clean();

            Projectiles.Clean();
            WeaponCoreBlockDefs.Clear();
            VanillaIds.Clear();
            VanillaCoreIds.Clear();
            WeaponCoreFixedBlockDefs.Clear();
            WeaponCoreTurretBlockDefs.Clear();

            foreach (var p in Projectiles.ProjectilePool)
            {
                p.AmmoEffect?.Stop();
            }

            Projectiles.ShrapnelToSpawn.Clear();
            Projectiles.ShrapnelPool.Clean();
            Projectiles.FragmentPool.Clean();
            Projectiles.ActiveProjetiles.ApplyChanges();
            Projectiles.ActiveProjetiles.Clear();
            Projectiles.ProjectilePool.Clear();
            Projectiles.HitEntityPool.Clean();
            Projectiles.CleanUp.Clear();
            Projectiles.VirtInfoPool.Clean();

            DbsToUpdate.Clear();
            GridTargetingAIs.Clear();

            DsUtil          = null;
            DsUtil2         = null;
            SlimsSortedList = null;
            Enforced        = null;
            StallReporter   = null;
            Proccessor      = null;
            Physics         = null;
            Camera          = null;
            Projectiles     = null;
            TrackingAi      = null;
            UiInput         = null;
            TargetUi        = null;
            Placer          = null;
            WheelUi         = null;
            TargetGps       = null;
            SApi.Unload();
            SApi                = null;
            Api                 = null;
            ApiServer           = null;
            Reporter            = null;
            WeaponDefinitions   = null;
            AnimationsToProcess = null;
            ProjectileTree.Clear();
            ProjectileTree     = null;
            Av                 = null;
            HudUi              = null;
            AllDefinitions     = null;
            SoundDefinitions   = null;
            ActiveCockPit      = null;
            ActiveControlBlock = null;
            ControlledEntity   = null;
        }
예제 #4
0
        internal void PurgeAll()
        {
            PurgedAll = true;
            FutureEvents.Purge((int)Tick);


            foreach (var comp in CompsToStart)
            {
                if (comp?.Platform != null)
                {
                    CloseComps(comp.MyCube);
                }
            }

            foreach (var readd in CompReAdds)
            {
                if (!readd.Ai.Closed)
                {
                    readd.Ai.AiForceClose();
                }
                if (readd.Comp?.Platform != null)
                {
                    CloseComps(readd.Comp.MyCube);
                }
            }

            foreach (var comp in CompsDelayed)
            {
                if (comp?.Platform != null)
                {
                    CloseComps(comp.MyCube);
                }
            }

            foreach (var gridAi in DelayedAiClean)
            {
                if (!gridAi.Closed)
                {
                    gridAi.AiForceClose();
                }
            }

            PlatFormPool.Clean();
            CompsToStart.ClearImmediate();
            DelayedAiClean.ClearImmediate();

            CompsDelayed.Clear();
            CompReAdds.Clear();
            GridAiPool.Clean();


            PurgeTerminalSystem(this);
            HudUi.Purge();
            TerminalMon.Purge();
            foreach (var reports in Reporter.ReportData.Values)
            {
                foreach (var report in reports)
                {
                    report.Clean();
                    Reporter.ReportPool.Return(report);
                }
                reports.Clear();
            }
            Reporter.ReportData.Clear();
            Reporter.ReportPool.Clean();

            PacketsToClient.Clear();
            PacketsToServer.Clear();

            AcqManager.Clean();

            CleanSounds(true);

            foreach (var e in Emitters)
            {
                e.StopSound(true);
            }
            foreach (var e in Av.HitEmitters)
            {
                e.StopSound(true);
            }
            foreach (var e in Av.FireEmitters)
            {
                e.StopSound(true);
            }
            foreach (var e in Av.TravelEmitters)
            {
                e.StopSound(true);
            }

            Emitters.Clear();
            Av.HitEmitters.Clear();
            Av.FireEmitters.Clear();
            Av.TravelEmitters.Clear();

            foreach (var item in EffectedCubes)
            {
                var cubeid     = item.Key;
                var blockInfo  = item.Value;
                var functBlock = blockInfo.FunctBlock;

                if (functBlock == null || functBlock.MarkedForClose)
                {
                    _effectPurge.Enqueue(cubeid);
                    continue;
                }

                functBlock.EnabledChanged -= ForceDisable;
                functBlock.Enabled         = blockInfo.FirstState;
                functBlock.SetDamageEffect(false);
                if (HandlesInput)
                {
                    functBlock.AppendingCustomInfo -= blockInfo.AppendCustomInfo;
                }
                _effectPurge.Enqueue(cubeid);
            }

            while (_effectPurge.Count != 0)
            {
                EffectedCubes.Remove(_effectPurge.Dequeue());
            }

            Av.Glows.Clear();
            Av.AvShotPool.Clean();

            DeferedUpBlockTypeCleanUp(true);
            BlockTypeCleanUp.Clear();

            foreach (var map in GridToInfoMap.Keys)
            {
                RemoveGridFromMap(map);
            }

            GridToInfoMap.Clear();
            GridMapPool.Clean();

            DirtyGridsTmp.Clear();

            foreach (var structure in WeaponPlatforms.Values)
            {
                foreach (var system in structure.WeaponSystems)
                {
                    system.Value.PreFirePairs.Clear();
                    system.Value.FireWhenDonePairs.Clear();
                    system.Value.FirePerShotPairs.Clear();
                    system.Value.RotatePairs.Clear();
                    system.Value.ReloadPairs.Clear();
                    foreach (var ammo in system.Value.AmmoTypes)
                    {
                        ammo.AmmoDef.Const.PrimeEntityPool?.Clean();
                        ammo.AmmoDef.Const.HitDefaultSoundPairs.Clear();
                        ammo.AmmoDef.Const.HitVoxelSoundPairs.Clear();
                        ammo.AmmoDef.Const.HitShieldSoundPairs.Clear();
                        ammo.AmmoDef.Const.HitFloatingSoundPairs.Clear();
                        ammo.AmmoDef.Const.HitPlayerSoundPairs.Clear();
                        ammo.AmmoDef.Const.TravelSoundPairs.Clear();
                        ammo.AmmoDef.Const.CustomSoundPairs.Clear();
                    }
                }

                structure.WeaponSystems.Clear();
            }
            WeaponPlatforms.Clear();

            foreach (var gridToMap in GridToBlockTypeMap)
            {
                foreach (var map in gridToMap.Value)
                {
                    ConcurrentListPool.Return(map.Value);
                }
                gridToMap.Value.Clear();
                BlockTypePool.Return(gridToMap.Value);
            }
            GridToBlockTypeMap.Clear();

            foreach (var playerGrids in PlayerEntityIdInRange)
            {
                playerGrids.Value.Clear();
            }

            PlayerEntityIdInRange.Clear();
            DirtyGridInfos.Clear();

            DsUtil.Purge();
            DsUtil2.Purge();

            ShootingWeapons.Clear();
            WeaponToPullAmmo.Clear();
            AmmoToPullQueue.Clear();
            ChargingWeaponsIndexer.Clear();
            WeaponsToRemoveAmmoIndexer.Clear();
            ChargingWeapons.Clear();
            Hits.Clear();
            HomingWeapons.Clear();
            GridToMasterAi.Clear();
            Players.Clear();
            IdToCompMap.Clear();
            AllArmorBaseDefinitions.Clear();
            HeavyArmorBaseDefinitions.Clear();
            AllArmorBaseDefinitions.Clear();
            AcquireTargets.Clear();
            LargeBlockSphereDb.Clear();
            SmallBlockSphereDb.Clear();
            AnimationsToProcess.Clear();
            _subTypeIdToWeaponDefs.Clear();
            WeaponDefinitions.Clear();
            SlimsSortedList.Clear();
            _destroyedSlims.Clear();
            _destroyedSlimsClient.Clear();
            _slimHealthClient.Clear();
            _slimsSet.Clear();
            _turretDefinitions.Clear();
            _tmpNearByBlocks.Clear();

            foreach (var av in Av.AvShots)
            {
                av.GlowSteps.Clear();
                Av.AvShotPool.Return(av);
            }
            Av.AvShotPool.Clean();
            Av.AvBarrels1.Clear();
            Av.AvBarrels2.Clear();
            Av.AvShots.Clear();
            Av.HitSounds.Clear();

            foreach (var errorpkt in ClientSideErrorPkt)
            {
                errorpkt.Packet.CleanUp();
            }
            ClientSideErrorPkt.Clear();

            GridEffectPool.Clean();
            GridEffectsPool.Clean();
            BlockTypePool.Clean();
            ConcurrentListPool.Clean();

            TargetInfoPool.Clean();
            PacketObjPool.Clean();

            InventoryMoveRequestPool.Clean();
            WeaponCoreBlockDefs.Clear();
            VanillaIds.Clear();
            VanillaCoreIds.Clear();
            WeaponCoreFixedBlockDefs.Clear();
            WeaponCoreTurretBlockDefs.Clear();
            VoxelCaches.Clear();
            ArmorCubes.Clear();

            foreach (var p in Projectiles.ProjectilePool)
            {
                p.Info?.AvShot?.AmmoEffect?.Stop();
            }

            Projectiles.ShrapnelToSpawn.Clear();
            Projectiles.ShrapnelPool.Clean();
            Projectiles.FragmentPool.Clean();
            Projectiles.ActiveProjetiles.Clear();
            Projectiles.ProjectilePool.Clear();
            Projectiles.HitEntityPool.Clean();
            Projectiles.VirtInfoPool.Clean();

            DbsToUpdate.Clear();
            GridTargetingAIs.Clear();

            DsUtil          = null;
            DsUtil2         = null;
            SlimsSortedList = null;
            Settings        = null;
            StallReporter   = null;
            TerminalMon     = null;
            Physics         = null;
            Camera          = null;
            Projectiles     = null;
            TrackingAi      = null;
            UiInput         = null;
            TargetUi        = null;
            Placer          = null;
            TargetGps       = null;
            SApi.Unload();
            SApi                = null;
            Api                 = null;
            ApiServer           = null;
            Reporter            = null;
            WeaponDefinitions   = null;
            AnimationsToProcess = null;
            ProjectileTree.Clear();
            ProjectileTree     = null;
            Av                 = null;
            HudUi              = null;
            AllDefinitions     = null;
            SoundDefinitions   = null;
            ActiveCockPit      = null;
            ActiveControlBlock = null;
            ControlledEntity   = null;
            TmpStorage         = null;
        }
예제 #5
0
        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}"); }
        }
예제 #6
0
        internal void AmmoPull()
        {
            var cachedInv = new Dictionary <MyDefinitionId, Dictionary <MyInventory, MyFixedPoint> >();

            Weapon weapon;

            while (WeaponAmmoPullQueue.TryDequeue(out weapon))
            {
                using (weapon.Comp.Ai?.MyGrid.Pin())
                    using (weapon.Comp.MyCube.Pin())
                    {
                        if (weapon.Comp.MyCube.MarkedForClose || weapon.Comp.Ai == null || weapon.Comp.Ai.MyGrid.MarkedForClose || !weapon.Comp.InventoryInited || weapon.Comp.Platform.State != MyWeaponPlatform.PlatformState.Ready || weapon.Comp.MyCube == null)
                        {
                            continue;
                        }
                        var   def = weapon.ActiveAmmoDef.AmmoDefinitionId;
                        float itemMass;
                        float itemVolume;

                        MyInventory.GetItemVolumeAndMass(def, out itemMass, out itemVolume);

                        var fullAmount      = 0.75f * weapon.System.MaxAmmoVolume;
                        var weaponInventory = weapon.Comp.BlockInventory;
                        var magsNeeded      = (int)((fullAmount - weapon.CurrentAmmoVolume) / itemVolume);

                        if (magsNeeded == 0 && weapon.System.MaxAmmoVolume > itemVolume)
                        {
                            magsNeeded = 1;
                        }

                        var magsAdded = 0;
                        lock (weapon.Comp.Ai.AmmoInventories[def])
                        {
                            List <MyTuple <MyInventory, int> > inventories = new List <MyTuple <MyInventory, int> >();

                            if (!cachedInv.ContainsKey(def))
                            {
                                cachedInv[def] = weapon.Comp.Ai.AmmoInventories[def].ToDictionary(kvp => kvp.Key, kvp => kvp.Value, new InventoryCompare());
                            }

                            foreach (var currentInventory in weapon.Comp.Ai.AmmoInventories[def])
                            {
                                var inventory     = currentInventory.Key;
                                var magsAvailable = (int)cachedInv[def][inventory];

                                if (((IMyInventory)inventory).CanTransferItemTo(weaponInventory, def))
                                {
                                    if (magsAvailable >= magsNeeded)
                                    {
                                        inventories.Add(new MyTuple <MyInventory, int> {
                                            Item1 = inventory, Item2 = magsNeeded
                                        });
                                        magsAdded += magsNeeded;
                                        magsNeeded = 0;
                                    }
                                    else
                                    {
                                        inventories.Add(new MyTuple <MyInventory, int> {
                                            Item1 = inventory, Item2 = magsAvailable
                                        });
                                        magsNeeded -= magsAvailable;
                                        magsAdded  += magsAvailable;
                                    }

                                    cachedInv[def][inventory] -= magsAdded;
                                }
                            }
                            weapon.CurrentAmmoVolume += magsAdded * itemVolume;

                            if (inventories.Count > 0)
                            {
                                AmmoToPullQueue.Enqueue(new MyTuple <Weapon, MyTuple <MyInventory, int>[]> {
                                    Item1 = weapon, Item2 = inventories.ToArray()
                                });
                            }

                            weapon.Comp.Session.AmmoPulls++;
                        }
                    }
            }
            cachedInv.Clear();
        }
예제 #7
0
        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);
                }
            }
        }