public static MyFixedPoint ConveyorSystemItemAmount(IMyConveyorEndpointBlock start, MyInventory destinationInventory, long playerId, MyDefinitionId itemId)
        {
            MyFixedPoint amount = 0;

            using (var invertedConductivity = new MyConveyorLine.InvertedConductivity())
            {
                SetTraversalPlayerId(playerId);
                SetTraversalInventoryItemDefinitionId(itemId);

                PrepareTraversal(start.ConveyorEndpoint, null, IsAccessAllowedPredicate, NeedsLargeTube(itemId) ? IsConveyorLargePredicate : null);
                foreach (var conveyorEndpoint in MyGridConveyorSystem.Pathfinding)
                {
                    MyCubeBlock owner = (conveyorEndpoint.CubeBlock != null && conveyorEndpoint.CubeBlock.HasInventory) ? conveyorEndpoint.CubeBlock : null;
                    if (owner == null)
                    {
                        continue;
                    }

                    for (int i = 0; i < owner.InventoryCount; ++i)
                    {
                        var inventory = owner.GetInventory(i) as MyInventory;
                        System.Diagnostics.Debug.Assert(inventory != null, "Null or other inventory type!");

                        if ((inventory.GetFlags() & MyInventoryFlags.CanSend) == 0)
                        {
                            continue;
                        }

                        if (inventory == destinationInventory)
                        {
                            continue;
                        }

                        amount += inventory.GetItemAmount(itemId);
                    }
                }
            }
            return(amount);
        }
