public void Init(MyDefinitionId typeId, IMyConveyorEndpointBlock block)
			{
				FirstEndpoint = block.ConveyorEndpoint;
				ClearData();

				Add(typeId, block);
			}
예제 #2
0
 public static void PullAllRequest(IMyConveyorEndpointBlock start, MyInventory destinationInventory, long playerId, MyObjectBuilderType?typeId = null)
 {
     SetTraversalPlayerId(playerId);
     m_tmpRequestedItemSet.Set(typeId);
     ItemPullAll(start, destinationInventory);
     m_tmpRequestedItemSet.Clear();
 }
예제 #3
0
 public static void PullAllRequest(IMyConveyorEndpointBlock start, MyInventory destinationInventory, long playerId, bool all)
 {
     SetTraversalPlayerId(playerId);
     m_tmpRequestedItemSet.Set(all);
     ItemPullAll(start, destinationInventory);
     m_tmpRequestedItemSet.Clear();
 }
        public void RemoveConveyorBlock(IMyConveyorEndpointBlock block)
        {
            if (block is MyShipConnector)
            {
                m_connectors.Remove(block as MyShipConnector);
            }

            if (IsClosing)
            {
                return;
            }

            if (OnBeforeRemoveEndpointBlock != null)
            {
                OnBeforeRemoveEndpointBlock(block);
            }

            for (int i = 0; i < block.ConveyorEndpoint.GetLineCount(); ++i)
            {
                MyConveyorLine line = block.ConveyorEndpoint.GetConveyorLine(i);
                line.DisconnectEndpoint(block.ConveyorEndpoint);

                if (line.IsDegenerate)
                {
                    m_lines.Remove(line);
                }
            }
        }
