AliveStatus enum

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

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

Поля (1)

МодификаторыТипИмя
ALIVE, DEMOTE, WAIT_FOR_ADJACENT_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.Codec;
class="kw">import com.hypixel.hytale.codec.KeyedCodec;
class="kw">import com.hypixel.hytale.codec.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.codec.lookup.CodecMapCodec;
class="kw">import com.hypixel.hytale.codec.validation.Validators;
class="kw">import com.hypixel.hytale.component.CommandBuffer;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.math.shape.Box;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.math.util.HashUtil;
class="kw">import com.hypixel.hytale.protocol.BlockMaterial;
class="kw">import com.hypixel.hytale.protocol.DrawType;
class="kw">import com.hypixel.hytale.server.core.asset.type.blockhitbox.BlockBoundingBoxes;
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.AbstractCachedAccessor;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.BlockOperations;
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 com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import com.hypixel.hytale.server.core.util.FillerBlockUtil;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector2i;

class="kw">public class="kw">abstract class FluidTicker {
   class="kw">public class="kw">static class="kw">final BuilderCodec<FluidTicker> BASE_CODEC = BuilderCodec.abstractBuilder(FluidTicker.class)
      .appendInherited(
         new KeyedCodec<>("FlowRate", Codec.FLOAT), (var0, var1) -> var0.flowRate = var1, var0 -> var0.flowRate, (var0, var1) -> var0.flowRate = var1.flowRate
      )
      .documentation("The tick frequency for this fluid type, in seconds")
      .addValidator(Validators.greaterThan(0.0F))
      .add()
      .<Boolean>appendInherited(
         new KeyedCodec<>("CanDemote", Codec.BOOLEAN),
         (var0, var1) -> var0.canDemote = var1,
         var0 -> var0.canDemote,
         (var0, var1) -> var0.canDemote = var1.canDemote
      )
      .documentation("If false then the fluid will stay at its level")
      .add()
      .appendInherited(
         new KeyedCodec<>("SupportedBy", Codec.STRING),
         (var0, var1) -> var0.supportedBy = var1,
         var0 -> var0.supportedBy,
         (var0, var1) -> var0.supportedBy = var1.supportedBy
      )
      .add()
      .build();
   class="kw">public class="kw">static class="kw">final CodecMapCodec<FluidTicker> CODEC = new CodecMapCodec<>("Type", true);
   class="kw">protected class="kw">static class="kw">final Vector2i[] ORTO_OFFSETS = new Vector2i[]{new Vector2i(-1, 0), new Vector2i(1, 0), new Vector2i(0, -1), new Vector2i(0, 1)};
   class="kw">protected class="kw">static class="kw">final int SPREAD_NO_PATH = Integer.MAX_VALUE;
   class="kw">protected class="kw">static class="kw">final int SPREAD_NO_CHUNK = 2147483646;
   class="kw">protected class="kw">static class="kw">final int OFFSET_DROP_NONE = 0;
   class="kw">public class="kw">static class="kw">final int FLUID_BLOCK_DISTANCE = 5;
   class="kw">private class="kw">static class="kw">final double FULL_DIMENSION_THRESHOLD = 0.9;
   class="kw">private class="kw">static class="kw">final double PARTIAL_DIMENSION_THRESHOLD = 0.6;
   class="kw">private class="kw">static class="kw">final double FACE_BLOCK_THRESHOLD = 0.1;
   class="kw">private float flowRate = 0.5F;
   class="kw">private boolean canDemote = true;
   class="kw">private String supportedBy;
   class="kw">private class="kw">transient int supportedById = 0;

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

   class="kw">public int getSupportedById() {
      if (this.supportedById == 0) {
         if (this.supportedBy != null) {
            this.supportedById = Fluid.getAssetMap().getIndex(this.supportedBy);
         } else {
            this.supportedById = Integer.MIN_VALUE;
         }
      }

      class="kw">return this.supportedById;
   }