Пример #2
0
        private ConveyorEndpointMapping ComputeMappingForBlock(IMyConveyorEndpointBlock processedBlock)
        {
            ConveyorEndpointMapping endpointMap = new ConveyorEndpointMapping();

            // Process pull mapping
            PullInformation pullInformation = processedBlock.GetPullInformation();
            if (pullInformation != null)
            {
                endpointMap.pullElements = new List<IMyConveyorEndpointBlock>();

                lock (Pathfinding)
                {
                    SetTraversalPlayerId(pullInformation.OwnerID);

                    // Pulling one specific item?
                    if (pullInformation.ItemDefinition != default(MyDefinitionId))
                    {
                        SetTraversalInventoryItemDefinitionId(pullInformation.ItemDefinition);

                        using (var invertedConductivity = new MyConveyorLine.InvertedConductivity())
                        {
                            PrepareTraversal(processedBlock.ConveyorEndpoint, null, IsAccessAllowedPredicate, NeedsLargeTube(pullInformation.ItemDefinition) ? IsConveyorLargePredicate : null);
                            foreach (var conveyorEndpoint in Pathfinding)
                            {
                                // Ignore endpoints without a block
                                if (conveyorEndpoint.CubeBlock == null) continue;

                                // Ignore blocks without inventory
                                if (!conveyorEndpoint.CubeBlock.HasInventory) continue;

                                // Ignore blocks that do not implement IMyConveyorEndpointBlock interface
                                IMyConveyorEndpointBlock endpointBlock = conveyorEndpoint.CubeBlock as IMyConveyorEndpointBlock;
                                if (endpointBlock == null) continue;

                                // Iterate inventories to make sure we can take the items
                                bool isInventoryAvailable = false;
                                for (int i = 0; i < conveyorEndpoint.CubeBlock.InventoryCount; ++i)
                                {
                                    var inventory = conveyorEndpoint.CubeBlock.GetInventory(i) as MyInventory;
                                    System.Diagnostics.Debug.Assert(inventory != null, "Null or other inventory type!");

                                    if ((inventory.GetFlags() & MyInventoryFlags.CanSend) == 0)
                                        continue;

                                    isInventoryAvailable = true;
                                    break;
                                }

                                if (isInventoryAvailable)
                                    endpointMap.pullElements.Add(endpointBlock);
                            }
                        }
                    }

                    else if (pullInformation.Constraint != null)
                    {
                        SetTraversalInventoryItemDefinitionId();
                        using (var invertedConductivity = new MyConveyorLine.InvertedConductivity())
                        {
                            // Once for small tubes
                            PrepareTraversal(processedBlock.ConveyorEndpoint, null, IsAccessAllowedPredicate, IsConveyorSmallPredicate);
                            foreach (var conveyorEndpoint in Pathfinding)
                            {
                                // Ignore originating block
                                if (conveyorEndpoint.CubeBlock == processedBlock as MyCubeBlock) continue;

                                // Ignore endpoints without a block
                                if (conveyorEndpoint.CubeBlock == null) continue;

                                // Ignore blocks without inventory
                                if (!conveyorEndpoint.CubeBlock.HasInventory) continue;

                                // Ignore blocks that do not implement IMyConveyorEndpointBlock interface
                                IMyConveyorEndpointBlock endpointBlock = conveyorEndpoint.CubeBlock as IMyConveyorEndpointBlock;
                                if (endpointBlock == null) continue;

                                // Iterate inventories to make sure we can take the items
                                bool isInventoryAvailable = false;
                                for (int i = 0; i < conveyorEndpoint.CubeBlock.InventoryCount; ++i)
                                {
                                    var inventory = conveyorEndpoint.CubeBlock.GetInventory(i) as MyInventory;
                                    System.Diagnostics.Debug.Assert(inventory != null, "Null or other inventory type!");

                                    if ((inventory.GetFlags() & MyInventoryFlags.CanSend) == 0)
                                        continue;

                                    isInventoryAvailable = true;
                                    break;
                                }

                                if (isInventoryAvailable)
                                    endpointMap.pullElements.Add(endpointBlock);
                            }

                            // Once for large tubes
                            PrepareTraversal(processedBlock.ConveyorEndpoint, null, IsAccessAllowedPredicate, null);
                            foreach (var conveyorEndpoint in Pathfinding)
                            {
                                // Ignore originating block
                                if (conveyorEndpoint.CubeBlock == processedBlock as MyCubeBlock) continue;

                                // Ignore endpoints without a block
                                if (conveyorEndpoint.CubeBlock == null) continue;

                                // Ignore blocks without inventory
                                if (!conveyorEndpoint.CubeBlock.HasInventory) continue;

                                // Ignore blocks that do not implement IMyConveyorEndpointBlock interface
                                IMyConveyorEndpointBlock endpointBlock = conveyorEndpoint.CubeBlock as IMyConveyorEndpointBlock;
                                if (endpointBlock == null) continue;

                                // Iterate inventories to make sure we can take the items
                                bool isInventoryAvailable = false;
                                for (int i = 0; i < conveyorEndpoint.CubeBlock.InventoryCount; ++i)
                                {
                                    var inventory = conveyorEndpoint.CubeBlock.GetInventory(i) as MyInventory;
                                    System.Diagnostics.Debug.Assert(inventory != null, "Null or other inventory type!");

                                    if ((inventory.GetFlags() & MyInventoryFlags.CanSend) == 0)
                                        continue;

                                    isInventoryAvailable = true;
                                    break;
                                }

                                if (isInventoryAvailable)
                                {
                                    if (!endpointMap.pullElements.Contains(endpointBlock))
                                        endpointMap.pullElements.Add(endpointBlock);
                                }
                            }
                        }
                    }
                }
            }

            // Process push mapping
            PullInformation pushInformation = processedBlock.GetPushInformation();
            if (pushInformation != null)
            {
                endpointMap.pushElements = new List<IMyConveyorEndpointBlock>();

                lock (Pathfinding)
                {
                    SetTraversalPlayerId(pushInformation.OwnerID);

                    HashSet<MyDefinitionId> definitions = new HashSet<MyDefinitionId>();
                    if (pushInformation.ItemDefinition != default(MyDefinitionId))
                    {
                        definitions.Add(pushInformation.ItemDefinition);
                    }

                    if (pushInformation.Constraint != null)
                    {
                        foreach (MyDefinitionId definition in pushInformation.Constraint.ConstrainedIds)
                            definitions.Add(definition);

                        foreach (MyObjectBuilderType constrainedType in pushInformation.Constraint.ConstrainedTypes)
                        {
                            MyDefinitionManager.Static.TryGetDefinitionsByTypeId(constrainedType, definitions);
                        }
                    }

                    // Empty constraint, no need to check, anything that can take items is okay, push requests will re-test anyway
                    if (definitions.Count == 0 && (pushInformation.Constraint == null || pushInformation.Constraint.Description == "Empty constraint"))
                    {
                        SetTraversalInventoryItemDefinitionId();
                        PrepareTraversal(processedBlock.ConveyorEndpoint, null, IsAccessAllowedPredicate);

                        foreach (var conveyorEndpoint in MyGridConveyorSystem.Pathfinding)
                        {
                            // Ignore originating block
                            if (conveyorEndpoint.CubeBlock == processedBlock as MyCubeBlock) continue;

                            // Ignore endpoints without a block
                            if (conveyorEndpoint.CubeBlock == null) continue;

                            // Ignore blocks without inventory
                            if (!conveyorEndpoint.CubeBlock.HasInventory) continue;

                            // Ignore blocks that do not implement IMyConveyorEndpointBlock interface
                            IMyConveyorEndpointBlock endpointBlock = conveyorEndpoint.CubeBlock as IMyConveyorEndpointBlock;
                            if (endpointBlock == null) continue;

                            MyCubeBlock owner = conveyorEndpoint.CubeBlock;

                            // Iterate inventories to make sure they can take the items
                            bool isInventoryAvailable = false;
                            for (int i = 0; i < owner.InventoryCount; ++i)
                            {
                                var inventory = owner.GetInventory(i) as MyInventory;
                                System.Diagnostics.Debug.Assert(inventory != null, "Null or other inventory type!");

                                if ((inventory.GetFlags() & MyInventoryFlags.CanReceive) == 0)
                                    continue;

                                isInventoryAvailable = true;
                                break;
                            }

                            if (isInventoryAvailable && !endpointMap.pushElements.Contains(endpointBlock))
                                endpointMap.pushElements.Add(endpointBlock);
                        }
                    }
                    else
                    {
                        // Iterate through all the constrained item definitions
                        foreach (MyDefinitionId definitionId in definitions)
                        {
                            SetTraversalInventoryItemDefinitionId(definitionId);

                            if (NeedsLargeTube(definitionId))
                            {
                                PrepareTraversal(processedBlock.ConveyorEndpoint, null, IsAccessAllowedPredicate, IsConveyorLargePredicate);
                            }
                            else
                            {
                                PrepareTraversal(processedBlock.ConveyorEndpoint, null, IsAccessAllowedPredicate);
                            }

                            foreach (var conveyorEndpoint in MyGridConveyorSystem.Pathfinding)
                            {
                                // Ignore originating block
                                if (conveyorEndpoint.CubeBlock == processedBlock as MyCubeBlock) continue;

                                // Ignore endpoints without a block
                                if (conveyorEndpoint.CubeBlock == null) continue;

                                // Ignore blocks without inventory
                                if (!conveyorEndpoint.CubeBlock.HasInventory) continue;

                                // Ignore blocks that do not implement IMyConveyorEndpointBlock interface
                                IMyConveyorEndpointBlock endpointBlock = conveyorEndpoint.CubeBlock as IMyConveyorEndpointBlock;
                                if (endpointBlock == null) continue;

                                MyCubeBlock owner = conveyorEndpoint.CubeBlock;

                                // Iterate inventories to make sure they can take the items
                                bool isInventoryAvailable = false;
                                for (int i = 0; i < owner.InventoryCount; ++i)
                                {
                                    var inventory = owner.GetInventory(i) as MyInventory;
                                    System.Diagnostics.Debug.Assert(inventory != null, "Null or other inventory type!");

                                    if ((inventory.GetFlags() & MyInventoryFlags.CanReceive) == 0)
                                        continue;

                                    // Make sure target inventory can take this item
                                    if (!inventory.CheckConstraint(definitionId))
                                        continue;

                                    isInventoryAvailable = true;
                                    break;
                                }

                                if (isInventoryAvailable && !endpointMap.pushElements.Contains(endpointBlock))
                                    endpointMap.pushElements.Add(endpointBlock);
                            }
                        }
                    }
                }
            }

            return endpointMap;
        }