예제 #5
0
 private static void ItemPullAll(IMyConveyorEndpointBlock start, MyInventory destinationInventory)
 {
     // First, search through small conveyor tubes and request only small items
     PrepareTraversal(start.ConveyorEndpoint, null, IsAccessAllowedPredicate);
     ItemPullAllInternal(destinationInventory, m_tmpRequestedItemSet, true);
     // Then, search again through all tubes and request all items
     PrepareTraversal(start.ConveyorEndpoint, null, IsAccessAllowedPredicate, IsConveyorLargePredicate);
     ItemPullAllInternal(destinationInventory, m_tmpRequestedItemSet, false);
 }
        public static bool PullAllRequest(IMyConveyorEndpointBlock start, MyInventory destinationInventory, long playerId, MyInventoryConstraint requestedTypeIds)
        {
            SetTraversalPlayerId(playerId);
            m_tmpRequestedItemSet.Set(requestedTypeIds);
            bool ret = ItemPullAll(start, destinationInventory);

            m_tmpRequestedItemSet.Clear();
            return(ret);
        }
			public MyPhysicalDistributionGroup(MyDefinitionId typeId, IMyConveyorEndpointBlock block)
			{
			    SinksByPriority = null; SourcesByPriority = null; SinkSourcePairs = null; FirstEndpoint = null;
				SinkDataByPriority = null; SourceDataByPriority = null; StockpilingStorage = null; OtherStorage = null;
				InputOutputData = new MyTuple<MySinkGroupData, MySourceGroupData>();
				MaxAvailableResources = 0f; ResourceState = MyResourceStateEnum.NoPower;
				AllocateData();

				Init(typeId, block);
			}
        public void AddConveyorBlock(IMyConveyorEndpointBlock endpointBlock)
        {
            if (endpointBlock is MyShipConnector)
            {
                m_connectors.Add(endpointBlock as MyShipConnector);
            }

            m_tmpConveyorPositionList.Clear();
            var endpoint = endpointBlock.ConveyorEndpoint;

            for (int i = 0; i < endpoint.GetLineCount(); ++i)
            {
                var position = endpoint.GetPosition(i);
                var line     = endpoint.GetConveyorLine(i);

                if (m_deserializedLines != null && m_deserializedLines.Contains(line))
                {
                    continue;
                }

                var otherBlock = m_grid.GetCubeBlock(position.NeighbourGridPosition);
                if (otherBlock == null)
                {
                    m_lines.Add(line);
                    continue;
                }

                var otherEndpointBlock = otherBlock.FatBlock as IMyConveyorEndpointBlock;
                var otherSegmentBlock  = otherBlock.FatBlock as IMyConveyorSegmentBlock;

                if (otherSegmentBlock != null)
                {
                    if (!TryMergeEndpointSegment(endpointBlock, otherSegmentBlock, position))
                    {
                        m_lines.Add(line);
                    }
                }
                else if (otherEndpointBlock != null)
                {
                    if (!TryMergeEndpointEndpoint(endpointBlock, otherEndpointBlock, position, position.GetConnectingPosition()))
                    {
                        m_lines.Add(line);
                    }
                }
                else
                {
                    m_lines.Add(line);
                }
            }
            m_tmpConveyorPositionList.Clear();
        }
        public static void PushAnyRequest(IMyConveyorEndpointBlock start, MyInventory srcInventory, long playerId)
        {
            if (srcInventory.Empty())
            {
                return;
            }

            // try all items and stop on first successfull
            foreach (var item in srcInventory.GetItems())
            {
                if (ItemPushRequest(start, srcInventory, playerId, item))
                {
                    return;
                }
            }
        }
        public virtual void OnBlockIntegrityChanged(MySlimBlock block)
        {
            IMyConveyorEndpointBlock conveyorEndpointBlock = block.FatBlock as IMyConveyorEndpointBlock;

            if (conveyorEndpointBlock != null)
            {
                ConveyorSystem.FlagForRecomputation();
            }

            IMyConveyorSegmentBlock conveyorSegmentBlock = block.FatBlock as IMyConveyorSegmentBlock;

            if (conveyorSegmentBlock != null)
            {
                ConveyorSystem.FlagForRecomputation();
            }
        }
        public static void AppendReachableEndpoints(IMyConveyorEndpoint source, long playerId, List <IMyConveyorEndpoint> reachable, MyPhysicalInventoryItem item, Predicate <IMyConveyorEndpoint> endpointFilter = null)
        {
            IMyConveyorEndpointBlock block = source.CubeBlock as IMyConveyorEndpointBlock;

            Debug.Assert(block != null);
            if (block == null)
            {
                return;
            }

            SetTraversalPlayerId(playerId);
            var itemId = item.Content.GetId();

            SetTraversalInventoryItemDefinitionId(itemId);

            m_pathfinding.FindReachable(block.ConveyorEndpoint, reachable, endpointFilter, IsAccessAllowedPredicate, NeedsLargeTube(itemId) ? IsConveyorLargePredicate : null);
        }
        public virtual void OnBlockRemoved(MySlimBlock block)
        {
            IMyConveyorEndpointBlock conveyorEndpointBlock = block.FatBlock as IMyConveyorEndpointBlock;

            if (conveyorEndpointBlock != null)
            {
                ConveyorSystem.FlagForRecomputation();
            }

            IMyConveyorSegmentBlock conveyorSegmentBlock = block.FatBlock as IMyConveyorSegmentBlock;

            if (conveyorSegmentBlock != null)
            {
                ConveyorSystem.FlagForRecomputation();
            }

            if (ShipSoundComponent != null && block.FatBlock as MyThrust != null)
            {
                ShipSoundComponent.ShipHasChanged = true;
            }
        }
        private bool TryMergeEndpointEndpoint(IMyConveyorEndpointBlock endpointBlock1, IMyConveyorEndpointBlock endpointBlock2, ConveyorLinePosition pos1, ConveyorLinePosition pos2)
        {
            MyConveyorLine line1 = endpointBlock1.ConveyorEndpoint.GetConveyorLine(pos1);

            if (line1 == null)
            {
                return(false);
            }

            MyConveyorLine line2 = endpointBlock2.ConveyorEndpoint.GetConveyorLine(pos2);

            if (line2 == null)
            {
                return(false);
            }

            if (line1.Type != line2.Type)
            {
                return(false);
            }

            if (line1.GetEndpoint(1) == null)
            {
                line1.Reverse();
            }
            Debug.Assert(line1.GetEndpoint(1) != null);
            if (line2.GetEndpoint(0) == null)
            {
                line2.Reverse();
            }
            Debug.Assert(line2.GetEndpoint(0) != null);

            line2.Merge(line1);
            endpointBlock1.ConveyorEndpoint.SetConveyorLine(pos1, line2);
            line1.RecalculateConductivity();
            line2.RecalculateConductivity();

            return(true);
        }
        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);
        }
        /// <summary>
        /// Tries to merge the conveyor lines of a conveyor block and segment block.
        /// Also changes the reference in the endpoint block to the correct line.
        /// </summary>
        private bool TryMergeEndpointSegment(IMyConveyorEndpointBlock endpoint, IMyConveyorSegmentBlock segmentBlock, ConveyorLinePosition endpointPosition)
        {
            MyConveyorLine endpointLine = endpoint.ConveyorEndpoint.GetConveyorLine(endpointPosition);

            if (endpointLine == null)
            {
                return(false);
            }

            // The conveyor segment cannot merge with the given endpoint
            if (!segmentBlock.ConveyorSegment.CanConnectTo(endpointPosition.GetConnectingPosition(), endpointLine.Type))
            {
                return(false);
            }

            MyConveyorLine segmentLine = segmentBlock.ConveyorSegment.ConveyorLine;

            segmentLine.Merge(endpointLine, segmentBlock);
            endpoint.ConveyorEndpoint.SetConveyorLine(endpointPosition, segmentLine);
            endpointLine.RecalculateConductivity();
            segmentLine.RecalculateConductivity();
            return(true);
        }
			public void Add(MyDefinitionId typeId, IMyConveyorEndpointBlock endpoint)
			{
                if (FirstEndpoint == null)
                    FirstEndpoint = endpoint.ConveyorEndpoint;

				var componentContainer = (endpoint as IMyEntity).Components;

                var sink = componentContainer.Get<MyResourceSinkComponent>();
                var source = componentContainer.Get<MyResourceSourceComponent>();

                bool containsSink = sink != null && sink.AcceptedResources.Contains(typeId);
                bool containsSource = source != null && source.ResourceTypes.Contains(typeId);
                if (containsSink && containsSource)
                {
                    SinkSourcePairs.Add(new MyTuple<MyResourceSinkComponent, MyResourceSourceComponent>(sink, source));
                }
                else if (containsSink)
                {
                    SinksByPriority[GetPriority(sink)].Add(sink);
                }
                else if (containsSource)
                {
                    SourcesByPriority[GetPriority(source)].Add(source);
                }
			}
