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; }
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; }