Пример #3
0
        public static MyFixedPoint ConveyorSystemItemAmount(IMyConveyorEndpointBlock start, MyInventory destinationInventory, long playerId, MyDefinitionId itemId)
        {
            MyFixedPoint amount = 0;
            using (var invertedConductivity = new MyConveyorLine.InvertedConductivity())
            {
                lock (Pathfinding)
                {
                    SetTraversalPlayerId(playerId);
                    SetTraversalInventoryItemDefinitionId(itemId);

                    PrepareTraversal(start.ConveyorEndpoint, null, IsAccessAllowedPredicate, NeedsLargeTube(itemId) ? IsConveyorLargePredicate : null);
                    foreach (var conveyorEndpoint in MyGridConveyorSystem.Pathfinding)
                    {
                        MyCubeBlock owner = (conveyorEndpoint.CubeBlock != null && conveyorEndpoint.CubeBlock.HasInventory) ? conveyorEndpoint.CubeBlock : null;
                        if (owner == null) continue;

                        for (int i = 0; i < owner.InventoryCount; ++i)
                        {
                            var inventory = owner.GetInventory(i) as MyInventory;
                            System.Diagnostics.Debug.Assert(inventory != null, "Null or other inventory type!");

                            if ((inventory.GetFlags() & MyInventoryFlags.CanSend) == 0)
                                continue;

                            if (inventory == destinationInventory)
                                continue;

                            amount += inventory.GetItemAmount(itemId);
                        }
                    }
                }
            }
            return amount;
        }