예제 #17
0
        private static bool ItemPullAll(IMyConveyorEndpointBlock start, MyInventory destinationInventory)
        {
            MyCubeBlock startingBlock = start as MyCubeBlock;
            if (startingBlock == null) return false;

            bool itemsPulled = false;

            // Try and get the block from the cache
            MyGridConveyorSystem conveyorSystem = startingBlock.CubeGrid.GridSystems.ConveyorSystem;
            MyGridConveyorSystem.ConveyorEndpointMapping endpoints = conveyorSystem.GetConveyorEndpointMapping(start);
            if (endpoints.pullElements != null)
            {
                // Iterate to the other elements, see if we can collect some amount of items to pull
                for (int i = 0; i < endpoints.pullElements.Count; i++)
                {
                    MyCubeBlock sourceBlock = endpoints.pullElements[i] as MyCubeBlock;
                    if (sourceBlock == null) continue;

                    int inventoryCount = sourceBlock.InventoryCount;
                    for (int inventoryIndex = 0; inventoryIndex < inventoryCount; inventoryIndex++)
                    {
                        MyInventory inventory = sourceBlock.GetInventory(inventoryIndex);
                        if ((inventory.GetFlags() & MyInventoryFlags.CanSend) == 0)
                            continue;

                        if (inventory == destinationInventory)
                            continue;

                        var items = inventory.GetItems().ToArray();
                        for (int itemIndex = 0; itemIndex < items.Length; itemIndex++)
                        {
                            var item = items[itemIndex];
                            var itemId = item.GetDefinitionId();

                            var amountThatFits = destinationInventory.ComputeAmountThatFits(itemId);
                            if (amountThatFits <= 0)
                                continue;

                            // Verify that this item can, in fact, make it past sorters, etc
                            if (!CanTransfer(start, endpoints.pullElements[i], itemId, false))
                                continue;

                            var availableAmount = inventory.GetItemAmount(itemId);
                            var transferAmount = MyFixedPoint.Min(availableAmount, amountThatFits);

                            MyInventory.Transfer(inventory, destinationInventory, itemId, MyItemFlags.None, transferAmount);
                            itemsPulled = true;

                            if (destinationInventory.CargoPercentage >= 0.99f)
                                break;
                        }

                        if (destinationInventory.CargoPercentage >= 0.99f)
                            break;
                    }

                    if (destinationInventory.CargoPercentage >= 0.99f)
                        break;
                }
            }

            else
            {
                // Cache may need to be recomputed
                if (!conveyorSystem.m_isRecomputingGraph)
                    conveyorSystem.RecomputeConveyorEndpoints();
            }
            return itemsPulled;
        }
예제 #18
0
        public static bool PullAllRequest(IMyConveyorEndpointBlock start, MyInventory destinationInventory, long playerId, MyInventoryConstraint requestedTypeIds)
        {
            MyCubeBlock startingBlock = start as MyCubeBlock;
            if (startingBlock == null) return false;

            m_tmpRequestedItemSet.Set(requestedTypeIds);

            // Try and get the block from the cache
            MyGridConveyorSystem conveyorSystem = startingBlock.CubeGrid.GridSystems.ConveyorSystem;
            MyGridConveyorSystem.ConveyorEndpointMapping endpoints = conveyorSystem.GetConveyorEndpointMapping(start);
            if (endpoints.pullElements != null)
            {
                bool didTransfer = false;

                // Iterate to the other elements, see if we can collect some amount of items to pull
                for (int i = 0; i < endpoints.pullElements.Count; i++)
                {
                    MyCubeBlock sourceBlock = endpoints.pullElements[i] as MyCubeBlock;
                    if (sourceBlock == null) continue;

                    int inventoryCount = sourceBlock.InventoryCount;
                    for (int inventoryIndex = 0; inventoryIndex < inventoryCount; inventoryIndex++)
                    {
                        MyInventory inventory = sourceBlock.GetInventory(inventoryIndex);
                        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 true;
                            }

                            var itemId = item.Content.GetId();

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

                            // Verify that this item can, in fact, make it past sorters, etc
                            if (!CanTransfer(start, endpoints.pullElements[i], itemId, false))
                                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;

                            didTransfer = true;
                            MyInventory.Transfer(inventory, destinationInventory, item.Content.GetId(), MyItemFlags.None, transferedAmount);

                            if (destinationInventory.CargoPercentage >= 0.99f)
                                break;
                        }

                        if (destinationInventory.CargoPercentage >= 0.99f)
                            break;
                    }

                    if (destinationInventory.CargoPercentage >= 0.99f)
                        break;
                }

                return didTransfer;
            }

            else
            {
                // Cache may need to be recomputed
                if (!conveyorSystem.m_isRecomputingGraph)
                    conveyorSystem.RecomputeConveyorEndpoints();
            }

            return false;
        }
예제 #19
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;
        }
예제 #20
0
        private static bool CanTransfer(IMyConveyorEndpointBlock start, IMyConveyorEndpointBlock endPoint, MyDefinitionId itemId, bool isPush)
        {
            MyGridConveyorSystem conveyorSystem = (start as MyCubeBlock).CubeGrid.GridSystems.ConveyorSystem;
            MyGridConveyorSystem.ConveyorEndpointMapping endpoints = conveyorSystem.GetConveyorEndpointMapping(start);

            // Verify that this item can, in fact, make it past sorters, etc
            bool canTransfer = true;
            if (endpoints.TryGetTransfer(endPoint, itemId, false, out canTransfer))
            {
                return canTransfer;
            }
            else
            {
                Tuple<IMyConveyorEndpointBlock, IMyConveyorEndpointBlock> tuple = new Tuple<IMyConveyorEndpointBlock, IMyConveyorEndpointBlock>(start, endPoint);
                lock (m_currentTransferComputationTasks)
                {
                    if (!m_currentTransferComputationTasks.ContainsKey(tuple))
                    {
                        TransferData transferData = new TransferData(start, endPoint, itemId, isPush);
                        ParallelTasks.Task task = ParallelTasks.Parallel.Start(ComputeTransferData, OnTransferDataComputed, transferData);
                        m_currentTransferComputationTasks.Add(tuple, task);
                    }
                }
                return false;
            }
        }
예제 #21
0
        public static void PushAnyRequest(IMyConveyorEndpointBlock start, MyInventory srcInventory, long playerId)
        {
            if (srcInventory.Empty())
                return;

            // try all items and stop on first successfull
            foreach (var item in srcInventory.GetItems())
            {
                if (ItemPushRequest(start, srcInventory, playerId, item))
                    return;
            }
        }
