TintIterator interface

Пакет: com.hypixel.hytale.server.core.prefab.selection.standard

Файл: com/hypixel/hytale/server/core/prefab/selection/standard/BlockSelection.java

Методы (1)

МодификаторыВозвратСигнатура
abstract void acceptvoid accept(int var1, int var2, int var3)

Исходный код

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

class="kw">import com.hypixel.hytale.assetstore.map.BlockTypeAssetMap;
class="kw">import com.hypixel.hytale.assetstore.map.IndexedLookupTableAssetMap;
class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.component.AddReason;
class="kw">import com.hypixel.hytale.component.ComponentAccessor;
class="kw">import com.hypixel.hytale.component.ComponentRegistry;
class="kw">import com.hypixel.hytale.component.ComponentType;
class="kw">import com.hypixel.hytale.component.Holder;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.component.RemoveReason;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.component.SystemType;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.math.Axis;
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.Rotation3f;
class="kw">import com.hypixel.hytale.math.vector.Vector3iUtil;
class="kw">import com.hypixel.hytale.metrics.MetricProvider;
class="kw">import com.hypixel.hytale.metrics.MetricResults;
class="kw">import com.hypixel.hytale.metrics.MetricsRegistry;
class="kw">import com.hypixel.hytale.protocol.Direction;
class="kw">import com.hypixel.hytale.protocol.Opacity;
class="kw">import com.hypixel.hytale.protocol.packets.buildertools.ClipboardEntityChange;
class="kw">import com.hypixel.hytale.protocol.packets.interface_.BlockChange;
class="kw">import com.hypixel.hytale.protocol.packets.interface_.EditorBlocksChange;
class="kw">import com.hypixel.hytale.protocol.packets.interface_.EditorSelection;
class="kw">import com.hypixel.hytale.protocol.packets.interface_.FluidChange;
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.asset.type.fluid.FluidTicker;
class="kw">import com.hypixel.hytale.server.core.asset.type.model.config.Model;
class="kw">import com.hypixel.hytale.server.core.blocktype.component.BlockPhysics;
class="kw">import com.hypixel.hytale.server.core.command.system.CommandSender;
class="kw">import com.hypixel.hytale.server.core.entity.entities.BlockEntity;
class="kw">import com.hypixel.hytale.server.core.io.NetworkSerializable;
class="kw">import com.hypixel.hytale.server.core.modules.block.BlockModule;
class="kw">import com.hypixel.hytale.server.core.modules.block.components.ItemContainerBlock;
class="kw">import com.hypixel.hytale.server.core.modules.entity.EntityModule;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.EntityScaleComponent;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.FromPrefab;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.HeadRotation;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.ModelComponent;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.PersistentModel;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
class="kw">import com.hypixel.hytale.server.core.modules.entity.item.ItemComponent;
class="kw">import com.hypixel.hytale.server.core.prefab.event.PrefabPlaceEntityEvent;
class="kw">import com.hypixel.hytale.server.core.prefab.selection.mask.BlockMask;
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.BlockOperations;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.BlockRotationUtil;
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.BlockComponentSection;
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.universe.world.storage.EntityStore;
class="kw">import com.hypixel.hytale.server.core.util.FillerBlockUtil;
class="kw">import it.unimi.dsi.fastutil.ints.IntList;
class="kw">import it.unimi.dsi.fastutil.longs.Long2IntMap;
class="kw">import it.unimi.dsi.fastutil.longs.Long2IntMaps;
class="kw">import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
class="kw">import it.unimi.dsi.fastutil.longs.Long2ObjectMaps;
class="kw">import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
class="kw">import it.unimi.dsi.fastutil.longs.LongIterator;
class="kw">import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
class="kw">import it.unimi.dsi.fastutil.longs.LongSet;
class="kw">import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectIterator;
class="kw">import java.io.IOException;
class="kw">import java.util.BitSet;
class="kw">import java.util.HashMap;
class="kw">import java.util.List;
class="kw">import java.util.concurrent.atomic.AtomicInteger;
class="kw">import java.util.concurrent.locks.ReentrantReadWriteLock;
class="kw">import java.util.function.Consumer;
class="kw">import java.util.function.IntUnaryOperator;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.joml.Quaterniond;
class="kw">import org.joml.Vector3d;
class="kw">import org.joml.Vector3i;
class="kw">import org.joml.Vector3ic;

class="kw">public class BlockSelection class="kw">implements NetworkSerializable<EditorBlocksChange>, MetricProvider {
   class="kw">public class="kw">static class="kw">final Consumer<Ref<EntityStore>> DEFAULT_ENTITY_CONSUMER = var0 -> {};
   class="kw">public class="kw">static class="kw">final MetricsRegistry<BlockSelection> METRICS_REGISTRY = new MetricsRegistry<BlockSelection>()
      .register("BlocksLock", var0 -> var0.blocksLock.toString(), Codec.STRING)
      .register("EntitiesLock", var0 -> var0.entitiesLock.toString(), Codec.STRING)
      .register("Position", var0 -> new Vector3i(var0.x, var0.y, var0.z), Vector3iUtil.CODEC)
      .register("Anchor", var0 -> new Vector3i(var0.anchorX, var0.anchorY, var0.anchorZ), Vector3iUtil.CODEC)
      .register("Min", BlockSelection::getSelectionMin, Vector3iUtil.CODEC)
      .register("Max", BlockSelection::getSelectionMax, Vector3iUtil.CODEC)
      .register("BlockCount", BlockSelection::getBlockCount, Codec.INTEGER)
      .register("EntityCount", BlockSelection::getEntityCount, Codec.INTEGER);
   class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
   class="kw">private int x;
   class="kw">private int y;
   class="kw">private int z;
   class="kw">private int anchorX;
   class="kw">private int anchorY;
   class="kw">private int anchorZ;
   class="kw">private int prefabId = -1;
   @Nonnull
   class="kw">private Vector3i min = new Vector3i();
   @Nonnull
   class="kw">private Vector3i max = new Vector3i();
   @Nonnull
   class="kw">private class="kw">final Long2ObjectMap<BlockSelection.BlockHolder> blocks;
   @Nonnull
   class="kw">private class="kw">final Long2ObjectMap<BlockSelection.FluidHolder> fluids;
   @Nonnull
   class="kw">private class="kw">final List<Holder<EntityStore>> entities;
   @Nonnull
   class="kw">private class="kw">final Long2IntMap tints;
   class="kw">private class="kw">final ReentrantReadWriteLock blocksLock = new ReentrantReadWriteLock();
   class="kw">private class="kw">final ReentrantReadWriteLock entitiesLock = new ReentrantReadWriteLock();
   @Nullable
   class="kw">private HashMap<BlockSelection.BlockHolder, BlockSelection.BlockHolder> blockInternCache;
   @Nullable
   class="kw">private HashMap<BlockSelection.FluidHolder, BlockSelection.FluidHolder> fluidInternCache;

   class="kw">public BlockSelection() {
      this.blocks = new Long2ObjectOpenHashMap();
      this.fluids = new Long2ObjectOpenHashMap();
      this.entities = new ObjectArrayList();
      this.tints = new Long2IntOpenHashMap();
   }

   class="kw">public BlockSelection(int var1, int var2) {
      this.blocks = new Long2ObjectOpenHashMap(var1);
      this.fluids = new Long2ObjectOpenHashMap(var1);
      this.entities = new ObjectArrayList(var2);
      this.tints = new Long2IntOpenHashMap();
   }

   class="kw">public BlockSelection(@Nonnull BlockSelection var1) {
      if (var1 == this) {
         throw new IllegalArgumentException("Cannot duplicate a BlockSelection with this method! Use clone()!");
      }

      this.blocks = new Long2ObjectOpenHashMap(var1.getBlockCount());
      this.fluids = new Long2ObjectOpenHashMap(var1.getFluidCount());
      this.entities = new ObjectArrayList(var1.getEntityCount());
      this.tints = new Long2IntOpenHashMap();
      this.copyPropertiesFrom(var1);
      this.add(var1);
   }

   class="kw">public int getX() {
      class="kw">return this.x;
   }

   class="kw">public int getY() {
      class="kw">return this.y;
   }

   class="kw">public int getZ() {
      class="kw">return this.z;
   }

   class="kw">public int getAnchorX() {
      class="kw">return this.anchorX;
   }

   class="kw">public int getAnchorY() {
      class="kw">return this.anchorY;
   }

   class="kw">public int getAnchorZ() {
      class="kw">return this.anchorZ;
   }

   @Nonnull
   class="kw">public Vector3i getSelectionMin() {
      class="kw">return new Vector3i(this.min);
   }

   @Nonnull
   class="kw">public Vector3i getSelectionMax() {
      class="kw">return new Vector3i(this.max);
   }

   class="kw">public boolean hasSelectionBounds() {
      class="kw">return !this.min.equals(Vector3iUtil.ZERO) || !this.max.equals(Vector3iUtil.ZERO);
   }

   class="kw">public int getBlockCount() {
      this.blocksLock.readLock().lock();

      try {
         class="kw">return this.blocks.size();
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }
   }

   class="kw">public int getFluidCount() {
      this.blocksLock.readLock().lock();

      try {
         class="kw">return this.fluids.size();
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }
   }

   class="kw">public int getTintCount() {
      this.blocksLock.readLock().lock();

      try {
         class="kw">return this.tints.size();
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }
   }

   class="kw">public long getSelectionVolume() {
      long var1 = (long)this.max.x - this.min.x;
      long var3 = (long)this.max.y - this.min.y;
      long var5 = (long)this.max.z - this.min.z;
      class="kw">return MathUtil.saturatedMultiply(MathUtil.saturatedMultiply(var1, var3), var5);
   }

   class="kw">public int getEntityCount() {
      this.entitiesLock.readLock().lock();

      try {
         class="kw">return this.entities.size();
      } class="kw">finally {
         this.entitiesLock.readLock().unlock();
      }
   }

   class="kw">public void setPosition(int var1, int var2, int var3) {
      this.x = var1;
      this.y = var2;
      this.z = var3;
   }

   class="kw">public void setAnchorAtWorldPos(int var1, int var2, int var3) {
      this.setAnchor(var1 - this.x, var2 - this.y, var3 - this.z);
   }

   class="kw">public void setAnchor(int var1, int var2, int var3) {
      this.anchorX = var1;
      this.anchorY = var2;
      this.anchorZ = var3;
   }

   class="kw">public void setSelectionArea(@Nonnull Vector3ic var1, @Nonnull Vector3ic var2) {
      this.min = Vector3iUtil.min(var1, var2);
      this.max = Vector3iUtil.max(var1, var2);
   }

   class="kw">public void setPrefabId(int var1) {
      this.prefabId = var1;
   }

   class="kw">public int getPrefabId() {
      class="kw">return this.prefabId;
   }

   class="kw">public void copyPropertiesFrom(@Nonnull BlockSelection var1) {
      this.x = var1.x;
      this.y = var1.y;
      this.z = var1.z;
      this.anchorX = var1.anchorX;
      this.anchorY = var1.anchorY;
      this.anchorZ = var1.anchorZ;
      this.min = new Vector3i(var1.min);
      this.max = new Vector3i(var1.max);
   }

   class="kw">public boolean canPlace(@Nonnull World var1, @Nonnull Vector3i var2, @Nullable IntList var3) {
      class="kw">return this.compare((var4, var5, var6, var7) -> {
         int var8 = var4 + var2.x() - this.anchorX;
         int var9 = var5 + var2.y() - this.anchorY;
         int var10 = var6 + var2.z() - this.anchorZ;
         int var11 = var1.getBlock(var8, var9, var10);
         class="kw">return var11 == 0 || var3 == null || var3.contains(var11);
      });
   }

   class="kw">public boolean matches(@Nonnull World var1, @Nonnull Vector3i var2) {
      class="kw">return this.compare((var3, var4, var5, var6) -> {
         int var7 = var3 + var2.x() - this.anchorX;
         int var8 = var4 + var2.y() - this.anchorY;
         int var9 = var5 + var2.z() - this.anchorZ;
         int var10 = var1.getBlock(var7, var8, var9);
         class="kw">return var6.blockId == var10;
      });
   }