   class="kw">public BlockTickStrategy tick(
      @Nonnull CommandBuffer<ChunkStore> var1,
      @Nonnull FluidTicker.CachedAccessor var2,
      @Nonnull FluidSection var3,
      @Nonnull BlockSection var4,
      @Nonnull Fluid var5,
      int var6,
      int var7,
      int var8,
      int var9
   ) {
      int var10 = var4.get(var7, var8, var9);
      if (!this.canOccupySolidBlocks() && isFullySolid(BlockType.getAssetMap().getAsset(var10))) {
         var3.setFluid(var7, var8, var9, 0, (byte)0);
         setTickingSurrounding(var2, var4, var7, var8, var9);
         class="kw">return BlockTickStrategy.SLEEP;
      } else {
         World var11 = var1.getExternalData().getWorld();
         long var12 = HashUtil.rehash(var7, var8, var9, 4030921250L);
         long var14 = var1.getExternalData().getWorld().getTick();
         int var16 = Math.round(this.flowRate * var11.getTps());
         class="kw">return (var12 + var14) % var16 != 0L ? BlockTickStrategy.CONTINUE : this.process(var11, var14, var2, var3, var4, var5, var6, var7, var8, var9);
      }
   }

   class="kw">public boolean canOccupySolidBlocks() {
      class="kw">return false;
   }

   class="kw">public BlockTickStrategy process(
      World var1,
      long var2,
      @Nonnull FluidTicker.Accessor var4,
      @Nonnull FluidSection var5,
      @Nonnull BlockSection var6,
      @Nonnull Fluid var7,
      int var8,
      int var9,
      int var10,
      int var11
   ) {
      byte var12 = var5.getFluidLevel(var9, var10, var11);

      class="kw">return class="kw">switch (this.isAlive(var4, var5, var6, var7, var8, var12, var9, var10, var11)) {
         case ALIVE -> this.spread(var1, var2, var4, var5, var6, var7, var8, var12, var9, var10, var11);
         case DEMOTE -> {
            if (var12 == 1) {
               var5.setFluid(var9, var10, var11, 0, (byte)0);
               setTickingSurrounding(var4, var6, var9, var10, var11);
               yield BlockTickStrategy.SLEEP;
            } else {
               var5.setFluid(var9, var10, var11, var8, (byte)((var12 == 0 ? var7.getMaxFluidLevel() : var12) - 1));
               setTickingSurrounding(var4, var6, var9, var10, var11);
               yield BlockTickStrategy.SLEEP;
            }
         }
         case WAIT_FOR_ADJACENT_CHUNK -> BlockTickStrategy.WAIT_FOR_ADJACENT_CHUNK_LOAD;
      };
   }