예제 #22
0
        public static bool ItemPushRequest(IMyConveyorEndpointBlock start, MyInventory srcInventory, long playerId, MyPhysicalInventoryItem toSend, MyFixedPoint? amount = null)
        {
            MyCubeBlock startingBlock = start as MyCubeBlock;
            if (startingBlock == null) return false;

            bool success = false;

            // Try and get the block from the cache
            MyGridConveyorSystem conveyorSystem = startingBlock.CubeGrid.GridSystems.ConveyorSystem;
            MyGridConveyorSystem.ConveyorEndpointMapping endpoints = conveyorSystem.GetConveyorEndpointMapping(start);
            if (endpoints.pushElements != null)
            {
                var toSendContentId = toSend.Content.GetId();

                MyFixedPoint remainingAmount = toSend.Amount;
                if (amount.HasValue)
                {
                    remainingAmount = amount.Value;
                }

                for (int i = 0; i<endpoints.pushElements.Count; i++)
                {
                    MyCubeBlock targetBlock = endpoints.pushElements[i] as MyCubeBlock;
                    if (targetBlock == null) continue;

                    int inventoryCount = targetBlock.InventoryCount;
                    for (int inventoryIndex = 0; inventoryIndex < inventoryCount; inventoryIndex++)
                    {
                        MyInventory inventory = targetBlock.GetInventory(inventoryIndex);

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

                        if (inventory == srcInventory)
                            continue;

                        var fittingAmount = inventory.ComputeAmountThatFits(toSendContentId);
                        fittingAmount = MyFixedPoint.Min(fittingAmount, remainingAmount);
                        if (!inventory.CheckConstraint(toSendContentId))
                            continue;
                        if (fittingAmount == 0)
                            continue;

                        // Verify that this item can, in fact, make it past sorters, etc
                        if (!CanTransfer(start, endpoints.pushElements[i], toSend.GetDefinitionId(), true))
                            continue;

                        MyInventory.Transfer(srcInventory, inventory, toSend.ItemId, -1, fittingAmount);
                        success = true;

                        remainingAmount -= fittingAmount;
                    }

                    if (remainingAmount <= 0)
                        break;
                }
            }

            else
            {
                // Cache may need to be recomputed
                if (!conveyorSystem.m_isRecomputingGraph)
                    conveyorSystem.RecomputeConveyorEndpoints();
            }

            return success;
        }
        public static bool ItemPushRequest(IMyConveyorEndpointBlock start, MyInventory srcInventory, long playerId, MyPhysicalInventoryItem toSend, MyFixedPoint?amount = null)
        {
            var itemBuilder = toSend.Content;

            if (amount.HasValue)
            {
                Debug.Assert(toSend.Content.TypeId == typeof(MyObjectBuilder_Ore) ||
                             toSend.Content.TypeId == typeof(MyObjectBuilder_Ingot) ||
                             MyFixedPoint.Floor(amount.Value) == amount.Value);
            }

            MyFixedPoint remainingAmount = toSend.Amount;

            if (amount.HasValue)
            {
                remainingAmount = amount.Value;
            }

            SetTraversalPlayerId(playerId);

            var toSendContentId = toSend.Content.GetId();

            SetTraversalInventoryItemDefinitionId(toSendContentId);

            if (NeedsLargeTube(toSendContentId))
            {
                PrepareTraversal(start.ConveyorEndpoint, null, IsAccessAllowedPredicate, IsConveyorLargePredicate);
            }
            else
            {
                PrepareTraversal(start.ConveyorEndpoint, null, IsAccessAllowedPredicate);
            }

            bool success = false;

            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.CanReceive) == 0)
                    {
                        continue;
                    }

                    if (inventory == srcInventory)
                    {
                        continue;
                    }

                    var fittingAmount = inventory.ComputeAmountThatFits(toSendContentId);
                    fittingAmount = MyFixedPoint.Min(fittingAmount, remainingAmount);
                    if (!inventory.CheckConstraint(toSendContentId))
                    {
                        continue;
                    }
                    if (fittingAmount == 0)
                    {
                        continue;
                    }

                    MyInventory.Transfer(srcInventory, inventory, toSend.ItemId, -1, fittingAmount);
                    success = true;
                }
            }
            return(success);
        }
예제 #24
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);
                        }
                    }
                }
            }
        }
예제 #25
0
 public bool TryGetTransfer(IMyConveyorEndpointBlock block, MyDefinitionId itemId, bool isPush, out bool canTransfer)
 {
     var tuple = new Tuple<IMyConveyorEndpointBlock, MyDefinitionId, bool>(block, itemId, isPush);
     return testedTransfers.TryGetValue(tuple, out canTransfer);
 }
예제 #26
0
        public static bool ItemPushRequest(IMyConveyorEndpointBlock start, MyInventory srcInventory, long playerId, MyPhysicalInventoryItem toSend, MyFixedPoint? amount = null)
        {
            var itemBuilder = toSend.Content;
            if (amount.HasValue)
                Debug.Assert(toSend.Content.TypeId == typeof(MyObjectBuilder_Ore) ||
                                toSend.Content.TypeId == typeof(MyObjectBuilder_Ingot) ||
                                MyFixedPoint.Floor(amount.Value) == amount.Value);

            MyFixedPoint remainingAmount = toSend.Amount;
            if (amount.HasValue)
            {
                remainingAmount = amount.Value;
            }

            SetTraversalPlayerId(playerId);

            var toSendContentId = toSend.Content.GetId();
            SetTraversalInventoryItemDefinitionId(toSendContentId);

            if (NeedsLargeTube(toSendContentId))
            {
                PrepareTraversal(start.ConveyorEndpoint, null, IsAccessAllowedPredicate, IsConveyorLargePredicate);
            }
            else
            {
                PrepareTraversal(start.ConveyorEndpoint, null, IsAccessAllowedPredicate);
            }

            bool success = false;

            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.CanReceive) == 0)
                        continue;

                    if (inventory == srcInventory)
                        continue;

                    var fittingAmount = inventory.ComputeAmountThatFits(toSendContentId);
                    fittingAmount = MyFixedPoint.Min(fittingAmount, remainingAmount);
                    if (!inventory.CheckConstraint(toSendContentId))
                        continue;
                    if (fittingAmount == 0)
                        continue;

                    MyInventory.Transfer(srcInventory, inventory, toSend.ItemId, -1, fittingAmount);
                    success = true;
                }
            }
            return success;
        }