   class="kw">public boolean compare(@Nonnull BlockSelection.BlockComparingIterator var1) {
      ObjectIterator var2 = this.blocks.long2ObjectEntrySet().iterator();

      while (var2.hasNext()) {
         Entry var3 = (Entry<BlockSelection.BlockHolder>)var2.next();
         long var4 = var3.getLongKey();
         BlockSelection.BlockHolder var6 = (BlockSelection.BlockHolder)var3.getValue();
         int var7 = BlockUtil.unpackX(var4);
         int var8 = BlockUtil.unpackY(var4);
         int var9 = BlockUtil.unpackZ(var4);
         if (!var1.test(var7, var8, var9, var6)) {
            class="kw">return false;
         }
      }

      class="kw">return true;
   }

   class="kw">public boolean hasBlockAtWorldPos(int var1, int var2, int var3) {
      class="kw">return this.hasBlockAtLocalPos(var1 - this.x, var2 - this.y, var3 - this.z);
   }

   class="kw">public boolean hasBlockAtLocalPos(int var1, int var2, int var3) {
      this.blocksLock.readLock().lock();

      try {
         class="kw">return this.blocks.containsKey(BlockUtil.pack(var1, var2, var3));
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }
   }

   class="kw">public int getBlockAtWorldPos(int var1, int var2, int var3) {
      class="kw">return this.getBlockAtLocalPos(var1 - this.x, var2 - this.y, var3 - this.z);
   }

   class="kw">private int getBlockAtLocalPos(int var1, int var2, int var3) {
      this.blocksLock.readLock().lock();

      try {
         BlockSelection.BlockHolder var4 = (BlockSelection.BlockHolder)this.blocks.get(BlockUtil.pack(var1, var2, var3));
         class="kw">return var4 == null ? Integer.MIN_VALUE : var4.blockId();
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }
   }

   class="kw">public BlockSelection.BlockHolder getBlockHolderAtWorldPos(int var1, int var2, int var3) {
      class="kw">return this.getBlockHolderAtLocalPos(var1 - this.x, var2 - this.y, var3 - this.z);
   }

   class="kw">private BlockSelection.BlockHolder getBlockHolderAtLocalPos(int var1, int var2, int var3) {
      this.blocksLock.readLock().lock();

      try {
         class="kw">return (BlockSelection.BlockHolder)this.blocks.get(BlockUtil.pack(var1, var2, var3));
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }
   }

   class="kw">public int getFluidAtWorldPos(int var1, int var2, int var3) {
      class="kw">return this.getFluidAtLocalPos(var1 - this.x, var2 - this.y, var3 - this.z);
   }

   class="kw">private int getFluidAtLocalPos(int var1, int var2, int var3) {
      this.blocksLock.readLock().lock();

      try {
         BlockSelection.FluidHolder var4 = (BlockSelection.FluidHolder)this.fluids.get(BlockUtil.pack(var1, var2, var3));
         class="kw">return var4 == null ? Integer.MIN_VALUE : var4.fluidId();
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }
   }

   class="kw">public byte getFluidLevelAtWorldPos(int var1, int var2, int var3) {
      class="kw">return this.getFluidLevelAtLocalPos(var1 - this.x, var2 - this.y, var3 - this.z);
   }

   class="kw">private byte getFluidLevelAtLocalPos(int var1, int var2, int var3) {
      this.blocksLock.readLock().lock();

      try {
         BlockSelection.FluidHolder var4 = (BlockSelection.FluidHolder)this.fluids.get(BlockUtil.pack(var1, var2, var3));
         class="kw">return var4 == null ? 0 : var4.fluidLevel();
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }
   }

   class="kw">public int getSupportValueAtWorldPos(int var1, int var2, int var3) {
      class="kw">return this.getSupportValueAtLocalPos(var1 - this.x, var2 - this.y, var3 - this.z);
   }

   class="kw">private int getSupportValueAtLocalPos(int var1, int var2, int var3) {
      this.blocksLock.readLock().lock();

      try {
         BlockSelection.BlockHolder var4 = (BlockSelection.BlockHolder)this.blocks.get(BlockUtil.pack(var1, var2, var3));
         class="kw">return var4 == null ? 0 : var4.supportValue();
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }
   }

   @Nullable
   class="kw">public Holder<ChunkStore> getStateAtWorldPos(int var1, int var2, int var3) {
      class="kw">return this.getStateAtLocalPos(var1 - this.x, var2 - this.y, var3 - this.z);
   }

   @Nullable
   class="kw">private Holder<ChunkStore> getStateAtLocalPos(int var1, int var2, int var3) {
      this.blocksLock.readLock().lock();

      try {
         BlockSelection.BlockHolder var4 = (BlockSelection.BlockHolder)this.blocks.get(BlockUtil.pack(var1, var2, var3));
         if (var4 == null) {
            class="kw">return null;
         }

         Holder var5 = var4.holder();
         class="kw">return var5 != null ? var5.clone() : null;
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }
   }

   class="kw">public void forEachBlock(@Nonnull BlockSelection.BlockIterator var1) {
      this.blocksLock.readLock().lock();

      try {
         Long2ObjectMaps.fastForEach(this.blocks, var1x -> {
            long var2 = var1x.getLongKey();
            BlockSelection.BlockHolder var4 = (BlockSelection.BlockHolder)var1x.getValue();
            int var5 = BlockUtil.unpackX(var2);
            int var6 = BlockUtil.unpackY(var2);
            int var7 = BlockUtil.unpackZ(var2);
            var1.accept(var5, var6, var7, var4);
         });
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }
   }

   class="kw">public void addTintAtLocalPos(int var1, int var2, int var3) {
      this.tints.put(BlockUtil.pack(var1, 0, var2), var3);
   }

   class="kw">public void addTintAtWorldPos(int var1, int var2, int var3) {
      this.tints.put(BlockUtil.pack(var1 - this.x, 0, var2 - this.z), var3);
   }

   class="kw">public int getTintAtWorldPos(int var1, int var2) {
      class="kw">return this.tints.getOrDefault(BlockUtil.pack(var1 - this.x, 0, var2 - this.z), -1);
   }

   class="kw">public boolean hasTintAtWorldPos(int var1, int var2) {
      class="kw">return this.tints.containsKey(BlockUtil.pack(var1 - this.x, 0, var2 - this.z));
   }

   class="kw">public void forEachTint(@Nonnull BlockSelection.TintIterator var1) {
      this.blocksLock.readLock().lock();

      try {
         Long2IntMaps.fastForEach(this.tints, var1x -> {
            long var2 = var1x.getLongKey();
            int var4 = var1x.getIntValue();
            int var5 = BlockUtil.unpackX(var2);
            int var6 = BlockUtil.unpackZ(var2);
            var1.accept(var5, var6, var4);
         });
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }
   }

   class="kw">public void forEachFluid(@Nonnull BlockSelection.FluidIterator var1) {
      this.blocksLock.readLock().lock();

      try {
         Long2ObjectMaps.fastForEach(this.fluids, var1x -> {
            long var2 = var1x.getLongKey();
            BlockSelection.FluidHolder var4 = (BlockSelection.FluidHolder)var1x.getValue();
            int var5 = BlockUtil.unpackX(var2);
            int var6 = BlockUtil.unpackY(var2);
            int var7 = BlockUtil.unpackZ(var2);
            var1.accept(var5, var6, var7, var4.fluidId(), var4.fluidLevel());
         });
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }
   }

   class="kw">public void forEachEntity(Consumer<Holder<EntityStore>> var1) {
      this.entitiesLock.readLock().lock();

      try {
         this.entities.forEach(var1);
      } class="kw">finally {
         this.entitiesLock.readLock().unlock();
      }
   }

   class="kw">public void copyFromAtWorld(int var1, int var2, int var3, @Nonnull WorldChunk var4, @Nullable BlockPhysics var5) {
      this.addBlockAtWorldPos(
         var1,
         var2,
         var3,
         var4.getBlock(var1, var2, var3),
         var4.getRotationIndex(var1, var2, var3),
         var4.getFiller(var1, var2, var3),
         var5 != null ? var5.get(var1, var2, var3) : 0,
         var4.getBlockComponentHolder(var1, var2, var3)
      );
      this.addFluidAtWorldPos(var1, var2, var3, var4.getFluidId(var1, var2, var3), var4.getFluidLevel(var1, var2, var3));
   }

   class="kw">public void addEmptyAtWorldPos(int var1, int var2, int var3) {
      this.addBlockAtWorldPos(var1, var2, var3, 0, 0, 0, 0);
      this.addFluidAtWorldPos(var1, var2, var3, 0, (byte)0);
   }

   class="kw">public void addBlockAtWorldPos(int var1, int var2, int var3, int var4, int var5, int var6, int var7) {
      this.addBlockAtWorldPos(var1, var2, var3, var4, var5, var6, var7, null);
   }

   class="kw">public void addBlockAtWorldPos(int var1, int var2, int var3, int var4, int var5, int var6, int var7, Holder<ChunkStore> var8) {
      this.addBlockAtLocalPos(var1 - this.x, var2 - this.y, var3 - this.z, var4, var5, var6, var7, var8);
   }

   class="kw">public void addBlockAtLocalPos(int var1, int var2, int var3, int var4, int var5, int var6, int var7) {
      this.addBlockAtLocalPos(var1, var2, var3, var4, var5, var6, var7, null);
   }

   class="kw">public void addBlockAtLocalPos(int var1, int var2, int var3, int var4, int var5, int var6, int var7, Holder<ChunkStore> var8) {
      this.blocksLock.writeLock().lock();

      try {
         this.addBlock0(var1, var2, var3, var4, var5, var6, var7, var8);
      } class="kw">finally {
         this.blocksLock.writeLock().unlock();
      }
   }

   class="kw">public void beginHolderInterning() {
      this.blockInternCache = new HashMap<>();
      this.fluidInternCache = new HashMap<>();
   }

   class="kw">public void endHolderInterning() {
      this.blockInternCache = null;
      this.fluidInternCache = null;
   }

   class="kw">public void trimToSize() {
      this.blocksLock.writeLock().lock();

      try {
         if (this.blocks class="kw">instanceof Long2ObjectOpenHashMap var1) {
            var1.trim();
         }

         if (this.fluids class="kw">instanceof Long2ObjectOpenHashMap var6) {
            var6.trim();
         }

         if (this.tints class="kw">instanceof Long2IntOpenHashMap var7) {
            var7.trim();
         }
      } class="kw">finally {
         this.blocksLock.writeLock().unlock();
      }
   }

   class="kw">private void addBlock0(int var1, int var2, int var3, int var4, int var5, int var6, int var7, Holder<ChunkStore> var8) {
      BlockSelection.BlockHolder var9 = new BlockSelection.BlockHolder(var4, var5, var6, var7, var8);
      if (this.blockInternCache != null && var8 == null) {
         var9 = this.blockInternCache.computeIfAbsent(var9, var0 -> (BlockSelection.BlockHolder)var0);
      }

      this.blocks.put(BlockUtil.pack(var1, var2, var3), var9);
   }

   class="kw">private void addBlock0(int var1, int var2, int var3, @Nonnull BlockSelection.BlockHolder var4) {
      this.blocks.put(BlockUtil.pack(var1, var2, var3), var4.cloneBlockHolder());
   }

   class="kw">public void addFluidAtWorldPos(int var1, int var2, int var3, int var4, byte var5) {
      this.addFluidAtLocalPos(var1 - this.x, var2 - this.y, var3 - this.z, var4, var5);
   }

   class="kw">public void addFluidAtLocalPos(int var1, int var2, int var3, int var4, byte var5) {
      this.blocksLock.writeLock().lock();

      try {
         this.addFluid0(var1, var2, var3, var4, var5);
      } class="kw">finally {
         this.blocksLock.writeLock().unlock();
      }
   }

