Newer
Older
void-pack-super-server / work / decompile-ee3ecae0 / net / minecraft / server / StructureGenerator.java
package net.minecraft.server;

import com.google.common.collect.Lists;
import com.mojang.datafixers.Dynamic;
import it.unimi.dsi.fastutil.longs.LongIterator;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.function.Function;
import javax.annotation.Nullable;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public abstract class StructureGenerator<C extends WorldGenFeatureConfiguration> extends WorldGenerator<C> {

    private static final Logger LOGGER = LogManager.getLogger();

    public StructureGenerator(Function<Dynamic<?>, ? extends C> function) {
        super(function);
    }

    @Override
    public WorldGenFeatureConfigured<C, ? extends StructureGenerator<C>> b(C c0) {
        return new WorldGenFeatureConfigured<>(this, c0);
    }

    @Override
    public boolean generate(GeneratorAccess generatoraccess, ChunkGenerator<? extends GeneratorSettingsDefault> chunkgenerator, Random random, BlockPosition blockposition, C c0) {
        if (!generatoraccess.getWorldData().shouldGenerateMapFeatures()) {
            return false;
        } else {
            int i = blockposition.getX() >> 4;
            int j = blockposition.getZ() >> 4;
            int k = i << 4;
            int l = j << 4;
            boolean flag = false;
            LongIterator longiterator = generatoraccess.getChunkAt(i, j).b(this.b()).iterator();

            while (longiterator.hasNext()) {
                Long olong = (Long) longiterator.next();
                ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(olong);
                StructureStart structurestart = generatoraccess.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z).a(this.b());

                if (structurestart != null && structurestart != StructureStart.a) {
                    structurestart.a(generatoraccess, chunkgenerator, random, new StructureBoundingBox(k, l, k + 15, l + 15), new ChunkCoordIntPair(i, j));
                    flag = true;
                }
            }

            return flag;
        }
    }

    protected StructureStart a(GeneratorAccess generatoraccess, BlockPosition blockposition, boolean flag) {
        List<StructureStart> list = this.a(generatoraccess, blockposition.getX() >> 4, blockposition.getZ() >> 4);
        Iterator iterator = list.iterator();

        while (iterator.hasNext()) {
            StructureStart structurestart = (StructureStart) iterator.next();

            if (structurestart.e() && structurestart.c().b((BaseBlockPosition) blockposition)) {
                if (!flag) {
                    return structurestart;
                }

                Iterator iterator1 = structurestart.d().iterator();

                while (iterator1.hasNext()) {
                    StructurePiece structurepiece = (StructurePiece) iterator1.next();

                    if (structurepiece.g().b((BaseBlockPosition) blockposition)) {
                        return structurestart;
                    }
                }
            }
        }

        return StructureStart.a;
    }

    public boolean a(GeneratorAccess generatoraccess, BlockPosition blockposition) {
        return this.a(generatoraccess, blockposition, false).e();
    }

    public boolean b(GeneratorAccess generatoraccess, BlockPosition blockposition) {
        return this.a(generatoraccess, blockposition, true).e();
    }

    @Nullable
    public BlockPosition getNearestGeneratedFeature(World world, ChunkGenerator<? extends GeneratorSettingsDefault> chunkgenerator, BlockPosition blockposition, int i, boolean flag) {
        if (!chunkgenerator.getWorldChunkManager().a(this)) {
            return null;
        } else {
            int j = blockposition.getX() >> 4;
            int k = blockposition.getZ() >> 4;
            int l = 0;
            SeededRandom seededrandom = new SeededRandom();

            while (l <= i) {
                int i1 = -l;

                while (true) {
                    if (i1 <= l) {
                        boolean flag1 = i1 == -l || i1 == l;

                        for (int j1 = -l; j1 <= l; ++j1) {
                            boolean flag2 = j1 == -l || j1 == l;

                            if (flag1 || flag2) {
                                ChunkCoordIntPair chunkcoordintpair = this.a(chunkgenerator, seededrandom, j, k, i1, j1);
                                StructureStart structurestart = world.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z, ChunkStatus.STRUCTURE_STARTS).a(this.b());

                                if (structurestart != null && structurestart.e()) {
                                    if (flag && structurestart.h()) {
                                        structurestart.i();
                                        return structurestart.a();
                                    }

                                    if (!flag) {
                                        return structurestart.a();
                                    }
                                }

                                if (l == 0) {
                                    break;
                                }
                            }
                        }

                        if (l != 0) {
                            ++i1;
                            continue;
                        }
                    }

                    ++l;
                    break;
                }
            }

            return null;
        }
    }

    private List<StructureStart> a(GeneratorAccess generatoraccess, int i, int j) {
        List<StructureStart> list = Lists.newArrayList();
        IChunkAccess ichunkaccess = generatoraccess.getChunkAt(i, j, ChunkStatus.STRUCTURE_REFERENCES);
        LongIterator longiterator = ichunkaccess.b(this.b()).iterator();

        while (longiterator.hasNext()) {
            long k = longiterator.nextLong();
            IChunkAccess ichunkaccess1 = generatoraccess.getChunkAt(ChunkCoordIntPair.getX(k), ChunkCoordIntPair.getZ(k), ChunkStatus.STRUCTURE_STARTS);
            StructureStart structurestart = ichunkaccess1.a(this.b());

            if (structurestart != null) {
                list.add(structurestart);
            }
        }

        return list;
    }

    protected ChunkCoordIntPair a(ChunkGenerator<?> chunkgenerator, Random random, int i, int j, int k, int l) {
        return new ChunkCoordIntPair(i + k, j + l);
    }

    public abstract boolean a(BiomeManager biomemanager, ChunkGenerator<?> chunkgenerator, Random random, int i, int j, BiomeBase biomebase);

    public abstract StructureGenerator.a a();

    public abstract String b();

    public abstract int c();

    public interface a {

        StructureStart create(StructureGenerator<?> structuregenerator, int i, int j, StructureBoundingBox structureboundingbox, int k, long l);
    }
}