예제 #27
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;
        }
예제 #28
0
        public static MyFixedPoint ItemPullRequest(IMyConveyorEndpointBlock start, MyInventory destinationInventory, long playerId, MyDefinitionId itemId, MyFixedPoint? amount = null, bool remove = false)
        {
            MyCubeBlock startingBlock = start as MyCubeBlock;
            if (startingBlock == null) return 0;

            MyFixedPoint transferred = 0;
            
            // Try and get the block from the cache
            MyGridConveyorSystem conveyorSystem = startingBlock.CubeGrid.GridSystems.ConveyorSystem;
            MyGridConveyorSystem.ConveyorEndpointMapping endpoints = conveyorSystem.GetConveyorEndpointMapping(start);
            if (endpoints.pullElements != null)
            {
                // Iterate to the other elements, see if we can collect some amount of items to pull
                for (int i = 0; i < endpoints.pullElements.Count; i++)
                {
                    MyCubeBlock sourceBlock = endpoints.pullElements[i] as MyCubeBlock;
                    if (sourceBlock == null) continue;

                    int inventoryCount = sourceBlock.InventoryCount;
                    for (int inventoryIndex = 0; inventoryIndex < inventoryCount; inventoryIndex++)
                    {
                        MyInventory inventory = sourceBlock.GetInventory(inventoryIndex);
                        if ((inventory.GetFlags() & MyInventoryFlags.CanSend) == 0)
                            continue;

                        if (inventory == destinationInventory)
                            continue;

                        // Verify that this item can, in fact, make it past sorters, etc
                        if (!CanTransfer(start, endpoints.pullElements[i], itemId, false))
                            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);
                            }
                        }

                        if (destinationInventory.CargoPercentage >= 0.99f)
                            break;
                    }

                    if (destinationInventory.CargoPercentage >= 0.99f)
                        break;
                }
            }

            else
            {
                // Cache may need to be recomputed
                if (!conveyorSystem.m_isRecomputingGraph)
                    conveyorSystem.RecomputeConveyorEndpoints();
            }
            return transferred;
        }
예제 #29
0
        public void AddConveyorBlock(IMyConveyorEndpointBlock endpointBlock)
        {
            // Invalidate iterator and add block
            m_endpointIterator = null;
            m_conveyorEndpointBlocks.Add(endpointBlock);

            if (endpointBlock is MyShipConnector)
                m_connectors.Add(endpointBlock as MyShipConnector);

            m_tmpConveyorPositionList.Clear();
            var endpoint = endpointBlock.ConveyorEndpoint;

            for (int i = 0; i < endpoint.GetLineCount(); ++i)
            {
                var position = endpoint.GetPosition(i);
                var line = endpoint.GetConveyorLine(i);

                if (m_deserializedLines != null && m_deserializedLines.Contains(line))
                    continue;

                var otherBlock = m_grid.GetCubeBlock(position.NeighbourGridPosition);
                if (otherBlock == null)
                {
                    m_lines.Add(line);
                    continue;
                }

                var otherEndpointBlock = otherBlock.FatBlock as IMyConveyorEndpointBlock;
                var otherSegmentBlock = otherBlock.FatBlock as IMyConveyorSegmentBlock;

                if (otherSegmentBlock != null)
                {
                    if (!TryMergeEndpointSegment(endpointBlock, otherSegmentBlock, position))
                    {
                        m_lines.Add(line);
                    }
                }
                else if (otherEndpointBlock != null)
                {
                    if (!TryMergeEndpointEndpoint(endpointBlock, otherEndpointBlock, position, position.GetConnectingPosition()))
                    {
                        m_lines.Add(line);
                    }
                }
                else
                {
                    m_lines.Add(line);
                }
            }
            m_tmpConveyorPositionList.Clear();
        }
예제 #30
0
        public static void PushAnyRequest(IMyConveyorEndpointBlock start, MyInventory srcInventory, long playerId)
        {
            if (srcInventory.Empty())
                return;

            var itemArray = srcInventory.GetItems().ToArray();
            foreach (var item in itemArray)
            {
                ItemPushRequest(start, srcInventory, playerId, item);
            }
        }
예제 #31
0
        /// <summary>
        /// Tries to merge the conveyor lines of a conveyor block and segment block.
        /// Also changes the reference in the endpoint block to the correct line.
        /// </summary>
        private bool TryMergeEndpointSegment(IMyConveyorEndpointBlock endpoint, IMyConveyorSegmentBlock segmentBlock, ConveyorLinePosition endpointPosition)
        {
            MyConveyorLine endpointLine = endpoint.ConveyorEndpoint.GetConveyorLine(endpointPosition);
            if (endpointLine == null) return false;

            // The conveyor segment cannot merge with the given endpoint
            if (!segmentBlock.ConveyorSegment.CanConnectTo(endpointPosition.GetConnectingPosition(), endpointLine.Type))
                return false;

            MyConveyorLine segmentLine = segmentBlock.ConveyorSegment.ConveyorLine;

            segmentLine.Merge(endpointLine, segmentBlock);
            endpoint.ConveyorEndpoint.SetConveyorLine(endpointPosition, segmentLine);
            endpointLine.RecalculateConductivity();
            segmentLine.RecalculateConductivity();
            return true;
        }
