FluidMode enum

Пакет: com.hypixel.hytale.builtin.buildertools.tooloperations

Файл: com/hypixel/hytale/builtin/buildertools/tooloperations/SculptOperation.java

Поля (1)

МодификаторыТипИмя
IGNORE, FIX, REMOVE

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.builtin.buildertools.tooloperations;

class="kw">import com.hypixel.hytale.assetstore.map.BlockTypeAssetMap;
class="kw">import com.hypixel.hytale.builtin.buildertools.utils.Material;
class="kw">import com.hypixel.hytale.builtin.buildertools.utils.Sample;
class="kw">import com.hypixel.hytale.component.ComponentAccessor;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.protocol.DrawType;
class="kw">import com.hypixel.hytale.protocol.InteractionType;
class="kw">import com.hypixel.hytale.protocol.Vector3i;
class="kw">import com.hypixel.hytale.protocol.packets.buildertools.BuilderToolOnUseInteraction;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.asset.type.fluid.Fluid;
class="kw">import com.hypixel.hytale.server.core.entity.entities.Player;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.mask.BlockPattern;
class="kw">import com.hypixel.hytale.server.core.universe.PlayerRef;
class="kw">import com.hypixel.hytale.server.core.universe.world.accessor.ChunkAccessor;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
class="kw">import java.util.ArrayDeque;
class="kw">import javax.annotation.Nonnull;

