public static void LoadDefinition(this MyHudBlockInfo blockInfo, MyCubeBlockDefinition definition, DictionaryReader<MyDefinitionId, int> materials, bool merge = true)
        {
            InitBlockInfo(blockInfo, definition);

            foreach (var material in materials)
            {
                var componentDefinition = MyDefinitionManager.Static.GetComponentDefinition(material.Key);
                var info = new MyHudBlockInfo.ComponentInfo();
                if (componentDefinition == null)
                {
                    MyPhysicalItemDefinition physicalDefinition = null;
                    if (!MyDefinitionManager.Static.TryGetPhysicalItemDefinition(material.Key, out physicalDefinition))
                        continue;
                    info.ComponentName = physicalDefinition.DisplayNameText;
                    info.Icon = physicalDefinition.Icon;
                    info.DefinitionId = physicalDefinition.Id;
                    info.TotalCount = 1;
                }
                else
                {
                    info.DefinitionId = componentDefinition.Id;
                    info.ComponentName = componentDefinition.DisplayNameText;
                    info.Icon = componentDefinition.Icon;
                    info.TotalCount = material.Value;
                }
                blockInfo.Components.Add(info);
            }

            if (merge) MergeSameComponents(blockInfo, definition);
        }
        public static void LoadDefinition(this MyHudBlockInfo blockInfo, MyCubeBlockDefinition definition, bool merge = true)
        {
            InitBlockInfo(blockInfo, definition);

            if (definition.MultiBlock != null)
            {
                MyDefinitionId defId = new MyDefinitionId(typeof(MyObjectBuilder_MultiBlockDefinition), definition.MultiBlock);
                MyMultiBlockDefinition multiBlockDef = MyDefinitionManager.Static.GetMultiBlockDefinition(defId);
                if (multiBlockDef != null)
                {
                    foreach (var blockPart in multiBlockDef.BlockDefinitions)
                    {
                        MyCubeBlockDefinition cubeBlockDef = null;
                        MyDefinitionManager.Static.TryGetDefinition(blockPart.Id, out cubeBlockDef);
                        if (cubeBlockDef != null)
                        {
                            AddComponentsForBlock(blockInfo, cubeBlockDef);
                        }
                    }
                }
            }
            else
            {
                AddComponentsForBlock(blockInfo, definition);
            }

            if (merge) MergeSameComponents(blockInfo, definition);
        }
        public void Adapt(IMyInventoryItem inventoryItem)
        {
            m_physItem = null;
            m_blockDef = null;

            var poob = inventoryItem.Content as MyObjectBuilder_PhysicalObject;
            if (poob != null) Adapt(poob.GetObjectId());
            else Adapt(inventoryItem.GetDefinitionId());
        }
 public MyGeneratedBlockLocation(MySlimBlock refBlock, MyCubeBlockDefinition blockDefinition, Vector3I position, Vector3I forward, Vector3I up, ushort? blockIdInCompound = null, MyGridInfo gridInfo = null)
 {
     RefBlock = refBlock;
     BlockDefinition = blockDefinition;
     Position = position;
     Orientation = new MyBlockOrientation(Base6Directions.GetDirection(ref forward), Base6Directions.GetDirection(ref up));
     BlockIdInCompound = blockIdInCompound;
     GridInfo = gridInfo;
     GeneratedBlockType = MyStringId.NullOrEmpty;
 }
 public MyGeneratedBlockLocation(MySlimBlock refBlock, MyCubeBlockDefinition blockDefinition, Vector3I position, MyBlockOrientation orientation, ushort? blockIdInCompound = null, MyGridInfo gridInfo = null)
 {
     RefBlock = refBlock;
     BlockDefinition = blockDefinition;
     Position = position;
     Orientation = orientation;
     BlockIdInCompound = blockIdInCompound;
     GridInfo = gridInfo;
     GeneratedBlockType = MyStringId.NullOrEmpty;
 }
        public bool TryAdapt(MyDefinitionId itemDefinition)
        {
            m_physItem = null;
            m_blockDef = null;

            if (MyDefinitionManager.Static.TryGetPhysicalItemDefinition(itemDefinition, out m_physItem)) return true;
            if (MyDefinitionManager.Static.TryGetCubeBlockDefinition(itemDefinition, out m_blockDef)) return true;

            return false;
        }
 public void Initialize(ref MyBlockBuildArea area, MyCubeBlockDefinition definition)
 {
     m_definition = definition;
     m_orientation = new MyBlockOrientation(area.OrientationForward, area.OrientationUp);
     m_posInGrid = area.PosInGrid;
     m_blockMin = area.BlockMin;
     m_blockMax = area.BlockMax;
     m_stepDelta = area.StepDelta;
     m_lookup.Clear();
 }
 private static void InitBlockInfo(MyHudBlockInfo blockInfo, MyCubeBlockDefinition definition)
 {
     blockInfo.BlockName = definition.DisplayNameText;
     blockInfo.BlockIcon = definition.Icon;
     blockInfo.BlockIntegrity = 0;
     blockInfo.CriticalComponentIndex = -1;
     blockInfo.CriticalIntegrity = 0;
     blockInfo.OwnershipIntegrity = 0;
     blockInfo.MissingComponentIndex = -1;
     blockInfo.Components.Clear();
 }
 public MyCubeBlockDefinitionWithVariants(MyCubeBlockDefinition definition, int variantIndex)
 {
     m_baseDefinition = definition;
     m_variantIndex = variantIndex;
     if (m_baseDefinition.Variants == null || m_baseDefinition.Variants.Count == 0)
     {
         m_variantIndex = -1;
     }
     else if (m_variantIndex != -1)
     {
         m_variantIndex %= m_baseDefinition.Variants.Count;
     }
 }
 private static void AddComponentsForBlock(MyHudBlockInfo blockInfo, MyCubeBlockDefinition definition)
 {
     for (int i = 0; i < definition.Components.Length; ++i)
     {
         var comp = definition.Components[i];
         var info = new MyHudBlockInfo.ComponentInfo();
         info.DefinitionId = comp.Definition.Id;
         info.ComponentName = comp.Definition.DisplayNameText;
         info.Icon = comp.Definition.Icon;
         info.TotalCount = comp.Count;
         blockInfo.Components.Add(info);
     }
 }
        public static void LoadDefinition(this MyHudBlockInfo blockInfo, MyCubeBlockDefinition definition, DictionaryReader<MyDefinitionId, int> materials, bool merge = true)
        {
            InitBlockInfo(blockInfo, definition);

            foreach (var material in materials)
            {
                var componentDefinition = MyDefinitionManager.Static.GetComponentDefinition(material.Key);
                var info = new MyHudBlockInfo.ComponentInfo();
                info.DefinitionId = componentDefinition.Id;
                info.ComponentName = componentDefinition.DisplayNameText;
                info.Icon = componentDefinition.Icon;
                info.TotalCount = material.Value;
                blockInfo.Components.Add(info);
            }

            if (merge) MergeSameComponents(blockInfo, definition);
        }
        // This function does some modifications to the cube block's object builder before it's built, usually integrity changes, etc...
        public virtual void BeforeCreateBlock(MyCubeBlockDefinition definition, MyEntity builder, MyObjectBuilder_CubeBlock ob, bool buildAsAdmin)
        {
            if (definition.EntityComponents == null) return;

            if (ob.ComponentContainer == null)
            {
                ob.ComponentContainer = new MyObjectBuilder_ComponentContainer();
            }

            foreach (var componentOb in definition.EntityComponents)
            {
                var data = new MyObjectBuilder_ComponentContainer.ComponentData();
                data.TypeId = componentOb.Key.ToString();
                data.Component = componentOb.Value;
                ob.ComponentContainer.Components.Add(data);
            }
        }
        public static MyObjectBuilder_BlockNavigationDefinition GetDefaultObjectBuilder(MyCubeBlockDefinition blockDefinition)
        {
            MyObjectBuilder_BlockNavigationDefinition ob = m_tmpDefaultOb;

            m_tmpStringBuilder.Clear();
            m_tmpStringBuilder.Append("Default_");
            m_tmpStringBuilder.Append(blockDefinition.Size.X);
            m_tmpStringBuilder.Append("_");
            m_tmpStringBuilder.Append(blockDefinition.Size.Y);
            m_tmpStringBuilder.Append("_");
            m_tmpStringBuilder.Append(blockDefinition.Size.Z);

            ob.Id = new MyDefinitionId(typeof(MyObjectBuilder_BlockNavigationDefinition), m_tmpStringBuilder.ToString());
            ob.Size = blockDefinition.Size;
            ob.Center = blockDefinition.Center;

            return ob;
        }
        public static void LoadDefinition(this MyHudBlockInfo blockInfo, MyCubeBlockDefinition definition, bool merge = true)
        {
            blockInfo.BlockName = definition.DisplayNameText;
            blockInfo.BlockIcon = definition.Icon;
            blockInfo.BlockIntegrity = 0;
            blockInfo.CriticalComponentIndex = -1;
            blockInfo.CriticalIntegrity = 0;
            blockInfo.OwnershipIntegrity = 0;
            blockInfo.MissingComponentIndex = -1;

            blockInfo.Components.Clear();
            for (int i = 0; i < definition.Components.Length; ++i)
            {
                var comp = definition.Components[i];
                var info = new MyHudBlockInfo.ComponentInfo();
                info.ComponentName = comp.Definition.DisplayNameText;
                info.Icon = comp.Definition.Icon;
                info.TotalCount = comp.Count;
                blockInfo.Components.Add(info);
            }

            // Merge same components
            if (merge)
            {
                for (int i = definition.Components.Length - 1; i >= 0; i--)
                {
                    for (int j = i - 1; j >= 0; j--)
                    {
                        if (definition.Components[i].Definition == definition.Components[j].Definition)
                        {
                            var info = blockInfo.Components[j];
                            info.TotalCount += blockInfo.Components[i].TotalCount;
                            blockInfo.Components[j] = info;
                            blockInfo.Components.RemoveAt(i);
                            break;
                        }
                    }
                }
            }

        }
        private static WeaponDescription CreateFrom(MyCubeBlockDefinition definition)
        {
            if (string.IsNullOrWhiteSpace(definition.DescriptionString))
                return new WeaponDescription();

            WeaponDescription desc = new WeaponDescription();
            try
            {
                XML_Amendments<WeaponDescription> ammender = new XML_Amendments<WeaponDescription>(desc);
                ammender.AmendAll(definition.DescriptionString, true);
                return ammender.Deserialize();
            }
            catch (Exception ex)
            {
                Logger.debugNotify("Failed to load description for a weapon", 10000, Logger.severity.ERROR);
                Logger log = new Logger("WeaponDescription", () => definition.Id.ToString());
                log.alwaysLog("Failed to load description for a weapon", Logger.severity.ERROR);
                log.alwaysLog("Exception: " + ex, Logger.severity.ERROR);
                return new WeaponDescription();
            }
        }
        public void Init(MyObjectBuilder_CubeBlock objectBuilder, MyCubeGrid cubeGrid, MyCubeBlock fatBlock)
        {
            ProfilerShort.Begin("SlimBlock.Init(objectBuilder, ...)");
            Debug.Assert(cubeGrid != null);
            FatBlock = fatBlock;
            m_soundEmitter.Entity = FatBlock;

            if (objectBuilder is MyObjectBuilder_CompoundCubeBlock)
                BlockDefinition = MyCompoundCubeBlock.GetCompoundCubeBlockDefinition();
            else
                BlockDefinition = MyDefinitionManager.Static.GetCubeBlockDefinition(objectBuilder.GetId());
            m_componentStack = new MyComponentStack(BlockDefinition, objectBuilder.IntegrityPercent, objectBuilder.BuildPercent);

            if (MyCubeGridDefinitions.GetCubeRotationOptions(BlockDefinition) == MyRotationOptionsEnum.None)
            {
                objectBuilder.BlockOrientation = MyBlockOrientation.Identity;
            }

            DeformationRatio = BlockDefinition.DeformationRatio;
            Min = objectBuilder.Min;

            Orientation = objectBuilder.BlockOrientation;
            if (!Orientation.IsValid)
                Orientation = MyBlockOrientation.Identity;

            Debug.Assert(Orientation.IsValid, "Orientation of block is not valid.");

            CubeGrid = cubeGrid;
            ColorMaskHSV = objectBuilder.ColorMaskHSV;

            if (BlockDefinition.CubeDefinition != null)
            {
                //Ensure we have always only one distinct orientation use
                Orientation = MyCubeGridDefinitions.GetTopologyUniqueOrientation(BlockDefinition.CubeDefinition.CubeTopology, Orientation);
            }

            ComputeMax(BlockDefinition, Orientation, ref Min, out Max);

            Matrix localMatrix;
            Orientation.GetMatrix(out localMatrix);
            Position = ComputePositionInGrid(ref localMatrix);

            UpdateShowParts();

            if (FatBlock == null)
            {
                bool isRenderedAsModel = !String.IsNullOrEmpty(BlockDefinition.Model);
                bool showConstructionModel = BlockDefinition.BlockTopology == MyBlockTopology.Cube && !ShowParts;
                if (isRenderedAsModel || showConstructionModel)
                {
                    FatBlock = new MyCubeBlock();
                    m_soundEmitter.Entity = FatBlock;
                }
            }

            if (FatBlock != null)
            {
                ProfilerShort.Begin("FatBlock.Init(objectBuilder, ...)");
                FatBlock.SlimBlock = this;
                FatBlock.Init(objectBuilder, cubeGrid);
                ProfilerShort.End();
            }

            if (objectBuilder.ConstructionStockpile != null)
            {
                EnsureConstructionStockpileExists();
                m_stockpile.Init(objectBuilder.ConstructionStockpile);
            }
            else if (objectBuilder.ConstructionInventory != null) // Backwards compatibility
            {
                EnsureConstructionStockpileExists();
                m_stockpile.Init(objectBuilder.ConstructionInventory);
            }

            if (FatBlock == null || FatBlock.GetType() == typeof(MyCubeBlock))
                m_objectBuilder = new MyObjectBuilder_CubeBlock();

            if (MyFakes.SHOW_DAMAGE_EFFECTS && FatBlock != null && BlockDefinition.RationEnoughForDamageEffect(Integrity / MaxIntegrity))
            {//start effect
                if (CurrentDamage>0)//fix for weird simple blocks having FatBlock - old save?
                {
                    FatBlock.SetDamageEffect(true);
                }
                
            }

            ProfilerShort.End();
        }
        /// <summary>
        /// Called when block is destroyed before being removed from grid
        /// </summary>
        //public void OnDestroy()
        //{
        //    if (FatBlock != null)
        //    {
        //        Profiler.Begin("MySlimBlock.OnDestroy");
        //        FatBlock.OnDestroy();
        //        Profiler.End();
        //    }
        //}

        public static void ComputeMax(MyCubeBlockDefinition definition, MyBlockOrientation orientation, ref Vector3I min, out Vector3I max)
        {
            Vector3I size = definition.Size - 1;
            MatrixI localMatrix = new MatrixI(orientation);
            Vector3I.TransformNormal(ref size, ref localMatrix, out size);
            Vector3I.Abs(ref size, out size);
            max = min + size;
        }
 public abstract void GetBlockPlacementMaterials(MyCubeBlockDefinition definition, Vector3I position, MyBlockOrientation orientation, MyCubeGrid grid);