   class="kw">private void addFluid0(int var1, int var2, int var3, int var4, byte var5) {
      BlockSelection.FluidHolder var6 = new BlockSelection.FluidHolder(var4, var5);
      if (this.fluidInternCache != null) {
         var6 = this.fluidInternCache.computeIfAbsent(var6, var0 -> (BlockSelection.FluidHolder)var0);
      }

      this.fluids.put(BlockUtil.pack(var1, var2, var3), var6);
   }

   class="kw">private void addEntity0(Holder<EntityStore> var1) {
      this.entities.add(var1);
   }

   class="kw">public void reserializeBlockStates(ChunkStore var1, boolean var2) {
      this.blocksLock.writeLock().lock();

      try {
         this.blocks
            .replaceAll(
               (var2x, var3) -> {
                  Holder var4 = var3.holder();
                  if (var4 == null && var3.filler == 0) {
                     BlockType var5 = BlockType.getAssetMap().getAsset(var3.blockId);
                     if (var5 == null) {
                        class="kw">return var3;
                     }

                     if (var5.getBlockEntity() != null) {
                        var4 = var5.getBlockEntity().clone();
                     }
                  }

                  if (var4 != null && var3.filler != 0) {
                     class="kw">return new BlockSelection.BlockHolder(var3.blockId(), var3.rotation(), var3.filler(), var3.supportValue(), null);
                  }

                  if (var4 == null) {
                     class="kw">return var3;
                  }

                  try {
                     ComponentRegistry var12 = ChunkStore.REGISTRY;
                     ComponentRegistry.Data var6 = var12.getData();
                     SystemType var7 = BlockModule.get().getMigrationSystemType();
                     BitSet var8 = var6.getSystemIndexesForType(var7);
                     int var9 = -1;

                     while ((var9 = var8.nextSetBit(var9 + 1)) >= 0) {
                        BlockModule.MigrationSystem var10 = var6.getSystem(var9, var7);
                        if (var10.test(var12, var4.getArchetype())) {
                           var10.onEntityAdd(var4, AddReason.LOAD, var1.getStore());
                        }
                     }

                     var9 = -1;

                     while ((var9 = var8.nextSetBit(var9 + 1)) >= 0) {
                        BlockModule.MigrationSystem var14 = var6.getSystem(var9, var7);
                        if (var14.test(var12, var4.getArchetype())) {
                           var14.onEntityRemoved(var4, RemoveReason.UNLOAD, var1.getStore());
                        }
                     }

                     if (var2) {
                        var4.tryRemoveComponent(var12.getUnknownComponentType());
                     }

                     class="kw">return !var4.hasSerializableComponents(var6)
                        ? new BlockSelection.BlockHolder(var3.blockId(), var3.rotation(), var3.filler(), var3.supportValue(), null)
                        : new BlockSelection.BlockHolder(var3.blockId(), var3.rotation(), var3.filler(), var3.supportValue(), var4.clone());
                  } catch (Throwable var11) {
                     throw new RuntimeException("Failed to read block state: " + var3, var11);
                  }
               }
            );
      } class="kw">finally {
         this.blocksLock.writeLock().unlock();
      }
   }

   class="kw">public void clearAllSupportValues() {
      this.setAllSupportValues(0);
   }

   class="kw">public void setAllSupportValues(int var1) {
      this.blocksLock.writeLock().lock();

      try {
         this.blocks
            .replaceAll(
               (var1x, var2) -> var2.supportValue() == var1
                  ? var2
                  : new BlockSelection.BlockHolder(var2.blockId(), var2.rotation(), var2.filler(), var1, var2.holder())
            );
      } class="kw">finally {
         this.blocksLock.writeLock().unlock();
      }
   }

   class="kw">public void setSupportValueAtLocalPos(int var1, int var2, int var3, int var4) {
      this.blocksLock.writeLock().lock();

      try {
         long var5 = BlockUtil.pack(var1, var2, var3);
         BlockSelection.BlockHolder var7 = (BlockSelection.BlockHolder)this.blocks.get(var5);
         if (var7 != null && var7.supportValue() != var4) {
            this.blocks.put(var5, new BlockSelection.BlockHolder(var7.blockId(), var7.rotation(), var7.filler(), var4, var7.holder()));
            class="kw">return;
         }
      } class="kw">finally {
         this.blocksLock.writeLock().unlock();
      }
   }

   class="kw">public void addEntityFromWorld(@Nonnull Holder<EntityStore> var1) {
      TransformComponent var2 = var1.getComponent(TransformComponent.getComponentType());
      assert var2 != null;
      var2.getPosition().sub(this.x, this.y, this.z);
      this.addEntityHolderRaw(var1);
   }

   class="kw">public void addEntityHolderRaw(Holder<EntityStore> var1) {
      this.entitiesLock.writeLock().lock();

      try {
         this.entities.add(var1);
      } class="kw">finally {
         this.entitiesLock.writeLock().unlock();
      }
   }

   class="kw">public void sortEntitiesByPosition() {
      this.entitiesLock.writeLock().lock();

      try {
         ComponentType var1 = TransformComponent.getComponentType();
         this.entities.sort((var1x, var2) -> {
            TransformComponent var3 = var1x.getComponent(var1);
            TransformComponent var4 = var2.getComponent(var1);
            if (var3 == null && var4 == null) {
               class="kw">return 0;
            }

            if (var3 == null) {
               class="kw">return 1;
            }

            if (var4 == null) {
               class="kw">return -1;
            }

            Vector3d var5 = var3.getPosition();
            Vector3d var6 = var4.getPosition();
            if (var5 == null && var6 == null) {
               class="kw">return 0;
            }

            if (var5 == null) {
               class="kw">return 1;
            }

            if (var6 == null) {
               class="kw">return -1;
            }

            int var7 = Double.compare(var5.x(), var6.x());
            if (var7 != 0) {
               class="kw">return var7;
            }

            var7 = Double.compare(var5.y(), var6.y());
            class="kw">return var7 != 0 ? var7 : Double.compare(var5.z(), var6.z());
         });
      } class="kw">finally {
         this.entitiesLock.writeLock().unlock();
      }
   }

   class="kw">public void placeNoReturn(@Nonnull World var1, Vector3i var2, ComponentAccessor<EntityStore> var3) {
      this.placeNoReturn(null, null, FeedbackConsumer.DEFAULT, var1, var2, null, var3);
   }

   class="kw">public void placeNoReturn(String var1, CommandSender var2, @Nonnull World var3, ComponentAccessor<EntityStore> var4) {
      this.placeNoReturn(var1, var2, FeedbackConsumer.DEFAULT, var3, Vector3iUtil.ZERO, null, var4);
   }

   class="kw">public void placeNoReturn(String var1, CommandSender var2, @Nonnull FeedbackConsumer var3, @Nonnull World var4, ComponentAccessor<EntityStore> var5) {
      this.placeNoReturn(var1, var2, var3, var4, Vector3iUtil.ZERO, null, var5);
   }

   class="kw">public void placeNoReturn(
      @Nullable String var1,
      @Nullable CommandSender var2,
      @Nonnull FeedbackConsumer var3,
      @Nonnull World var4,
      @Nullable Vector3ic var5,
      @Nullable BlockMask var6,
      ComponentAccessor<EntityStore> var7
   ) {
      IntUnaryOperator var8;
      if (var5 != null && var5.x() != 0) {
         var8 = var2x -> var2x + this.x + var5.x() - this.anchorX;
      } else {
         var8 = var1x -> var1x + this.x - this.anchorX;
      }

      IntUnaryOperator var9;
      if (var5 != null && var5.y() != 0) {
         var9 = var2x -> var2x + this.y + var5.y() - this.anchorY;
      } else {
         var9 = var1x -> var1x + this.y - this.anchorY;
      }

      IntUnaryOperator var10;
      if (var5 != null && var5.z() != 0) {
         var10 = var2x -> var2x + this.z + var5.z() - this.anchorZ;
      } else {
         var10 = var1x -> var1x + this.z - this.anchorZ;
      }

      LongSet var11 = new LongOpenHashSet();
      this.blocksLock.readLock().lock();

      try {
         BlockTypeAssetMap var12 = BlockType.getAssetMap();
         int var13 = this.blocks.size() + this.fluids.size();
         AtomicInteger var14 = new AtomicInteger();
         var4.getBlockBulkRelative(
            this.blocks,
            var8,
            var9,
            var10,
            (var11x, var12x, var13x, var15, var16, var17x, var18, var19, var20, var21) -> {
               int var22 = var12x.blockId();
               Holder var23 = var12x.holder();
               this.placeBlockNoReturn(
                  var1,
                  var2,
                  var3,
                  var4,
                  var6,
                  var11,
                  var12,
                  var13,
                  var14.incrementAndGet(),
                  var13x,
                  var15,
                  var16,
                  var17x,
                  var18,
                  var22,
                  var12x.rotation(),
                  var12x.filler(),
                  var23 != null ? var23.clone() : null,
                  var7
               );
            }
         );
         var4.getBlockBulkRelative(
            this.fluids,
            var8,
            var9,
            var10,
            (var11x, var12x, var13x, var15, var16, var17x, var18, var19, var20, var21) -> this.placeFluidNoReturn(
               var1,
               var2,
               var3,
               var4,
               var6,
               var11,
               var12,
               var13,
               var14.incrementAndGet(),
               var13x,
               var15,
               var16,
               var17x,
               var18,
               var12x.fluidId,
               var12x.fluidLevel,
               var7
            )
         );
         this.forEachTint((var3x, var4x, var5x) -> {
            int var6 = this.x + var3x;
            int var7 = this.z + var4x;
            long var8 = ChunkUtil.indexChunkFromBlock(var6, var7);
            WorldChunk var10 = var4.getNonTickingChunk(var8);
            var10.getBlockChunk().setTint(var6, var7, var5x);
            var11.add(var8);
         });
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }

      var11.forEach(
         var1x -> var4.getChunkLighting().invalidateLightInChunk(var4.getChunkStore(), ChunkUtil.xOfChunkIndex(var1x), ChunkUtil.zOfChunkIndex(var1x))
      );
      this.placeEntities(var4, var5);
      if (this.getTintCount() > 0) {
         var11.forEach(var1x -> var4.getNotificationHandler().updateChunkTints(var1x));
      }

      var11.forEach(var1x -> var4.getNotificationHandler().updateChunk(var1x));
   }

   class="kw">private void placeBlockNoReturn(
      String var1,
      CommandSender var2,
      @Nonnull FeedbackConsumer var3,
      @Nonnull World var4,
      @Nullable BlockMask var5,
      @Nonnull LongSet var6,
      @Nonnull BlockTypeAssetMap<String, BlockType> var7,
      int var8,
      int var9,
      long var10,
      @Nonnull WorldChunk var12,
      int var13,
      int var14,
      int var15,
      int var16,
      int var17,
      int var18,
      Holder<ChunkStore> var19,
      ComponentAccessor<EntityStore> var20
   ) {
      if (var14 >= 0 && var14 < 320) {
         int var21 = var12.getBlock(var13, var14, var15);
         if (var5 == null || !var5.isExcluded(var4, var13, var14, var15, this.min, this.max, var21)) {
            BlockChunk var22 = var12.getBlockChunk();
            BlockType var23 = var7.getAsset(var16);
            if (var22.setBlock(var13, var14, var15, var16, var17, var18)) {
               if (var23 != null && FluidTicker.isFullySolid(var23)) {
                  this.clearFluidAtPosition(var4, var12, var13, var14, var15);
               }

               short var24 = var22.getHeight(var13, var15);
               if (var24 <= var14) {
                  if (var24 == var14 && var16 == 0) {
                     var22.updateHeight(var13, var15, (short)var14);
                  } else if (var24 < var14 && var16 != 0 && var23 != null && var23.getOpacity() != Opacity.Transparent) {
                     var22.setHeight(var13, var15, (short)var14);
                  }
               }
            }

            this.clearBlockItemContainer(var4, var12, var13, var14, var15);
            var12.setState(var13, var14, var15, var23, var17, var19);
            var6.add(var10);
            var3.accept(var1, var8, var9, var2, var20);
         }
      }
   }

