SpreadOutcome enum

Пакет: com.hypixel.hytale.server.core.asset.type.fluid

Файл: com/hypixel/hytale/server/core/asset/type/fluid/FiniteFluidTicker.java

Поля (1)

МодификаторыТипИмя
SUCCESS, UNLOADED_CHUNK

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.asset.type.fluid;

class="kw">import com.hypixel.hytale.assetstore.map.BlockTypeAssetMap;
class="kw">import com.hypixel.hytale.codec.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.math.util.HashUtil;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktick.BlockTickStrategy;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.FluidSection;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import java.util.Arrays;
class="kw">import java.util.Collections;
class="kw">import java.util.List;
class="kw">import java.util.Random;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector2i;

class="kw">public class FiniteFluidTicker class="kw">extends FluidTicker {
   @Nonnull
   class="kw">public class="kw">static class="kw">final BuilderCodec<FiniteFluidTicker> CODEC = BuilderCodec.builder(FiniteFluidTicker.class, FiniteFluidTicker::new, FluidTicker.BASE_CODEC)
      .build();
   @Nonnull
   class="kw">private class="kw">static class="kw">final Vector2i[] DIAG_OFFSETS = new Vector2i[]{new Vector2i(-1, -1), new Vector2i(1, 1), new Vector2i(1, -1), new Vector2i(-1, 1)};
   class="kw">private class="kw">static class="kw">final int MAX_DROP_DISTANCE = 2;
   @Nonnull
   class="kw">private class="kw">static class="kw">final List<List<Vector2i[]>> OFFSETS_LISTS = new ObjectArrayList();
   class="kw">private class="kw">static class="kw">final int RANDOM_VARIANTS = 16;

   class="kw">public FiniteFluidTicker() {
   }

   @Nonnull
   @Override
   class="kw">protected FluidTicker.AliveStatus isAlive(
      @Nonnull FluidTicker.Accessor var1, @Nonnull FluidSection var2, @Nonnull BlockSection var3, Fluid var4, int var5, byte var6, int var7, int var8, int var9
   ) {
      class="kw">return FluidTicker.AliveStatus.ALIVE;
   }

   @Nonnull
   @Override
   class="kw">protected BlockTickStrategy spread(
      World var1,
      long var2,
      @Nonnull FluidTicker.Accessor var4,
      @Nonnull FluidSection var5,
      BlockSection var6,
      @Nonnull Fluid var7,
      int var8,
      byte var9,
      int var10,
      int var11,
      int var12
   ) {
      boolean var13 = var5.getY() != ChunkUtil.chunkCoordinate(var11 - 1);
      FluidSection var14 = var13 ? var4.getFluidSectionByBlock(var10, var11 - 1, var12) : var5;
      BlockSection var15 = var13 ? var4.getBlockSectionByBlock(var10, var11 - 1, var12) : var6;
      if (var14 != null && var15 != null) {
         int var16 = var14.getFluidId(var10, var11 - 1, var12);
         byte var17 = var14.getFluidLevel(var10, var11 - 1, var12);
         class="kw">return this.spreadDownwards(var4, var5, var6, var14, var15, var10, var11, var12, var7, var8, var9, var16, var17)
            ? BlockTickStrategy.CONTINUE
            : this.spreadSideways(var2, var4, var5, var6, var10, var11, var12, var7, var8, var9);
      } else {
         class="kw">return BlockTickStrategy.WAIT_FOR_ADJACENT_CHUNK_LOAD;
      }
   }

   class="kw">private boolean spreadDownwards(
      @Nonnull FluidTicker.Accessor var1,
      @Nonnull FluidSection var2,
      BlockSection var3,
      @Nonnull FluidSection var4,
      @Nonnull BlockSection var5,
      int var6,
      int var7,
      int var8,
      @Nonnull Fluid var9,
      int var10,
      byte var11,
      int var12,
      byte var13
   ) {
      if (var10 != var12 && var12 != 0) {
         class="kw">return false;
      }

      if (isSolid(BlockType.getAssetMap().getAsset(var5.get(var6, var7 - 1, var8)))) {
         class="kw">return false;
      }

      int var14 = this.getTopY(var1, var2, var6, var7, var8, var9, var10);
      boolean var15 = ChunkUtil.chunkCoordinate(var14) != var2.getY();
      FluidSection var16 = var15 ? var1.getFluidSectionByBlock(var6, var14, var8) : var2;
      BlockSection var17 = var15 ? var1.getBlockSectionByBlock(var6, var14, var8) : var3;
      int var18 = var16.getFluidLevel(var6, var14, var8);
      int var19 = Math.min(var18, var9.getMaxFluidLevel() - var13);
      if (var19 == 0) {
         class="kw">return false;
      }

      int var20 = var12 == 0 ? var19 : var13 + var19;
      var4.setFluid(var6, var7 - 1, var8, var10, (byte)var20);
      setTickingSurrounding(var1, var5, var6, var7 - 1, var8);
      boolean var21;
      if (var19 == var18) {
         var21 = var16.setFluid(var6, var14, var8, 0, (byte)0);
      } else {
         var21 = var16.setFluid(var6, var14, var8, var10, (byte)(var18 - var19));
      }

      setTickingSurrounding(var1, var17, var6, var14, var8);
      class="kw">return var21;
   }

