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