Пример #4
0
        public static void ItemPullRequest(IMyConveyorEndpointBlock start, MyInventory destinationInventory, long playerId, MyDefinitionId itemId, MyFixedPoint? amount = null)
        {
            using (var invertedConductivity = new MyConveyorLine.InvertedConductivity())
            {
                if (amount.HasValue)
                    Debug.Assert(itemId.TypeId == typeof(MyObjectBuilder_Ore) ||
                                 itemId.TypeId == typeof(MyObjectBuilder_Ingot) ||
                                 MyFixedPoint.Floor(amount.Value) == amount.Value);

                SetTraversalPlayerId(playerId);
                SetTraversalInventoryItemDefinitionId(itemId);

                PrepareTraversal(start.ConveyorEndpoint, null, IsAccessAllowedPredicate, NeedsLargeTube(itemId) ? IsConveyorLargePredicate : null);
                foreach (var conveyorEndpoint in MyGridConveyorSystem.Pathfinding)
                {
                    IMyInventoryOwner owner = conveyorEndpoint.CubeBlock as IMyInventoryOwner;
                    if (owner == null) continue;

                    for (int i = 0; i < owner.InventoryCount; ++i)
                    {
                        var inventory = owner.GetInventory(i);
                        if ((inventory.GetFlags() & MyInventoryFlags.CanSend) == 0)
                            continue;

                        if (inventory == destinationInventory)
                            continue;

                        if (amount.HasValue)
                        {
                            var availableAmount = inventory.GetItemAmount(itemId);
                            availableAmount = amount.HasValue ? MyFixedPoint.Min(availableAmount, amount.Value) : availableAmount;
                            if (availableAmount == 0)
                                continue;

                            MyInventory.Transfer(inventory, destinationInventory, itemId, MyItemFlags.None, availableAmount);

                            amount -= availableAmount;
                            if (amount.Value == 0)
                                return;
                        }
                        else
                        {
                            MyInventory.Transfer(inventory, destinationInventory, itemId, MyItemFlags.None);
                        }
                    }
                }
            }
        }