   @Nonnull
   class="kw">private BlockTickStrategy spreadSideways(
      long var1,
      @Nonnull FluidTicker.Accessor var3,
      @Nonnull FluidSection var4,
      BlockSection var5,
      int var6,
      int var7,
      int var8,
      @Nonnull Fluid var9,
      int var10,
      byte var11
   ) {
      if (var11 == 1) {
         class="kw">return BlockTickStrategy.SLEEP;
      }

      int var12 = var11;
      BlockTypeAssetMap var13 = BlockType.getAssetMap();
      long var14 = HashUtil.rehash(var6, var7, var8, 4032035379L);
      int var16 = OFFSETS_LISTS.size() + (int)((var14 + var1) % OFFSETS_LISTS.size());
      List var17 = OFFSETS_LISTS.get(var16 % OFFSETS_LISTS.size());

      for (int var18 = 0; var18 < var17.size(); var18++) {
         Vector2i[] var19 = var17.get(var18);
         int var20 = this.getSpreadOffsets(var13, var3, var4, var5, var6, var7, var8, var19, var10, 2);
         boolean var21 = var20 != 0;

         for (int var22 = 0; var22 < var19.length && var12 != 1; var22++) {
            if (!var21 || (var20 & 1 << var22) != 0) {
               Vector2i var23 = var19[var22];
               FiniteFluidTicker.SpreadOutcome var24 = this.spreadToOffset(var3, var4, var5, var23, var6, var7, var8, var9, var10, var11);
               if (var24 != null) {
                  class="kw">switch (var24) {
                     case SUCCESS:
                        var12--;
                        break;
                     case UNLOADED_CHUNK:
                        class="kw">return BlockTickStrategy.WAIT_FOR_ADJACENT_CHUNK_LOAD;
                  }
               }
            }
         }

         if (var21) {
            break;
         }
      }

      if (var12 == var11) {
         class="kw">return BlockTickStrategy.SLEEP;
      } else {
         class="kw">return !this.drainFromTopBlock(var3, var4, var5, var6, var7, var8, var9, var10, (byte)(var11 - var12))
            ? BlockTickStrategy.WAIT_FOR_ADJACENT_CHUNK_LOAD
            : BlockTickStrategy.CONTINUE;
      }
   }

   @Nullable
   class="kw">private FiniteFluidTicker.SpreadOutcome spreadToOffset(
      @Nonnull FluidTicker.Accessor var1,
      FluidSection var2,
      BlockSection var3,
      @Nonnull Vector2i var4,
      int var5,
      int var6,
      int var7,
      Fluid var8,
      int var9,
      byte var10
   ) {
      if (!isOffsetConnected(var1, var3, var4, var5, var6, var7)) {
         class="kw">return null;
      }

      int var11 = var4.x();
      int var12 = var4.y();
      int var13 = var5 + var11;
      int var14 = var7 + var12;
      boolean var15 = !ChunkUtil.isSameChunkSection(var5, var6, var7, var13, var6, var14);
      FluidSection var16 = var15 ? var1.getFluidSectionByBlock(var13, var6, var14) : var2;
      BlockSection var17 = var15 ? var1.getBlockSectionByBlock(var13, var6, var14) : var3;
      if (var16 != null && var17 != null) {
         int var18 = var17.get(var13, var6, var14);
         BlockType var19 = BlockType.getAssetMap().getAsset(var18);
         if (isSolid(var19)) {
            class="kw">return null;
         }

         int var20 = var16.getFluidId(var13, var6, var14);
         byte var21 = var16.getFluidLevel(var13, var6, var14);
         int var22 = 1;
         if (var20 == 0 || var20 == var9 && var21 < var10 - 1) {
            if (var20 == var9) {
               var22 = var21 + 1;
            }

            if (var16.setFluid(var13, var6, var14, var9, (byte)var22)) {
               setTickingSurrounding(var1, var17, var13, var6, var14);
               class="kw">return FiniteFluidTicker.SpreadOutcome.SUCCESS;
            }
         }

         class="kw">return null;
      } else {
         class="kw">return FiniteFluidTicker.SpreadOutcome.UNLOADED_CHUNK;
      }
   }