   @Nonnull
   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
   ) {
      if (!this.canDemote) {
         class="kw">return FluidTicker.AliveStatus.ALIVE;
      }

      int var10 = this.getSupportedById();
      BlockTypeAssetMap var11 = BlockType.getAssetMap();
      FluidSection var12 = ChunkUtil.chunkCoordinate(var8 + 1) == var2.getY() ? var2 : var1.getFluidSectionByBlock(var7, var8 + 1, var9);
      if (var12 == null) {
         class="kw">return FluidTicker.AliveStatus.WAIT_FOR_ADJACENT_CHUNK;
      }

      int var13 = var12.getFluidId(var7, var8 + 1, var9);
      if (var13 != var5 && var13 != var10) {
         BlockType var14 = var11.getAsset(var3.get(var7, var8, var9));
         int var15 = var3.getRotationIndex(var7, var8, var9);
         int var16 = var3.getFiller(var7, var8, var9);
         boolean var17 = false;

         for (Vector2i var21 : ORTO_OFFSETS) {
            int var22 = var21.x;
            int var23 = var21.y;
            int var24 = var22 + var7;
            int var25 = var8;
            int var26 = var23 + var9;
            boolean var27 = !ChunkUtil.isSameChunkSection(var7, var8, var9, var24, var25, var26);
            FluidSection var28 = var27 ? var1.getFluidSectionByBlock(var24, var25, var26) : var2;
            BlockSection var29 = var27 ? var1.getBlockSectionByBlock(var24, var25, var26) : var3;
            if (var28 != null && var29 != null) {
               int var30 = var28.getFluidId(var24, var8, var26);
               if (var10 != Integer.MIN_VALUE && var30 == var10) {
                  BlockType var35 = var11.getAsset(var29.get(var24, var25, var26));
                  if (var35 != null) {
                     int var36 = var29.getRotationIndex(var24, var25, var26);
                     int var37 = var29.getFiller(var24, var25, var26);
                     if (!this.blocksFluidFrom(var35, var36, var22, var23, var37) && !this.blocksFluidFrom(var14, var15, -var22, -var23, var16)) {
                        class="kw">return FluidTicker.AliveStatus.ALIVE;
                     }
                  }
               } else {
                  byte var31 = var28.getFluidLevel(var24, var25, var26);
                  if (var30 != 0 && var30 == var5 && var31 > var6) {
                     BlockType var32 = var11.getAsset(var29.get(var24, var25, var26));
                     if (var32 != null) {
                        int var33 = var29.getRotationIndex(var24, var25, var26);
                        int var34 = var29.getFiller(var24, var25, var26);
                        if (!this.blocksFluidFrom(var32, var33, var22, var23, var34) && !this.blocksFluidFrom(var14, var15, -var22, -var23, var16)) {
                           class="kw">return FluidTicker.AliveStatus.ALIVE;
                        }
                     }
                  }
               }
            } else {
               var17 = true;
            }
         }

         class="kw">return var17 ? FluidTicker.AliveStatus.WAIT_FOR_ADJACENT_CHUNK : FluidTicker.AliveStatus.DEMOTE;
      } else {
         class="kw">return FluidTicker.AliveStatus.ALIVE;
      }
   }

   class="kw">protected class="kw">abstract BlockTickStrategy spread(
      World var1, long var2, FluidTicker.Accessor var4, FluidSection var5, BlockSection var6, Fluid var7, int var8, byte var9, int var10, int var11, int var12
   );

   class="kw">public class="kw">static void setTickingSurrounding(@Nonnull FluidTicker.Accessor var0, BlockSection var1, int var2, int var3, int var4) {
      for (int var5 = -1; var5 <= 1; var5++) {
         for (int var6 = -1; var6 <= 1; var6++) {
            for (int var7 = -1; var7 <= 1; var7++) {
               int var8 = var2 + var7;
               int var9 = var3 + var5;
               int var10 = var4 + var6;
               BlockSection var11 = ChunkUtil.isSameChunkSection(var2, var3, var4, var8, var9, var10) ? var1 : var0.getBlockSectionByBlock(var8, var9, var10);
               if (var11 != null) {
                  var11.setTicking(var8, var9, var10, true);
               }
            }
         }
      }
   }

   class="kw">protected int getSpreadOffsets(
      @Nonnull BlockTypeAssetMap<String, BlockType> var1,
      @Nonnull FluidTicker.Accessor var2,
      @Nonnull FluidSection var3,
      BlockSection var4,
      int var5,
      int var6,
      int var7,
      @Nonnull Vector2i[] var8,
      int var9,
      int var10
   ) {
      int var11 = Integer.MAX_VALUE;
      int var12 = 0;

      for (int var13 = 0; var13 < var8.length; var13++) {
         Vector2i var14 = var8[var13];
         int var15 = this.distanceToDrop(var1, var2, var3, var4, var5, var6, var7, var14, var9, var10);
         if (var15 == 2147483646) {
            class="kw">return 2147483646;
         }

         if (var15 < var11) {
            var12 = 0;
            var11 = var15;
         }

         if (var15 <= var11 && var15 != Integer.MAX_VALUE) {
            var12 |= 1 << var13;
         }
      }

      class="kw">return var12;
   }

   class="kw">protected int distanceToDrop(
      @Nonnull BlockTypeAssetMap<String, BlockType> var1,
      @Nonnull FluidTicker.Accessor var2,
      @Nonnull FluidSection var3,
      BlockSection var4,
      int var5,
      int var6,
      int var7,
      @Nonnull Vector2i var8,
      int var9,
      int var10
   ) {
      int var11 = var8.x;
      int var12 = var8.y;
      int var13 = var6 - 1;
      FluidSection var14 = var3;
      BlockSection var15 = var4;
      boolean var16 = var3.getY() != ChunkUtil.chunkCoordinate(var13);
      if (var16) {
         var14 = var2.getFluidSectionByBlock(var5, var13, var7);
         var15 = var2.getBlockSectionByBlock(var5, var13, var7);
      }

      int var17 = var5;
      int var18 = var7;
      int var19 = this.getSupportedById();

      for (int var20 = 1; var20 < var10; var20++) {
         int var21 = var5 + var11 * var20;
         int var22 = var7 + var12 * var20;
         if (!ChunkUtil.isSameChunk(var17, var18, var21, var22)) {
            var17 = var21;
            var18 = var22;
            var3 = var2.getFluidSectionByBlock(var21, var6, var22);
            var4 = var2.getBlockSectionByBlock(var21, var6, var22);
            if (var16) {
               var14 = var2.getFluidSectionByBlock(var5, var13, var7);
               var15 = var2.getBlockSectionByBlock(var5, var13, var7);
            } else {
               var14 = var3;
               var15 = var4;
            }
         }

         if (var3 == null || var4 == null || var14 == null || var15 == null) {
            class="kw">return 2147483646;
         }

         int var23 = var3.getFluidId(var21, var6, var22);
         BlockType var24 = var1.getAsset(var4.get(var21, var6, var22));
         if (var23 != 0 && (var23 != var9 || var23 == var19 || var19 == Integer.MIN_VALUE) || var23 == 0 && isSolid(var24)) {
            break;
         }

         BlockType var25 = var1.getAsset(var15.get(var21, var13, var22));
         if (!isSolid(var25)) {
            class="kw">return var20;
         }
      }

      class="kw">return Integer.MAX_VALUE;
   }

   class="kw">public class="kw">static boolean isFullySolid(@Nonnull BlockType var0) {
      DrawType var1 = var0.getDrawType();
      class="kw">return var0.getMaterial() == BlockMaterial.Solid && (var1 == DrawType.Cube || var1 == DrawType.CubeWithModel);
   }

   class="kw">public class="kw">static boolean isSolid(@Nonnull BlockType var0) {
      DrawType var1 = var0.getDrawType();
      class="kw">return var1 == DrawType.Cube || var1 == DrawType.CubeWithModel;
   }

   class="kw">public boolean blocksFluidFrom(@Nonnull BlockType var1, int var2, int var3, int var4) {
      class="kw">return this.blocksFluidFrom(var1, var2, var3, var4, 0);
   }

   class="kw">public boolean blocksFluidFrom(@Nonnull BlockType var1, int var2, int var3, int var4, int var5) {
      if (var1.getMaterial() != BlockMaterial.Solid) {
         class="kw">return false;
      }

      if (isFullySolid(var1)) {
         class="kw">return true;
      }

      int var6 = var1.getHitboxTypeIndex();
      BlockBoundingBoxes var7 = BlockBoundingBoxes.getAssetMap().getAsset(var6);
      if (var7 == null) {
         class="kw">return true;
      }

      BlockBoundingBoxes.RotatedVariantBoxes var8 = var7.get(var2);
      Box var9 = var8.getBoundingBox();
      if (!var7.protrudesUnitBox() && var5 == 0) {
         double var40 = var9.max.x - var9.min.x;
         double var41 = var9.max.y - var9.min.y;
         double var42 = var9.max.z - var9.min.z;
         boolean var43 = var41 > 0.9;
         if (!var43) {
            class="kw">return false;
         }

         boolean var44 = var42 > 0.9;
         boolean var45 = var40 < 0.6;
         if (!var45 || !var44) {
            boolean var46 = var40 > 0.9;
            boolean var47 = var42 < 0.6;
            if (!var46 || !var47) {
               Box[] var21 = var8.getDetailBoxes();
               if (var21.length > 1) {
                  class="kw">return boxesBlockFace(var21, var3, var4);
               }

               double var48 = 0.0;
               if (var3 > 0 && var9.min.x < 0.1) {
                  var48 = var41 * var42;
               } else if (var3 < 0 && var9.max.x > 0.9) {
                  var48 = var41 * var42;
               } else if (var4 > 0 && var9.min.z < 0.1) {
                  var48 = var41 * var40;
               } else if (var4 < 0 && var9.max.z > 0.9) {
                  var48 = var41 * var40;
               }

               class="kw">return var48 > 0.9;
            } else if (var4 == 0) {
               class="kw">return false;
            } else {
               class="kw">return var4 > 0 ? var9.min.z < 0.1 : var9.max.z > 0.9;
            }
         } else if (var3 == 0) {
            class="kw">return false;
         } else {
            class="kw">return var3 > 0 ? var9.min.x < 0.1 : var9.max.x > 0.9;
         }
      } else {
         int var10 = FillerBlockUtil.unpackX(var5);
         int var11 = FillerBlockUtil.unpackY(var5);
         int var12 = FillerBlockUtil.unpackZ(var5);
         Box[] var13 = var8.getDetailBoxes();
         double var14 = 0.0;

         for (Box var19 : var13) {
            double var20 = Math.max(var19.min.x, var10);
            double var22 = Math.min(var19.max.x, var10 + 1);
            double var24 = Math.max(var19.min.y, var11);
            double var26 = Math.min(var19.max.y, var11 + 1);
            double var28 = Math.max(var19.min.z, var12);
            double var30 = Math.min(var19.max.z, var12 + 1);
            if (!(var22 <= var20) && !(var26 <= var24) && !(var30 <= var28)) {
               double var32 = var22 - var20;
               double var34 = var26 - var24;
               double var36 = var30 - var28;
               double var38 = 0.0;
               if (var3 != 0) {
                  var38 = var34 * var36;
               } else if (var4 != 0) {
                  var38 = var34 * var32;
               }

               var14 = Math.max(var14, var38);
            }
         }

         class="kw">return var14 > 0.9;
      }
   }

   class="kw">private class="kw">static boolean boxesBlockFace(Box[] var0, int var1, int var2) {
      double var3 = 0.0;

      for (Box var8 : var0) {
         double var9 = 0.0;
         if (var1 > 0 && var8.min.x < 0.1) {
            double var17 = var8.max.y - var8.min.y;
            double var20 = var8.max.z - var8.min.z;
            var9 = var17 * var20;
         } else if (var1 < 0 && var8.max.x > 0.9) {
            double var16 = var8.max.y - var8.min.y;
            double var19 = var8.max.z - var8.min.z;
            var9 = var16 * var19;
         } else if (var2 > 0 && var8.min.z < 0.1) {
            double var15 = var8.max.y - var8.min.y;
            double var18 = var8.max.x - var8.min.x;
            var9 = var15 * var18;
         } else if (var2 < 0 && var8.max.z > 0.9) {
            double var11 = var8.max.y - var8.min.y;
            double var13 = var8.max.x - var8.min.x;
            var9 = var11 * var13;
         }

         var3 += var9;
      }

      class="kw">return var3 > 0.9;
   }

   class="kw">public boolean isSelfFluid(int var1, int var2) {
      class="kw">return var1 == var2 || var2 == this.getSupportedById();
   }

   class="kw">public boolean canDemote() {
      class="kw">return this.canDemote;
   }

   class="kw">public class="kw">interface Accessor {
      @Nullable
      FluidSection getFluidSection(int var1, int var2, int var3);

      @Nullable
      class="kw">default FluidSection getFluidSectionByBlock(int var1, int var2, int var3) {
         class="kw">return this.getFluidSection(ChunkUtil.chunkCoordinate(var1), ChunkUtil.chunkCoordinate(var2), ChunkUtil.chunkCoordinate(var3));
      }

      @Nullable
      BlockSection getBlockSection(int var1, int var2, int var3);

      @Nullable
      class="kw">default BlockSection getBlockSectionByBlock(int var1, int var2, int var3) {
         class="kw">return this.getBlockSection(ChunkUtil.chunkCoordinate(var1), ChunkUtil.chunkCoordinate(var2), ChunkUtil.chunkCoordinate(var3));
      }

      @Deprecated(forRemoval = true)
      void setBlock(int var1, int var2, int var3, int var4);
   }

   class="kw">public enum AliveStatus {
      ALIVE,
      DEMOTE,
      WAIT_FOR_ADJACENT_CHUNK;

      AliveStatus() {
      }
   }

   class="kw">public class="kw">static class CachedAccessor class="kw">extends AbstractCachedAccessor class="kw">implements FluidTicker.Accessor {
      class="kw">private class="kw">static class="kw">final ThreadLocal<FluidTicker.CachedAccessor> THREAD_LOCAL = ThreadLocal.withInitial(FluidTicker.CachedAccessor::new);
      class="kw">private class="kw">static class="kw">final AbstractCachedAccessor.Registry REGISTRY = new AbstractCachedAccessor.Registry();
      class="kw">private class="kw">static class="kw">final AbstractCachedAccessor.Key<FluidSection> FLUID_COMPONENT = REGISTRY.forSection(FluidSection::getComponentType);
      class="kw">private class="kw">static class="kw">final AbstractCachedAccessor.Key<BlockSection> BLOCK_COMPONENT = REGISTRY.forSection(BlockSection::getComponentType);
      class="kw">private CommandBuffer<ChunkStore> commandBuffer;
      class="kw">public FluidSection selfFluidSection;
      class="kw">public BlockSection selfBlockSection;

      class="kw">protected CachedAccessor() {
         super(REGISTRY);
      }

      @Nonnull
      class="kw">public class="kw">static FluidTicker.CachedAccessor of(CommandBuffer<ChunkStore> var0, @Nonnull FluidSection var1, BlockSection var2, int var3) {
         FluidTicker.CachedAccessor var4 = THREAD_LOCAL.get();
         var4.init(var0, var1, var2, var3);
         var4.insertSectionComponent(FLUID_COMPONENT, var1, var1.getX(), var1.getY(), var1.getZ());
         var4.insertSectionComponent(BLOCK_COMPONENT, var2, var1.getX(), var1.getY(), var1.getZ());
         class="kw">return var4;
      }

      class="kw">private void init(CommandBuffer<ChunkStore> var1, @Nonnull FluidSection var2, BlockSection var3, int var4) {
         this.init(var1, var2.getX(), var2.getY(), var2.getZ(), var4);
         this.commandBuffer = var1;
         this.selfFluidSection = var2;
         this.selfBlockSection = var3;
      }

      @Override
      class="kw">public FluidSection getFluidSection(int var1, int var2, int var3) {
         class="kw">return this.getComponentSection(var1, var2, var3, FLUID_COMPONENT);
      }

      @Override
      class="kw">public BlockSection getBlockSection(int var1, int var2, int var3) {
         class="kw">return this.getComponentSection(var1, var2, var3, BLOCK_COMPONENT);
      }

      @Override
      class="kw">public void setBlock(int var1, int var2, int var3, int var4) {
         Ref var5 = this.getSection(ChunkUtil.chunkCoordinate(var1), ChunkUtil.chunkCoordinate(var2), ChunkUtil.chunkCoordinate(var3));
         if (var5 != null && var5.isValid()) {
            this.commandBuffer.run(var5x -> {
               if (var5.isValid()) {
                  BlockOperations.setBlock(var5x.getExternalData(), var5, var1, var2, var3, var4, BlockType.getAssetMap().getAsset(var4), 0, 0, 0);
               }
            });
         }
      }
   }
}