private void ProcessCell(MyStorageData cache, IMyStorage storage, Vector3I cell, long detectorId)
        {
            //bool m_miningDebug = false;

            if (cache == null || storage == null)
            {
                return;
            }

            Vector3I vector3I         = cell << 3;
            Vector3I lodVoxelRangeMax = vector3I + 7;

            // Advice cache because of performance issues
            var flag = MyVoxelRequestFlags.ContentCheckedDeep;

            Stopwatch stopwatch = Stopwatch.StartNew();

            storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 0, vector3I, lodVoxelRangeMax, ref flag);
            stopwatch.Stop();

            int readingTime = (int)((stopwatch.ElapsedTicks * 1000000) / Stopwatch.Frequency);

            if (readingTime > 1000)
            {
                int changeAmount = (int)(readingTime / 1000);

                if (MyAPIGateway.Physics.ServerSimulationRatio < 1.00f)
                {
                    sleepTimer += changeAmount * 100;
                }
                else
                {
                    sleepTimer = Math.Max(sleepTimer - 1, 1);
                }

                MyAPIGateway.Parallel.Sleep(sleepTimer);
            }

            //if (m_miningDebug)
            //Logging.Instance.WriteLine($"ProcessCell.ReadRange(1) took {(stopwatch.ElapsedTicks * 1000000)/Stopwatch.Frequency} microseconds");

            if (cache.ContainsVoxelsAboveIsoLevel())
            {
                //Stopwatch stopwatch2 = Stopwatch.StartNew();
                storage.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, vector3I, lodVoxelRangeMax, ref flag);
                //stopwatch2.Stop();

                //if (m_miningDebug)
                //Logging.Instance.WriteLine($"ProcessCell.ReadRange(2) took {(stopwatch2.ElapsedTicks * 1000000)/Stopwatch.Frequency} microseconds");

                Vector3I p = default(Vector3I);
                p.Z = 0;
                while (p.Z < 8)
                {
                    p.Y = 0;
                    while (p.Y < 8)
                    {
                        p.X = 0;
                        while (p.X < 8)
                        {
                            int linearIdx = cache.ComputeLinear(ref p);

                            if (cache.Content(linearIdx) > 127)
                            {
                                byte b = cache.Material(linearIdx);

                                if (HasFilterUpgrade)
                                {
                                    var voxelDefinition = MyDefinitionManager.Static.GetVoxelMaterialDefinition(b);

                                    if (voxelDefinition != null && voxelDefinition.MinedOre != null)
                                    {
                                        foreach (string mat in OreListSelected)
                                        {
                                            if (voxelDefinition.MinedOre.ToLower() == mat.ToLower())
                                            {
                                                Materials.AddMaterial(b, vector3I + p);
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        Materials.AddMaterial(b, vector3I + p);
                                    }
                                }
                                else
                                {
                                    Materials.AddMaterial(b, vector3I + p);
                                }
                            }
                            p.X++;
                        }
                        p.Y++;
                    }
                    p.Z++;
                }
            }
        }
        private bool IsValidVoxelTarget(NaniteMiningItem target, IMyEntity entity)
        {
            if (entity == null)
            {
                return(false);
            }

            byte         material2 = 0;
            float        amount = 0;
            IMyVoxelBase voxel = entity as IMyVoxelBase;
            Vector3D     targetMin = target.Position;
            Vector3D     targetMax = target.Position;
            Vector3I     minVoxel, maxVoxel;

            MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxel.PositionLeftBottomCorner, ref targetMin, out minVoxel);
            MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxel.PositionLeftBottomCorner, ref targetMax, out maxVoxel);

            MyVoxelBase voxelBase = voxel as MyVoxelBase;

            minVoxel += voxelBase.StorageMin;
            maxVoxel += voxelBase.StorageMin;

            voxel.Storage.ClampVoxel(ref minVoxel);
            voxel.Storage.ClampVoxel(ref maxVoxel);

            MyStorageData cache = new MyStorageData();

            cache.Resize(minVoxel, maxVoxel);
            var flag = MyVoxelRequestFlags.AdviseCache;

            cache.ClearContent(0);
            cache.ClearMaterials(0);

            byte original = 0;

            voxel.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, minVoxel, maxVoxel, ref flag);

            original  = cache.Content(0);
            material2 = cache.Material(0);

            if (original == MyVoxelConstants.VOXEL_CONTENT_EMPTY)
            {
                Logging.Instance.WriteLine("[Mining] Content is empty!", 2);
                MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                                                          { AddMinedPosition(target); });
                return(false);
            }

            Logging.Instance.WriteLine($"[Mining] Material: SizeLinear: {cache.SizeLinear}, Size3D: {cache.Size3D}, AboveISO: {cache.ContainsVoxelsAboveIsoLevel()}", 2);
            cache.Content(0, 0);

            var voxelMat = target.Definition;

            target.Amount = CalculateAmount(voxelMat, original * 8f);

            Logging.Instance.WriteLine($"[Mining] Removing: {target.Position} ({material2} {amount})", 2);

            if (material2 == 0)
            {
                Logging.Instance.WriteLine("[Mining] Material is 0", 2);
                MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                                                          { AddMinedPosition(target); });
                return(false);
            }

            if (target.Amount == 0f)
            {
                Logging.Instance.WriteLine("[Mining] Amount is 0", 2);
                MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                                                          { AddMinedPosition(target); });
                return(false);
            }

            return(true);
        }
