예제 #1
0
        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);
        }
예제 #2
0
        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);
        }