private static int PerformVoxelOp( List <MyVoxelBase> voxels, List <OrientedBoundingBoxD> boxes, byte replacementMaterial, int materialLimit, VoxelMiningBuffer miningBuffer, bool disableFarmingItems) { var result = PerformVoxelOpInternal(voxels, boxes, replacementMaterial, materialLimit, miningBuffer, disableFarmingItems); if (result <= 0) { return(result); } var voxelIds = new EntityId[voxels.Count]; for (var i = 0; i < voxelIds.Length; i++) { voxelIds[i] = voxels[i].Id; } var serializedBoxes = new SerializableOrientedBoundingBoxD[boxes.Count]; for (var i = 0; i < serializedBoxes.Length; i++) { serializedBoxes[i] = boxes[i]; } MyMultiplayerModApi.Static.RaiseStaticEvent(x => PerformVoxelOpClient, voxelIds, serializedBoxes, replacementMaterial, materialLimit, disableFarmingItems); return(result); }
private static int PerformVoxelOpInternal( List <MyVoxelBase> voxels, List <OrientedBoundingBoxD> boxes, byte replacementMaterial, int materialLimit, VoxelMiningBuffer miningBuffer, bool disableFarmingItems) { var data = VoxelData; var usedMaterial = 0; using (PoolManager.Get(out List <OrientedBoundingBoxD> storageBoxes)) foreach (var voxel in voxels) { if (materialLimit < usedMaterial) { break; } var invWorld = voxel.PositionComp.WorldMatrixInvScaled; var storageBounds = BoundingBoxD.CreateInvalid(); storageBoxes.Clear(); var voxelOffset = (voxel.Size >> 1) + voxel.StorageMin; foreach (var obb in boxes) { var storageObb = obb; storageObb.Transform(invWorld); storageObb.HalfExtent /= voxel.VoxelSize; storageObb.Center = storageObb.Center / voxel.VoxelSize + voxelOffset; storageBoxes.Add(storageObb); storageBounds.Include(storageObb.GetAABB()); } var storageMin = Vector3I.Max(Vector3I.Floor(storageBounds.Min), voxel.StorageMin); var storageMax = Vector3I.Min(Vector3I.Ceiling(storageBounds.Max), voxel.StorageMax); var localBox = new BoundingBox(storageMin, storageMax); localBox.Translate(-voxel.SizeInMetresHalf - voxel.StorageMin); if (voxel.IntersectStorage(ref localBox, false) == ContainmentType.Disjoint) { continue; } data.Resize(storageMin, storageMax); voxel.Storage.ReadRange(data, MyStorageDataTypeFlags.ContentAndMaterial, 0, storageMin, storageMax); var modified = false; var modifiedVoxels = BoundingBoxD.CreateInvalid(); foreach (var pt in new BoundingBoxI(Vector3I.Zero, storageMax - storageMin).EnumeratePoints()) { if (materialLimit < usedMaterial) { break; } var contained = false; var voxelBox = new BoundingBoxD(storageMin + pt, storageMin + pt + 1); foreach (var storageBox in storageBoxes) { if (storageBox.Intersects(ref voxelBox)) { contained = true; break; } } if (!contained) { continue; } var tmpPt = pt; var index = data.ComputeLinear(ref tmpPt); var content = data.Content(index); if (content <= 0) { continue; } var material = data.Material(index); if (material == replacementMaterial) { continue; } usedMaterial += content; miningBuffer?.Add(material, content); data.Material(index, replacementMaterial); modified = true; modifiedVoxels.Include(voxelBox); } if (!modified) { continue; } voxel.Storage.WriteRange(data, MyStorageDataTypeFlags.Material, storageMin, storageMax); if (!disableFarmingItems) { continue; } modifiedVoxels.Min = (modifiedVoxels.Min - voxelOffset) * voxel.VoxelSize; modifiedVoxels.Max = (modifiedVoxels.Max - voxelOffset) * voxel.VoxelSize; voxel.DisableFarmingItemsIn(OrientedBoundingBoxD.Create(modifiedVoxels, voxel.WorldMatrix)); } return(usedMaterial); }