Beispiel #3
0
        private unsafe void ProcessCell(MyStorageData cache, IMyStorage storage, Vector3I cell, long detectorId)
        {
            Vector3I lodVoxelRangeMin = cell << 3;
            Vector3I lodVoxelRangeMax = (Vector3I)(lodVoxelRangeMin + 7);

            storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 2, lodVoxelRangeMin, lodVoxelRangeMax);
            if (cache.ContainsVoxelsAboveIsoLevel())
            {
                Vector3I            vectori3;
                MyVoxelRequestFlags preciseOrePositions = MyVoxelRequestFlags.PreciseOrePositions;
                storage.ReadRange(cache, MyStorageDataTypeFlags.Material, 2, lodVoxelRangeMin, lodVoxelRangeMax, ref preciseOrePositions);
                MaterialPositionData[] materialData = MaterialData;
                vectori3.Z = 0;
                while (vectori3.Z < 8)
                {
                    vectori3.Y = 0;
                    while (true)
                    {
                        if (vectori3.Y >= 8)
                        {
                            int *numPtr4 = (int *)ref vectori3.Z;
                            numPtr4[0]++;
                            break;
                        }
                        vectori3.X = 0;
                        while (true)
                        {
                            if (vectori3.X >= 8)
                            {
                                int *numPtr3 = (int *)ref vectori3.Y;
                                numPtr3[0]++;
                                break;
                            }
                            int linearIdx = cache.ComputeLinear(ref vectori3);
                            if (cache.Content(linearIdx) > 0x7f)
                            {
                                byte     index      = cache.Material(linearIdx);
                                Vector3D vectord    = ((vectori3 + lodVoxelRangeMin) * 4f) + 2f;
                                Vector3 *vectorPtr1 = (Vector3 *)ref materialData[index].Sum;
                                vectorPtr1[0] += vectord;
                                int *numPtr1 = (int *)ref materialData[index].Count;
                                numPtr1[0]++;
                            }
                            int *numPtr2 = (int *)ref vectori3.X;
                            numPtr2[0]++;
                        }
                    }
                }
                MyEntityOreDeposit item = null;
                for (int i = 0; i < materialData.Length; i++)
                {
                    if (materialData[i].Count != 0)
                    {
                        MyVoxelMaterialDefinition voxelMaterialDefinition = MyDefinitionManager.Static.GetVoxelMaterialDefinition((byte)i);
                        if ((voxelMaterialDefinition != null) && voxelMaterialDefinition.IsRare)
                        {
                            if (item == null)
                            {
                                item = new MyEntityOreDeposit(this.VoxelMap, cell, detectorId);
                            }
                            MyEntityOreDeposit.Data data = new MyEntityOreDeposit.Data {
                                Material             = voxelMaterialDefinition,
                                AverageLocalPosition = (Vector3)Vector3D.Transform((materialData[i].Sum / ((float)materialData[i].Count)) - this.VoxelMap.SizeInMetresHalf, Quaternion.CreateFromRotationMatrix(this.VoxelMap.WorldMatrix))
                            };
                            item.Materials.Add(data);
                        }
                    }
                }
                if (item != null)
                {
                    this.m_result.Add(item);
                }
                else
                {
                    this.m_emptyCells.Add(cell);
                }
                Array.Clear(materialData, 0, materialData.Length);
            }
        }