   class="kw">private void placeFluidNoReturn(
      String var1,
      CommandSender var2,
      @Nonnull FeedbackConsumer var3,
      @Nonnull World var4,
      BlockMask var5,
      @Nonnull LongSet var6,
      BlockTypeAssetMap<String, BlockType> var7,
      int var8,
      int var9,
      long var10,
      @Nonnull WorldChunk var12,
      int var13,
      int var14,
      int var15,
      int var16,
      byte var17,
      ComponentAccessor<EntityStore> var18
   ) {
      if (var14 >= 0 && var14 < 320) {
         int var19 = ChunkUtil.chunkCoordinate(var14);
         Store var20 = var4.getChunkStore().getStore();
         ChunkColumn var21 = var20.getComponent(var12.getReference(), ChunkColumn.getComponentType());
         Ref var22 = var21.getSection(var19);
         FluidSection var23 = var20.ensureAndGetComponent(var22, FluidSection.getComponentType());
         var23.setFluid(var13, var14, var15, var16, var17);
         var6.add(var10);
         var3.accept(var1, var8, var9, var2, var18);
      }
   }

   class="kw">private void clearFluidAtPosition(@Nonnull World var1, @Nonnull WorldChunk var2, int var3, int var4, int var5) {
      Ref var6 = var2.getReference();
      if (var6 != null && var6.isValid()) {
         Store var7 = var1.getChunkStore().getStore();
         ChunkColumn var8 = var7.getComponent(var6, ChunkColumn.getComponentType());
         if (var8 != null) {
            Ref var9 = var8.getSection(ChunkUtil.chunkCoordinate(var4));
            if (var9 != null) {
               FluidSection var10 = var7.getComponent(var9, FluidSection.getComponentType());
               if (var10 != null) {
                  var10.setFluid(var3, var4, var5, 0, (byte)0);
               }
            }
         }
      }
   }

   class="kw">private void clearBlockItemContainer(@Nonnull World var1, @Nonnull WorldChunk var2, int var3, int var4, int var5) {
      Ref var6 = var2.getReference();
      if (var6 != null && var6.isValid()) {
         Store var7 = var1.getChunkStore().getStore();
         ChunkColumn var8 = var7.getComponent(var6, ChunkColumn.getComponentType());
         if (var8 != null) {
            Ref var9 = var8.getSection(ChunkUtil.chunkCoordinate(var4));
            if (var9 != null) {
               BlockComponentSection var10 = var7.getComponent(var9, BlockComponentSection.getComponentType());
               if (var10 != null) {
                  int var11 = ChunkUtil.indexBlock(var3, var4, var5);
                  Ref var12 = var10.getBlockReference(var11);
                  if (var12 != null) {
                     ItemContainerBlock var15 = var12.getStore().getComponent(var12, ItemContainerBlock.getComponentType());
                     if (var15 != null) {
                        var15.getItemContainer().dropAllItemStacks();
                     }
                  } else {
                     Holder var13 = var10.getBlockHolder(var11);
                     if (var13 != null) {
                        ItemContainerBlock var14 = var13.getComponent(ItemContainerBlock.getComponentType());
                        if (var14 != null) {
                           var14.getItemContainer().dropAllItemStacks();
                        }
                     }
                  }
               }
            }
         }
      }
   }

   @Nonnull
   class="kw">public BlockSelection place(CommandSender var1, @Nonnull World var2) {
      class="kw">return this.place(var1, var2, Vector3iUtil.ZERO, null);
   }

   @Nonnull
   class="kw">public BlockSelection place(CommandSender var1, @Nonnull World var2, BlockMask var3) {
      class="kw">return this.place(var1, var2, Vector3iUtil.ZERO, var3);
   }

   @Nonnull
   class="kw">public BlockSelection place(CommandSender var1, @Nonnull World var2, Vector3ic var3, BlockMask var4) {
      class="kw">return this.place(var1, var2, var3, var4, DEFAULT_ENTITY_CONSUMER);
   }

   @Nonnull
   class="kw">public BlockSelection place(
      CommandSender var1, @Nonnull World var2, @Nullable Vector3ic var3, @Nullable BlockMask var4, @Nonnull Consumer<Ref<EntityStore>> var5
   ) {
      class="kw">return this.place(var1, var2, var3, var4, var5, false);
   }

   @Nonnull
   class="kw">public BlockSelection place(
      CommandSender var1, @Nonnull World var2, @Nullable Vector3ic var3, @Nullable BlockMask var4, @Nonnull Consumer<Ref<EntityStore>> var5, boolean var6
   ) {
      class="kw">return this.place(var1, var2, var3, var4, var5, var6, null);
   }

   @Nonnull
   class="kw">public BlockSelection place(
      CommandSender var1,
      @Nonnull World var2,
      @Nullable Vector3ic var3,
      @Nullable BlockMask var4,
      @Nonnull Consumer<Ref<EntityStore>> var5,
      boolean var6,
      @Nullable IntUnaryOperator var7
   ) {
      class="kw">return this.place(var1, var2, var3, var4, var5, var6, var7, false);
   }

   @Nonnull
   class="kw">public BlockSelection place(
      CommandSender var1,
      @Nonnull World var2,
      @Nullable Vector3ic var3,
      @Nullable BlockMask var4,
      @Nonnull Consumer<Ref<EntityStore>> var5,
      boolean var6,
      @Nullable IntUnaryOperator var7,
      boolean var8
   ) {
      BlockSelection var9 = new BlockSelection(this.getBlockCount(), 0);
      var9.setAnchor(this.anchorX, this.anchorY, this.anchorZ);
      var9.setPosition(this.x, this.y, this.z);
      var9.beginHolderInterning();
      IntUnaryOperator var10;
      if (var3 != null && var3.x() != 0) {
         var10 = var2x -> var2x + this.x + var3.x() - this.anchorX;
      } else {
         var10 = var1x -> var1x + this.x - this.anchorX;
      }

      IntUnaryOperator var11;
      if (var3 != null && var3.y() != 0) {
         var11 = var2x -> var2x + this.y + var3.y() - this.anchorY;
      } else {
         var11 = var1x -> var1x + this.y - this.anchorY;
      }

      IntUnaryOperator var12;
      if (var3 != null && var3.z() != 0) {
         var12 = var2x -> var2x + this.z + var3.z() - this.anchorZ;
      } else {
         var12 = var1x -> var1x + this.z - this.anchorZ;
      }

      LongSet var13 = new LongOpenHashSet();
      this.blocksLock.readLock().lock();

      try {
         BlockTypeAssetMap var14 = BlockType.getAssetMap();
         var2.getBlockBulkRelative(
            this.blocks,
            var10,
            var11,
            var12,
            (var10x, var11x, var12x, var14x, var15x, var16, var17, var18x, var19, var20) -> {
               int var21 = var11x.blockId();
               int var22 = var7 != null ? var7.applyAsInt(var21) : var21;
               int var23 = var8 ? var21 : var22;
               if (!var6 || var23 != 0 || var11x.filler() != 0) {
                  Holder var24 = var11x.holder();
                  this.placeBlock(
                     var1,
                     var2,
                     var4,
                     var9,
                     var13,
                     var14,
                     var12x,
                     var14x,
                     var15x,
                     var16,
                     var17,
                     var18x,
                     var19,
                     var20,
                     var22,
                     var11x.rotation(),
                     var11x.filler(),
                     var24 != null ? var24.clone() : null,
                     var11x.supportValue()
                  );
               }
            }
         );
         IndexedLookupTableAssetMap var15 = Fluid.getAssetMap();
         var2.getBlockBulkRelative(
            this.fluids,
            var10,
            var11,
            var12,
            (var6x, var7x, var8x, var10x, var11x, var12x, var13x, var14x, var15x, var16) -> this.placeFluid(
               var1, var2, var9, var13, var15, var8x, var10x, var11x, var12x, var13x, var14x, var15x, var16, var7x.fluidId, var7x.fluidLevel
            )
         );
         this.forEachTint((var4x, var5x, var6x) -> {
            int var7 = this.x + var4x;
            int var8 = this.z + var5x;
            long var9 = ChunkUtil.indexChunkFromBlock(var7, var8);
            WorldChunk var11 = var2.getNonTickingChunk(var9);
            int var12 = var11.getBlockChunk().getTint(var7, var8);
            var9.addTintAtWorldPos(var7, var8, var12);
            var11.getBlockChunk().setTint(var7, var8, var6x);
            var13.add(var9);
         });
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }

      var13.forEach(
         var1x -> var2.getChunkLighting().invalidateLightInChunk(var2.getChunkStore(), ChunkUtil.xOfChunkIndex(var1x), ChunkUtil.zOfChunkIndex(var1x))
      );
      this.placeEntities(var2, var3, var5);
      if (this.getTintCount() > 0) {
         var13.forEach(var1x -> var2.getNotificationHandler().updateChunkTints(var1x));
      }

      var13.forEach(var1x -> var2.getNotificationHandler().updateChunk(var1x));
      var9.endHolderInterning();
      var9.trimToSize();
      class="kw">return var9;
   }

   class="kw">private void placeBlock(
      CommandSender var1,
      @Nonnull World var2,
      @Nullable BlockMask var3,
      @Nonnull BlockSelection var4,
      @Nonnull LongSet var5,
      @Nonnull BlockTypeAssetMap<String, BlockType> var6,
      long var7,
      @Nonnull WorldChunk var9,
      int var10,
      int var11,
      int var12,
      int var13,
      int var14,
      int var15,
      int var16,
      int var17,
      int var18,
      Holder<ChunkStore> var19,
      int var20
   ) {
      if (var11 >= 0 && var11 < 320) {
         Store var21 = var9.getWorld().getChunkStore().getStore();
         ChunkColumn var22 = var21.getComponent(var9.getReference(), ChunkColumn.getComponentType());
         Ref var23 = var22.getSection(ChunkUtil.chunkCoordinate(var11));
         BlockSection var24 = var21.getComponent(var23, BlockSection.getComponentType());
         int var25 = var9.getBlock(var10, var11, var12);
         if (var3 == null || !var3.isExcluded(var2, var10, var11, var12, this.min, this.max, var25)) {
            BlockPhysics var26 = var23 != null ? var21.getComponent(var23, BlockPhysics.getComponentType()) : null;
            int var27 = var26 != null ? var26.get(var10, var11, var12) : 0;
            int var28 = var24.getFiller(var10, var11, var12);
            int var29 = var24.getRotationIndex(var10, var11, var12);
            Holder var30 = var9.getBlockComponentHolder(var10, var11, var12);
            boolean var31 = var25 != var16 || var29 != var17 || var28 != var18 || var27 != var20 || var30 != null || var19 != null;
            if (var31) {
               var4.addBlockAtLocalPos(var13, var14, var15, var25, var29, var28, var27, var30);
            }

            BlockChunk var32 = var9.getBlockChunk();
            BlockType var33 = var6.getAsset(var16);
            if (var32.setBlock(var10, var11, var12, var16, var17, var18)) {
               if (var33 != null && FluidTicker.isFullySolid(var33)) {
                  this.clearFluidAtPosition(var2, var9, var10, var11, var12);
               }

               short var34 = var32.getHeight(var10, var12);
               if (var34 <= var11) {
                  if (var34 == var11 && var16 == 0) {
                     var32.updateHeight(var10, var12, (short)var11);
                  } else if (var34 < var11 && var16 != 0 && var33.getOpacity() != Opacity.Transparent) {
                     var32.setHeight(var10, var12, (short)var11);
                  }
               }

               if (var20 != var27) {
                  if (var20 != 0) {
                     if (var26 == null) {
                        var26 = var21.ensureAndGetComponent(var23, BlockPhysics.getComponentType());
                     }

                     var26.set(var10, var11, var12, var20);
                  } else if (var26 != null) {
                     var26.set(var10, var11, var12, 0);
                  }
               }
            }

            this.clearBlockItemContainer(var2, var9, var10, var11, var12);
            var9.setState(var10, var11, var12, var33, var17, var19);
            var5.add(var7);
         }
      } else {
         if (var2.getChunkStore().supportsCubicSections()) {
            this.placeBlockOutOfBand(var2, var3, var4, var5, var6, var7, var10, var11, var12, var13, var14, var15, var16, var17, var18, var20);
         }
      }
   }