예제 #32
0
 public void AddTransfer(IMyConveyorEndpointBlock block, MyDefinitionId itemId, bool isPush, bool canTransfer)
 {
     var tuple = new Tuple<IMyConveyorEndpointBlock, MyDefinitionId, bool>(block, itemId, isPush);
     testedTransfers[tuple] = canTransfer;
 }
        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);
        }
예제 #34
0
        public static void RecomputeMappingForBlock(IMyConveyorEndpointBlock processedBlock)
        {
            MyCubeBlock block = processedBlock as MyCubeBlock;
            if (block == null
                || block.CubeGrid == null
                || block.CubeGrid.GridSystems == null
                || block.CubeGrid.GridSystems.ConveyorSystem == null) return;

            ConveyorEndpointMapping endpointMap = block.CubeGrid.GridSystems.ConveyorSystem.ComputeMappingForBlock(processedBlock);

            // Update current mapping
            if (block.CubeGrid.GridSystems.ConveyorSystem.m_conveyorConnections.ContainsKey(processedBlock))
            {
                block.CubeGrid.GridSystems.ConveyorSystem.m_conveyorConnections[processedBlock] = endpointMap;
            }
            else
            {
                block.CubeGrid.GridSystems.ConveyorSystem.m_conveyorConnections.Add(processedBlock, endpointMap);
            }

            // Update future mapping if recomputation is in progress
            if (block.CubeGrid.GridSystems.ConveyorSystem.m_isRecomputingGraph)
            {
                if (block.CubeGrid.GridSystems.ConveyorSystem.m_conveyorConnectionsForThread.ContainsKey(processedBlock))
                {
                    block.CubeGrid.GridSystems.ConveyorSystem.m_conveyorConnectionsForThread[processedBlock] = endpointMap;
                }
                else
                {
                    block.CubeGrid.GridSystems.ConveyorSystem.m_conveyorConnectionsForThread.Add(processedBlock, endpointMap);
                }
            }
        }
예제 #35
0
 public virtual void RegisterInSystems(MyCubeBlock block)
 {
     if (block.GetType() != typeof(MyCubeBlock))
     {
         MyCubeBlock block1;
         if (this.ResourceDistributor != null)
         {
             MyResourceSourceComponent source = block.Components.Get <MyResourceSourceComponent>();
             if (source != null)
             {
                 this.ResourceDistributor.AddSource(source);
             }
             MyResourceSinkComponent sink = block.Components.Get <MyResourceSinkComponent>();
             if (!(block is MyThrust) && (sink != null))
             {
                 this.ResourceDistributor.AddSink(sink);
             }
             IMyRechargeSocketOwner owner = block as IMyRechargeSocketOwner;
             if (owner != null)
             {
                 owner.RechargeSocket.ResourceDistributor = this.ResourceDistributor;
             }
         }
         if (this.WeaponSystem != null)
         {
             IMyGunObject <MyDeviceBase> gun = block as IMyGunObject <MyDeviceBase>;
             if (gun != null)
             {
                 this.WeaponSystem.Register(gun);
             }
         }
         if (this.TerminalSystem != null)
         {
             MyTerminalBlock block6 = block as MyTerminalBlock;
             if (block6 != null)
             {
                 this.TerminalSystem.Add(block6);
             }
         }
         if ((block == null) || !block.HasInventory)
         {
             block1 = null;
         }
         else
         {
             block1 = block;
         }
         MyCubeBlock block2 = block1;
         if (block2 != null)
         {
             this.ConveyorSystem.Add(block2);
         }
         IMyConveyorEndpointBlock endpointBlock = block as IMyConveyorEndpointBlock;
         if (endpointBlock != null)
         {
             endpointBlock.InitializeConveyorEndpoint();
             this.ConveyorSystem.AddConveyorBlock(endpointBlock);
         }
         IMyConveyorSegmentBlock segmentBlock = block as IMyConveyorSegmentBlock;
         if (segmentBlock != null)
         {
             segmentBlock.InitializeConveyorSegment();
             this.ConveyorSystem.AddSegmentBlock(segmentBlock);
         }
         MyReflectorLight reflector = block as MyReflectorLight;
         if (reflector != null)
         {
             this.ReflectorLightSystem.Register(reflector);
         }
         if (block.Components.Contains(typeof(MyDataBroadcaster)))
         {
             MyDataBroadcaster broadcaster = block.Components.Get <MyDataBroadcaster>();
             this.RadioSystem.Register(broadcaster);
         }
         if (block.Components.Contains(typeof(MyDataReceiver)))
         {
             MyDataReceiver reciever = block.Components.Get <MyDataReceiver>();
             this.RadioSystem.Register(reciever);
         }
         if (MyFakes.ENABLE_WHEEL_CONTROLS_IN_COCKPIT)
         {
             MyMotorSuspension motor = block as MyMotorSuspension;
             if (motor != null)
             {
                 this.WheelSystem.Register(motor);
             }
         }
         IMyLandingGear gear = block as IMyLandingGear;
         if (gear != null)
         {
             this.LandingSystem.Register(gear);
         }
         MyGyro gyro = block as MyGyro;
         if (gyro != null)
         {
             this.GyroSystem.Register(gyro);
         }
         MyCameraBlock camera = block as MyCameraBlock;
         if (camera != null)
         {
             this.CameraSystem.Register(camera);
         }
     }
     block.OnRegisteredToGridSystems();
 }
예제 #36
0
 public ConveyorEndpointMapping GetConveyorEndpointMapping(IMyConveyorEndpointBlock block)
 {
     if (m_conveyorConnections.ContainsKey(block))
         return m_conveyorConnections[block];
     return new ConveyorEndpointMapping();
 }
