Bounds enum

Пакет: com.hypixel.hytale.builtin.triggervolumes.effect.builtin

Файл: com/hypixel/hytale/builtin/triggervolumes/effect/builtin/ReplaceBlockTypeEffect.java

Поля (1)

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

Исходный код

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

class="kw">import com.hypixel.hytale.builtin.triggervolumes.YawRotation;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.EffectOrigin;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.TriggerContext;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.effect.TriggerEffect;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.manager.VolumeEntry;
class="kw">import com.hypixel.hytale.builtin.triggervolumes.shape.TriggerVolumeShape;
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.codecs.EnumCodec;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.math.block.BlockUtil;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.math.util.MathUtil;
class="kw">import com.hypixel.hytale.math.vector.Vector3dUtil;
class="kw">import com.hypixel.hytale.server.core.asset.type.blockhitbox.BlockBoundingBoxes;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.Rotation;
class="kw">import com.hypixel.hytale.server.core.asset.type.blocktype.config.RotationTuple;
class="kw">import com.hypixel.hytale.server.core.asset.type.fluid.Fluid;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.mask.BlockFilter;
class="kw">import com.hypixel.hytale.server.core.universe.world.World;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.BlockChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.ChunkColumn;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
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 it.unimi.dsi.fastutil.ints.IntIterator;
class="kw">import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
class="kw">import it.unimi.dsi.fastutil.ints.IntSet;
class="kw">import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Vector3d;

class="kw">public class ReplaceBlockTypeEffect class="kw">extends TriggerEffect {
   @Nonnull
   class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
   class="kw">private class="kw">static class="kw">final String[] STRINGS = new String[0];
   @Nonnull
   class="kw">public class="kw">static class="kw">final BuilderCodec<ReplaceBlockTypeEffect> CODEC = BuilderCodec.builder(ReplaceBlockTypeEffect.class, ReplaceBlockTypeEffect::new, BASE_CODEC)
      .append(
         new KeyedCodec<>("FromBlockTypes", Codec.STRING_ARRAY),
         (var0, var1) -> var0.fromBlockTypes = var1 != null ? var1 : STRINGS,
         var0 -> var0.fromBlockTypes.length == 0 ? null : var0.fromBlockTypes
      )
      .add()
      .append(new KeyedCodec<>("FromBlockState", Codec.STRING, false), (var0, var1) -> var0.fromBlockState = var1, var0 -> var0.fromBlockState)
      .add()
      .append(new KeyedCodec<>("ToBlockType", Codec.STRING), (var0, var1) -> var0.toBlockType = var1, var0 -> var0.toBlockType)
      .add()
      .append(new KeyedCodec<>("ToBlockState", Codec.STRING, false), (var0, var1) -> var0.toBlockState = var1, var0 -> var0.toBlockState)
      .add()
      .append(
         new KeyedCodec<>("Bounds", new EnumCodec<>(ReplaceBlockTypeEffect.Bounds.class), false),
         (var0, var1) -> var0.bounds = var1 != null ? var1 : ReplaceBlockTypeEffect.Bounds.SHAPE,
         var0 -> var0.bounds
      )
      .add()
      .append(new KeyedCodec<>("X", Codec.FLOAT, false), (var0, var1) -> var0.sizeX = var1 != null ? var1 : 0.0F, var0 -> var0.sizeX)
      .add()
      .append(new KeyedCodec<>("Y", Codec.FLOAT, false), (var0, var1) -> var0.sizeY = var1 != null ? var1 : 0.0F, var0 -> var0.sizeY)
      .add()
      .append(new KeyedCodec<>("Z", Codec.FLOAT, false), (var0, var1) -> var0.sizeZ = var1 != null ? var1 : 0.0F, var0 -> var0.sizeZ)
      .add()
      .append(new KeyedCodec<>("Offset", Vector3dUtil.CODEC, false), (var0, var1) -> var0.offset = var1 != null ? var1 : new Vector3d(), var0 -> var0.offset)
      .add()
      .append(
         new KeyedCodec<>("Origin", new EnumCodec<>(EffectOrigin.class), false),
         (var0, var1) -> var0.origin = var1 != null ? var1 : EffectOrigin.VOLUME_ORIGIN,
         var0 -> var0.origin
      )
      .add()
      .append(new KeyedCodec<>("Rotation", new EnumCodec<>(Rotation.class), false), (var0, var1) -> var0.rotation = var1, var0 -> var0.rotation)
      .add()
      .append(new KeyedCodec<>("Pitch", new EnumCodec<>(Rotation.class), false), (var0, var1) -> var0.pitch = var1, var0 -> var0.pitch)
      .add()
      .append(new KeyedCodec<>("Roll", new EnumCodec<>(Rotation.class), false), (var0, var1) -> var0.roll = var1, var0 -> var0.roll)
      .add()
      .build();
   @Nonnull
   class="kw">private String[] fromBlockTypes = STRINGS;
   @Nullable
   class="kw">private String fromBlockState;
   @Nullable
   class="kw">private String toBlockType;
   @Nullable
   class="kw">private String toBlockState;
   @Nonnull
   class="kw">private ReplaceBlockTypeEffect.Bounds bounds = ReplaceBlockTypeEffect.Bounds.SHAPE;
   class="kw">private float sizeX;
   class="kw">private float sizeY;
   class="kw">private float sizeZ;
   @Nonnull
   class="kw">private Vector3d offset = new Vector3d();
   @Nonnull
   class="kw">private EffectOrigin origin = EffectOrigin.VOLUME_ORIGIN;
   @Nonnull
   class="kw">private Rotation rotation = Rotation.None;
   @Nonnull
   class="kw">private Rotation pitch = Rotation.None;
   @Nonnull
   class="kw">private Rotation roll = Rotation.None;

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

