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

import com.google.common.base.MoreObjects;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.util.Iterator;
import java.util.function.Predicate;
import javax.annotation.Nullable;

public class ShapeDetector {

    private final Predicate<ShapeDetectorBlock>[][][] a;
    private final int b;
    private final int c;
    private final int d;

    public ShapeDetector(Predicate<ShapeDetectorBlock>[][][] apredicate) {
        this.a = apredicate;
        this.b = apredicate.length;
        if (this.b > 0) {
            this.c = apredicate[0].length;
            if (this.c > 0) {
                this.d = apredicate[0][0].length;
            } else {
                this.d = 0;
            }
        } else {
            this.c = 0;
            this.d = 0;
        }

    }

    public int a() {
        return this.b;
    }

    public int b() {
        return this.c;
    }

    public int c() {
        return this.d;
    }

    @Nullable
    private ShapeDetector.ShapeDetectorCollection a(BlockPosition blockposition, EnumDirection enumdirection, EnumDirection enumdirection1, LoadingCache<BlockPosition, ShapeDetectorBlock> loadingcache) {
        for (int i = 0; i < this.d; ++i) {
            for (int j = 0; j < this.c; ++j) {
                for (int k = 0; k < this.b; ++k) {
                    if (!this.a[k][j][i].test(loadingcache.getUnchecked(a(blockposition, enumdirection, enumdirection1, i, j, k)))) {
                        return null;
                    }
                }
            }
        }

        return new ShapeDetector.ShapeDetectorCollection(blockposition, enumdirection, enumdirection1, loadingcache, this.d, this.c, this.b);
    }

    @Nullable
    public ShapeDetector.ShapeDetectorCollection a(IWorldReader iworldreader, BlockPosition blockposition) {
        LoadingCache<BlockPosition, ShapeDetectorBlock> loadingcache = a(iworldreader, false);
        int i = Math.max(Math.max(this.d, this.c), this.b);
        Iterator iterator = BlockPosition.a(blockposition, blockposition.b(i - 1, i - 1, i - 1)).iterator();

        while (iterator.hasNext()) {
            BlockPosition blockposition1 = (BlockPosition) iterator.next();
            EnumDirection[] aenumdirection = EnumDirection.values();
            int j = aenumdirection.length;

            for (int k = 0; k < j; ++k) {
                EnumDirection enumdirection = aenumdirection[k];
                EnumDirection[] aenumdirection1 = EnumDirection.values();
                int l = aenumdirection1.length;

                for (int i1 = 0; i1 < l; ++i1) {
                    EnumDirection enumdirection1 = aenumdirection1[i1];

                    if (enumdirection1 != enumdirection && enumdirection1 != enumdirection.opposite()) {
                        ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = this.a(blockposition1, enumdirection, enumdirection1, loadingcache);

                        if (shapedetector_shapedetectorcollection != null) {
                            return shapedetector_shapedetectorcollection;
                        }
                    }
                }
            }
        }

        return null;
    }

    public static LoadingCache<BlockPosition, ShapeDetectorBlock> a(IWorldReader iworldreader, boolean flag) {
        return CacheBuilder.newBuilder().build(new ShapeDetector.BlockLoader(iworldreader, flag));
    }

    protected static BlockPosition a(BlockPosition blockposition, EnumDirection enumdirection, EnumDirection enumdirection1, int i, int j, int k) {
        if (enumdirection != enumdirection1 && enumdirection != enumdirection1.opposite()) {
            BaseBlockPosition baseblockposition = new BaseBlockPosition(enumdirection.getAdjacentX(), enumdirection.getAdjacentY(), enumdirection.getAdjacentZ());
            BaseBlockPosition baseblockposition1 = new BaseBlockPosition(enumdirection1.getAdjacentX(), enumdirection1.getAdjacentY(), enumdirection1.getAdjacentZ());
            BaseBlockPosition baseblockposition2 = baseblockposition.d(baseblockposition1);

            return blockposition.b(baseblockposition1.getX() * -j + baseblockposition2.getX() * i + baseblockposition.getX() * k, baseblockposition1.getY() * -j + baseblockposition2.getY() * i + baseblockposition.getY() * k, baseblockposition1.getZ() * -j + baseblockposition2.getZ() * i + baseblockposition.getZ() * k);
        } else {
            throw new IllegalArgumentException("Invalid forwards & up combination");
        }
    }