   class="kw">private void placeFluid(
      CommandSender var1,
      @Nonnull World var2,
      @Nonnull BlockSelection var3,
      @Nonnull LongSet var4,
      IndexedLookupTableAssetMap<String, Fluid> var5,
      long var6,
      @Nonnull WorldChunk var8,
      int var9,
      int var10,
      int var11,
      int var12,
      int var13,
      int var14,
      int var15,
      byte var16
   ) {
      if (var10 >= 0 && var10 < 320) {
         int var17 = ChunkUtil.chunkCoordinate(var10);
         Store var18 = var2.getChunkStore().getStore();
         ChunkColumn var19 = var18.getComponent(var8.getReference(), ChunkColumn.getComponentType());
         Ref var20 = var19.getSection(var17);
         FluidSection var21 = var18.ensureAndGetComponent(var20, FluidSection.getComponentType());
         int var22 = var21.getFluidId(var9, var10, var11);
         byte var23 = var21.getFluidLevel(var9, var10, var11);
         if (var22 != var15 || var23 != var16) {
            var3.addFluidAtLocalPos(var12, var13, var14, var22, var23);
         }

         var21.setFluid(var9, var10, var11, var15, var16);
         var4.add(var6);
      } else {
         if (var2.getChunkStore().supportsCubicSections()) {
            this.placeFluidOutOfBand(var2, var3, var4, var6, var9, var10, var11, var12, var13, var14, var15, var16);
         }
      }
   }

   class="kw">private void placeBlockOutOfBand(
      @Nonnull World var1,
      @Nullable BlockMask var2,
      @Nonnull BlockSelection var3,
      @Nonnull LongSet var4,
      @Nonnull BlockTypeAssetMap<String, BlockType> var5,
      long var6,
      int var8,
      int var9,
      int var10,
      int var11,
      int var12,
      int var13,
      int var14,
      int var15,
      int var16,
      int var17
   ) {
      ChunkStore var18 = var1.getChunkStore();
      Ref var19 = var18.getChunkSectionReferenceAtBlock(var8, var9, var10);
      if (var19 != null && var19.isValid()) {
         Store var20 = var18.getStore();
         BlockSection var21 = var20.getComponent(var19, BlockSection.getComponentType());
         if (var21 != null) {
            int var22 = var21.get(var8, var9, var10);
            if (var2 == null || !var2.isExcluded(var1, var8, var9, var10, this.min, this.max, var22)) {
               int var23 = var21.getRotationIndex(var8, var9, var10);
               int var24 = var21.getFiller(var8, var9, var10);
               BlockPhysics var25 = var20.getComponent(var19, BlockPhysics.getComponentType());
               int var26 = var25 != null ? var25.get(var8, var9, var10) : 0;
               var3.addBlockAtLocalPos(var11, var12, var13, var22, var23, var24, var26, null);
               BlockType var27 = var5.getAsset(var14);
               if (var27 != null) {
                  int var28 = 542;
                  boolean var29 = BlockOperations.setBlock(var18, var19, var8, var9, var10, var14, var27, var15, var16, var28);
                  if (var29 && var17 != var26) {
                     if (var17 != 0) {
                        if (var25 == null) {
                           var25 = var20.ensureAndGetComponent(var19, BlockPhysics.getComponentType());
                        }

                        var25.set(var8, var9, var10, var17);
                     } else if (var25 != null) {
                        var25.set(var8, var9, var10, 0);
                     }
                  }

                  var4.add(var6);
               }
            }
         }
      }
   }

   class="kw">private void placeFluidOutOfBand(
      @Nonnull World var1,
      @Nonnull BlockSelection var2,
      @Nonnull LongSet var3,
      long var4,
      int var6,
      int var7,
      int var8,
      int var9,
      int var10,
      int var11,
      int var12,
      byte var13
   ) {
      ChunkStore var14 = var1.getChunkStore();
      Ref var15 = var14.getChunkSectionReferenceAtBlock(var6, var7, var8);
      if (var15 != null && var15.isValid()) {
         Store var16 = var14.getStore();
         FluidSection var17 = var16.ensureAndGetComponent(var15, FluidSection.getComponentType());
         int var18 = var17.getFluidId(var6, var7, var8);
         byte var19 = var17.getFluidLevel(var6, var7, var8);
         var2.addFluidAtLocalPos(var9, var10, var11, var18, var19);
         var17.setFluid(var6, var7, var8, var12, var13);
         var3.add(var4);
      }
   }

   class="kw">private void placeEntities(@Nonnull World var1, @Nonnull Vector3ic var2) {
      this.placeEntities(var1, var2, DEFAULT_ENTITY_CONSUMER);
   }

   class="kw">private void placeEntities(@Nonnull World var1, @Nonnull Vector3ic var2, @Nonnull Consumer<Ref<EntityStore>> var3) {
      this.entitiesLock.readLock().lock();

      try {
         for (Holder var5 : this.entities) {
            Ref var6 = this.placeEntity(var1, var5.clone(), var2, this.prefabId);
            if (var6 != null) {
               var3.accept(var6);
            }
         }
      } class="kw">finally {
         this.entitiesLock.readLock().unlock();
      }
   }

   @Nullable
   class="kw">private Ref<EntityStore> placeEntity(@Nonnull World var1, @Nonnull Holder<EntityStore> var2, @Nonnull Vector3ic var3, int var4) {
      TransformComponent var5 = var2.getComponent(TransformComponent.getComponentType());
      assert var5 != null;
      var5.getPosition().add(this.x + var3.x() - this.anchorX, this.y + var3.y() - this.anchorY, this.z + var3.z() - this.anchorZ);
      Store var6 = var1.getEntityStore().getStore();
      PrefabPlaceEntityEvent var7 = new PrefabPlaceEntityEvent(var4, var2);
      var6.invoke(var7);
      if (var7.isCancelled()) {
         class="kw">return null;
      }

      var2.addComponent(FromPrefab.getComponentType(), FromPrefab.INSTANCE);
      Ref var8 = new Ref<>(var6);
      var1.execute(() -> var6.addEntity(var2, var8, AddReason.LOAD));
      class="kw">return var8;
   }

   @Nonnull
   class="kw">public BlockSelection rotate(@Nonnull Axis var1, int var2) {
      class="kw">return this.rotate(var1, var2, RotateBlockMode.ALL);
   }

   @Nonnull
   class="kw">public BlockSelection rotate(@Nonnull Axis var1, int var2, @Nonnull RotateBlockMode var3) {
      BlockSelection var4 = new BlockSelection(this.getBlockCount(), this.getEntityCount());
      var4.copyPropertiesFrom(this);
      int var5 = this.x + this.anchorX;
      int var6 = this.y + this.anchorY;
      int var7 = this.z + this.anchorZ;
      Vector3i var8 = new Vector3i(this.min.x() - var5, this.min.y() - var6, this.min.z() - var7);
      var1.rotate(var8, var2);
      var8.add(var5, var6, var7);
      Vector3i var9 = new Vector3i(this.max.x() - var5, this.max.y() - var6, this.max.z() - var7);
      var1.rotate(var9, var2);
      var9.add(var5, var6, var7);
      var4.setSelectionArea(Vector3iUtil.min(var8, var9), Vector3iUtil.max(var8, var9));
      Vector3i var10 = new Vector3i(0, 0, 0);
      Rotation var11 = Rotation.ofDegrees(var2);
      BlockTypeAssetMap var12 = var3 != RotateBlockMode.NON_FULL_BLOCKS && var3 != RotateBlockMode.NON_UNIFORM ? null : BlockType.getAssetMap();
      this.forEachBlock(
         (var8x, var9x, var10x, var11x) -> {
            var10.set(var8x - this.anchorX, var9x - this.anchorY, var10x - this.anchorZ);
            var1.rotate(var10, var2);
            int var12 = var11x.blockId;
            Holder var13 = var11x.holder;
            RotationTuple var14 = RotationTuple.get(var11x.rotation);

            RotationTuple var15 = class="kw">switch (var3) {
               case ALL -> var14.composeOnAxis(var1, var11);
               case NON_FULL_BLOCKS -> {
                  BlockType var18 = var12.getAsset(var12);
                  boolean var20 = var18 != null && "Full".equals(var18.getHitboxType());
                  yield var20 ? var14 : var14.composeOnAxis(var1, var11);
               }
               case NON_UNIFORM -> {
                  BlockType var16 = var12.getAsset(var12);
                  boolean var17 = var16 != null && var16.hasUniformTextures();
                  yield var17 ? var14 : var14.composeOnAxis(var1, var11);
               }
               case NOTHING -> var14;
            };
            int var19 = BlockRotationUtil.getRotatedFiller(var11x.filler, var1, var11);
            var4.addBlock0(
               var10.x() + this.anchorX,
               var10.y() + this.anchorY,
               var10.z() + this.anchorZ,
               var12,
               var15.index(),
               var19,
               var11x.supportValue(),
               var13 != null ? var13.clone() : null
            );
         }
      );
      Quaterniond var13 = new Quaterniond().rotateAxis(Math.toRadians(var2), var1.getDirection().x(), var1.getDirection().y(), var1.getDirection().z());
      this.forEachEntity(var5x -> {
         Holder var6 = var5x.clone();
         TransformComponent var7 = var6.getComponent(TransformComponent.getComponentType());
         assert var7 != null;
         Vector3d var8 = var7.getPosition();
         HeadRotation var9 = var6.getComponent(HeadRotation.getComponentType());
         boolean var10 = var6.getComponent(BlockEntity.getComponentType()) != null;
         Vector3d var11 = var10 ? new Vector3d(0.5, 0.0, 0.5) : new Vector3d(0.5, 0.5, 0.5);
         var8.sub(this.anchorX, this.anchorY, this.anchorZ).sub(var11);
         var1.rotate(var8, var2);
         var8.add(this.anchorX, this.anchorY, this.anchorZ).add(var11);
         composeAxisRotation(var13, var7.getRotation());
         if (var9 != null) {
            composeAxisRotation(var13, var9.getRotation());
         }

         var4.addEntity0(var6);
      });
      Vector3i var14 = new Vector3i(0, 0, 0);
      this.forEachFluid((var5x, var6x, var7x, var8x, var9x) -> {
         var14.set(var5x - this.anchorX, var6x - this.anchorY, var7x - this.anchorZ);
         var1.rotate(var14, var2);
         var4.addFluid0(var14.x() + this.anchorX, var14.y() + this.anchorY, var14.z() + this.anchorZ, var8x, var9x);
      });
      class="kw">return var4;
   }