class="kw">public class SculptOperation class="kw">extends ToolOperation {
   class="kw">private class="kw">static class="kw">final BlockTypeAssetMap<String, BlockType> assetMap = BlockType.getAssetMap();
   class="kw">private Vector3i hit;
   class="kw">private int bufferWidth;
   class="kw">private int bufferHeight;
   class="kw">private double erosionStrength;
   class="kw">private boolean sampleNearby;
   class="kw">private boolean heightMap = false;
   class="kw">private class="kw">final int[] KERNEL_WEIGHTS;
   class="kw">private class="kw">final double KERNEL_STABLE;
   class="kw">private class="kw">final double EROSION_RANGE;
   class="kw">private class="kw">final int KERNEL_TOTAL;
   class="kw">private class="kw">final Material nonSampleMat;
   class="kw">private class="kw">final boolean isPrimary;
   class="kw">private class="kw">final SculptOperation.FluidMode fluidMode;
   class="kw">private class="kw">static class="kw">final Material AIR = Material.block(0);
   class="kw">public class="kw">static class="kw">final double EROSION_STRENGTH_SCALE = 10.0;
   class="kw">private class="kw">static class="kw">final double HEIGHTMAP_EROSION_BIAS = 0.1;
   class="kw">public class="kw">static class="kw">final double HEIGHTMAP_RAISE_THRESHOLD = 0.35;
   class="kw">public class="kw">static class="kw">final double HEIGHTMAP_LOWER_THRESHOLD = -0.75;
   class="kw">private double erosionPreCalc;
   class="kw">private double erosionThresholdLow;
   class="kw">private double erosionThresholdHigh;
   class="kw">private int halfBufferWidth;
   class="kw">private int halfBufferHeight;
   class="kw">public class="kw">static class="kw">final SculptOperation.Kernel NORMAL_KERNEL = new SculptOperation.Kernel(
      25.5, 12.0, new int[]{1, 2, 1, 2, 3, 2, 1, 2, 1, 2, 3, 2, 3, 1, 3, 2, 3, 2, 1, 2, 1, 2, 3, 2, 1, 2, 1}
   );
   class="kw">public class="kw">static class="kw">final SculptOperation.Kernel UNIFORM_KERNEL = new SculptOperation.Kernel(
      12.0, 8.0, new int[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
   );
   class="kw">public class="kw">static class="kw">final SculptOperation.Kernel GAUSS_KERNEL = new SculptOperation.Kernel(
      12.0, 5.5, new int[]{0, 1, 0, 1, 2, 1, 0, 1, 0, 1, 2, 1, 2, 2, 2, 1, 2, 1, 0, 1, 0, 1, 2, 1, 0, 1, 0}
   );
   class="kw">public class="kw">static class="kw">final SculptOperation.Kernel NEIGHBOUR_KERNEL = new SculptOperation.Kernel(
      2.0, 1.5, new int[]{0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}
   );
   class="kw">public class="kw">static class="kw">final SculptOperation.Kernel SQUARE_KERNEL = new SculptOperation.Kernel(
      1.75, 2.0, new int[]{0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}
   );
   class="kw">public class="kw">static class="kw">final SculptOperation.Kernel NORMAL_HEIGHTMAP = new SculptOperation.Kernel(
      -1.0, 1.15, new int[]{0, 1, 2, 1, 0, 1, 3, 4, 3, 1, 2, 4, 2, 4, 2, 1, 3, 4, 3, 1, 0, 1, 2, 1, 0}
   );
   class="kw">public class="kw">static class="kw">final SculptOperation.Kernel UNIFORM_HEIGHTMAP = new SculptOperation.Kernel(
      -1.0, 1.15, new int[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
   );
   class="kw">public class="kw">static class="kw">final SculptOperation.Kernel GAUSS_HEIGHTMAP = new SculptOperation.Kernel(
      -1.0, 1.15, new int[]{0, 0, 1, 0, 0, 0, 1, 2, 1, 0, 1, 2, 0, 2, 1, 0, 1, 2, 1, 0, 0, 0, 1, 0, 0}
   );
   class="kw">public class="kw">static class="kw">final SculptOperation.Kernel NEIGHBOUR_HEIGHTMAP = new SculptOperation.Kernel(
      -1.0, 1.15, new int[]{1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1}
   );
   class="kw">public class="kw">static class="kw">final SculptOperation.Kernel SQUARE_HEIGHTMAP = new SculptOperation.Kernel(
      -1.0, 1.15, new int[]{1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1}
   );
   class="kw">public class="kw">static class="kw">final SculptOperation.Kernel NORMAL_FLAT = new SculptOperation.Kernel(
      10.0, 5.0, new int[]{0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 3, 1, 3, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0}
   );
   class="kw">public class="kw">static class="kw">final SculptOperation.Kernel UNIFORM_FLAT = new SculptOperation.Kernel(
      4.0, 3.0, new int[]{0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0}
   );
   class="kw">public class="kw">static class="kw">final SculptOperation.Kernel GAUSS_FLAT = new SculptOperation.Kernel(
      6.0, 3.0, new int[]{0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0}
   );
   class="kw">public class="kw">static class="kw">final SculptOperation.Kernel NEIGHBOUR_FLAT = new SculptOperation.Kernel(
      2.0, 1.5, new int[]{0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}
   );
   class="kw">public class="kw">static class="kw">final SculptOperation.Kernel SQUARE_FLAT = new SculptOperation.Kernel(
      1.75, 2.0, new int[]{0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0}
   );
   class="kw">private class="kw">static class="kw">final int INCREASE_BUFFER = 2;
   class="kw">public class="kw">static class="kw">final int HEIGHTMAP_EXTRA_WIDTH = 4;
   class="kw">public class="kw">static class="kw">final int HEIGHTMAP_EXTRA_HEIGHT = 20;
   class="kw">private int[][][] buffer;
   class="kw">private int[][][] mutatedBuffer;
   class="kw">private int[][][] fluidBuffer;
   class="kw">private boolean hasAnyFluid;
   class="kw">private int[][] heightMapBuffer;
   class="kw">private class="kw">final boolean isAltPlaySculptBrushModDown;

   class="kw">public SculptOperation(
      @Nonnull Ref<EntityStore> var1,
      @Nonnull Player var2,
      @Nonnull PlayerRef var3,
      @Nonnull BuilderToolOnUseInteraction var4,
      @Nonnull ComponentAccessor<EntityStore> var5
   ) {
      super(var1, var4, var5);
      String var6 = (String)this.args.tool().get("sampling");
      String var7 = (String)this.args.tool().get("mode");
      if (var7 == null) {
         var7 = "Full";
      }

      SculptOperation.Kernel var8;
      if ("Heightmap".equals(var7)) {
         this.heightMap = true;

         var8 = class="kw">switch (var6) {
            case "Uniform" -> UNIFORM_HEIGHTMAP;
            case "Gaussian" -> GAUSS_HEIGHTMAP;
            case "Neighbor" -> NEIGHBOUR_HEIGHTMAP;
            case "Square" -> SQUARE_HEIGHTMAP;
            class="kw">default -> NORMAL_HEIGHTMAP;
         };
      } else if ("Flat".equals(var7)) {
         var8 = class="kw">switch (var6) {
            case "Uniform" -> UNIFORM_FLAT;
            case "Gaussian" -> GAUSS_FLAT;
            case "Neighbor" -> NEIGHBOUR_FLAT;
            case "Square" -> SQUARE_FLAT;
            class="kw">default -> NORMAL_FLAT;
         };
      } else {
         var8 = class="kw">switch (var6) {
            case "Uniform" -> UNIFORM_KERNEL;
            case "Gaussian" -> GAUSS_KERNEL;
            case "Neighbor" -> NEIGHBOUR_KERNEL;
            case "Square" -> SQUARE_KERNEL;
            class="kw">default -> NORMAL_KERNEL;
         };
      }

      this.KERNEL_WEIGHTS = var8.weights();
      this.KERNEL_STABLE = var8.stable();
      this.EROSION_RANGE = var8.range();
      this.KERNEL_TOTAL = var8.total();
      this.isAltPlaySculptBrushModDown = var4.isAltPlaySculptBrushModDown;
      this.sampleNearby = (Boolean)this.args.tool().get("useExistingBlocks");
      if (this.isAltPlaySculptBrushModDown) {
         this.erosionStrength = 0.0;
      } else {
         this.erosionStrength = ((Integer)this.args.tool().get("erosionStrength")).intValue() / 10.0;
      }
      this.fluidMode = class="kw">switch ((String)this.args.tool().get("fluidMode")) {
         case "Fix" -> SculptOperation.FluidMode.FIX;
         case "Remove" -> SculptOperation.FluidMode.REMOVE;
         class="kw">default -> SculptOperation.FluidMode.IGNORE;
      };
      this.isPrimary = this.interactionType == InteractionType.Primary;
      if (this.heightMap) {
         this.erosionStrength += 0.1;
      }

      if (this.isPrimary) {
         this.erosionStrength *= -1.0;
      }

      if (!this.sampleNearby) {
         this.nonSampleMat = this.pattern.equals(BlockPattern.EMPTY) ? Material.fromKey("Rock_Stone") : Material.fromPattern(this.pattern, this.random);
      } else {
         this.nonSampleMat = null;
      }

      this.erosionPreCalc = -this.EROSION_RANGE * this.erosionStrength;
      this.erosionThresholdLow = this.KERNEL_STABLE + this.erosionPreCalc;
      this.erosionThresholdHigh = this.KERNEL_STABLE + 1.0 + this.erosionPreCalc;
      this.bufferWidth = this.getBrushWidth() + 2;
      this.bufferHeight = this.getBrushHeight() + 2;
      if (this.bufferWidth % 2 == 0) {
         this.bufferWidth++;
      }

      if (this.bufferHeight % 2 == 0) {
         this.bufferHeight++;
      }

      if (this.heightMap) {
         this.bufferWidth += 4;
         this.bufferHeight += 20;
      }

      this.halfBufferWidth = this.bufferWidth / 2;
      this.halfBufferHeight = this.bufferHeight / 2;
   }

   @Override
   class="kw">public void execute(ComponentAccessor<EntityStore> var1) {
      this.executeAt(this.x, this.y, this.z, var1);
   }

   @Override
   class="kw">public void executeAt(int var1, int var2, int var3, ComponentAccessor<EntityStore> var4) {
      this.prepareBuffersForCenter(var1, var2 + this.originOffsetY, var3);
      super.executeAt(var1, var2, var3, var4);
      if (this.fluidMode == SculptOperation.FluidMode.FIX) {
         this.floodFillFluids();
      }
   }

   class="kw">private void prepareBuffersForCenter(int var1, int var2, int var3) {
      this.hit = new Vector3i(var1, var2, var3);
      boolean var4 = this.fluidMode != SculptOperation.FluidMode.IGNORE;
      this.fluidBuffer = var4 ? new int[this.bufferWidth][this.bufferHeight][this.bufferWidth] : null;
      this.buffer = bufferRegion(this.edit.getAccessor(), this.hit, this.bufferWidth, this.bufferHeight, this.bufferWidth, this.fluidBuffer);
      this.hasAnyFluid = var4 && hasNonEmptyFluid(this.fluidBuffer, this.bufferWidth, this.bufferHeight);
      this.mutatedBuffer = this.fluidMode == SculptOperation.FluidMode.FIX ? copyBuffer(this.buffer) : null;
      this.heightMapBuffer = this.heightMap ? preCalcBuffer(this.hit.y, this.buffer) : null;
   }

   @Override
   class="kw">protected boolean executeBlock(int var1, int var2, int var3) {
      if (this.hit == null) {
         class="kw">return false;
      }

      int var4 = var1 - this.hit.x + this.halfBufferWidth;
      int var5 = var2 - this.hit.y + this.halfBufferHeight;
      int var6 = var3 - this.hit.z + this.halfBufferWidth;
      int var7 = this.heightMap ? 2 : 1;
      if (var4 >= var7 && var5 >= var7 && var6 >= var7 && var4 < this.bufferWidth - var7 && var5 < this.bufferHeight - var7 && var6 < this.bufferWidth - var7) {
         if (this.buffer[var4][var5][var6] == -1) {
            this.setAir(var1, var2, var3);
         }

         if (this.fluidMode == SculptOperation.FluidMode.REMOVE && this.hasAnyFluid && this.fluidBuffer[var4][var5][var6] != 0) {
            this.edit.clearFluid(var1, var2, var3);
         }

         if (this.heightMap) {
            if (var2 != this.hit.y) {
               class="kw">return true;
            }

            Sample.Result2D var8 = Sample.calcDeltaHeights(
               var4, var5, var6, this.heightMapBuffer, this.buffer, this.KERNEL_WEIGHTS, this.KERNEL_TOTAL, this.hit.y, this.sampleNearby
            );
            this.smoothBlocks(var1, var3, var8);
         } else if (this.sampleNearby) {
            Sample.Result3D var9 = Sample.calculate3D(var4, var5, var6, this.buffer, this.KERNEL_WEIGHTS);
            this.smoothBlocks(var1, var2, var3, var9);
         } else {
            int var10 = Sample.calculateAirWeight3D(var4, var5, var6, this.buffer, this.KERNEL_WEIGHTS);
            this.smoothBlocksFast(var1, var2, var3, var10, this.buffer[var4][var5][var6]);
         }

         class="kw">return true;
      } else {
         class="kw">return true;
      }
   }

   class="kw">private void smoothBlocks(int var1, int var2, int var3, Sample.Result3D var4) {
      int var5 = var4.airWeight();
      int var6 = var4.sampledBlock();
      Material var7 = var6 > 0 ? Material.block(var6) : Material.fromPattern(this.pattern, this.random);
      if (var5 <= this.erosionThresholdLow) {
         if (var4.originalBlock() <= 0) {
            this.setSolid(var1, var2, var3, var7);
         }
      } else if (var5 > this.erosionThresholdHigh && var4.originalBlock() != 0) {
         this.setAir(var1, var2, var3);
      }
   }

   class="kw">private Material getNonSampleMat() {
      class="kw">return this.nonSampleMat != null ? this.nonSampleMat : Material.fromPattern(this.pattern, this.random);
   }

   class="kw">private void setSolid(int var1, int var2, int var3, Material var4) {
      if (this.hasAnyFluid) {
         int var5 = var1 - this.hit.x + this.halfBufferWidth;
         int var6 = var2 - this.hit.y + this.halfBufferHeight;
         int var7 = var3 - this.hit.z + this.halfBufferWidth;
         if (var5 >= 0
            && var6 >= 0
            && var7 >= 0
            && var5 < this.bufferWidth
            && var6 < this.bufferHeight
            && var7 < this.bufferWidth
            && this.fluidBuffer[var5][var6][var7] != 0) {
            this.edit.clearFluid(var1, var2, var3);
         }
      }

      this.edit.setMaterialWithFiller(var1, var2, var3, var4);
      this.updateMutatedBuffer(var1, var2, var3, var4.getBlockId());
   }

   class="kw">private void setAir(int var1, int var2, int var3) {
      this.edit.setMaterialWithFiller(var1, var2, var3, AIR);
      this.updateMutatedBuffer(var1, var2, var3, 0);
   }

   class="kw">private void updateMutatedBuffer(int var1, int var2, int var3, int var4) {
      if (this.mutatedBuffer != null) {
         int var5 = var1 - this.hit.x + this.halfBufferWidth;
         int var6 = var2 - this.hit.y + this.halfBufferHeight;
         int var7 = var3 - this.hit.z + this.halfBufferWidth;
         if (var5 >= 0 && var6 >= 0 && var7 >= 0 && var5 < this.bufferWidth && var6 < this.bufferHeight && var7 < this.bufferWidth) {
            this.mutatedBuffer[var5][var6][var7] = var4;
         }
      }
   }

   class="kw">private void smoothBlocksFast(int var1, int var2, int var3, int var4, int var5) {
      if (var4 <= this.erosionThresholdLow) {
         if (var5 <= 0) {
            this.setSolid(var1, var2, var3, this.getNonSampleMat());
         } else {
            Material var6 = this.getNonSampleMat();
            if (var6.getBlockId() != var5) {
               this.setSolid(var1, var2, var3, var6);
            }
         }
      } else if (var4 > this.erosionThresholdHigh) {
         if (var5 != 0) {
            this.setAir(var1, var2, var3);
         }
      } else {
         Material var7 = this.getNonSampleMat();
         if (var7.getBlockId() != var5) {
            this.setSolid(var1, var2, var3, var7);
         }
      }
   }

   class="kw">private void smoothBlocks(int var1, int var2, Sample.Result2D var3) {
      if (var3.currentHeight() != -1) {
         Material var4;
         if (!this.sampleNearby) {
            var4 = this.getNonSampleMat();
         } else if (var3.sampledBlock() == 0) {
            var4 = Material.fromPattern(this.pattern, this.random);
         } else {
            var4 = Material.block(var3.sampledBlock());
         }

         double var5 = var3.deltaHeight() + this.erosionPreCalc;
         int var7 = var3.currentHeight();
         if (var5 > 0.35) {
            int var8 = Math.max((int)var5, 1);

            for (int var9 = 1; var9 <= var8; var9++) {
               this.setSolid(var1, var7 + var9, var2, var4);
            }
         } else if (var5 < -0.75) {
            int var14 = Math.min((int)var5, -1);

            for (int var15 = 0; var15 > var14; var15--) {
               this.setAir(var1, var7 + var15, var2);
            }

            int var16 = var7 + var14;
            this.setSolid(var1, var16, var2, var4);
            int var10 = var1 - this.hit.x + this.halfBufferWidth;
            int var11 = var2 - this.hit.z + this.halfBufferWidth;
            int var12 = var16 - 1;

            while (true) {
               int var13 = var12 - this.hit.y + this.halfBufferHeight;
               if (var13 < 0 || var13 >= this.bufferHeight) {
                  break;
               }

               if (this.buffer[var10][var13][var11] <= 0) {
                  this.setSolid(var1, var12, var2, var4);
               }

               var12--;
            }
         } else if (!this.sampleNearby && var4.getBlockId() != var3.originalBlock()) {
            this.setSolid(var1, var7, var2, var4);
         }
      }
   }

   class="kw">private void floodFillFluids() {
      boolean[][] var1 = new boolean[this.bufferWidth][this.bufferWidth];
      int[][] var2 = new int[this.bufferWidth][this.bufferWidth];
      boolean[][] var3 = new boolean[this.bufferWidth][this.bufferWidth];
      ArrayDeque var4 = new ArrayDeque<>(this.bufferWidth * this.bufferWidth);

      for (int var5 = this.bufferHeight - 1; var5 >= 0; var5--) {
         int var6 = this.hit.y - this.halfBufferHeight + var5;

         for (int var7 = 0; var7 < this.bufferWidth; var7++) {
            for (int var8 = 0; var8 < this.bufferWidth; var8++) {
               var3[var7][var8] = false;
               int var9 = this.fluidBuffer[var7][var5][var8];
               boolean var10 = var1[var7][var8];
               var1[var7][var8] = false;
               int var11 = var9 != 0 ? var9 : var2[var7][var8];
               var2[var7][var8] = 0;
               if (var11 != 0 || var10) {
                  if (this.mutatedBuffer[var7][var5][var8] <= 0) {
                     var4.add(new SculptOperation.FluidFillEntry(var7, var8, var11));
                     var3[var7][var8] = true;
                  } else {
                     var1[var7][var8] = true;
                     if (var11 != 0) {
                        var2[var7][var8] = var11;
                     }
                  }
               }
            }
         }

         while (!var4.isEmpty()) {
            SculptOperation.FluidFillEntry var15 = var4.poll();
            int var16 = var15.bx();
            int var17 = var15.bz();
            int var18 = var15.fluidId();
            var1[var16][var17] = true;
            int var19 = this.fluidBuffer[var16][var5][var17];
            if (var19 != 0) {
               var18 = var19;
            } else if (var18 == 0) {
               var18 = this.findNearbyFluidIdFromBuffer(var16, var5, var17);
            }

            if (var18 != 0) {
               Fluid var12 = Fluid.getAssetMap().getAsset(var18);
               if (var12 != null) {
                  int var13 = this.hit.x - this.halfBufferWidth + var16;
                  int var14 = this.hit.z - this.halfBufferWidth + var17;
                  this.edit.setMaterial(var13, var6, var14, Material.fluid(var18, (byte)var12.getMaxFluidLevel()));
                  this.fluidBuffer[var16][var5][var17] = var18;
                  var2[var16][var17] = var18;
               }
            }

            if (var16 > 0 && !var3[var16 - 1][var17] && this.mutatedBuffer[var16 - 1][var5][var17] <= 0) {
               var3[var16 - 1][var17] = true;
               var4.add(new SculptOperation.FluidFillEntry(var16 - 1, var17, var18));
            }

            if (var16 < this.bufferWidth - 1 && !var3[var16 + 1][var17] && this.mutatedBuffer[var16 + 1][var5][var17] <= 0) {
               var3[var16 + 1][var17] = true;
               var4.add(new SculptOperation.FluidFillEntry(var16 + 1, var17, var18));
            }

            if (var17 > 0 && !var3[var16][var17 - 1] && this.mutatedBuffer[var16][var5][var17 - 1] <= 0) {
               var3[var16][var17 - 1] = true;
               var4.add(new SculptOperation.FluidFillEntry(var16, var17 - 1, var18));
            }

            if (var17 < this.bufferWidth - 1 && !var3[var16][var17 + 1] && this.mutatedBuffer[var16][var5][var17 + 1] <= 0) {
               var3[var16][var17 + 1] = true;
               var4.add(new SculptOperation.FluidFillEntry(var16, var17 + 1, var18));
            }
         }
      }
   }

   class="kw">private int findNearbyFluidIdFromBuffer(int var1, int var2, int var3) {
      if (var2 + 1 < this.bufferHeight) {
         int var4 = this.fluidBuffer[var1][var2 + 1][var3];
         if (var4 != 0) {
            class="kw">return var4;
         }
      }

      if (var1 > 0) {
         int var5 = this.fluidBuffer[var1 - 1][var2][var3];
         if (var5 != 0) {
            class="kw">return var5;
         }
      }

      if (var1 < this.bufferWidth - 1) {
         int var6 = this.fluidBuffer[var1 + 1][var2][var3];
         if (var6 != 0) {
            class="kw">return var6;
         }
      }

      if (var3 > 0) {
         int var7 = this.fluidBuffer[var1][var2][var3 - 1];
         if (var7 != 0) {
            class="kw">return var7;
         }
      }

      if (var3 < this.bufferWidth - 1) {
         int var8 = this.fluidBuffer[var1][var2][var3 + 1];
         if (var8 != 0) {
            class="kw">return var8;
         }
      }

      if (var2 > 0) {
         int var9 = this.fluidBuffer[var1][var2 - 1][var3];
         if (var9 != 0) {
            class="kw">return var9;
         }
      }

      class="kw">return 0;
   }

   class="kw">public class="kw">static int[][] preCalcBuffer(int var0, int[][][] var1) {
      int var2 = var1[0].length;
      int var3 = var1.length;
      int[][] var4 = new int[var3][var3];

      for (int var5 = 0; var5 < var3; var5++) {
         for (int var6 = 0; var6 < var3; var6++) {
            if (var1[var5][var2 - 1][var6] > 0) {
               var4[var5][var6] = -1;
            } else {
               int var7 = var2 - 2;

               for (int var8 = 0; var8 <= 0 && var7 >= 0; var7--) {
                  var8 = var1[var5][var7][var6];
               }

               if (var7 == -1) {
                  var4[var5][var6] = -1;
               } else {
                  var4[var5][var6] = var7 + 1 + var0 - var2 / 2;
               }
            }
         }
      }

      class="kw">return var4;
   }

   class="kw">private class="kw">static int[][][] copyBuffer(int[][][] var0) {
      int var1 = var0.length;
      int var2 = var0[0].length;
      int var3 = var0[0][0].length;
      int[][][] var4 = new int[var1][var2][var3];

      for (int var5 = 0; var5 < var1; var5++) {
         for (int var6 = 0; var6 < var2; var6++) {
            System.arraycopy(var0[var5][var6], 0, var4[var5][var6], 0, var3);
         }
      }

      class="kw">return var4;
   }

   class="kw">private class="kw">static boolean hasNonEmptyFluid(int[][][] var0, int var1, int var2) {
      for (int var3 = 0; var3 < var1; var3++) {
         for (int var4 = 0; var4 < var2; var4++) {
            for (int var5 = 0; var5 < var1; var5++) {
               if (var0[var3][var4][var5] != 0) {
                  class="kw">return true;
               }
            }
         }
      }

      class="kw">return false;
   }

   class="kw">public class="kw">static int filterFullBlockForBuffer(int var0, Int2IntOpenHashMap var1) {
      if (var0 == 0) {
         class="kw">return 0;
      }

      int var2 = var1.get(var0);
      if (var2 == Integer.MIN_VALUE) {
         BlockType var3 = assetMap.getAsset(var0);
         if (var3 == null) {
            var2 = -1;
         } else {
            DrawType var4 = var3.getDrawType();
            var2 = var4 != DrawType.Cube && var4 != DrawType.CubeWithModel ? -1 : var0;
         }

         var1.put(var0, var2);
      }

      class="kw">return var2;
   }

   class="kw">public class="kw">static int[][][] bufferRegion(ChunkAccessor var0, Vector3i var1, int var2, int var3, int var4, int[][][] var5) {
      int[][][] var6 = new int[var2][var3][var4];
      Int2IntOpenHashMap var7 = new Int2IntOpenHashMap();
      var7.defaultReturnValue(Integer.MIN_VALUE);
      int var8 = var1.x - var2 / 2;
      int var9 = var8 + var2 - 1;
      int var10 = var1.z - var4 / 2;
      int var11 = var10 + var4 - 1;
      int var12 = var1.y - var3 / 2;
      int var13 = var8 >> 5;
      int var14 = var9 >> 5;
      int var15 = var10 >> 5;
      int var16 = var11 >> 5;

      for (int var17 = var13; var17 <= var14; var17++) {
         for (int var18 = var15; var18 <= var16; var18++) {
            WorldChunk var19 = var0.getChunk(ChunkUtil.indexChunk(var17, var18));
            if (var19 != null) {
               int var20 = Math.max(var8, var17 << 5);
               int var21 = Math.min(var9, (var17 << 5) + 31);
               int var22 = Math.max(var10, var18 << 5);
               int var23 = Math.min(var11, (var18 << 5) + 31);

               for (int var24 = var20; var24 <= var21; var24++) {
                  int var25 = var24 - var8;

                  for (int var26 = var22; var26 <= var23; var26++) {
                     int var27 = var26 - var10;

                     for (int var28 = 0; var28 < var3; var28++) {
                        int var29 = var12 + var28;
                        int var30 = var19.getBlock(var24, var29, var26);
                        var6[var25][var28][var27] = filterFullBlockForBuffer(var30, var7);
                        if (var5 != null) {
                           var5[var25][var28][var27] = var19.getFluidId(var24, var29, var26);
                        }
                     }
                  }
               }
            }
         }
      }

      class="kw">return var6;
   }

   class="kw">private record FluidFillEntry(int bx, int bz, int fluidId) {
      class="kw">private FluidFillEntry {
      }
   }

   class="kw">private enum FluidMode {
      IGNORE,
      FIX,
      REMOVE;

      FluidMode() {
      }
   }

   class="kw">public record Kernel(double stable, double range, int[] weights, int total) {
      class="kw">public Kernel(double var1, double var3, int[] var5) {
         this(var1, var3, var5, sumWeights(var5));
      }

      class="kw">public Kernel {
      }

      class="kw">private class="kw">static int sumWeights(int[] var0) {
         int var1 = 0;

         for (int var5 : var0) {
            var1 += var5;
         }

         class="kw">return var1;
      }
   }
}