Пример #5
0
        private static void ItemPullAllInternal(MyInventory destinationInventory, PullRequestItemSet requestedTypeIds, bool onlySmall)
        {
            SetTraversalInventoryItemDefinitionId();
            Debug.Assert(m_tmpPullRequests.Count == 0, "m_tmpPullRequests is not empty!");
            using (var invertedConductivity = new MyConveyorLine.InvertedConductivity())
            {
                foreach (var conveyorEndpoint in MyGridConveyorSystem.Pathfinding)
                {
                    IMyInventoryOwner owner = conveyorEndpoint.CubeBlock as IMyInventoryOwner;
                    if (owner == null) continue;

                    for (int i = 0; i < owner.InventoryCount; ++i)
                    {
                        var inventory = owner.GetInventory(i);
                        if ((inventory.GetFlags() & MyInventoryFlags.CanSend) == 0)
                            continue;

                        if (inventory == destinationInventory)
                            continue;

                        m_tmpInventoryItems.Clear();
                        foreach (var item in inventory.GetItems())
                        {
                            m_tmpInventoryItems.Add(item);
                        }

                        foreach (var item in m_tmpInventoryItems)
                        {
                            if (destinationInventory.VolumeFillFactor >= 1.0f)
                            {
                                m_tmpInventoryItems.Clear();
                                return;
                            }

                            var itemId = item.Content.GetId();

                            if (requestedTypeIds != null && !requestedTypeIds.Contains(itemId))
                                continue;

                            if (onlySmall && NeedsLargeTube(itemId))
                                continue;

                            var transferedAmount = item.Amount;

                            var oxygenBottle = item.Content as Sandbox.Common.ObjectBuilders.Definitions.MyObjectBuilder_OxygenContainerObject;
                            if (oxygenBottle != null && oxygenBottle.OxygenLevel == 1f)
                                continue;

                            if (!MySession.Static.CreativeMode)
                            {
                                var fittingAmount = destinationInventory.ComputeAmountThatFits(item.Content.GetId());
                                if (item.Content.TypeId != typeof(MyObjectBuilder_Ore) &&
                                    item.Content.TypeId != typeof(MyObjectBuilder_Ingot))
                                {
                                    fittingAmount = MyFixedPoint.Floor(fittingAmount);
                                }
                                transferedAmount = MyFixedPoint.Min(fittingAmount, transferedAmount);
                            }
                            if (transferedAmount == 0)
                                continue;

                            // SK: this is mental
                            m_tmpPullRequests.Add(new MyTuple<IMyConveyorEndpointBlock, MyPhysicalInventoryItem>(m_startingEndpoint.CubeBlock as IMyConveyorEndpointBlock, item));
                            //MyInventory.Transfer(inventory, destinationInventory, item.Content.GetId(), MyItemFlags.None, transferedAmount);
                        }
                    }
                }
            }

            foreach (var tuple in m_tmpPullRequests)
            {
                if (destinationInventory.VolumeFillFactor >= 1.0f)
                {
                    m_tmpPullRequests.Clear();
                    return;
                }

                var start = tuple.Item1;
                var item = tuple.Item2;

                var transferedAmount = item.Amount;
                var fittingAmount = destinationInventory.ComputeAmountThatFits(item.Content.GetId());
                if (item.Content.TypeId != typeof(MyObjectBuilder_Ore) &&
                    item.Content.TypeId != typeof(MyObjectBuilder_Ingot))
                {
                    fittingAmount = MyFixedPoint.Floor(fittingAmount);
                }
                transferedAmount = MyFixedPoint.Min(fittingAmount, transferedAmount);

                if (transferedAmount == 0)
                    continue;

                var itemId = item.Content.GetId();

                SetTraversalInventoryItemDefinitionId(itemId);
                ItemPullRequest(start, destinationInventory, m_playerIdForAccessiblePredicate, itemId, transferedAmount);
            }

            m_tmpPullRequests.Clear();
        }
        public static MyFixedPoint ItemPullRequest(IMyConveyorEndpointBlock start, MyInventory destinationInventory, long playerId, MyDefinitionId itemId, MyFixedPoint? amount = null, bool remove = false)
        {
            MyFixedPoint transferred = 0;
            using (var invertedConductivity = new MyConveyorLine.InvertedConductivity())
            {
                /*if (amount.HasValue)
                    Debug.Assert(itemId.TypeId == typeof(MyObjectBuilder_Ore) ||
                                 itemId.TypeId == typeof(MyObjectBuilder_Ingot) ||
                                 MyFixedPoint.Floor(amount.Value) == amount.Value);*/

                SetTraversalPlayerId(playerId);
                SetTraversalInventoryItemDefinitionId(itemId);

                PrepareTraversal(start.ConveyorEndpoint, null, IsAccessAllowedPredicate, NeedsLargeTube(itemId) ? IsConveyorLargePredicate : null);
                foreach (var conveyorEndpoint in MyGridConveyorSystem.Pathfinding)
                {
                    MyCubeBlock owner = (conveyorEndpoint.CubeBlock != null && conveyorEndpoint.CubeBlock.HasInventory) ? conveyorEndpoint.CubeBlock : null;
                    if (owner == null) continue;

                    for (int i = 0; i < owner.InventoryCount; ++i)
                    {
                        var inventory = owner.GetInventory(i) as MyInventory;
                        System.Diagnostics.Debug.Assert(inventory != null, "Null or other inventory type!");

                        if ((inventory.GetFlags() & MyInventoryFlags.CanSend) == 0)
                            continue;

                        if (inventory == destinationInventory)
                            continue;
                        
                        var availableAmount = inventory.GetItemAmount(itemId);
                        if (amount.HasValue)
                        {
                            availableAmount = amount.HasValue ? MyFixedPoint.Min(availableAmount, amount.Value) : availableAmount;
                            if (availableAmount == 0)
                                continue;

                            if (remove)
                            {
                                transferred += inventory.RemoveItemsOfType(availableAmount, itemId);
                            }
                            else
                            {
                                transferred += MyInventory.Transfer(inventory, destinationInventory, itemId, MyItemFlags.None, availableAmount);
                            }
                            

                            amount -= availableAmount;
                            if (amount.Value == 0)
                                return transferred;
                        }
                        else
                        {
                            if (remove)
                            {
                                transferred += inventory.RemoveItemsOfType(availableAmount, itemId);
                            }
                            else
                            {
                                transferred += MyInventory.Transfer(inventory, destinationInventory, itemId, MyItemFlags.None, availableAmount);
                            }
                        }
                    }
                }
            }
            return transferred;
        }
        public static MyFixedPoint ItemPullRequest(IMyConveyorEndpointBlock start, MyInventory destinationInventory, long playerId, MyDefinitionId itemId, MyFixedPoint?amount = null, bool remove = false)
        {
            MyFixedPoint transferred = 0;

            using (var invertedConductivity = new MyConveyorLine.InvertedConductivity())
            {
                /*if (amount.HasValue)
                 *  Debug.Assert(itemId.TypeId == typeof(MyObjectBuilder_Ore) ||
                 *               itemId.TypeId == typeof(MyObjectBuilder_Ingot) ||
                 *               MyFixedPoint.Floor(amount.Value) == amount.Value);*/

                SetTraversalPlayerId(playerId);
                SetTraversalInventoryItemDefinitionId(itemId);

                PrepareTraversal(start.ConveyorEndpoint, null, IsAccessAllowedPredicate, NeedsLargeTube(itemId) ? IsConveyorLargePredicate : null);
                foreach (var conveyorEndpoint in MyGridConveyorSystem.Pathfinding)
                {
                    MyCubeBlock owner = (conveyorEndpoint.CubeBlock != null && conveyorEndpoint.CubeBlock.HasInventory) ? conveyorEndpoint.CubeBlock : null;
                    if (owner == null)
                    {
                        continue;
                    }

                    for (int i = 0; i < owner.InventoryCount; ++i)
                    {
                        var inventory = owner.GetInventory(i) as MyInventory;
                        System.Diagnostics.Debug.Assert(inventory != null, "Null or other inventory type!");

                        if ((inventory.GetFlags() & MyInventoryFlags.CanSend) == 0)
                        {
                            continue;
                        }

                        if (inventory == destinationInventory)
                        {
                            continue;
                        }

                        var availableAmount = inventory.GetItemAmount(itemId);
                        if (amount.HasValue)
                        {
                            availableAmount = amount.HasValue ? MyFixedPoint.Min(availableAmount, amount.Value) : availableAmount;
                            if (availableAmount == 0)
                            {
                                continue;
                            }

                            if (remove)
                            {
                                transferred += inventory.RemoveItemsOfType(availableAmount, itemId);
                            }
                            else
                            {
                                transferred += MyInventory.Transfer(inventory, destinationInventory, itemId, MyItemFlags.None, availableAmount);
                            }


                            amount -= availableAmount;
                            if (amount.Value == 0)
                            {
                                return(transferred);
                            }
                        }
                        else
                        {
                            if (remove)
                            {
                                transferred += inventory.RemoveItemsOfType(availableAmount, itemId);
                            }
                            else
                            {
                                transferred += MyInventory.Transfer(inventory, destinationInventory, itemId, MyItemFlags.None, availableAmount);
                            }
                        }
                    }
                }
            }
            return(transferred);
        }
        private static bool ItemPullAllInternal(MyInventory destinationInventory, PullRequestItemSet requestedTypeIds, bool onlySmall)
        {
            bool pullCreated = false;

            SetTraversalInventoryItemDefinitionId();
            Debug.Assert(m_tmpPullRequests.Count == 0, "m_tmpPullRequests is not empty!");
            using (var invertedConductivity = new MyConveyorLine.InvertedConductivity())
            {
                foreach (var conveyorEndpoint in MyGridConveyorSystem.Pathfinding)
                {
                    MyCubeBlock owner = (conveyorEndpoint.CubeBlock != null && conveyorEndpoint.CubeBlock.HasInventory) ? conveyorEndpoint.CubeBlock : null;
                    if (owner == null)
                    {
                        continue;
                    }

                    for (int i = 0; i < owner.InventoryCount; ++i)
                    {
                        var inventory = owner.GetInventory(i) as MyInventory;
                        System.Diagnostics.Debug.Assert(inventory != null, "Null or other inventory type!");

                        if ((inventory.GetFlags() & MyInventoryFlags.CanSend) == 0)
                        {
                            continue;
                        }

                        if (inventory == destinationInventory)
                        {
                            continue;
                        }

                        m_tmpInventoryItems.Clear();
                        foreach (var item in inventory.GetItems())
                        {
                            m_tmpInventoryItems.Add(item);
                        }

                        foreach (var item in m_tmpInventoryItems)
                        {
                            if (destinationInventory.VolumeFillFactor >= 1.0f)
                            {
                                m_tmpInventoryItems.Clear();
                                return(pullCreated);
                            }

                            var itemId = item.Content.GetId();

                            if (requestedTypeIds != null && !requestedTypeIds.Contains(itemId))
                            {
                                continue;
                            }

                            if (onlySmall && NeedsLargeTube(itemId))
                            {
                                continue;
                            }

                            var transferedAmount = item.Amount;

                            var oxygenBottle = item.Content as Sandbox.Common.ObjectBuilders.Definitions.MyObjectBuilder_GasContainerObject;
                            if (oxygenBottle != null && oxygenBottle.GasLevel == 1f)
                            {
                                continue;
                            }

                            if (!MySession.Static.CreativeMode)
                            {
                                var fittingAmount = destinationInventory.ComputeAmountThatFits(item.Content.GetId());
                                if (item.Content.TypeId != typeof(MyObjectBuilder_Ore) &&
                                    item.Content.TypeId != typeof(MyObjectBuilder_Ingot))
                                {
                                    fittingAmount = MyFixedPoint.Floor(fittingAmount);
                                }
                                transferedAmount = MyFixedPoint.Min(fittingAmount, transferedAmount);
                            }
                            if (transferedAmount == 0)
                            {
                                continue;
                            }

                            // SK: this is mental
                            m_tmpPullRequests.Add(new MyTuple <IMyConveyorEndpointBlock, MyPhysicalInventoryItem>(m_startingEndpoint.CubeBlock as IMyConveyorEndpointBlock, item));
                            //MyInventory.Transfer(inventory, destinationInventory, item.Content.GetId(), MyItemFlags.None, transferedAmount);
                        }
                    }
                }
            }

            foreach (var tuple in m_tmpPullRequests)
            {
                if (destinationInventory.VolumeFillFactor >= 1.0f)
                {
                    m_tmpPullRequests.Clear();
                    return(pullCreated);
                }

                var start = tuple.Item1;
                var item  = tuple.Item2;

                var transferedAmount = item.Amount;
                var fittingAmount    = destinationInventory.ComputeAmountThatFits(item.Content.GetId());
                if (item.Content.TypeId != typeof(MyObjectBuilder_Ore) &&
                    item.Content.TypeId != typeof(MyObjectBuilder_Ingot))
                {
                    fittingAmount = MyFixedPoint.Floor(fittingAmount);
                }
                transferedAmount = MyFixedPoint.Min(fittingAmount, transferedAmount);

                if (transferedAmount == 0)
                {
                    continue;
                }

                var itemId = item.Content.GetId();

                SetTraversalInventoryItemDefinitionId(itemId);
                ItemPullRequest(start, destinationInventory, m_playerIdForAccessiblePredicate, itemId, transferedAmount);
                pullCreated = true;
            }

            m_tmpPullRequests.Clear();
            return(pullCreated);
        }