   @Nonnull
   class="kw">public BlockSelection rotate(@Nonnull Axis var1, int var2, @Nonnull Vector3d var3) {
      BlockSelection var4 = new BlockSelection(this.getBlockCount(), this.getEntityCount());
      var4.copyPropertiesFrom(this);
      Vector3d var5 = new Vector3d(0.0, 0.0, 0.0);
      Rotation var6 = Rotation.ofDegrees(var2);
      Vector3d var7 = new Vector3d(var3).sub(this.x, this.y, this.z);
      this.forEachBlock(
         (var6x, var7x, var8x, var9x) -> {
            var5.set(var6x - var7.x, var7x - var7.y, var8x - var7.z);
            var1.rotate(var5, var2);
            int var10 = var9x.blockId;
            Holder var11 = var9x.holder;
            int var12 = var9x.supportValue();
            RotationTuple var13 = RotationTuple.get(var9x.rotation);
            RotationTuple var14 = var13.composeOnAxis(var1, var6);
            int var15 = BlockRotationUtil.getRotatedFiller(var9x.filler, var1, var6);
            var4.addBlock0(
               (int)(var5.x() + var7.x),
               (int)(var5.y() + var7.y),
               (int)(var5.z() + var7.z),
               var10,
               var14.index(),
               var15,
               var12,
               var11 != null ? var11.clone() : null
            );
         }
      );
      Quaterniond var8 = new Quaterniond().rotateAxis(Math.toRadians(var2), var1.getDirection().x(), var1.getDirection().y(), var1.getDirection().z());
      this.forEachEntity(var5x -> {
         Holder var6 = var5x.clone();
         TransformComponent var7 = var6.getComponent(TransformComponent.getComponentType());
         assert var7 != null;
         Vector3d var8 = var7.getPosition();
         HeadRotation var9 = var6.getComponent(HeadRotation.getComponentType());
         boolean var10 = var5x.getComponent(BlockEntity.getComponentType()) != null;
         Vector3d var11 = var10 ? new Vector3d(0.5, 0.0, 0.5) : new Vector3d(0.5, 0.5, 0.5);
         var8.sub(this.anchorX, this.anchorY, this.anchorZ).sub(var11);
         var1.rotate(var8, var2);
         var8.add(this.anchorX, this.anchorY, this.anchorZ).add(var11);
         composeAxisRotation(var8, var7.getRotation());
         if (var9 != null) {
            composeAxisRotation(var8, var9.getRotation());
         }

         var4.addEntity0(var6);
      });
      Vector3d var9 = new Vector3d(0.0, 0.0, 0.0);
      this.forEachFluid((var5x, var6x, var7x, var8x, var9x) -> {
         var9.set(var5x - var7.x, var6x - var7.y, var7x - var7.z);
         var1.rotate(var9, var2);
         var4.addFluid0((int)(var9.x() + var7.x), (int)(var9.y() + var7.y), (int)(var9.z() + var7.z), var8x, var9x);
      });
      class="kw">return var4;
   }

   class="kw">private class="kw">static void composeAxisRotation(@Nonnull Quaterniond var0, @Nonnull Rotation3f var1) {
      var1.premul(var0);
   }

   class="kw">private void rotateEntities(@Nonnull BlockSelection var1, @Nonnull Quaterniond var2) {
      this.forEachEntity(var3 -> {
         Holder var4 = var3.clone();
         TransformComponent var5 = var4.getComponent(TransformComponent.getComponentType());
         assert var5 != null;
         Vector3d var6 = var5.getPosition();
         HeadRotation var7 = var4.getComponent(HeadRotation.getComponentType());
         boolean var8 = var3.getComponent(BlockEntity.getComponentType()) != null;
         Vector3d var9 = var8 ? new Vector3d(0.5, 0.0, 0.5) : new Vector3d(0.5, 0.5, 0.5);
         var6.sub(this.anchorX, this.anchorY, this.anchorZ).sub(var9);
         var2.transform(var6);
         var6.add(this.anchorX, this.anchorY, this.anchorZ).add(var9);
         composeAxisRotation(var2, var5.getRotation());
         if (var7 != null) {
            composeAxisRotation(var2, var7.getRotation());
         }

         var1.addEntity0(var4);
      });
   }

   @Nonnull
   class="kw">public BlockSelection rotateArbitrary(float var1, float var2, float var3) {
      double var4 = Math.toRadians(var2);
      double var6 = Math.toRadians(var1);
      double var8 = Math.toRadians(var3);
      Quaterniond var10 = new Quaterniond().rotateYXZ(var6, var4, var8);
      Quaterniond var11 = new Quaterniond(var10).conjugate();
      Vector3d var12 = new Vector3d();
      int var13 = Integer.MAX_VALUE;
      int var14 = Integer.MAX_VALUE;
      int var15 = Integer.MAX_VALUE;
      int var16 = Integer.MIN_VALUE;
      int var17 = Integer.MIN_VALUE;
      int var18 = Integer.MIN_VALUE;
      int var19 = Integer.MAX_VALUE;
      int var20 = Integer.MAX_VALUE;
      int var21 = Integer.MAX_VALUE;
      int var22 = Integer.MIN_VALUE;
      int var23 = Integer.MIN_VALUE;
      int var24 = Integer.MIN_VALUE;
      this.blocksLock.readLock().lock();

      try {
         ObjectIterator var25 = this.blocks.long2ObjectEntrySet().iterator();

         while (var25.hasNext()) {
            Entry var26 = (Entry<BlockSelection.BlockHolder>)var25.next();
            long var27 = var26.getLongKey();
            int var29 = BlockUtil.unpackX(var27) - this.anchorX;
            int var30 = BlockUtil.unpackY(var27) - this.anchorY;
            int var31 = BlockUtil.unpackZ(var27) - this.anchorZ;
            var19 = Math.min(var19, var29);
            var20 = Math.min(var20, var30);
            var21 = Math.min(var21, var31);
            var22 = Math.max(var22, var29);
            var23 = Math.max(var23, var30);
            var24 = Math.max(var24, var31);
         }
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }

      boolean var54 = var19 != Integer.MAX_VALUE;
      BlockSelection var55 = new BlockSelection(var54 ? this.getBlockCount() : 0, this.getEntityCount());
      var55.copyPropertiesFrom(this);
      if (var54) {
         int[][] var56 = new int[][]{
            {var19, var20, var21},
            {var22, var20, var21},
            {var19, var23, var21},
            {var22, var23, var21},
            {var19, var20, var24},
            {var22, var20, var24},
            {var19, var23, var24},
            {var22, var23, var24}
         };

         for (int[] var62 : var56) {
            var12.set(var62[0], var62[1], var62[2]);
            var10.transform(var12);
            int var32 = MathUtil.floor(var12.x);
            int var33 = MathUtil.floor(var12.y);
            int var34 = MathUtil.floor(var12.z);
            var13 = Math.min(var13, var32);
            var14 = Math.min(var14, var33);
            var15 = Math.min(var15, var34);
            var16 = Math.max(var16, var32 + 1);
            var17 = Math.max(var17, var33 + 1);
            var18 = Math.max(var18, var34 + 1);
         }

         Rotation var57 = Rotation.ofDegrees(Math.round(var1 / 90.0F) * 90);
         Rotation var59 = Rotation.ofDegrees(Math.round(var2 / 90.0F) * 90);
         Rotation var61 = Rotation.ofDegrees(Math.round(var3 / 90.0F) * 90);
         RotationTuple var63 = RotationTuple.of(var57, var59, var61);
         this.blocksLock.readLock().lock();

         try {
            for (int var64 = var13; var64 <= var16; var64++) {
               for (int var66 = var14; var66 <= var17; var66++) {
                  for (int var68 = var15; var68 <= var18; var68++) {
                     var12.set(var64, var66, var68);
                     var11.transform(var12);
                     int var35 = (int)Math.round(var12.x);
                     int var36 = (int)Math.round(var12.y);
                     int var37 = (int)Math.round(var12.z);
                     long var38 = BlockUtil.pack(var35 + this.anchorX, var36 + this.anchorY, var37 + this.anchorZ);
                     BlockSelection.BlockHolder var40 = (BlockSelection.BlockHolder)this.blocks.get(var38);
                     if (var40 != null) {
                        RotationTuple var41 = RotationTuple.get(var40.rotation());
                        RotationTuple var42 = RotationTuple.compose(var63, var41);
                        if (var42 == null) {
                           var42 = var41;
                        }

                        int var43 = var40.filler();
                        if (var43 != 0) {
                           int var44 = FillerBlockUtil.unpackX(var43);
                           int var45 = FillerBlockUtil.unpackY(var43);
                           int var46 = FillerBlockUtil.unpackZ(var43);
                           var12.set(var44, var45, var46);
                           var10.transform(var12);
                           var43 = FillerBlockUtil.pack((int)Math.round(var12.x), (int)Math.round(var12.y), (int)Math.round(var12.z));
                        }

                        Holder var75 = var40.holder();
                        var55.addBlock0(
                           var64 + this.anchorX,
                           var66 + this.anchorY,
                           var68 + this.anchorZ,
                           var40.blockId(),
                           var42.index(),
                           var43,
                           var40.supportValue(),
                           var75 != null ? var75.clone() : null
                        );
                     }
                  }
               }
            }

            for (int var65 = var13; var65 <= var16; var65++) {
               for (int var67 = var14; var67 <= var17; var67++) {
                  for (int var69 = var15; var69 <= var18; var69++) {
                     var12.set(var65, var67, var69);
                     var11.transform(var12);
                     int var70 = (int)Math.round(var12.x);
                     int var71 = (int)Math.round(var12.y);
                     int var72 = (int)Math.round(var12.z);
                     long var73 = BlockUtil.pack(var70 + this.anchorX, var71 + this.anchorY, var72 + this.anchorZ);
                     BlockSelection.FluidHolder var74 = (BlockSelection.FluidHolder)this.fluids.get(var73);
                     if (var74 != null) {
                        var55.addFluid0(var65 + this.anchorX, var67 + this.anchorY, var69 + this.anchorZ, var74.fluidId(), var74.fluidLevel());
                     }
                  }
               }
            }
         } class="kw">finally {
            this.blocksLock.readLock().unlock();
         }

         var55.setSelectionArea(
            new Vector3i(var13 + this.anchorX + this.x, var14 + this.anchorY + this.y, var15 + this.anchorZ + this.z),
            new Vector3i(var16 + this.anchorX + this.x, var17 + this.anchorY + this.y, var18 + this.anchorZ + this.z)
         );
      }

      this.rotateEntities(var55, var10);
      class="kw">return var55;
   }

   @Nonnull
   class="kw">public BlockSelection flip(@Nonnull Axis var1) {
      BlockTypeAssetMap var2 = BlockType.getAssetMap();
      BlockSelection var3 = new BlockSelection(this.getBlockCount(), this.getEntityCount());
      var3.copyPropertiesFrom(this);
      int var4 = this.x + this.anchorX;
      int var5 = this.y + this.anchorY;
      int var6 = this.z + this.anchorZ;
      Vector3i var7 = new Vector3i(this.min.x() - var4, this.min.y() - var5, this.min.z() - var6);
      var1.flip(var7);
      var7.add(var4, var5, var6);
      Vector3i var8 = new Vector3i(this.max.x() - var4, this.max.y() - var5, this.max.z() - var6);
      var1.flip(var8);
      var8.add(var4, var5, var6);
      var3.setSelectionArea(Vector3iUtil.min(var7, var8), Vector3iUtil.max(var7, var8));
      Vector3i var9 = new Vector3i(0, 0, 0);
      this.forEachBlock(
         (var5x, var6x, var7x, var8x) -> {
            var9.set(var5x - this.anchorX, var6x - this.anchorY, var7x - this.anchorZ);
            var1.flip(var9);
            int var9 = var8x.blockId;
            Holder var10 = var8x.holder;
            int var11 = var8x.supportValue();
            int var12 = var8x.filler;
            BlockType var13 = var2.getAsset(var9);
            if (var13 == null) {
               var3.addBlock0(
                  var9.x() + this.anchorX,
                  var9.y() + this.anchorY,
                  var9.z() + this.anchorZ,
                  var9,
                  var8x.rotation,
                  var8x.filler,
                  var8x.supportValue(),
                  var8x.holder != null ? var8x.holder.clone() : null
               );
            } else {
               RotationTuple var14 = RotationTuple.get(var8x.rotation);
               RotationTuple var15 = BlockRotationUtil.getFlipped(var14, var13.getFlipType(), var1);
               if (var15 == null) {
                  var15 = var14;
               }

               int var16 = BlockRotationUtil.getFlippedFiller(var12, var1);
               var3.addBlock0(
                  var9.x() + this.anchorX,
                  var9.y() + this.anchorY,
                  var9.z() + this.anchorZ,
                  var9,
                  var15.index(),
                  var16,
                  var11,
                  var10 != null ? var10.clone() : null
               );
            }
         }
      );
      this.forEachEntity(var3x -> {
         Holder var4 = var3x.clone();
         HeadRotation var5 = var4.getComponent(HeadRotation.getComponentType());
         TransformComponent var6 = var4.getComponent(TransformComponent.getComponentType());
         assert var6 != null;
         Vector3d var7 = var6.getPosition();
         Rotation3f var8 = var6.getRotation();
         boolean var9 = var3x.getComponent(BlockEntity.getComponentType()) != null;
         Vector3d var10 = var9 ? new Vector3d(0.5, 0.0, 0.5) : new Vector3d(0.5, 0.5, 0.5);
         var7.sub(this.anchorX, this.anchorY, this.anchorZ).sub(var10);
         var1.flip(var7);
         var7.add(this.anchorX, this.anchorY, this.anchorZ).add(var10);
         var1.flipRotation(var8);
         if (var5 != null) {
            var1.flipRotation(var5.getRotation());
         }

         var3.addEntity0(var4);
      });
      class="kw">return var3;
   }