   class="kw">private boolean drainFromTopBlock(
      @Nonnull FluidTicker.Accessor var1, @Nonnull FluidSection var2, BlockSection var3, int var4, int var5, int var6, @Nonnull Fluid var7, int var8, byte var9
   ) {
      int var10 = this.getTopY(var1, var2, var4, var5, var6, var7, var8);
      boolean var11 = var2.getY() != ChunkUtil.chunkCoordinate(var10);
      FluidSection var12 = var11 ? var1.getFluidSectionByBlock(var4, var10, var6) : var2;
      BlockSection var13 = var11 ? var1.getBlockSectionByBlock(var4, var10, var6) : var3;
      if (var12 != null && var13 != null) {
         byte var14 = var12.getFluidLevel(var4, var10, var6);
         if (var14 > var9) {
            setTickingSurrounding(var1, var13, var4, var10, var6);
            class="kw">return var12.setFluid(var4, var10, var6, var8, (byte)(var14 - var9));
         }

         if (var14 == var9) {
            setTickingSurrounding(var1, var13, var4, var10, var6);
            class="kw">return var12.setFluid(var4, var10, var6, 0, (byte)0);
         }

         int var15 = var10;
         boolean var16 = true;
         FluidSection var17 = var12;
         BlockSection var18 = var13;

         while (var9 > 0) {
            boolean var19 = ChunkUtil.chunkCoordinate(var15) != var17.getY();
            if (var19) {
               var17 = var1.getFluidSectionByBlock(var4, var15, var6);
               var18 = var1.getBlockSectionByBlock(var4, var15, var6);
               if (var17 == null || var18 == null) {
                  class="kw">return false;
               }
            }

            int var20 = var17.getFluidLevel(var4, var15, var6);
            int var21 = Math.min(var20, var9);
            if (var21 == var20) {
               var16 &= var17.setFluid(var4, var15, var6, 0, (byte)0);
            } else {
               var16 &= var17.setFluid(var4, var15, var6, var8, (byte)var20);
               setTickingSurrounding(var1, var18, var4, var15, var6);
            }

            var9 -= (byte)var21;
            var15--;
         }

         class="kw">return var16;
      } else {
         class="kw">return false;
      }
   }

   class="kw">private int getTopY(@Nonnull FluidTicker.Accessor var1, @Nonnull FluidSection var2, int var3, int var4, int var5, @Nonnull Fluid var6, int var7) {
      int var8 = var4;
      FluidSection var9 = var2.getY() != ChunkUtil.chunkCoordinate(var8 + 1) ? var1.getFluidSectionByBlock(var3, var8 + 1, var5) : var2;

      while (true) {
         if (var2.getY() != ChunkUtil.chunkCoordinate(var8)) {
            var2 = var1.getFluidSectionByBlock(var3, var8, var5);
         }

         if (var9.getY() != ChunkUtil.chunkCoordinate(var8 + 1)) {
            var9 = var1.getFluidSectionByBlock(var3, var8 + 1, var5);
         }

         if (var2.getFluidLevel(var3, var8, var5) != var6.getMaxFluidLevel() || var9.getFluidId(var3, var8 + 1, var5) != var7) {
            class="kw">return var8;
         }

         var8++;
      }
   }

   class="kw">private class="kw">static boolean isOffsetConnected(@Nonnull FluidTicker.Accessor var0, BlockSection var1, @Nonnull Vector2i var2, int var3, int var4, int var5) {
      int var6 = var2.x();
      int var7 = var2.y();
      if (var6 != 0 && var7 != 0) {
         BlockSection var8 = ChunkUtil.isSameChunkSection(var3, var4, var5, var3 + var6, var4, var5) ? var1 : var0.getBlockSection(var3 + var6, var4, var5);
         BlockSection var9 = ChunkUtil.isSameChunkSection(var3, var4, var5, var3, var4, var5 + var7) ? var1 : var0.getBlockSection(var3, var4, var5 + var7);
         if (var8 != null && var9 != null) {
            int var10 = var8.get(var3 + var6, var4, var5);
            int var11 = var9.get(var3, var4, var5 + var7);
            class="kw">return var10 == 0 || var11 == 0 || !isSolid(BlockType.getAssetMap().getAsset(var10)) || !isSolid(BlockType.getAssetMap().getAsset(var11));
         } else {
            class="kw">return false;
         }
      } else {
         class="kw">return true;
      }
   }

   class="kw">static {
      List var0 = List.of(ORTO_OFFSETS, DIAG_OFFSETS);
      Random var1 = new Random(51966L);

      for (int var2 = 0; var2 < 16; var2++) {
         ObjectArrayList var3 = new ObjectArrayList();

         for (Vector2i[] var5 : var0) {
            List var6 = Arrays.asList(var5);
            Collections.shuffle(var6, var1);
            var3.add(var6.toArray(Vector2i[]::new));
         }

         OFFSETS_LISTS.add(var3);
      }
   }

   class="kw">private enum SpreadOutcome {
      SUCCESS,
      UNLOADED_CHUNK;

      SpreadOutcome() {
      }
   }
}