Пример #9
0
        public static void ItemPullRequest(IMyConveyorEndpointBlock start, MyInventory destinationInventory, long playerId, MyDefinitionId itemId, MyFixedPoint?amount = null)
        {
            using (var invertedConductivity = new MyConveyorLine.InvertedConductivity())
            {
                if (amount.HasValue)
                {
                    Debug.Assert(itemId.TypeId == typeof(MyObjectBuilder_Ore) ||
                                 itemId.TypeId == typeof(MyObjectBuilder_Ingot) ||
                                 MyFixedPoint.Floor(amount.Value) == amount.Value);
                }

                SetTraversalPlayerId(playerId);
                SetTraversalInventoryItemDefinitionId(itemId);

                PrepareTraversal(start.ConveyorEndpoint, null, IsAccessAllowedPredicate, NeedsLargeTube(itemId) ? IsConveyorLargePredicate : null);
                foreach (var conveyorEndpoint in MyGridConveyorSystem.Pathfinding)
                {
                    IMyInventoryOwner owner = conveyorEndpoint.CubeBlock as IMyInventoryOwner;
                    if (owner == null)
                    {
                        continue;
                    }

                    for (int i = 0; i < owner.InventoryCount; ++i)
                    {
                        var inventory = owner.GetInventory(i);
                        if ((inventory.GetFlags() & MyInventoryFlags.CanSend) == 0)
                        {
                            continue;
                        }

                        if (inventory == destinationInventory)
                        {
                            continue;
                        }

                        if (amount.HasValue)
                        {
                            var availableAmount = inventory.GetItemAmount(itemId);
                            availableAmount = amount.HasValue ? MyFixedPoint.Min(availableAmount, amount.Value) : availableAmount;
                            if (availableAmount == 0)
                            {
                                continue;
                            }

                            MyInventory.Transfer(inventory, destinationInventory, itemId, MyItemFlags.None, availableAmount);

                            amount -= availableAmount;
                            if (amount.Value == 0)
                            {
                                return;
                            }
                        }
                        else
                        {
                            MyInventory.Transfer(inventory, destinationInventory, itemId, MyItemFlags.None);
                        }
                    }
                }
            }
        }