   @Nonnull
   class="kw">public BlockSelection relativize() {
      class="kw">return this.relativize(this.anchorX, this.anchorY, this.anchorZ);
   }

   @Nonnull
   class="kw">public BlockSelection relativize(int var1, int var2, int var3) {
      if (var1 == 0 && var2 == 0 && var3 == 0) {
         class="kw">return this.cloneSelection();
      }

      BlockSelection var4 = new BlockSelection(this.getBlockCount(), this.getEntityCount());
      var4.setAnchor(this.anchorX - var1, this.anchorY - var2, this.anchorZ - var3);
      var4.setPosition(this.x - var1, this.y - var2, this.z - var3);
      var4.setSelectionArea(new Vector3i(this.min).sub(var1, var2, var3), new Vector3i(this.max).sub(var1, var2, var3));
      this.forEachBlock((var4x, var5, var6, var7) -> var4.addBlock0(var4x - var1, var5 - var2, var6 - var3, var7));
      this.forEachFluid((var4x, var5, var6, var7, var8) -> var4.addFluid0(var4x - var1, var5 - var2, var6 - var3, var7, var8));
      this.forEachTint((var3x, var4x, var5) -> var4.addTintAtLocalPos(var3x - var1, var4x - var3, var5));
      this.forEachEntity(var4x -> {
         Holder var5 = var4x.clone();
         TransformComponent var6 = var5.getComponent(TransformComponent.getComponentType());
         assert var6 != null;
         var6.getPosition().sub(var1, var2, var3);
         var4.addEntity0(var5);
      });
      class="kw">return var4;
   }

   class="kw">public void relativizeInPlace() {
      this.relativizeInPlace(this.anchorX, this.anchorY, this.anchorZ);
   }

   class="kw">public void relativizeInPlace(int var1, int var2, int var3) {
      if (var1 != 0 || var2 != 0 || var3 != 0) {
         this.blocksLock.writeLock().lock();

         try {
            Long2ObjectMap var4 = new Long2ObjectOpenHashMap(this.blocks.size());
            Long2ObjectMaps.fastForEach(
               this.blocks,
               var4x -> {
                  long var5 = var4x.getLongKey();
                  var4.put(
                     BlockUtil.pack(BlockUtil.unpackX(var5) - var1, BlockUtil.unpackY(var5) - var2, BlockUtil.unpackZ(var5) - var3),
                     (BlockSelection.BlockHolder)var4x.getValue()
                  );
               }
            );
            this.blocks.clear();
            this.blocks.putAll(var4);
            Long2ObjectMap var5 = new Long2ObjectOpenHashMap(this.fluids.size());
            Long2ObjectMaps.fastForEach(
               this.fluids,
               var4x -> {
                  long var5 = var4x.getLongKey();
                  var5.put(
                     BlockUtil.pack(BlockUtil.unpackX(var5) - var1, BlockUtil.unpackY(var5) - var2, BlockUtil.unpackZ(var5) - var3),
                     (BlockSelection.FluidHolder)var4x.getValue()
                  );
               }
            );
            this.fluids.clear();
            this.fluids.putAll(var5);
            Long2IntMap var6 = new Long2IntOpenHashMap(this.tints.size());
            Long2IntMaps.fastForEach(this.tints, var3x -> {
               long var4 = var3x.getLongKey();
               var6.put(BlockUtil.pack(BlockUtil.unpackX(var4) - var1, 0, BlockUtil.unpackZ(var4) - var3), var3x.getIntValue());
            });
            this.tints.clear();
            this.tints.putAll(var6);
            this.setAnchor(this.anchorX - var1, this.anchorY - var2, this.anchorZ - var3);
            this.setPosition(this.x - var1, this.y - var2, this.z - var3);
            this.setSelectionArea(new Vector3i(this.min).sub(var1, var2, var3), new Vector3i(this.max).sub(var1, var2, var3));
         } class="kw">finally {
            this.blocksLock.writeLock().unlock();
         }

         this.entitiesLock.writeLock().lock();

         try {
            for (Holder var16 : this.entities) {
               TransformComponent var17 = var16.getComponent(TransformComponent.getComponentType());
               if (var17 != null) {
                  var17.getPosition().sub(var1, var2, var3);
               }
            }
         } class="kw">finally {
            this.entitiesLock.writeLock().unlock();
         }
      }
   }

   @Nonnull
   class="kw">public BlockSelection cloneSelection() {
      BlockSelection var1 = new BlockSelection(this.getBlockCount(), this.getEntityCount());
      var1.copyPropertiesFrom(this);
      this.blocksLock.readLock().lock();

      try {
         Long2ObjectMaps.fastForEach(
            this.blocks, var1x -> var1.blocks.put(var1x.getLongKey(), ((BlockSelection.BlockHolder)var1x.getValue()).cloneBlockHolder())
         );
         var1.fluids.putAll(this.fluids);
         var1.tints.putAll(this.tints);
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }

      this.entitiesLock.readLock().lock();

      try {
         this.entities.forEach(var1x -> var1.entities.add(var1x.clone()));
      } class="kw">finally {
         this.entitiesLock.readLock().unlock();
      }

      class="kw">return var1;
   }

   class="kw">public void add(@Nonnull BlockSelection var1) {
      this.entitiesLock.writeLock().lock();

      try {
         var1.forEachEntity(var2 -> {
            Holder var3 = var2.clone();
            TransformComponent var4 = var3.getComponent(TransformComponent.getComponentType());
            assert var4 != null;
            var4.getPosition().add(var1.x, var1.y, var1.z).sub(this.x, this.y, this.z);
            this.addEntity0(var3);
         });
      } class="kw">finally {
         this.entitiesLock.writeLock().unlock();
      }

      this.blocksLock.writeLock().lock();

      try {
         var1.forEachBlock((var2, var3, var4, var5) -> this.addBlock0(var2 + var1.x - this.x, var3 + var1.y - this.y, var4 + var1.z - this.z, var5));
         var1.forEachFluid((var2, var3, var4, var5, var6) -> this.addFluid0(var2 + var1.x - this.x, var3 + var1.y - this.y, var4 + var1.z - this.z, var5, var6));
      } class="kw">finally {
         this.blocksLock.writeLock().unlock();
      }
   }

   @Nonnull
   @Override
   class="kw">public MetricResults toMetricResults() {
      class="kw">return METRICS_REGISTRY.toMetricResults(this);
   }

   @Nonnull
   class="kw">public EditorBlocksChange toPacket() {
      EditorBlocksChange var1 = new EditorBlocksChange();
      this.blocksLock.readLock().lock();

      try {
         int var2 = this.getBlockCount();
         List var3 = new ObjectArrayList(var2);
         this.forEachBlock((var2x, var3x, var4x, var5x) -> {
            if (var5x.filler == 0) {
               var3.add(new BlockChange(var2x - this.anchorX, var3x - this.anchorY, var4x - this.anchorZ, var5x.blockId, (byte)var5x.rotation));
            }
         });
         List var4 = new ObjectArrayList();
         this.forEachFluid((var2x, var3x, var4x, var5x, var6) -> {
            if (var5x != 0) {
               var4.add(new FluidChange(var2x - this.anchorX, var3x - this.anchorY, var4x - this.anchorZ, var5x, var6));
            }
         });
         var1.blocksChange = var3.toArray(BlockChange[]::new);
         var1.fluidsChange = var4.toArray(FluidChange[]::new);
         var1.advancedPreview = true;
         var1.blocksCount = var2;
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }

      this.entitiesLock.readLock().lock();

      try {
         if (!this.entities.isEmpty()) {
            ObjectArrayList var13 = new ObjectArrayList(this.entities.size());

            for (Holder var15 : this.entities) {
               ClipboardEntityChange var5 = toClipboardEntityChange(var15, this.anchorX, this.anchorY, this.anchorZ);
               if (var5 != null) {
                  var13.add(var5);
               }
            }

            var1.entityChanges = (ClipboardEntityChange[])var13.toArray(ClipboardEntityChange[]::new);
         }
      } class="kw">finally {
         this.entitiesLock.readLock().unlock();
      }

      class="kw">return var1;
   }

   @Nullable
   class="kw">public class="kw">static ClipboardEntityChange toClipboardEntityChange(@Nonnull Holder<EntityStore> var0, double var1, double var3, double var5) {
      TransformComponent var7 = var0.getComponent(TransformComponent.getComponentType());
      if (var7 != null && var7.getPosition() != null) {
         Vector3d var8 = var7.getPosition();
         ClipboardEntityChange var9 = new ClipboardEntityChange();
         var9.x = (float)(var8.x() - var1);
         var9.y = (float)(var8.y() - var3);
         var9.z = (float)(var8.z() - var5);
         BlockEntity var10 = var0.getComponent(BlockEntity.getComponentType());
         if (var10 != null) {
            String var11 = var10.getBlockTypeKey();
            var9.blockId = var11 != null ? BlockType.getAssetMap().getIndex(var11) : 0;
         }

         ModelComponent var16 = var0.getComponent(ModelComponent.getComponentType());
         if (var16 != null && var16.getModel() != null) {
            var9.model = var16.getModel().toPacket();
         }

         if (var9.model == null) {
            PersistentModel var12 = var0.getComponent(PersistentModel.getComponentType());
            if (var12 != null) {
               Model var13 = var12.getModelReference().toModel();
               if (var13 != null) {
                  var9.model = var13.toPacket();
               }
            }
         }

         ItemComponent var17 = var0.getComponent(ItemComponent.getComponentType());
         if (var17 != null && var17.getItemStack() != null) {
            var9.itemId = var17.getItemStack().getItemId();
         }

         Rotation3f var18 = var7.getRotation();
         if (var18 != null) {
            var9.bodyOrientation = new Direction(var18.y(), var18.x(), var18.z());
         }

         HeadRotation var14 = var0.getComponent(HeadRotation.getComponentType());
         if (var14 != null && var14.getRotation() != null) {
            Rotation3f var15 = var14.getRotation();
            var9.lookOrientation = new Direction(var15.y(), var15.x(), var15.z());
         }

         EntityScaleComponent var19 = var0.getComponent(EntityScaleComponent.getComponentType());
         var9.scale = var19 != null ? var19.getScale() : 0.0F;
         class="kw">return var9;
      } else {
         class="kw">return null;
      }
   }

   @Nonnull
   class="kw">public EditorSelection toEditorSelectionBounds() {
      EditorSelection var1 = new EditorSelection();
      if (this.min != null) {
         var1.minX = this.min.x();
         var1.minY = this.min.y();
         var1.minZ = this.min.z();
      }

      if (this.max != null) {
         var1.maxX = this.max.x();
         var1.maxY = this.max.y();
         var1.maxZ = this.max.z();
      }

      class="kw">return var1;
   }

   @Nonnull
   class="kw">public EditorBlocksChange toSelectionPacket() {
      EditorBlocksChange var1 = new EditorBlocksChange();
      var1.selection = this.toEditorSelectionBounds();
      class="kw">return var1;
   }