Beispiel #4
0
        public static void RemoveVoxelContent(long voxelId, Vector3D position, out byte materialRemoved, out float amountOfMaterial)
        {
            materialRemoved  = 0;
            amountOfMaterial = 0f;

            IMyEntity entity;

            if (!MyAPIGateway.Entities.TryGetEntityById(voxelId, out entity))
            {
                return;
            }

            var      voxel = entity as IMyVoxelBase;
            var      targetMin = position;
            var      targetMax = position;
            Vector3I minVoxel, maxVoxel;

            MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxel.PositionLeftBottomCorner, ref targetMin, out minVoxel);
            MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxel.PositionLeftBottomCorner, ref targetMax, out maxVoxel);

            MyVoxelBase voxelBase = voxel as MyVoxelBase;

            minVoxel += voxelBase.StorageMin;
            maxVoxel += voxelBase.StorageMin + 1;

            voxel.Storage.ClampVoxel(ref minVoxel);
            voxel.Storage.ClampVoxel(ref maxVoxel);

            MyStorageData cache = new MyStorageData();

            cache.Resize(minVoxel, maxVoxel);
            var flag = MyVoxelRequestFlags.AdviseCache;

            cache.ClearContent(0);
            cache.ClearMaterials(0);

            byte original = 0;
            byte material = 0;

            // I don't really think pinning is necessary since I'm in the main thread, but this hasn't been working for awhile, so I'll keep it here.
            voxel.Storage.PinAndExecute(() =>
            {
                voxel.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, minVoxel, maxVoxel, ref flag);

                // Grab content and material
                original = cache.Content(0);
                material = cache.Material(0);

                if (original == MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                {
                    //Logging.Instance.WriteLine(string.Format("Content is empty"));
                    return;
                }

                // Remove Content
                Logging.Instance.WriteLine($"Material: SizeLinear: {cache.SizeLinear}, Size3D: {cache.Size3D}, AboveISO: {cache.ContainsVoxelsAboveIsoLevel()}");
                cache.Content(0, 0);
                voxel.Storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, minVoxel, maxVoxel);
            });

            // Calculate Material Mined
            var voxelMat = MyDefinitionManager.Static.GetVoxelMaterialDefinition(material);

            materialRemoved  = material;
            amountOfMaterial = CalculateAmount(voxelMat, original * 3.9f);

            // This will sync the clients.  Apparently voxel writes do not sync, lovely.
            if (Sync.IsServer)
            {
                VoxelRemovalData data = new VoxelRemovalData();
                data.VoxelID  = voxelId;
                data.Position = position;
                MyAPIGateway.Multiplayer.SendMessageToOthers(8969, ASCIIEncoding.ASCII.GetBytes(MyAPIGateway.Utilities.SerializeToXML(data)));
            }
        }
        private void ProcessCell(MyStorageData cache, IMyStorage storage, Vector3I cell)
        {
            var min = cell << MyOreDetectorComponent.CELL_SIZE_IN_VOXELS_BITS;
            var max = min + (MyOreDetectorComponent.CELL_SIZE_IN_LOD_VOXELS - 1);

            storage.PinAndExecute(() =>
            {
                storage.ReadRange(cache, MyStorageDataTypeFlags.Content, MyOreDetectorComponent.QUERY_LOD, min, max);
                if (!cache.ContainsVoxelsAboveIsoLevel())
                {
                    return;
                }

                storage.ReadRange(cache, MyStorageDataTypeFlags.Material, MyOreDetectorComponent.QUERY_LOD, min, max);
            });

            var      materialData = MaterialData;
            Vector3I c;

            for (c.Z = 0; c.Z < MyOreDetectorComponent.CELL_SIZE_IN_LOD_VOXELS; ++c.Z)
            {
                for (c.Y = 0; c.Y < MyOreDetectorComponent.CELL_SIZE_IN_LOD_VOXELS; ++c.Y)
                {
                    for (c.X = 0; c.X < MyOreDetectorComponent.CELL_SIZE_IN_LOD_VOXELS; ++c.X)
                    {
                        int i = cache.ComputeLinear(ref c);
                        if (cache.Content(i) > MyVoxelDataConstants.IsoLevel)
                        {
                            const float VOXEL_SIZE      = MyVoxelConstants.VOXEL_SIZE_IN_METRES * (1 << MyOreDetectorComponent.QUERY_LOD);
                            const float VOXEL_SIZE_HALF = VOXEL_SIZE * 0.5f;
                            var         material        = cache.Material(i);

                            Vector3D localPos = (c + min) * VOXEL_SIZE + VOXEL_SIZE_HALF;
                            materialData[material].Sum   += localPos;
                            materialData[material].Count += 1;

                            var      pos = Vector3.Transform(localPos - VoxelMap.SizeInMetresHalf, Quaternion.CreateFromRotationMatrix(VoxelMap.WorldMatrix));
                            Vector3D worldpos;
                            MyVoxelCoordSystems.LocalPositionToWorldPosition((VoxelMap.PositionComp.GetPosition() - (Vector3D)VoxelMap.StorageMin), ref pos, out worldpos);

                            if (materialData[material].Positions == null)
                            {
                                materialData[material].Positions = new List <Vector3D>();
                            }
                            materialData[material].Positions.Add(worldpos);
                        }
                    }
                }
            }

            MyEntityOreDeposit result = null;

            for (int materialIdx = 0; materialIdx < materialData.Length; ++materialIdx)
            {
                if (materialData[materialIdx].Count == 0)
                {
                    continue;
                }

                var material = MyDefinitionManager.Static.GetVoxelMaterialDefinition((byte)materialIdx);
                if (material != null && material.IsRare)
                {
                    if (result == null)
                    {
                        result = new MyEntityOreDeposit(VoxelMap, cell);
                    }

                    result.Materials.Add(new MyEntityOreDeposit.Data()
                    {
                        Material             = material,
                        AverageLocalPosition = Vector3D.Transform((materialData[materialIdx].Sum / materialData[materialIdx].Count - VoxelMap.SizeInMetresHalf), Quaternion.CreateFromRotationMatrix(VoxelMap.WorldMatrix)),
                        Positions            = materialData[materialIdx].Positions,
                    });
                }
            }

            if (result != null)
            {
                m_result.Add(result);
            }
            else
            {
                m_emptyCells.Add(cell);
            }

            Array.Clear(materialData, 0, materialData.Length);

            return;
        }