Пример #10
0
        private ConveyorEndpointMapping ComputeMappingForBlock(IMyConveyorEndpointBlock processedBlock)
        {
            ConveyorEndpointMapping endpointMap = new ConveyorEndpointMapping();

            // Process pull mapping
            PullInformation pullInformation = processedBlock.GetPullInformation();
            if (pullInformation != null)
            {
                endpointMap.pullElements = new List<IMyConveyorEndpointBlock>();

                lock (Pathfinding)
                {
                    SetTraversalPlayerId(pullInformation.OwnerID);

                    // Pulling one specific item?
                    if (pullInformation.ItemDefinition != default(MyDefinitionId))
                    {
                        SetTraversalInventoryItemDefinitionId(pullInformation.ItemDefinition);

                        using (var invertedConductivity = new MyConveyorLine.InvertedConductivity())
                        {
                            PrepareTraversal(processedBlock.ConveyorEndpoint, null, IsAccessAllowedPredicate, NeedsLargeTube(pullInformation.ItemDefinition) ? IsConveyorLargePredicate : null);
                            AddReachableEndpoints(processedBlock, endpointMap.pullElements, MyInventoryFlags.CanSend);
                        }
                    }

                    else if (pullInformation.Constraint != null)
                    {
                        SetTraversalInventoryItemDefinitionId();
                        using (var invertedConductivity = new MyConveyorLine.InvertedConductivity())
                        {
                            // Once for small tubes
                            PrepareTraversal(processedBlock.ConveyorEndpoint, null, IsAccessAllowedPredicate, IsConveyorSmallPredicate);
                            AddReachableEndpoints(processedBlock, endpointMap.pullElements, MyInventoryFlags.CanSend);

                            // Once for large tubes
                            PrepareTraversal(processedBlock.ConveyorEndpoint, null, IsAccessAllowedPredicate, null);
                            AddReachableEndpoints(processedBlock, endpointMap.pullElements, MyInventoryFlags.CanSend);
                        }
                    }
                }
            }

            // Process push mapping
            PullInformation pushInformation = processedBlock.GetPushInformation();
            if (pushInformation != null)
            {
                endpointMap.pushElements = new List<IMyConveyorEndpointBlock>();

                lock (Pathfinding)
                {
                    SetTraversalPlayerId(pushInformation.OwnerID);

                    HashSet<MyDefinitionId> definitions = new HashSet<MyDefinitionId>();
                    if (pushInformation.ItemDefinition != default(MyDefinitionId))
                    {
                        definitions.Add(pushInformation.ItemDefinition);
                    }

                    if (pushInformation.Constraint != null)
                    {
                        foreach (MyDefinitionId definition in pushInformation.Constraint.ConstrainedIds)
                            definitions.Add(definition);

                        foreach (MyObjectBuilderType constrainedType in pushInformation.Constraint.ConstrainedTypes)
                        {
                            MyDefinitionManager.Static.TryGetDefinitionsByTypeId(constrainedType, definitions);
                        }
                    }

                    // Empty constraint, no need to check, anything that can take items is okay, push requests will re-test anyway
                    if (definitions.Count == 0 && (pushInformation.Constraint == null || pushInformation.Constraint.Description == "Empty constraint"))
                    {
                        SetTraversalInventoryItemDefinitionId();
                        PrepareTraversal(processedBlock.ConveyorEndpoint, null, IsAccessAllowedPredicate);
                        AddReachableEndpoints(processedBlock, endpointMap.pushElements, MyInventoryFlags.CanReceive);
                    }
                    else
                    {
                        // Iterate through all the constrained item definitions
                        foreach (MyDefinitionId definitionId in definitions)
                        {
                            SetTraversalInventoryItemDefinitionId(definitionId);

                            if (NeedsLargeTube(definitionId))
                                PrepareTraversal(processedBlock.ConveyorEndpoint, null, IsAccessAllowedPredicate, IsConveyorLargePredicate);
                            else
                                PrepareTraversal(processedBlock.ConveyorEndpoint, null, IsAccessAllowedPredicate);

                            AddReachableEndpoints(processedBlock, endpointMap.pushElements, MyInventoryFlags.CanReceive, definitionId);
                        }
                    }
                }
            }

            return endpointMap;
        }