   @Nonnull
   class="kw">public EditorBlocksChange toBoundsOnlyPacket() {
      EditorBlocksChange var1 = this.toSelectionPacket();
      var1.blocksOmitted = true;
      var1.blocksCount = this.getBlockCount();
      int var2 = this.x + this.anchorX;
      int var3 = this.y + this.anchorY;
      int var4 = this.z + this.anchorZ;
      EditorSelection var5 = new EditorSelection();
      var5.minX = this.min.x() - var2;
      var5.minY = this.min.y() - var3;
      var5.minZ = this.min.z() - var4;
      var5.maxX = this.max.x() - var2;
      var5.maxY = this.max.y() - var3;
      var5.maxZ = this.max.z() - var4;
      var1.anchorBounds = var5;
      class="kw">return var1;
   }

   @Nonnull
   class="kw">public EditorBlocksChange toShapePacket(int var1) {
      this.blocksLock.readLock().lock();

      try {
         int var2 = Integer.MAX_VALUE;
         int var3 = Integer.MAX_VALUE;
         int var4 = Integer.MAX_VALUE;
         int var5 = Integer.MIN_VALUE;
         int var6 = Integer.MIN_VALUE;
         int var7 = Integer.MIN_VALUE;
         ObjectIterator var8 = this.blocks.long2ObjectEntrySet().iterator();

         while (var8.hasNext()) {
            Entry var9 = (Entry<BlockSelection.BlockHolder>)var8.next();
            BlockSelection.BlockHolder var10 = (BlockSelection.BlockHolder)var9.getValue();
            if (var10.filler() == 0 && var10.blockId() > 0) {
               long var11 = var9.getLongKey();
               int var13 = BlockUtil.unpackX(var11) - this.anchorX;
               int var14 = BlockUtil.unpackY(var11) - this.anchorY;
               int var15 = BlockUtil.unpackZ(var11) - this.anchorZ;
               if (var13 < var2) {
                  var2 = var13;
               }

               if (var14 < var3) {
                  var3 = var14;
               }

               if (var15 < var4) {
                  var4 = var15;
               }

               if (var13 > var5) {
                  var5 = var13;
               }

               if (var14 > var6) {
                  var6 = var14;
               }

               if (var15 > var7) {
                  var7 = var15;
               }
            }
         }

         if (var2 == Integer.MAX_VALUE) {
            class="kw">return this.toBoundsOnlyPacket();
         }

         long var32 = (long)var5 - var2 + 1L;
         long var33 = (long)var6 - var3 + 1L;
         long var12 = (long)var7 - var4 + 1L;
         long var34 = var32 * var33 * var12;
         if (var34 > var1) {
            class="kw">return this.toBoundsOnlyPacket();
         }

         int var16 = (int)var32;
         int var17 = (int)var12;
         byte[] var18 = new byte[(int)(var34 + 7L >> 3)];
         ObjectIterator var19 = this.blocks.long2ObjectEntrySet().iterator();

         while (var19.hasNext()) {
            Entry var20 = (Entry<BlockSelection.BlockHolder>)var19.next();
            BlockSelection.BlockHolder var21 = (BlockSelection.BlockHolder)var20.getValue();
            if (var21.filler() == 0 && var21.blockId() > 0) {
               long var22 = var20.getLongKey();
               int var24 = BlockUtil.unpackX(var22) - this.anchorX - var2;
               int var25 = BlockUtil.unpackY(var22) - this.anchorY - var3;
               int var26 = BlockUtil.unpackZ(var22) - this.anchorZ - var4;
               long var27 = ((long)var25 * var17 + var26) * var16 + var24;
               var18[(int)(var27 >> 3)] = (byte)(var18[(int)(var27 >> 3)] | (byte)(1 << (int)(var27 & 7L)));
            }
         }

         EditorBlocksChange var35 = new EditorBlocksChange();
         var35.blocksOmitted = true;
         var35.blocksCount = this.blocks.size();
         EditorSelection var36 = new EditorSelection();
         var36.minX = var2;
         var36.minY = var3;
         var36.minZ = var4;
         var36.maxX = var5;
         var36.maxY = var6;
         var36.maxZ = var7;
         var35.anchorBounds = var36;
         var35.shapeOccupancy = var18;
         class="kw">return var35;
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }
   }

   @Nonnull
   class="kw">public EditorBlocksChange toPacketWithSelection() {
      EditorBlocksChange var1 = this.toPacket();
      if (this.min != null && this.max != null) {
         EditorSelection var2 = new EditorSelection();
         var2.minX = this.min.x();
         var2.minY = this.min.y();
         var2.minZ = this.min.z();
         var2.maxX = this.max.x();
         var2.maxY = this.max.y();
         var2.maxZ = this.max.z();
         var1.selection = var2;
      }

      class="kw">return var1;
   }

   class="kw">public void tryFixFiller(boolean var1) {
      this.blocksLock.readLock().lock();

      LongOpenHashSet var2;
      try {
         var2 = new LongOpenHashSet(this.blocks.keySet());
      } class="kw">finally {
         this.blocksLock.readLock().unlock();
      }

      BlockTypeAssetMap var3 = BlockType.getAssetMap();
      IndexedLookupTableAssetMap var4 = BlockBoundingBoxes.getAssetMap();
      LongIterator var5 = var2.iterator();

      while (var5.hasNext()) {
         long var6 = var5.nextLong();
         int var8 = BlockUtil.unpackX(var6);
         int var9 = BlockUtil.unpackY(var6);
         int var10 = BlockUtil.unpackZ(var6);
         BlockSelection.BlockHolder var11 = this.getBlockHolderAtLocalPos(var8, var9, var10);
         if (var11 != null) {
            int var12 = var11.blockId;
            if (var12 != 0) {
               BlockType var13 = (BlockType)var3.getAsset(var12);
               if (var13 != null) {
                  String var14 = var13.getId();
                  if (var11.filler != 0) {
                     int var15 = FillerBlockUtil.unpackX(var11.filler);
                     int var16 = FillerBlockUtil.unpackY(var11.filler);
                     int var17 = FillerBlockUtil.unpackZ(var11.filler);
                     BlockSelection.BlockHolder var18 = this.getBlockHolderAtLocalPos(var8 - var15, var9 - var16, var10 - var17);
                     if (var18 == null) {
                        this.addBlockAtLocalPos(var8, var9, var10, 0, 0, 0, 0);
                     } else {
                        BlockType var19 = (BlockType)var3.getAsset(var18.blockId);
                        if (var19 == null) {
                           this.addBlockAtLocalPos(var8, var9, var10, 0, 0, 0, 0);
                        } else {
                           String var20 = var19.getId();
                           BlockBoundingBoxes var21 = (BlockBoundingBoxes)var4.getAsset(var19.getHitboxTypeIndex());
                           if (var21 != null
                              && (
                                 !var14.equals(var20)
                                    || var18.rotation != var11.rotation
                                    || !var21.get(var11.rotation).getBoundingBox().containsBlock(var15, var16, var17)
                              )) {
                              this.addBlockAtLocalPos(var8, var9, var10, 0, 0, 0, 0);
                           }
                        }
                     }
                  } else {
                     BlockBoundingBoxes var24 = (BlockBoundingBoxes)var4.getAsset(var13.getHitboxTypeIndex());
                     if (var24 != null && var24.protrudesUnitBox()) {
                        FillerBlockUtil.forEachFillerBlock(
                           var24.get(var11.rotation),
                           (var10x, var11x, var12x) -> {
                              if (var10x != 0 || var11x != 0 || var12x != 0) {
                                 int var13 = var8 + var10x;
                                 int var14 = var9 + var11x;
                                 int var15 = var10 + var12x;
                                 BlockSelection.BlockHolder var16 = this.getBlockHolderAtLocalPos(var13, var14, var15);
                                 BlockType var17 = var16 != null ? (BlockType)var3.getAsset(var16.blockId) : null;
                                 int var18 = FillerBlockUtil.pack(var10x, var11x, var12x);
                                 if (var17 == null || !var17.getId().equals(var14) || var18 != var16.filler) {
                                    if (!var1 && var16 != null && var16.blockId != 0) {
                                       throw new IllegalArgumentException(
                                          "Cannot replace "
                                             + var17.getId()
                                             + " with "
                                             + var13.getId()
                                             + " in order to repair filler\n at "
                                             + var13
                                             + ", "
                                             + var14
                                             + ", "
                                             + var15
                                             + "\n base "
                                             + var8
                                             + ", "
                                             + var9
                                             + ", "
                                             + var10
                                       );
                                    }

                                    this.addBlockAtLocalPos(var13, var14, var15, var12, var11.rotation, var18, 0);
                                 }
                              }
                           }
                        );
                     }
                  }
               }
            }
         }
      }
   }

   class="kw">public void reserializeEntities(@Nonnull Store<EntityStore> var1, boolean var2) class="kw">throws IOException {
      this.entitiesLock.writeLock().lock();

      try {
         if (this.entities.isEmpty()) {
            class="kw">return;
         }

         ComponentRegistry var3 = EntityStore.REGISTRY;
         ComponentRegistry.Data var4 = var3.getData();
         SystemType var5 = EntityModule.get().getMigrationSystemType();
         BitSet var6 = var4.getSystemIndexesForType(var5);
         int var7 = -1;

         while ((var7 = var6.nextSetBit(var7 + 1)) >= 0) {
            EntityModule.MigrationSystem var8 = var4.getSystem(var7, var5);

            for (int var9 = 0; var9 < this.entities.size(); var9++) {
               Holder var10 = this.entities.get(var9);
               if (var8.test(var3, var10.getArchetype())) {
                  var8.onEntityAdd(var10, AddReason.LOAD, var1);
               }
            }
         }

         var7 = -1;

         while ((var7 = var6.nextSetBit(var7 + 1)) >= 0) {
            EntityModule.MigrationSystem var15 = var4.getSystem(var7, var5);

            for (int var17 = 0; var17 < this.entities.size(); var17++) {
               Holder var19 = this.entities.get(var17);
               if (var15.test(var3, var19.getArchetype())) {
                  var15.onEntityRemoved(var19, RemoveReason.UNLOAD, var1);
               }
            }
         }

         if (var2) {
            for (int var16 = 0; var16 < this.entities.size(); var16++) {
               Holder var18 = this.entities.get(var16);
               var18.tryRemoveComponent(var3.getUnknownComponentType());
            }
         }
      } class="kw">finally {
         this.entitiesLock.writeLock().unlock();
      }
   }

   @Nonnull
   @Override
   class="kw">public String toString() {
      class="kw">return "BlockSelection{blocksLock="
         + this.blocksLock
         + ", x="
         + this.x
         + ", y="
         + this.y
         + ", z="
         + this.z
         + ", anchorX="
         + this.anchorX
         + ", anchorY="
         + this.anchorY
         + ", anchorZ="
         + this.anchorZ
         + ", min="
         + this.min
         + ", max="
         + this.max
         + "}";
   }

   @FunctionalInterface
   class="kw">public class="kw">interface BlockComparingIterator {
      boolean test(int var1, int var2, int var3, BlockSelection.BlockHolder var4);
   }

   class="kw">public record BlockHolder(int blockId, int rotation, int filler, int supportValue, Holder<ChunkStore> holder) {
      class="kw">public BlockHolder {
      }

      @Nonnull
      class="kw">public BlockSelection.BlockHolder cloneBlockHolder() {
         class="kw">return this.holder == null ? this : new BlockSelection.BlockHolder(this.blockId, this.rotation, this.filler, this.supportValue, this.holder.clone());
      }
   }

   @FunctionalInterface
   class="kw">public class="kw">interface BlockIterator {
      void accept(int var1, int var2, int var3, BlockSelection.BlockHolder var4);
   }

   class="kw">public enum FallbackMode {
      PASS_THOUGH,
      COPY;

      FallbackMode() {
      }
   }

   class="kw">public record FluidHolder(int fluidId, byte fluidLevel) {
      class="kw">public FluidHolder {
      }
   }

   @FunctionalInterface
   class="kw">public class="kw">interface FluidIterator {
      void accept(int var1, int var2, int var3, int var4, byte var5);
   }

   @FunctionalInterface
   class="kw">public class="kw">interface TintIterator {
      void accept(int var1, int var2, int var3);
   }
}