    public static class Shape {

        public final Vec3D position;
        public final Vec3D velocity;
        public final int yaw;

        public Shape(Vec3D vec3d, Vec3D vec3d1, int i) {
            this.position = vec3d;
            this.velocity = vec3d1;
            this.yaw = i;
        }
    }

    public static class ShapeDetectorCollection {

        private final BlockPosition a;
        private final EnumDirection b;
        private final EnumDirection c;
        private final LoadingCache<BlockPosition, ShapeDetectorBlock> d;
        private final int e;
        private final int f;
        private final int g;

        public ShapeDetectorCollection(BlockPosition blockposition, EnumDirection enumdirection, EnumDirection enumdirection1, LoadingCache<BlockPosition, ShapeDetectorBlock> loadingcache, int i, int j, int k) {
            this.a = blockposition;
            this.b = enumdirection;
            this.c = enumdirection1;
            this.d = loadingcache;
            this.e = i;
            this.f = j;
            this.g = k;
        }

        public BlockPosition a() {
            return this.a;
        }

        public EnumDirection getFacing() {
            return this.b;
        }

        public EnumDirection c() {
            return this.c;
        }

        public int d() {
            return this.e;
        }

        public int e() {
            return this.f;
        }

        public ShapeDetectorBlock a(int i, int j, int k) {
            return (ShapeDetectorBlock) this.d.getUnchecked(ShapeDetector.a(this.a, this.getFacing(), this.c(), i, j, k));
        }

        public String toString() {
            return MoreObjects.toStringHelper(this).add("up", this.c).add("forwards", this.b).add("frontTopLeft", this.a).toString();
        }

        public ShapeDetector.Shape a(EnumDirection enumdirection, BlockPosition blockposition, double d0, Vec3D vec3d, double d1) {
            EnumDirection enumdirection1 = this.getFacing();
            EnumDirection enumdirection2 = enumdirection1.f();
            double d2 = (double) (this.a().getY() + 1) - d0 * (double) this.e();
            double d3;
            double d4;

            if (enumdirection2 == EnumDirection.NORTH) {
                d3 = (double) blockposition.getX() + 0.5D;
                d4 = (double) (this.a().getZ() + 1) - (1.0D - d1) * (double) this.d();
            } else if (enumdirection2 == EnumDirection.SOUTH) {
                d3 = (double) blockposition.getX() + 0.5D;
                d4 = (double) this.a().getZ() + (1.0D - d1) * (double) this.d();
            } else if (enumdirection2 == EnumDirection.WEST) {
                d3 = (double) (this.a().getX() + 1) - (1.0D - d1) * (double) this.d();
                d4 = (double) blockposition.getZ() + 0.5D;
            } else {
                d3 = (double) this.a().getX() + (1.0D - d1) * (double) this.d();
                d4 = (double) blockposition.getZ() + 0.5D;
            }

            double d5;
            double d6;

            if (enumdirection1.opposite() == enumdirection) {
                d5 = vec3d.x;
                d6 = vec3d.z;
            } else if (enumdirection1.opposite() == enumdirection.opposite()) {
                d5 = -vec3d.x;
                d6 = -vec3d.z;
            } else if (enumdirection1.opposite() == enumdirection.f()) {
                d5 = -vec3d.z;
                d6 = vec3d.x;
            } else {
                d5 = vec3d.z;
                d6 = -vec3d.x;
            }

            int i = (enumdirection1.get2DRotationValue() - enumdirection.opposite().get2DRotationValue()) * 90;

            return new ShapeDetector.Shape(new Vec3D(d3, d2, d4), new Vec3D(d5, vec3d.y, d6), i);
        }
    }

    static class BlockLoader extends CacheLoader<BlockPosition, ShapeDetectorBlock> {

        private final IWorldReader a;
        private final boolean b;

        public BlockLoader(IWorldReader iworldreader, boolean flag) {
            this.a = iworldreader;
            this.b = flag;
        }

        public ShapeDetectorBlock load(BlockPosition blockposition) throws Exception {
            return new ShapeDetectorBlock(this.a, blockposition, this.b);
        }
    }
}