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

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nullable;

public class Pathfinder {

    private final Path a = new Path();
    private final Set<PathPoint> b = Sets.newHashSet();
    private final PathPoint[] c = new PathPoint[32];
    private final int d;
    private final PathfinderAbstract e;

    public Pathfinder(PathfinderAbstract pathfinderabstract, int i) {
        this.e = pathfinderabstract;
        this.d = i;
    }

    @Nullable
    public PathEntity a(ChunkCache chunkcache, EntityInsentient entityinsentient, Set<BlockPosition> set, float f, int i, float f1) {
        this.a.a();
        this.e.a(chunkcache, entityinsentient);
        PathPoint pathpoint = this.e.b();
        Map<PathDestination, BlockPosition> map = (Map) set.stream().collect(Collectors.toMap((blockposition) -> {
            return this.e.a((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ());
        }, Function.identity()));
        PathEntity pathentity = this.a(pathpoint, map, f, i, f1);

        this.e.a();
        return pathentity;
    }

    @Nullable
    private PathEntity a(PathPoint pathpoint, Map<PathDestination, BlockPosition> map, float f, int i, float f1) {
        Set<PathDestination> set = map.keySet();

        pathpoint.e = 0.0F;
        pathpoint.f = this.a(pathpoint, set);
        pathpoint.g = pathpoint.f;
        this.a.a();
        this.b.clear();
        this.a.a(pathpoint);
        int j = 0;
        int k = (int) ((float) this.d * f1);

        while (!this.a.e()) {
            ++j;
            if (j >= k) {
                break;
            }

            PathPoint pathpoint1 = this.a.c();

            pathpoint1.i = true;
            set.stream().filter((pathdestination) -> {
                return pathpoint1.c((PathPoint) pathdestination) <= (float) i;
            }).forEach(PathDestination::e);
            if (set.stream().anyMatch(PathDestination::f)) {
                break;
            }

            if (pathpoint1.a(pathpoint) < f) {
                int l = this.e.a(this.c, pathpoint1);

                for (int i1 = 0; i1 < l; ++i1) {
                    PathPoint pathpoint2 = this.c[i1];
                    float f2 = pathpoint1.a(pathpoint2);

                    pathpoint2.j = pathpoint1.j + f2;
                    float f3 = pathpoint1.e + f2 + pathpoint2.k;

                    if (pathpoint2.j < f && (!pathpoint2.c() || f3 < pathpoint2.e)) {
                        pathpoint2.h = pathpoint1;
                        pathpoint2.e = f3;
                        pathpoint2.f = this.a(pathpoint2, set) * 1.5F;
                        if (pathpoint2.c()) {
                            this.a.a(pathpoint2, pathpoint2.e + pathpoint2.f);
                        } else {
                            pathpoint2.g = pathpoint2.e + pathpoint2.f;
                            this.a.a(pathpoint2);
                        }
                    }
                }
            }
        }

        Stream stream;

        if (set.stream().anyMatch(PathDestination::f)) {
            stream = set.stream().filter(PathDestination::f).map((pathdestination) -> {
                return this.a(pathdestination.d(), (BlockPosition) map.get(pathdestination), true);
            }).sorted(Comparator.comparingInt(PathEntity::e));
        } else {
            stream = set.stream().map((pathdestination) -> {
                return this.a(pathdestination.d(), (BlockPosition) map.get(pathdestination), false);
            }).sorted(Comparator.comparingDouble(PathEntity::l).thenComparingInt(PathEntity::e));
        }

        Optional<PathEntity> optional = stream.findFirst();

        if (!optional.isPresent()) {
            return null;
        } else {
            PathEntity pathentity = (PathEntity) optional.get();

            return pathentity;
        }
    }

    private float a(PathPoint pathpoint, Set<PathDestination> set) {
        float f = Float.MAX_VALUE;

        float f1;

        for (Iterator iterator = set.iterator(); iterator.hasNext(); f = Math.min(f1, f)) {
            PathDestination pathdestination = (PathDestination) iterator.next();

            f1 = pathpoint.a(pathdestination);
            pathdestination.a(f1, pathpoint);
        }

        return f;
    }

    private PathEntity a(PathPoint pathpoint, BlockPosition blockposition, boolean flag) {
        List<PathPoint> list = Lists.newArrayList();
        PathPoint pathpoint1 = pathpoint;

        list.add(0, pathpoint);

        while (pathpoint1.h != null) {
            pathpoint1 = pathpoint1.h;
            list.add(0, pathpoint1);
        }

        return new PathEntity(list, blockposition, flag);
    }
}