예제 #37
0
 public virtual void UnregisterFromSystems(MyCubeBlock block)
 {
     if (block.GetType() != typeof(MyCubeBlock))
     {
         if (this.ResourceDistributor != null)
         {
             MyResourceSourceComponent source = block.Components.Get <MyResourceSourceComponent>();
             if (source != null)
             {
                 this.ResourceDistributor.RemoveSource(source);
             }
             MyResourceSinkComponent sink = block.Components.Get <MyResourceSinkComponent>();
             if (sink != null)
             {
                 this.ResourceDistributor.RemoveSink(sink, true, false);
             }
             IMyRechargeSocketOwner owner = block as IMyRechargeSocketOwner;
             if (owner != null)
             {
                 owner.RechargeSocket.ResourceDistributor = null;
             }
         }
         if (this.WeaponSystem != null)
         {
             IMyGunObject <MyDeviceBase> gun = block as IMyGunObject <MyDeviceBase>;
             if (gun != null)
             {
                 this.WeaponSystem.Unregister(gun);
             }
         }
         if (this.TerminalSystem != null)
         {
             MyTerminalBlock block5 = block as MyTerminalBlock;
             if (block5 != null)
             {
                 this.TerminalSystem.Remove(block5);
             }
         }
         if (block.HasInventory)
         {
             this.ConveyorSystem.Remove(block);
         }
         IMyConveyorEndpointBlock block2 = block as IMyConveyorEndpointBlock;
         if (block2 != null)
         {
             this.ConveyorSystem.RemoveConveyorBlock(block2);
         }
         IMyConveyorSegmentBlock segmentBlock = block as IMyConveyorSegmentBlock;
         if (segmentBlock != null)
         {
             this.ConveyorSystem.RemoveSegmentBlock(segmentBlock);
         }
         MyReflectorLight reflector = block as MyReflectorLight;
         if (reflector != null)
         {
             this.ReflectorLightSystem.Unregister(reflector);
         }
         MyDataBroadcaster broadcaster = block.Components.Get <MyDataBroadcaster>();
         if (broadcaster != null)
         {
             this.RadioSystem.Unregister(broadcaster);
         }
         MyDataReceiver reciever = block.Components.Get <MyDataReceiver>();
         if (reciever != null)
         {
             this.RadioSystem.Unregister(reciever);
         }
         if (MyFakes.ENABLE_WHEEL_CONTROLS_IN_COCKPIT)
         {
             MyMotorSuspension motor = block as MyMotorSuspension;
             if (motor != null)
             {
                 this.WheelSystem.Unregister(motor);
             }
         }
         IMyLandingGear gear = block as IMyLandingGear;
         if (gear != null)
         {
             this.LandingSystem.Unregister(gear);
         }
         MyGyro gyro = block as MyGyro;
         if (gyro != null)
         {
             this.GyroSystem.Unregister(gyro);
         }
         MyCameraBlock camera = block as MyCameraBlock;
         if (camera != null)
         {
             this.CameraSystem.Unregister(camera);
         }
     }
     block.OnUnregisteredFromGridSystems();
 }
예제 #38
0
        public void RemoveConveyorBlock(IMyConveyorEndpointBlock block)
        {
            // Invalidate iterator and remove block
            m_endpointIterator = null;
            m_conveyorEndpointBlocks.Remove(block);

            if (block is MyShipConnector)
                m_connectors.Remove(block as MyShipConnector);

            if (IsClosing) return;

            if (OnBeforeRemoveEndpointBlock != null)
                OnBeforeRemoveEndpointBlock(block);

            for (int i = 0; i < block.ConveyorEndpoint.GetLineCount(); ++i)
            {
                MyConveyorLine line = block.ConveyorEndpoint.GetConveyorLine(i);
                line.DisconnectEndpoint(block.ConveyorEndpoint);

                if (line.IsDegenerate)
                    m_lines.Remove(line);
            }
        }
        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;
        }
예제 #40
0
        private bool TryMergeEndpointEndpoint(IMyConveyorEndpointBlock endpointBlock1, IMyConveyorEndpointBlock endpointBlock2, ConveyorLinePosition pos1, ConveyorLinePosition pos2)
        {
            MyConveyorLine line1 = endpointBlock1.ConveyorEndpoint.GetConveyorLine(pos1);
            if (line1 == null)
                return false;

            MyConveyorLine line2 = endpointBlock2.ConveyorEndpoint.GetConveyorLine(pos2);
            if (line2 == null)
                return false;

            if (line1.Type != line2.Type)
                return false;

            if (line1.GetEndpoint(1) == null)
                line1.Reverse();
            Debug.Assert(line1.GetEndpoint(1) != null);
            if (line2.GetEndpoint(0) == null)
                line2.Reverse();
            Debug.Assert(line2.GetEndpoint(0) != null);

            line2.Merge(line1);
            endpointBlock1.ConveyorEndpoint.SetConveyorLine(pos1, line2);
            line1.RecalculateConductivity();
            line2.RecalculateConductivity();

            return true;
        }
예제 #41
0
        public void RemoveConveyorBlock(IMyConveyorEndpointBlock block)
        {
            if (block is MyShipConnector)
                m_connectors.Remove(block as MyShipConnector);

            if (IsClosing) return;

            for (int i = 0; i < block.ConveyorEndpoint.GetLineCount(); ++i)
            {
                MyConveyorLine line = block.ConveyorEndpoint.GetConveyorLine(i);
                line.DisconnectEndpoint(block.ConveyorEndpoint);

                if (line.IsDegenerate)
                    m_lines.Remove(line);
            }
        }