   @Override
   class="kw">public void execute(@Nonnull TriggerContext var1) {
      if (this.fromBlockTypes.length != 0 && this.toBlockType != null && !this.toBlockType.isBlank()) {
         World var2 = var1.getStore().getExternalData().getWorld();
         ReplaceBlockTypeEffect.TargetType var3 = this.resolveToTarget();
         if (var3 != null) {
            BlockFilter.BlocksAndFluids var4 = BlockFilter.parseBlocksAndFluids(this.fromBlockTypes);
            IntSet var5 = this.resolveFromBlocks(var4.blocks());
            IntSet var6 = var4.fluids();
            if (!var5.isEmpty() || var6 != null && !var6.isEmpty()) {
               ChunkStore var7 = var2.getChunkStore();
               Store var8 = var7.getStore();
               Vector3d var9 = new Vector3d();
               Vector3d var10 = new Vector3d();
               Vector3d var11 = new Vector3d();
               LongOpenHashSet var12 = new LongOpenHashSet();

               for (VolumeEntry var14 : var1.getSpatialVolumes()) {
                  TriggerVolumeShape var15 = var14.getShape();
                  Vector3d var16 = var14.getPosition();
                  if (this.bounds == ReplaceBlockTypeEffect.Bounds.AABB) {
                     Vector3d var17 = this.origin == EffectOrigin.VOLUME_ORIGIN
                        ? var16
                        : var1.resolveOrigin(this.origin, null, TriggerContext.MissingActor.FALLBACK_TO_VOLUME);
                     this.getConfiguredAABB(var17, var9, var10);
                  } else {
                     var15.getWorldAABB(var16, var9, var10);
                  }

                  int var36 = MathUtil.floor(var9.x());
                  int var18 = MathUtil.floor(var9.y());
                  int var19 = MathUtil.floor(var9.z());
                  int var20 = MathUtil.floor(var10.x());
                  int var21 = MathUtil.floor(var10.y());
                  int var22 = MathUtil.floor(var10.z());

                  for (int var23 = var36; var23 <= var20; var23++) {
                     for (int var24 = var18; var24 <= var21; var24++) {
                        if (var24 >= 0 && var24 < 320) {
                           for (int var25 = var19; var25 <= var22; var25++) {
                              if (this.containsBlock(var15, var16, var9, var10, var11, var23, var24, var25)) {
                                 Ref var26 = var7.getChunkReference(ChunkUtil.indexChunkFromBlock(var23, var25));
                                 if (var26 != null && var26.isValid()) {
                                    BlockChunk var27 = var8.getComponent(var26, BlockChunk.getComponentType());
                                    if (var27 != null) {
                                       BlockSection var28 = var27.getSectionAtBlockY(var24);
                                       int var29 = var27.getBlock(var23, var24, var25);
                                       int var30 = var28.getFiller(var23, var24, var25);
                                       boolean var31 = var6 != null && !var6.isEmpty() && matchesFluid(var8, var26, var6, var23, var24, var25);
                                       if ((var30 == 0 || var31) && (var5.contains(var29) || var31)) {
                                          WorldChunk var32 = var8.getComponent(var26, WorldChunk.getComponentType());
                                          if (var32 != null) {
                                             boolean var33 = var30 != 0;
                                             boolean var34 = this.rotation != Rotation.None || this.pitch != Rotation.None || this.roll != Rotation.None;
                                             int var35 = var34 ? RotationTuple.index(this.rotation, this.pitch, this.roll) : -1;
                                             replaceMatchedCell(var7, var26, var32, var28, var33, var23, var24, var25, var3, var35, var12);
                                          }
                                       }
                                    }
                                 }
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }

   @Nullable
   class="kw">private ReplaceBlockTypeEffect.TargetType resolveToTarget() {
      BlockFilter.BlocksAndFluids var1 = BlockFilter.parseBlocksAndFluids(new String[]{this.toBlockType});
      if (var1.hasInvalidBlocks()) {
         LOGGER.at(Level.FINE).log("ReplaceBlockType: unknown ToBlockType '%s'", this.toBlockType);
         class="kw">return null;
      }

      int var2 = var1.blocks().size();
      int var3 = var1.fluids() != null ? var1.fluids().size() : 0;
      if (var2 + var3 != 1) {
         LOGGER.at(Level.FINE).log("ReplaceBlockType: ToBlockType '%s' resolves to %d blocks and %d fluids", this.toBlockType, var2, var3);
         class="kw">return null;
      }

      if (var2 == 1) {
         IntIterator var8 = var1.blocks().iterator();
         int var5 = var8.nextInt();
         if (this.toBlockState != null && !this.toBlockState.isBlank()) {
            BlockType var6 = BlockType.getAssetMap().getAsset(var5);
            BlockType var7 = var6 != null ? var6.getBlockForState(this.toBlockState) : null;
            if (var7 == null) {
               LOGGER.at(Level.FINE).log("ReplaceBlockType: ToBlockType '%s' does not define BlockState '%s'", this.toBlockType, this.toBlockState);
               class="kw">return null;
            } else {
               class="kw">return new ReplaceBlockTypeEffect.TargetType(BlockType.getAssetMap().getIndex(var7.getId()), 0);
            }
         } else {
            class="kw">return new ReplaceBlockTypeEffect.TargetType(var5, 0);
         }
      } else {
         IntIterator var4 = var1.fluids().iterator();
         class="kw">return new ReplaceBlockTypeEffect.TargetType(0, var4.nextInt());
      }
   }

   @Nonnull
   class="kw">private IntSet resolveFromBlocks(@Nonnull IntSet var1) {
      if (this.fromBlockState != null && !this.fromBlockState.isBlank()) {
         IntOpenHashSet var2 = new IntOpenHashSet(var1.size());
         IntIterator var3 = var1.iterator();

         while (var3.hasNext()) {
            int var4 = var3.nextInt();
            BlockType var5 = BlockType.getAssetMap().getAsset(var4);
            BlockType var6 = var5 != null ? var5.getBlockForState(this.fromBlockState) : null;
            if (var6 == null) {
               LOGGER.at(Level.FINE)
                  .log(
                     "ReplaceBlockType: FromBlockType '%s' does not define BlockState '%s'",
                     var5 != null ? var5.getId() : String.valueOf(var4),
                     this.fromBlockState
                  );
            } else {
               var2.add(BlockType.getAssetMap().getIndex(var6.getId()));
            }
         }

         class="kw">return var2;
      } else {
         class="kw">return var1;
      }
   }

   class="kw">private class="kw">static boolean matchesFluid(@Nonnull Store<ChunkStore> var0, @Nonnull Ref<ChunkStore> var1, @Nonnull IntSet var2, int var3, int var4, int var5) {
      ChunkColumn var6 = var0.getComponent(var1, ChunkColumn.getComponentType());
      if (var6 == null) {
         class="kw">return false;
      }

      Ref var7 = var6.getSection(ChunkUtil.chunkCoordinate(var4));
      if (var7 != null && var7.isValid()) {
         FluidSection var8 = var0.getComponent(var7, FluidSection.getComponentType());
         if (var8 == null) {
            class="kw">return false;
         }

         int var9 = var8.getFluidId(var3, var4, var5);
         class="kw">return var2.contains(var9);
      } else {
         class="kw">return false;
      }
   }

   class="kw">private class="kw">static void replaceMatchedCell(
      @Nonnull ChunkStore var0,
      @Nonnull Ref<ChunkStore> var1,
      @Nonnull WorldChunk var2,
      @Nonnull BlockSection var3,
      boolean var4,
      int var5,
      int var6,
      int var7,
      @Nonnull ReplaceBlockTypeEffect.TargetType var8,
      int var9,
      @Nonnull LongOpenHashSet var10
   ) {
      if (var8.fluidId() != 0) {
         if (!var4) {
            var2.setBlock(var5, var6, var7, 0, BlockType.EMPTY, 0, 0, 256);
         }

         setFluid(var0, var1, var5, var6, var7, var8.fluidId());
      } else {
         clearFluid(var0, var1, var5, var6, var7);
         if (!var4) {
            BlockType var11 = BlockType.getAssetMap().getAsset(var8.blockId());
            if (var11 != null) {
               int var12 = var9 >= 0 ? var9 : var3.getRotationIndex(var5, var6, var7);
               BlockBoundingBoxes.RotatedVariantBoxes var13 = FillerBlockUtil.multiCellFootprint(var8.blockId(), var12);
               if (var13 != null) {
                  if (!FillerBlockUtil.isFootprintFree(var10, var5, var6, var7, var13)) {
                     class="kw">return;
                  }

                  FillerBlockUtil.forEachFillerBlock(var13, (var4x, var5x, var6x) -> clearStructureAt(var0, var5 + var4x, var6 + var5x, var7 + var6x));
               }

               var2.setBlock(var5, var6, var7, var8.blockId(), var11, var12, 0, 256);
               if (var13 != null) {
                  FillerBlockUtil.markFootprint(var10, var5, var6, var7, var13);
               } else {
                  var10.add(BlockUtil.pack(var5, var6, var7));
               }
            }
         }
      }
   }

   class="kw">private class="kw">static void clearStructureAt(@Nonnull ChunkStore var0, int var1, int var2, int var3) {
      if (var2 >= 0 && var2 < 320) {
         Store var4 = var0.getStore();
         Ref var5 = var0.getChunkReference(ChunkUtil.indexChunkFromBlock(var1, var3));
         if (var5 != null && var5.isValid()) {
            BlockChunk var6 = var4.getComponent(var5, BlockChunk.getComponentType());
            if (var6 != null) {
               int var7 = var6.getSectionAtBlockY(var2).getFiller(var1, var2, var3);
               int var8 = var1 - FillerBlockUtil.unpackX(var7);
               int var9 = var2 - FillerBlockUtil.unpackY(var7);
               int var10 = var3 - FillerBlockUtil.unpackZ(var7);
               if (var9 >= 0 && var9 < 320) {
                  Ref var11 = var0.getChunkReference(ChunkUtil.indexChunkFromBlock(var8, var10));
                  if (var11 != null && var11.isValid()) {
                     BlockChunk var12 = var4.getComponent(var11, BlockChunk.getComponentType());
                     if (var12 != null) {
                        if (var12.getBlock(var8, var9, var10) != 0) {
                           WorldChunk var13 = var4.getComponent(var11, WorldChunk.getComponentType());
                           if (var13 != null) {
                              var13.setBlock(var8, var9, var10, 0, BlockType.EMPTY, 0, 0, 256);
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }

   class="kw">private class="kw">static void setFluid(@Nonnull ChunkStore var0, @Nonnull Ref<ChunkStore> var1, int var2, int var3, int var4, int var5) {
      Fluid var6 = Fluid.getAssetMap().getAsset(var5);
      if (var6 != null) {
         Store var7 = var0.getStore();
         ChunkColumn var8 = var7.getComponent(var1, ChunkColumn.getComponentType());
         if (var8 != null) {
            Ref var9 = var8.getSection(ChunkUtil.chunkCoordinate(var3));
            if (var9 != null && var9.isValid()) {
               FluidSection var10 = var7.ensureAndGetComponent(var9, FluidSection.getComponentType());
               var10.setFluid(var2, var3, var4, var5, (byte)var6.getMaxFluidLevel());
            }
         }
      }
   }

   class="kw">private class="kw">static void clearFluid(@Nonnull ChunkStore var0, @Nonnull Ref<ChunkStore> var1, int var2, int var3, int var4) {
      Store var5 = var0.getStore();
      ChunkColumn var6 = var5.getComponent(var1, ChunkColumn.getComponentType());
      if (var6 != null) {
         Ref var7 = var6.getSection(ChunkUtil.chunkCoordinate(var3));
         if (var7 != null && var7.isValid()) {
            FluidSection var8 = var5.getComponent(var7, FluidSection.getComponentType());
            if (var8 != null) {
               if (var8.getFluidId(var2, var3, var4) != 0) {
                  var8.setFluid(var2, var3, var4, 0, (byte)0);
               }
            }
         }
      }
   }

   class="kw">private boolean containsBlock(
      @Nonnull TriggerVolumeShape var1,
      @Nonnull Vector3d var2,
      @Nonnull Vector3d var3,
      @Nonnull Vector3d var4,
      @Nonnull Vector3d var5,
      int var6,
      int var7,
      int var8
   ) {
      var5.set(var6 + 0.5, var7 + 0.5, var8 + 0.5);
      class="kw">return this.bounds != ReplaceBlockTypeEffect.Bounds.AABB
         ? var1.contains(var2, var5)
         : var5.x() >= var3.x() && var5.x() <= var4.x() && var5.y() >= var3.y() && var5.y() <= var4.y() && var5.z() >= var3.z() && var5.z() <= var4.z();
   }

   @Override
   class="kw">public void rotateInPlace(float var1, @Nonnull Vector3d var2) {
      if (this.origin == EffectOrigin.VOLUME_ORIGIN) {
         int var3 = YawRotation.quarterTurns(var1);
         if (var3 > 0) {
            Vector3d var4 = new Vector3d(this.offset).add(this.sizeX, 0.0, this.sizeZ);
            YawRotation.rotateBlockOffset(var4, var1, var2);
            YawRotation.rotateBlockOffset(this.offset, var1, var2);
            this.sizeX = (float)(var4.x() - this.offset.x());
            this.sizeZ = (float)(var4.z() - this.offset.z());
            if (this.rotation != null) {
               this.rotation = YawRotation.rotate(this.rotation, var3);
            }
         } else {
            YawRotation.rotateBlockOffset(this.offset, var1, var2);
         }
      }
   }

   class="kw">private void getConfiguredAABB(@Nonnull Vector3d var1, @Nonnull Vector3d var2, @Nonnull Vector3d var3) {
      Vector3d var4 = this.offset != null ? this.offset : new Vector3d();
      var2.set(var1).add(var4);
      var3.set(var2).add(this.sizeX, this.sizeY, this.sizeZ);
      double var5 = Math.min(var2.x(), var3.x());
      double var7 = Math.min(var2.y(), var3.y());
      double var9 = Math.min(var2.z(), var3.z());
      double var11 = Math.max(var2.x(), var3.x());
      double var13 = Math.max(var2.y(), var3.y());
      double var15 = Math.max(var2.z(), var3.z());
      var2.set(var5, var7, var9);
      var3.set(var11, var13, var15);
   }

   class="kw">public enum Bounds {
      SHAPE,
      AABB;

      Bounds() {
      }
   }

   class="kw">private record TargetType(int blockId, int fluidId) {
      class="kw">private TargetType {
      }
   }
}