Exemple #19
0
 public void Init(MyObjectBuilder_GunBase objectBuilder, MyCubeBlockDefinition cubeBlockDefinition, IMyGunBaseUser gunBaseUser)
 {
     if (cubeBlockDefinition is MyWeaponBlockDefinition)
     {
         MyWeaponBlockDefinition weaponBlockDefinition = cubeBlockDefinition as MyWeaponBlockDefinition;
         Init(objectBuilder, weaponBlockDefinition.WeaponDefinitionId, gunBaseUser);
     }
     else
     {
         // Backward compatibility
         MyDefinitionId weaponDefinitionId = GetBackwardCompatibleDefinitionId(cubeBlockDefinition.Id.TypeId);
         Init(objectBuilder, weaponDefinitionId, gunBaseUser);
     }
 }
 // Convention: All these functions will erase the RequiredMaterials first thing when they're called
 public abstract void GetGridSpawnMaterials(MyCubeBlockDefinition definition, MatrixD worldMatrix, bool isStatic);
 public float GetBlockMass(string model, MyCubeBlockDefinition def)
 {
     var sh = BlockShapePool.GetBreakableShape(model, def);
     var mass = sh.GetMass();
     BlockShapePool.EnqueShape(model, def.Id, sh);
     return mass;
 }
Exemple #22
0
        public void InitPressurization()
        {
            IsCubePressurized = new Dictionary <Vector3I, Dictionary <Vector3I, bool> >();

            for (int i = 0; i < Size.X; i++)
            {
                for (int j = 0; j < Size.Y; j++)
                {
                    for (int k = 0; k < Size.Z; k++)
                    {
                        Vector3 originalStartOffset = new Vector3(i, j, k);
                        Vector3 originalEndOffset   = new Vector3(i, j, k) + Vector3.One;

                        Vector3I intOffset = new Vector3I(i, j, k);

                        IsCubePressurized[intOffset] = new Dictionary <Vector3I, bool>();

                        foreach (var direction in Base6Directions.IntDirections)
                        {
                            var normal = direction;

                            IsCubePressurized[intOffset][normal] = false;

                            if (normal.X == 1 && i != Size.X - 1)
                            {
                                continue;
                            }
                            if (normal.X == -1 && i != 0)
                            {
                                continue;
                            }

                            if (normal.Y == 1 && j != Size.Y - 1)
                            {
                                continue;
                            }
                            if (normal.Y == -1 && j != 0)
                            {
                                continue;
                            }

                            if (normal.Z == 1 && k != Size.Z - 1)
                            {
                                continue;
                            }
                            if (normal.Z == -1 && k != 0)
                            {
                                continue;
                            }

                            foreach (var mountPoint in MountPoints)
                            {
                                if (normal == mountPoint.Normal)
                                {
                                    int      wallIndex = MyCubeBlockDefinition.GetMountPointWallIndex(Base6Directions.GetDirection(ref normal));
                                    Vector3I blockSize = Size;
                                    Vector3  originalStart = mountPoint.Start;
                                    Vector3  originalEnd = mountPoint.End;
                                    Vector3  start, end;
                                    MyCubeBlockDefinition.UntransformMountPointPosition(ref originalStart, wallIndex, blockSize, out start);
                                    MyCubeBlockDefinition.UntransformMountPointPosition(ref originalEnd, wallIndex, blockSize, out end);
                                    Vector3 endOffset;
                                    Vector3 startOffset;
                                    MyCubeBlockDefinition.UntransformMountPointPosition(ref originalStartOffset, wallIndex, blockSize, out startOffset);
                                    MyCubeBlockDefinition.UntransformMountPointPosition(ref originalEndOffset, wallIndex, blockSize, out endOffset);

                                    Vector3 eo = new Vector3(Math.Max(startOffset.X, endOffset.X), Math.Max(startOffset.Y, endOffset.Y), Math.Max(startOffset.Z, endOffset.Z));
                                    Vector3 so = new Vector3(Math.Min(startOffset.X, endOffset.X), Math.Min(startOffset.Y, endOffset.Y), Math.Min(startOffset.Z, endOffset.Z));

                                    if (start.X - 0.05 <= so.X && end.X + 0.05 > eo.X &&
                                        start.Y - 0.05 <= so.Y && end.Y + 0.05 > eo.Y)
                                    {
                                        IsCubePressurized[intOffset][normal] = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        //public static ObservableCollection<InventoryEditorModel> GetInventory(this MyObjectBuilder_EntityBase objectBuilderBase)
        //{
        //    var inventoryEditors = new ObservableCollection<InventoryEditorModel>();

        //    if (objectBuilderBase.ComponentContainer != null)
        //    {
        //        var inventoryBase = objectBuilderBase.ComponentContainer.Components.FirstOrDefault(e => e.TypeId == "MyInventoryBase");

        //        if (inventoryBase != null)
        //        {
        //            var singleInventory = inventoryBase.Component as MyObjectBuilder_Inventory;
        //            if (singleInventory != null)
        //            {
        //                var iem = ParseInventory(singleInventory);
        //                if (iem != null)
        //                    inventoryEditors.Add(iem);
        //            }

        //            var aggregate = inventoryBase.Component as MyObjectBuilder_InventoryAggregate;
        //            if (aggregate != null)
        //                foreach (var field in aggregate.Inventories)
        //                {
        //                    var iem = ParseInventory(field as MyObjectBuilder_Inventory);
        //                    if (iem != null)
        //                        inventoryEditors.Add(iem);
        //                }
        //        }
        //    }
        //    return inventoryEditors;
        //}

        public static ObservableCollection<InventoryEditorModel> GetInventory(this MyObjectBuilder_ComponentContainer componentContainer, MyCubeBlockDefinition definition = null)
        {
            var inventoryEditors = new ObservableCollection<InventoryEditorModel>();

            if (componentContainer != null)
            {
                var inventoryBase = componentContainer.Components.FirstOrDefault(e => e.TypeId == "MyInventoryBase");

                if (inventoryBase != null)
                {
                    var singleInventory = inventoryBase.Component as MyObjectBuilder_Inventory;
                    if (singleInventory != null)
                    {
                        var iem = ParseInventory(singleInventory, definition);
                        if (iem != null)
                            inventoryEditors.Add(iem);
                    }

                    var aggregate = inventoryBase.Component as MyObjectBuilder_InventoryAggregate;
                    if (aggregate != null)
                        foreach (var field in aggregate.Inventories)
                        {
                            var iem = ParseInventory(field as MyObjectBuilder_Inventory, definition);
                            if (iem != null)
                                inventoryEditors.Add(iem);
                        }
                }
            }
            return inventoryEditors;
        }
        private static InventoryEditorModel ParseInventory(MyObjectBuilder_Inventory inventory, MyCubeBlockDefinition definition = null)
        {
            if (inventory == null)
                return null;
            float volumeMultiplier = 1f; // Unsure if there should be a default of 1 if there isn't a InventorySize defined.

            if (definition == null)
                volumeMultiplier = 0.4f;
            else
            {
                var definitionType = definition.GetType();
                var invSizeField = definitionType.GetField("InventorySize");
                var inventoryMaxVolumeField = definitionType.GetField("InventoryMaxVolume");
                if (invSizeField != null)
                {
                    var invSize = (Vector3)invSizeField.GetValue(definition);
                    volumeMultiplier = invSize.X * invSize.Y * invSize.Z;
                }
                if (inventoryMaxVolumeField != null)
                {
                    var maxSize = (float)inventoryMaxVolumeField.GetValue(definition);
                    volumeMultiplier = MathHelper.Min(volumeMultiplier, maxSize);
                }
            }

            var settings = SpaceEngineersCore.WorldResource.Checkpoint.Settings;
            return new InventoryEditorModel(inventory, volumeMultiplier * 1000 * settings.InventorySizeMultiplier, null) { Name = inventory.InventoryFlags.ToString(), IsValid = true };
        }
 /// <summary>
 /// Checkes whether blocks A and B have matching mount point on one of their sides. Each block is given by its
 /// definition, rotation and position in grid. Position has to be relative to same center. Also, normal relative to block A specifies
 /// wall which is used for checking.
 /// </summary>
 public static bool CheckMountPointsForSide(MyCubeBlockDefinition defA, MyCubeBlockDefinition.MountPoint[] mountPointsA, ref MyBlockOrientation orientationA, ref Vector3I positionA, ref Vector3I normalA,
                                            MyCubeBlockDefinition defB, MyCubeBlockDefinition.MountPoint[] mountPointsB, ref MyBlockOrientation orientationB, ref Vector3I positionB)
 {
     TransformMountPoints(m_cacheMountPointsA, defA, mountPointsA, ref orientationA);
     TransformMountPoints(m_cacheMountPointsB, defB, mountPointsB, ref orientationB);
     return CheckMountPointsForSide(m_cacheMountPointsA, ref orientationA, ref positionA, defA.Id, ref normalA, m_cacheMountPointsB, ref orientationB, ref positionB, defB.Id);
 }
		public static bool CheckNeighborMountPointsForCompound(
			Vector3 currentMin, Vector3 currentMax, MyCubeBlockDefinition.MountPoint thisMountPoint, ref Vector3I thisMountPointTransformedNormal, MyCubeBlockDefinition thisDefinition,
			Vector3I neighborPosition, MyCubeBlockDefinition neighborDefinition, MyCubeBlockDefinition.MountPoint[] neighborMountPoints, MyBlockOrientation neighborOrientation,
			List<MyCubeBlockDefinition.MountPoint> otherMountPoints)
        {
			if (!thisMountPoint.Enabled)
				return false;

            var currentBox = new BoundingBox(currentMin - neighborPosition, currentMax - neighborPosition);

			TransformMountPoints(otherMountPoints, neighborDefinition, neighborMountPoints, ref neighborOrientation);

            foreach (var otherMountPoint in otherMountPoints)
            {
                // Skip mount points which exclude themselves (are not allowed to touch).
                if ((((thisMountPoint.ExclusionMask & otherMountPoint.PropertiesMask) != 0 ||
                      (thisMountPoint.PropertiesMask & otherMountPoint.ExclusionMask) != 0) &&
					thisDefinition.Id != neighborDefinition.Id) || !otherMountPoint.Enabled)
                    continue;

                // Check normals on compound side with the same direction (we are in the same block)
                if (MyFakes.ENABLE_TEST_BLOCK_CONNECTIVITY_CHECK && (thisMountPointTransformedNormal - otherMountPoint.Normal != Vector3I.Zero))
                    continue;

                var otherBox = new BoundingBox(Vector3.Min(otherMountPoint.Start, otherMountPoint.End), Vector3.Max(otherMountPoint.Start, otherMountPoint.End));
                if (currentBox.Intersects(otherBox))
                    return true;
            }

            return false;
        }
        /// <summary>
        /// Performs check whether small cube block given by its definition, rotation  can be connected to large grid. 
        /// Function checks whether a mount point on placed block exists in opposite direction than addNomal.
        /// </summary>
        /// <param name="grid">Grid in which the check is performed.</param>
        /// <param name="def">Definition of small cube block for checking.</param>
        /// <param name="rotation">Rotation of the small cube block.</param>
        /// <param name="addNormal">Grid hit normal.</param>
        /// <returns>True when small block can be connected, otherwise false.</returns>
        public static bool CheckConnectivitySmallBlockToLargeGrid(MyCubeGrid grid, MyCubeBlockDefinition def, ref Quaternion rotation, ref Vector3I addNormal)
        {
            Debug.Assert(grid.GridSizeEnum == MyCubeSize.Large);
            Debug.Assert(def.CubeSize  == MyCubeSize.Small);

            ProfilerShort.Begin("MyCubeBuilder.CheckMountPoints");
            try
            {
                var mountPoints = def.MountPoints;
                if (mountPoints == null)
                    return false;

                for (int i = 0; i < mountPoints.Length; ++i)
                {
                    var thisMountPoint = mountPoints[i];

                    Vector3I transformedNormal;
                    Vector3I.Transform(ref thisMountPoint.Normal, ref rotation, out transformedNormal);
                    Debug.Assert(transformedNormal.RectangularLength() == 1);

                    if (addNormal == -transformedNormal)
                        return true;
                }

                return false;
            }
            finally
            {
                m_cacheNeighborBlocks.Clear();
                ProfilerShort.End();
            }
        }
 public override bool ConnectionAllowed(ref Vector3I otherBlockMinPos, ref Vector3I otherBlockMaxPos, ref Vector3I faceNormal, MyCubeBlockDefinition def)
 {
     return ConnectionAllowedInternal(ref faceNormal, def);
 }
        protected static void AddFastBuildModelWithSubparts(ref MatrixD matrix, List<MatrixD> matrices, List<string> models, MyCubeBlockDefinition blockDefinition)
        {
            if (string.IsNullOrEmpty(blockDefinition.Model))
                return;

            matrices.Add(matrix);
            models.Add(blockDefinition.Model);
            var data = new MyEntitySubpart.Data();

            MyCubeBlockDefinition subBlockDefinition;
            MatrixD subBlockMatrix;
            Vector3 dummyPosition;

            MyModel modelData = MyModels.GetModelOnlyData(blockDefinition.Model);
            foreach (var dummy in modelData.Dummies)
            {
                if (MyEntitySubpart.GetSubpartFromDummy(blockDefinition.Model, dummy.Key, dummy.Value, ref data)) 
                {
                    MatrixD mCopy = MatrixD.Multiply(data.InitialTransform, matrix);
                    matrices.Add(mCopy);
                    models.Add(data.File);
                }
                else if (MyFakes.ENABLE_SUBBLOCKS 
                    && MyCubeBlock.GetSubBlockDataFromDummy(blockDefinition, dummy.Key, dummy.Value, false, out subBlockDefinition, out subBlockMatrix, out dummyPosition))
                {
                    if (!string.IsNullOrEmpty(subBlockDefinition.Model)) 
                    {
                        // Repair subblock matrix to have int axes (because preview renderer does not allow such non integer rotation).
                        Vector3I forward = Vector3I.Round(Vector3.DominantAxisProjection(subBlockMatrix.Forward));
                        Vector3I invForward = Vector3I.One - Vector3I.Abs(forward);
                        Vector3I right = Vector3I.Round(Vector3.DominantAxisProjection((Vector3)subBlockMatrix.Right * invForward));
                        Vector3I up;
                        Vector3I.Cross(ref right, ref forward, out up);

                        subBlockMatrix.Forward = forward;
                        subBlockMatrix.Right = right;
                        subBlockMatrix.Up = up;

                        MatrixD mCopy = MatrixD.Multiply(subBlockMatrix, matrix);
                        matrices.Add(mCopy);
                        models.Add(subBlockDefinition.Model);
                    }
                }

            }
        }
        private bool ConnectionAllowedInternal(ref Vector3I faceNormal, MyCubeBlockDefinition def)
        {
            if (IsWorking) return true;
            if (def != this.BlockDefinition) return true;

            Base6Directions.Direction connectionDirection = Orientation.TransformDirectionInverse(Base6Directions.GetDirection(faceNormal));
            if (connectionDirection != m_forward) return true;

            return false;
        }
        /// <summary>
        /// Performs check whether cube block given by its definition, rotation and position is connected to some other
        /// block in a given grid.
        /// </summary>
        /// <param name="grid">Grid in which the check is performed.</param>
        /// <param name="rotation">Rotation of the cube block within grid.</param>
        /// <param name="position">Position of the cube block within grid.</param>
        /// <returns>True when there is a connectable neighbor connected by a mount point, otherwise false.</returns>
        public static bool CheckConnectivity(IMyGridConnectivityTest grid, MyCubeBlockDefinition def, MyCubeBlockDefinition.MountPoint[] mountPoints, ref Quaternion rotation, ref Vector3I position)
        {
            ProfilerShort.Begin("MyCubeBuilder.CheckMountPoints");
            try
            {
                if (mountPoints == null)
                    return false;

                var center = def.Center;
                var size = def.Size;
                Vector3I rotatedSize;
                Vector3I rotatedCenter;
                Vector3I.Transform(ref center, ref rotation, out rotatedCenter);
                Vector3I.Transform(ref size, ref rotation, out rotatedSize);

                for (int i = 0; i < mountPoints.Length; ++i)
                {
                    var thisMountPoint = mountPoints[i];
                    Vector3 centeredStart = thisMountPoint.Start - center;
                    Vector3 centeredEnd = thisMountPoint.End - center;
                    if (MyFakes.ENABLE_TEST_BLOCK_CONNECTIVITY_CHECK)
                    {
                        // This code is used to avoid mixed start, end values, overlapped values on sides. So as result we need precise neighbour(s). Not neighbours touched on edges.

                        // Start and end sometimes have exchanged values
                        Vector3 start = Vector3.Min(thisMountPoint.Start, thisMountPoint.End);
                        Vector3 end = Vector3.Max(thisMountPoint.Start, thisMountPoint.End);

                        // Clamp only overlapped values on sides not thickness of aabb of mount point
                        Vector3I clampMask = Vector3I.One - Vector3I.Abs(thisMountPoint.Normal);
                        Vector3I invClampMask = Vector3I.One - clampMask;
                        Vector3 clampedStart = invClampMask * start + Vector3.Clamp(start, Vector3.Zero, size) * clampMask + 0.001f * clampMask;
                        Vector3 clampedEnd = invClampMask * end + Vector3.Clamp(end, Vector3.Zero, size) * clampMask - 0.001f * clampMask;

                        centeredStart = clampedStart - center;
                        centeredEnd = clampedEnd - center;
                    }

                    var centeredStartI = Vector3I.Floor(centeredStart);
                    var centeredEndI = Vector3I.Floor(centeredEnd);

                    Vector3 rotatedStart, rotatedEnd;
                    Vector3.Transform(ref centeredStart, ref rotation, out rotatedStart);
                    Vector3.Transform(ref centeredEnd, ref rotation, out rotatedEnd);

                    Vector3I rotatedStartICorrect, rotatedEndICorrect;
                    Vector3I.Transform(ref centeredStartI, ref rotation, out rotatedStartICorrect);
                    Vector3I.Transform(ref centeredEndI, ref rotation, out rotatedEndICorrect);

                    // Correction of rotation. Normally we perform computations in integers and so these are not needed, but when
                    // transforming floats, we can end up rotating eg. 0.5f to -0.5f which, after Floor operation, would be like rotation of 0 to -1 (ie. wrong).
                    // By rotating both floored and floating point versions, I can find out what change occured and handle it accordingly.
                    var rotatedStartI = Vector3I.Floor(rotatedStart);
                    var rotatedEndI = Vector3I.Floor(rotatedEnd);
                    var correctionStart = rotatedStartICorrect - rotatedStartI;
                    var correctionEnd = rotatedEndICorrect - rotatedEndI;
                    rotatedStart += correctionStart;
                    rotatedEnd += correctionEnd;

                    Vector3 gridPosStart = position + rotatedStart;
                    Vector3 gridPosEnd = position + rotatedEnd;

                    m_cacheNeighborBlocks.Clear();

                    var currentMin = Vector3.Min(gridPosStart, gridPosEnd);
                    var currentMax = Vector3.Max(gridPosStart, gridPosEnd);

                    var minI = Vector3I.Floor(currentMin);
                    var maxI = Vector3I.Floor(currentMax);
                    grid.GetConnectedBlocks(minI, maxI, m_cacheNeighborBlocks);
                    //MyCubeBuilder.Static.GetOverlappedGizmoBlocks(minI, maxI, m_cacheNeighborBlocks);                   

                    if (m_cacheNeighborBlocks.Count == 0)
                        continue;

                    Vector3I transformedNormal;
                    Vector3I.Transform(ref thisMountPoint.Normal, ref rotation, out transformedNormal);
                    Debug.Assert(transformedNormal.RectangularLength() == 1);

                    minI -= transformedNormal;
                    maxI -= transformedNormal;

                    Vector3I transformedNormalNegative = -transformedNormal;

                    foreach (var neighbor in m_cacheNeighborBlocks.Values)
                    {
                        if (neighbor.Position == position)
                        {
                            if (MyFakes.ENABLE_COMPOUND_BLOCKS)
                            {
                                // If this neighbor does not want to connect, check another one
                                if (neighbor.FatBlock != null && neighbor.FatBlock.CheckConnectionAllowed && !neighbor.FatBlock.ConnectionAllowed(ref minI, ref maxI, ref transformedNormalNegative, def))
                                    continue;

                                if (neighbor.FatBlock is MyCompoundCubeBlock)
                                {
                                    MyCompoundCubeBlock compoundBlock = neighbor.FatBlock as MyCompoundCubeBlock;
                                    foreach (var blockInCompound in compoundBlock.GetBlocks())
                                    {
										var blockInCompoundMountPoints = blockInCompound.BlockDefinition.GetBuildProgressModelMountPoints(blockInCompound.BuildLevelRatio);
										if (CheckNeighborMountPointsForCompound(currentMin, currentMax, thisMountPoint, ref transformedNormal, def,
																				neighbor.Position, blockInCompound.BlockDefinition, blockInCompoundMountPoints, blockInCompound.Orientation, m_cacheMountPointsA))
                                            return true;
                                    }
                                }
                                else
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {

                            // If this neighbor does not want to connect, check another one
                            if (neighbor.FatBlock != null && neighbor.FatBlock.CheckConnectionAllowed && !neighbor.FatBlock.ConnectionAllowed(ref minI, ref maxI, ref transformedNormalNegative, def))
                                continue;

                            if (neighbor.FatBlock is MyCompoundCubeBlock)
                            {
                                MyCompoundCubeBlock compoundBlock = neighbor.FatBlock as MyCompoundCubeBlock;
                                foreach (var blockInCompound in compoundBlock.GetBlocks())
                                {
									var blockInCompoundMountPoints = blockInCompound.BlockDefinition.GetBuildProgressModelMountPoints(blockInCompound.BuildLevelRatio);
                                    if (CheckNeighborMountPoints(currentMin, currentMax, thisMountPoint, ref transformedNormal, def,
																 neighbor.Position, blockInCompound.BlockDefinition, blockInCompoundMountPoints, blockInCompound.Orientation, m_cacheMountPointsA))
                                        return true;
                                }
                            }
                            else
                            {
								var buildLevelRatio = 1.0f;
								if(neighbor.FatBlock != null && neighbor.FatBlock.SlimBlock != null)
									buildLevelRatio = neighbor.FatBlock.SlimBlock.BuildLevelRatio;
								var neighborMountPoints = neighbor.Definition.GetBuildProgressModelMountPoints(buildLevelRatio);
                                if (CheckNeighborMountPoints(currentMin, currentMax, thisMountPoint, ref transformedNormal, def,
															 neighbor.Position, neighbor.Definition, neighborMountPoints, neighbor.Orientation, m_cacheMountPointsA))
                                    return true;
                            }
                        }
                    }
                }

                return false;
            }
            finally
            {
                m_cacheNeighborBlocks.Clear();
                ProfilerShort.End();
            }
        }