375 lines
13 KiB
Java
375 lines
13 KiB
Java
package net.minecraft.server.level;
|
|
|
|
import org.apache.logging.log4j.LogManager;
|
|
import java.util.Collections;
|
|
import net.minecraft.world.phys.AABB;
|
|
import net.minecraft.core.particles.ParticleOptions;
|
|
import net.minecraft.sounds.SoundSource;
|
|
import net.minecraft.sounds.SoundEvent;
|
|
import net.minecraft.world.level.levelgen.Heightmap;
|
|
import net.minecraft.world.level.chunk.ChunkSource;
|
|
import net.minecraft.world.DifficultyInstance;
|
|
import net.minecraft.world.level.border.WorldBorder;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.world.level.BlockGetter;
|
|
import net.minecraft.world.level.block.EntityBlock;
|
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
import net.minecraft.world.level.block.Blocks;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.level.lighting.LevelLightEngine;
|
|
import net.minecraft.world.level.biome.Biome;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.entity.Entity;
|
|
import java.util.function.Predicate;
|
|
import net.minecraft.world.level.material.FluidState;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.core.BlockPos;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.world.level.chunk.ChunkStatus;
|
|
import net.minecraft.world.level.ChunkPos;
|
|
import net.minecraft.Util;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.world.level.biome.BiomeManager;
|
|
import net.minecraft.world.level.material.Fluid;
|
|
import net.minecraft.world.level.block.Block;
|
|
import net.minecraft.world.level.TickList;
|
|
import net.minecraft.world.level.levelgen.ChunkGeneratorSettings;
|
|
import net.minecraft.world.level.dimension.Dimension;
|
|
import java.util.Random;
|
|
import net.minecraft.world.level.storage.LevelData;
|
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
|
import java.util.List;
|
|
import org.apache.logging.log4j.Logger;
|
|
import net.minecraft.world.level.LevelAccessor;
|
|
|
|
public class WorldGenRegion implements LevelAccessor {
|
|
private static final Logger LOGGER;
|
|
private final List<ChunkAccess> cache;
|
|
private final int x;
|
|
private final int z;
|
|
private final int size;
|
|
private final ServerLevel level;
|
|
private final long seed;
|
|
private final int seaLevel;
|
|
private final LevelData levelData;
|
|
private final Random random;
|
|
private final Dimension dimension;
|
|
private final ChunkGeneratorSettings settings;
|
|
private final TickList<Block> blockTicks;
|
|
private final TickList<Fluid> liquidTicks;
|
|
private final BiomeManager biomeManager;
|
|
|
|
public WorldGenRegion(final ServerLevel xd, final List<ChunkAccess> list) {
|
|
this.blockTicks = new WorldGenTickList<Block>(fk -> this.getChunk(fk).getBlockTicks());
|
|
this.liquidTicks = new WorldGenTickList<Fluid>(fk -> this.getChunk(fk).getLiquidTicks());
|
|
final int integer4 = Mth.floor(Math.sqrt(list.size()));
|
|
if (integer4 * integer4 != list.size()) {
|
|
throw Util.<IllegalStateException>pauseInIde(new IllegalStateException("Cache size is not a square."));
|
|
}
|
|
final ChunkPos bje5 = list.get(list.size() / 2).getPos();
|
|
this.cache = list;
|
|
this.x = bje5.x;
|
|
this.z = bje5.z;
|
|
this.size = integer4;
|
|
this.level = xd;
|
|
this.seed = xd.getSeed();
|
|
this.settings = (ChunkGeneratorSettings)xd.getChunkSource().getGenerator().getSettings();
|
|
this.seaLevel = xd.getSeaLevel();
|
|
this.levelData = xd.getLevelData();
|
|
this.random = xd.getRandom();
|
|
this.dimension = xd.getDimension();
|
|
this.biomeManager = new BiomeManager(this, LevelData.obfuscateSeed(this.seed), this.dimension.getType().getBiomeZoomer());
|
|
}
|
|
|
|
public int getCenterX() {
|
|
return this.x;
|
|
}
|
|
|
|
public int getCenterZ() {
|
|
return this.z;
|
|
}
|
|
|
|
@Override
|
|
public ChunkAccess getChunk(final int integer1, final int integer2) {
|
|
return this.getChunk(integer1, integer2, ChunkStatus.EMPTY);
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public ChunkAccess getChunk(final int integer1, final int integer2, final ChunkStatus cab, final boolean boolean4) {
|
|
ChunkAccess bzv6;
|
|
if (this.hasChunk(integer1, integer2)) {
|
|
final ChunkPos bje7 = this.cache.get(0).getPos();
|
|
final int integer3 = integer1 - bje7.x;
|
|
final int integer4 = integer2 - bje7.z;
|
|
bzv6 = this.cache.get(integer3 + integer4 * this.size);
|
|
if (bzv6.getStatus().isOrAfter(cab)) {
|
|
return bzv6;
|
|
}
|
|
}
|
|
else {
|
|
bzv6 = null;
|
|
}
|
|
if (!boolean4) {
|
|
return null;
|
|
}
|
|
final ChunkAccess bzv7 = this.cache.get(0);
|
|
final ChunkAccess bzv8 = this.cache.get(this.cache.size() - 1);
|
|
WorldGenRegion.LOGGER.error("Requested chunk : {} {}", integer1, integer2);
|
|
WorldGenRegion.LOGGER.error("Region bounds : {} {} | {} {}", bzv7.getPos().x, bzv7.getPos().z, bzv8.getPos().x, bzv8.getPos().z);
|
|
if (bzv6 != null) {
|
|
throw Util.<RuntimeException>pauseInIde(new RuntimeException(String.format("Chunk is not of correct status. Expecting %s, got %s | %s %s", cab, bzv6.getStatus(), integer1, integer2)));
|
|
}
|
|
throw Util.<RuntimeException>pauseInIde(new RuntimeException(String.format("We are asking a region for a chunk out of bound | %s %s", integer1, integer2)));
|
|
}
|
|
|
|
@Override
|
|
public boolean hasChunk(final int integer1, final int integer2) {
|
|
final ChunkAccess bzv4 = this.cache.get(0);
|
|
final ChunkAccess bzv5 = this.cache.get(this.cache.size() - 1);
|
|
return integer1 >= bzv4.getPos().x && integer1 <= bzv5.getPos().x && integer2 >= bzv4.getPos().z && integer2 <= bzv5.getPos().z;
|
|
}
|
|
|
|
@Override
|
|
public BlockState getBlockState(final BlockPos fk) {
|
|
return this.getChunk(fk.getX() >> 4, fk.getZ() >> 4).getBlockState(fk);
|
|
}
|
|
|
|
@Override
|
|
public FluidState getFluidState(final BlockPos fk) {
|
|
return this.getChunk(fk).getFluidState(fk);
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public Player getNearestPlayer(final double double1, final double double2, final double double3, final double double4, final Predicate<Entity> predicate) {
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public int getSkyDarken() {
|
|
return 0;
|
|
}
|
|
|
|
@Override
|
|
public BiomeManager getBiomeManager() {
|
|
return this.biomeManager;
|
|
}
|
|
|
|
@Override
|
|
public Biome getUncachedNoiseBiome(final int integer1, final int integer2, final int integer3) {
|
|
return this.level.getUncachedNoiseBiome(integer1, integer2, integer3);
|
|
}
|
|
|
|
@Override
|
|
public LevelLightEngine getLightEngine() {
|
|
return this.level.getLightEngine();
|
|
}
|
|
|
|
@Override
|
|
public boolean destroyBlock(final BlockPos fk, final boolean boolean2, @Nullable final Entity akn) {
|
|
final BlockState byg5 = this.getBlockState(fk);
|
|
if (byg5.isAir()) {
|
|
return false;
|
|
}
|
|
if (boolean2) {
|
|
final BlockEntity bwi6 = byg5.getBlock().isEntityBlock() ? this.getBlockEntity(fk) : null;
|
|
Block.dropResources(byg5, this.level, fk, bwi6, akn, ItemStack.EMPTY);
|
|
}
|
|
return this.setBlock(fk, Blocks.AIR.defaultBlockState(), 3);
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public BlockEntity getBlockEntity(final BlockPos fk) {
|
|
final ChunkAccess bzv3 = this.getChunk(fk);
|
|
BlockEntity bwi4 = bzv3.getBlockEntity(fk);
|
|
if (bwi4 != null) {
|
|
return bwi4;
|
|
}
|
|
final CompoundTag jt5 = bzv3.getBlockEntityNbt(fk);
|
|
if (jt5 != null) {
|
|
if ("DUMMY".equals(jt5.getString("id"))) {
|
|
final Block bpe6 = this.getBlockState(fk).getBlock();
|
|
if (!(bpe6 instanceof EntityBlock)) {
|
|
return null;
|
|
}
|
|
bwi4 = ((EntityBlock)bpe6).newBlockEntity(this.level);
|
|
}
|
|
else {
|
|
bwi4 = BlockEntity.loadStatic(jt5);
|
|
}
|
|
if (bwi4 != null) {
|
|
bzv3.setBlockEntity(fk, bwi4);
|
|
return bwi4;
|
|
}
|
|
}
|
|
if (bzv3.getBlockState(fk).getBlock() instanceof EntityBlock) {
|
|
WorldGenRegion.LOGGER.warn("Tried to access a block entity before it was created. {}", fk);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public boolean setBlock(final BlockPos fk, final BlockState byg, final int integer) {
|
|
final ChunkAccess bzv5 = this.getChunk(fk);
|
|
final BlockState byg2 = bzv5.setBlockState(fk, byg, false);
|
|
if (byg2 != null) {
|
|
this.level.onBlockStateChange(fk, byg2, byg);
|
|
}
|
|
final Block bpe7 = byg.getBlock();
|
|
if (bpe7.isEntityBlock()) {
|
|
if (bzv5.getStatus().getChunkType() == ChunkStatus.ChunkType.LEVELCHUNK) {
|
|
bzv5.setBlockEntity(fk, ((EntityBlock)bpe7).newBlockEntity(this));
|
|
}
|
|
else {
|
|
final CompoundTag jt8 = new CompoundTag();
|
|
jt8.putInt("x", fk.getX());
|
|
jt8.putInt("y", fk.getY());
|
|
jt8.putInt("z", fk.getZ());
|
|
jt8.putString("id", "DUMMY");
|
|
bzv5.setBlockEntityNbt(jt8);
|
|
}
|
|
}
|
|
else if (byg2 != null && byg2.getBlock().isEntityBlock()) {
|
|
bzv5.removeBlockEntity(fk);
|
|
}
|
|
if (byg.hasPostProcess(this, fk)) {
|
|
this.markPosForPostprocessing(fk);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private void markPosForPostprocessing(final BlockPos fk) {
|
|
this.getChunk(fk).markPosForPostprocessing(fk);
|
|
}
|
|
|
|
@Override
|
|
public boolean addFreshEntity(final Entity akn) {
|
|
final int integer3 = Mth.floor(akn.getX() / 16.0);
|
|
final int integer4 = Mth.floor(akn.getZ() / 16.0);
|
|
this.getChunk(integer3, integer4).addEntity(akn);
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean removeBlock(final BlockPos fk, final boolean boolean2) {
|
|
return this.setBlock(fk, Blocks.AIR.defaultBlockState(), 3);
|
|
}
|
|
|
|
@Override
|
|
public WorldBorder getWorldBorder() {
|
|
return this.level.getWorldBorder();
|
|
}
|
|
|
|
@Override
|
|
public boolean isClientSide() {
|
|
return false;
|
|
}
|
|
|
|
@Deprecated
|
|
@Override
|
|
public ServerLevel getLevel() {
|
|
return this.level;
|
|
}
|
|
|
|
@Override
|
|
public LevelData getLevelData() {
|
|
return this.levelData;
|
|
}
|
|
|
|
@Override
|
|
public DifficultyInstance getCurrentDifficultyAt(final BlockPos fk) {
|
|
if (!this.hasChunk(fk.getX() >> 4, fk.getZ() >> 4)) {
|
|
throw new RuntimeException("We are asking a region for a chunk out of bound");
|
|
}
|
|
return new DifficultyInstance(this.level.getDifficulty(), this.level.getDayTime(), 0L, this.level.getMoonBrightness());
|
|
}
|
|
|
|
@Override
|
|
public ChunkSource getChunkSource() {
|
|
return this.level.getChunkSource();
|
|
}
|
|
|
|
@Override
|
|
public long getSeed() {
|
|
return this.seed;
|
|
}
|
|
|
|
@Override
|
|
public TickList<Block> getBlockTicks() {
|
|
return this.blockTicks;
|
|
}
|
|
|
|
@Override
|
|
public TickList<Fluid> getLiquidTicks() {
|
|
return this.liquidTicks;
|
|
}
|
|
|
|
@Override
|
|
public int getSeaLevel() {
|
|
return this.seaLevel;
|
|
}
|
|
|
|
@Override
|
|
public Random getRandom() {
|
|
return this.random;
|
|
}
|
|
|
|
@Override
|
|
public void blockUpdated(final BlockPos fk, final Block bpe) {
|
|
}
|
|
|
|
@Override
|
|
public int getHeight(final Heightmap.Types a, final int integer2, final int integer3) {
|
|
return this.getChunk(integer2 >> 4, integer3 >> 4).getHeight(a, integer2 & 0xF, integer3 & 0xF) + 1;
|
|
}
|
|
|
|
@Override
|
|
public void playSound(@Nullable final Player ayg, final BlockPos fk, final SoundEvent aah, final SoundSource aaj, final float float5, final float float6) {
|
|
}
|
|
|
|
@Override
|
|
public void addParticle(final ParticleOptions gt, final double double2, final double double3, final double double4, final double double5, final double double6, final double double7) {
|
|
}
|
|
|
|
@Override
|
|
public void levelEvent(@Nullable final Player ayg, final int integer2, final BlockPos fk, final int integer4) {
|
|
}
|
|
|
|
@Override
|
|
public BlockPos getSharedSpawnPos() {
|
|
return this.level.getSharedSpawnPos();
|
|
}
|
|
|
|
@Override
|
|
public Dimension getDimension() {
|
|
return this.dimension;
|
|
}
|
|
|
|
@Override
|
|
public boolean isStateAtPosition(final BlockPos fk, final Predicate<BlockState> predicate) {
|
|
return predicate.test(this.getBlockState(fk));
|
|
}
|
|
|
|
@Override
|
|
public <T extends Entity> List<T> getEntitiesOfClass(final Class<? extends T> class1, final AABB cvc, @Nullable final Predicate<? super T> predicate) {
|
|
return Collections.<T>emptyList();
|
|
}
|
|
|
|
@Override
|
|
public List<Entity> getEntities(@Nullable final Entity akn, final AABB cvc, @Nullable final Predicate<? super Entity> predicate) {
|
|
return Collections.<Entity>emptyList();
|
|
}
|
|
|
|
@Override
|
|
public List<Player> players() {
|
|
return Collections.<Player>emptyList();
|
|
}
|
|
|
|
static {
|
|
LOGGER = LogManager.getLogger();
|
|
}
|
|
}
|