예제 #42
0
 public static bool PullAllRequest(IMyConveyorEndpointBlock start, MyInventory destinationInventory, long playerId, bool all)
 {
     SetTraversalPlayerId(playerId);
     m_tmpRequestedItemSet.Set(all);
     bool ret = ItemPullAll(start, destinationInventory);
     m_tmpRequestedItemSet.Clear();
     return ret;
 }
예제 #43
0
 public static void PullAllRequest(IMyConveyorEndpointBlock start, MyInventory destinationInventory, long playerId, MyInventoryConstraint requestedTypeIds)
 {
     SetTraversalPlayerId(playerId);
     m_tmpRequestedItemSet.Set(requestedTypeIds);
     ItemPullAll(start, destinationInventory);
     m_tmpRequestedItemSet.Clear();
 }
예제 #44
0
 public TransferData(IMyConveyorEndpointBlock start, IMyConveyorEndpointBlock endPoint, MyDefinitionId itemId, bool isPush)
 {
     m_start = start;
     m_endPoint = endPoint;
     m_itemId = itemId;
     m_isPush = isPush;
 }
예제 #45
0
 public static void PullAllRequest(IMyConveyorEndpointBlock start, MyInventory destinationInventory, long playerId, MyObjectBuilderType? typeId = null)
 {
     SetTraversalPlayerId(playerId);
     m_tmpRequestedItemSet.Set(typeId);
     ItemPullAll(start, destinationInventory);
     m_tmpRequestedItemSet.Clear();
 }
예제 #46
0
 private static void ItemPullAll(IMyConveyorEndpointBlock start, MyInventory destinationInventory)
 {
     // First, search through small conveyor tubes and request only small items
     PrepareTraversal(start.ConveyorEndpoint, null, IsAccessAllowedPredicate);
     ItemPullAllInternal(destinationInventory, m_tmpRequestedItemSet, true);
     // Then, search again through all tubes and request all items
     PrepareTraversal(start.ConveyorEndpoint, null, IsAccessAllowedPredicate, IsConveyorLargePredicate);
     ItemPullAllInternal(destinationInventory, m_tmpRequestedItemSet, false);
 }
예제 #47
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);
                        }
                    }
                }
            }
        }
        private void DisableUnreachableInventoryControls(MyInventory srcInventory, MyPhysicalInventoryItem item, MyGuiControlList list)
        {
            bool fromUser = srcInventory.Owner == m_userAsOwner;
            bool fromInteracted = srcInventory.Owner == m_interactedAsOwner;

            // srcEndpoint will be the endpoint from which we search the graph
            var srcInventoryOwner = srcInventory.Owner;
            IMyConveyorEndpointBlock srcEndpoint = null;
            // Search the interacted's graph if we want to transfer from the user
            if (fromUser)
            {
                if (m_interactedAsEntity != null)
                    srcEndpoint = m_interactedAsEntity as IMyConveyorEndpointBlock;
            }
            else if (srcInventoryOwner != null)
            {
                srcEndpoint = srcInventoryOwner as IMyConveyorEndpointBlock;
            }

            IMyConveyorEndpointBlock interactedEndpoint = null;
            if (m_interactedAsEntity != null)
            {
                interactedEndpoint = m_interactedAsEntity as IMyConveyorEndpointBlock;
            }

            if (srcEndpoint != null)
            {
                long ownerId = MySession.Static.LocalPlayerId;
                m_interactedEndpointBlock = interactedEndpoint;
                MyGridConveyorSystem.AppendReachableEndpoints(srcEndpoint.ConveyorEndpoint, ownerId, m_reachableInventoryOwners, item, m_endpointPredicate);
            }

            foreach (var control in list.Controls.GetVisibleControls())
            {
                if (!control.Enabled)
                    continue;

                var ownerControl = (MyGuiControlInventoryOwner)control;
                var owner = ownerControl.InventoryOwner;

                IMyConveyorEndpoint endpoint = null;
                var ownerBlock = owner as IMyConveyorEndpointBlock;
                if (ownerBlock != null)
                    endpoint = ownerBlock.ConveyorEndpoint;

                // TODO: Make some of these as functions so we don't have to call it even when not used due to lazy evaluation
                bool transferIsLocal = owner == srcInventoryOwner;
                bool transferIsClose = (fromUser && owner == m_interactedAsOwner) || (fromInteracted && owner == m_userAsOwner);
                bool transferIsFar = !transferIsLocal && !transferIsClose;
                bool endpointUnreachable = !m_reachableInventoryOwners.Contains(endpoint);
                bool interactedReachable = interactedEndpoint != null && m_reachableInventoryOwners.Contains(interactedEndpoint.ConveyorEndpoint);
                // If interacted is reachable but does not have inventory, than you cant take anything out from it.
                // WARNING: no need for check of null on m_interactedAsEntity, because interactedEndpoint is checked above already (that will be null also if the other is)
                bool toOwnerThroughInteracted = owner == m_userAsOwner && interactedReachable && m_interactedAsEntity.HasInventory;

                if (transferIsFar && endpointUnreachable && !toOwnerThroughInteracted)
                {
                    for (int i = 0; i < owner.InventoryCount; ++i)
                    {
                        if (!ownerControl.ContentGrids[i].Enabled)
                            continue;

                        ownerControl.ContentGrids[i].Enabled = false;
                        m_controlsDisabledWhileDragged.Add(ownerControl.ContentGrids[i]);
                    }
                }
            }

            m_reachableInventoryOwners.Clear();
        }
예제 #49
0
 private static SlimProfilerEntry SingleMethodEntryProvider_GridConveyorRequest(IMyConveyorEndpointBlock __anyBlock, string __key)
 {
     if (__anyBlock is IMyEntity entity)
     {
         return(ProfilerData.EntityEntry(entity)?.GetSlim(__key));
     }
     return(null);
 }