1615 lines
63 KiB
Diff
1615 lines
63 KiB
Diff
From 1c0aa00f7386228c8dc1695964edf10261ea6e47 Mon Sep 17 00:00:00 2001
|
|
From: Poweruser_rs <poweruser.rs@hotmail.com>
|
|
Date: Sun, 28 Feb 2016 22:55:26 +0100
|
|
Subject: [PATCH] Async path searches
|
|
|
|
|
|
diff --git a/src/main/java/net/frozenorb/ThreadingManager.java b/src/main/java/net/frozenorb/ThreadingManager.java
|
|
index f56e68e1b..ed1dfbbc2 100644
|
|
--- a/src/main/java/net/frozenorb/ThreadingManager.java
|
|
+++ b/src/main/java/net/frozenorb/ThreadingManager.java
|
|
@@ -9,6 +9,8 @@ import java.util.concurrent.ExecutorService;
|
|
import java.util.concurrent.Executors;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
+import net.frozenorb.pathsearch.PathSearchThrottlerThread;
|
|
+import net.frozenorb.pathsearch.jobs.PathSearchJob;
|
|
import net.minecraft.server.NBTCompressedStreamTools;
|
|
import net.minecraft.server.NBTTagCompound;
|
|
|
|
@@ -20,12 +22,15 @@ public class ThreadingManager {
|
|
private final Logger log = LogManager.getLogger();
|
|
private ExecutorService nbtFileService = Executors.newSingleThreadExecutor(new NamePriorityThreadFactory(Thread.NORM_PRIORITY - 2, "mSpigot_NBTFileSaver"));
|
|
private static ThreadingManager instance;
|
|
+ private PathSearchThrottlerThread pathSearchThrottler;
|
|
|
|
public ThreadingManager() {
|
|
instance = this;
|
|
+ this.pathSearchThrottler = new PathSearchThrottlerThread(2);
|
|
}
|
|
|
|
public void shutdown() {
|
|
+ this.pathSearchThrottler.shutdown();
|
|
this.nbtFileService.shutdown();
|
|
while(!this.nbtFileService.isTerminated()) {
|
|
try {
|
|
@@ -72,4 +77,8 @@ public class ThreadingManager {
|
|
this.file = null;
|
|
}
|
|
}
|
|
+
|
|
+ public static boolean queuePathSearch(PathSearchJob pathSearchJob) {
|
|
+ return instance.pathSearchThrottler.queuePathSearch(pathSearchJob);
|
|
+ }
|
|
}
|
|
diff --git a/src/main/java/net/frozenorb/WeakChunkCache.java b/src/main/java/net/frozenorb/WeakChunkCache.java
|
|
new file mode 100644
|
|
index 000000000..4b0c8fd4f
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/frozenorb/WeakChunkCache.java
|
|
@@ -0,0 +1,113 @@
|
|
+package net.frozenorb;
|
|
+
|
|
+import net.minecraft.server.Block;
|
|
+import net.minecraft.server.Blocks;
|
|
+import net.minecraft.server.Chunk;
|
|
+import net.minecraft.server.IBlockAccess;
|
|
+import net.minecraft.server.TileEntity;
|
|
+import net.minecraft.server.World;
|
|
+
|
|
+public class WeakChunkCache implements IBlockAccess {
|
|
+ private int lowerChunkX;
|
|
+ private int lowerChunkZ;
|
|
+ private Chunk[][] chunks;
|
|
+ private boolean ownArray = false;
|
|
+
|
|
+ public WeakChunkCache(Chunk[][] chunks, int lowerChunkX, int lowerChunkZ) {
|
|
+ this.chunks = chunks;
|
|
+ this.lowerChunkX = lowerChunkX;
|
|
+ this.lowerChunkZ = lowerChunkZ;
|
|
+ }
|
|
+
|
|
+ public WeakChunkCache(World world, int chunkX, int chunkZ, int chunkRadius) {
|
|
+ this(world, chunkX - chunkRadius, chunkZ - chunkRadius, chunkX + chunkRadius, chunkZ + chunkRadius);
|
|
+ }
|
|
+
|
|
+ public WeakChunkCache(World world, int lowerChunkX, int lowerChunkZ, int upperChunkX, int upperChunkZ) {
|
|
+ this.lowerChunkX = lowerChunkX;
|
|
+ this.lowerChunkZ = lowerChunkZ;
|
|
+
|
|
+ this.chunks = new Chunk[upperChunkX - this.lowerChunkX + 1][upperChunkZ - this.lowerChunkZ + 1];
|
|
+ this.ownArray = true;
|
|
+
|
|
+ for (int chunkX = this.lowerChunkX; chunkX <= upperChunkX; ++chunkX) {
|
|
+ for (int chunkZ = this.lowerChunkZ; chunkZ <= upperChunkZ; ++chunkZ) {
|
|
+ this.chunks[chunkX - this.lowerChunkX][chunkZ - this.lowerChunkZ] = world.getChunkIfLoaded(chunkX, chunkZ);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public WeakChunkCache(World world, int lowerBlockX, int lowerBlockY, int lowerBlockZ, int upperBlockX, int upperBlockY, int upperBlockZ, int blockRadius) {
|
|
+ this(world, (lowerBlockX - blockRadius) >> 4,
|
|
+ (lowerBlockZ - blockRadius) >> 4,
|
|
+ (upperBlockX + blockRadius) >> 4,
|
|
+ (upperBlockZ + blockRadius) >> 4);
|
|
+ }
|
|
+
|
|
+ public Block getType(int x, int y, int z) {
|
|
+ Block block = Blocks.AIR;
|
|
+
|
|
+ if (y >= 0 && y < 256) {
|
|
+ int indexX = (x >> 4) - this.lowerChunkX;
|
|
+ int indexZ = (z >> 4) - this.lowerChunkZ;
|
|
+
|
|
+ if (indexX >= 0 && indexX < this.chunks.length && indexZ >= 0 && indexZ < this.chunks[indexX].length) {
|
|
+ Chunk chunk = this.chunks[indexX][indexZ];
|
|
+
|
|
+ if (chunk != null) {
|
|
+ block = chunk.getType(x & 15, y, z & 15);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return block;
|
|
+ }
|
|
+
|
|
+ public TileEntity getTileEntity(int x, int y, int z) {
|
|
+ int indexX = (x >> 4) - this.lowerChunkX;
|
|
+ int indexZ = (z >> 4) - this.lowerChunkZ;
|
|
+
|
|
+ Chunk chunk = this.chunks[indexX][indexZ];
|
|
+ if(chunk != null) {
|
|
+ return chunk.e(x & 15, y, z & 15);
|
|
+ }
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+ public int getData(int x, int y, int z) {
|
|
+ if (y >= 0 && y < 256) {
|
|
+ int indexX = (x >> 4) - this.lowerChunkX;
|
|
+ int indexZ = (z >> 4) - this.lowerChunkZ;
|
|
+ if (indexX >= 0 && indexX < this.chunks.length && indexZ >= 0 && indexZ < this.chunks[indexX].length) {
|
|
+ Chunk chunk = this.chunks[indexX][indexZ];
|
|
+ if(chunk != null) {
|
|
+ return chunk.getData(x & 15, y, z & 15);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ public int getBlockPower(int i, int j, int k, int l) {
|
|
+ return this.getType(i, j, k).c(this, i, j, k, l);
|
|
+ }
|
|
+
|
|
+ public boolean isLoaded(int x, int y, int z) {
|
|
+ int indexX = (x >> 4) - this.lowerChunkX;
|
|
+ int indexZ = (z >> 4) - this.lowerChunkZ;
|
|
+ if (indexX >= 0 && indexX < this.chunks.length && indexZ >= 0 && indexZ < this.chunks[indexX].length) {
|
|
+ return this.chunks[indexX][indexZ] != null;
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ public void clear() {
|
|
+ if(this.ownArray) {
|
|
+ for(int i = 0; i < this.chunks.length; i++) {
|
|
+ for(int j = 0; j < this.chunks[i].length; j++) {
|
|
+ this.chunks[i][j] = null;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/frozenorb/pathsearch/AsyncNavigation.java b/src/main/java/net/frozenorb/pathsearch/AsyncNavigation.java
|
|
new file mode 100644
|
|
index 000000000..d4c6b1014
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/frozenorb/pathsearch/AsyncNavigation.java
|
|
@@ -0,0 +1,203 @@
|
|
+package net.frozenorb.pathsearch;
|
|
+
|
|
+import java.util.HashMap;
|
|
+import java.util.Iterator;
|
|
+import java.util.Map.Entry;
|
|
+import java.util.UUID;
|
|
+
|
|
+import org.bukkit.util.BlockVector;
|
|
+
|
|
+import net.frozenorb.ThreadingManager;
|
|
+import net.frozenorb.pathsearch.cache.SearchCacheEntry;
|
|
+import net.frozenorb.pathsearch.cache.SearchCacheEntryEntity;
|
|
+import net.frozenorb.pathsearch.cache.SearchCacheEntryPosition;
|
|
+import net.frozenorb.pathsearch.jobs.PathSearchJob;
|
|
+import net.frozenorb.pathsearch.jobs.PathSearchJobEntity;
|
|
+import net.frozenorb.pathsearch.jobs.PathSearchJobNavigationEntity;
|
|
+import net.frozenorb.pathsearch.jobs.PathSearchJobNavigationPosition;
|
|
+import net.frozenorb.pathsearch.jobs.PathSearchJobPosition;
|
|
+import net.frozenorb.pathsearch.jobs.PathSearchQueuingManager;
|
|
+import net.minecraft.server.Entity;
|
|
+import net.minecraft.server.EntityInsentient;
|
|
+import net.minecraft.server.MathHelper;
|
|
+import net.minecraft.server.Navigation;
|
|
+import net.minecraft.server.PathEntity;
|
|
+import net.minecraft.server.World;
|
|
+
|
|
+public class AsyncNavigation extends Navigation {
|
|
+
|
|
+ private HashMap<UUID, SearchCacheEntry> searchCache;
|
|
+ private HashMap<PositionPathSearchType, SearchCacheEntryPosition> positionSearchCache;
|
|
+ private static double minimumDistanceForOffloadingSquared = 0.0D;
|
|
+ private int cleanUpDelay = 0;
|
|
+ private PathSearchQueuingManager queuingManager;
|
|
+
|
|
+ public AsyncNavigation(EntityInsentient entityinsentient, World world) {
|
|
+ super(entityinsentient, world);
|
|
+ this.searchCache = new HashMap<UUID, SearchCacheEntry>();
|
|
+ this.positionSearchCache = new HashMap<PositionPathSearchType, SearchCacheEntryPosition>();
|
|
+ this.queuingManager = new PathSearchQueuingManager();
|
|
+ }
|
|
+
|
|
+ private BlockVector createBlockVectorForPosition(int x, int y, int z) {
|
|
+ return new BlockVector(x, y, z);
|
|
+ }
|
|
+
|
|
+ private void issueSearch(Entity target, float range, boolean j, boolean k, boolean l, boolean m) {
|
|
+ this.queuingManager.queueSearch(new PathSearchJobNavigationEntity(this.a, target, range, j, k, l, m));
|
|
+ }
|
|
+
|
|
+ private void issueSearch(PositionPathSearchType type, int x, int y, int z, float range, boolean j, boolean k, boolean l, boolean m) {
|
|
+ this.queuingManager.queueSearch(new PathSearchJobNavigationPosition(type, this.a, x, y, z, range, j, k, l, m));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void cancelSearch(PathSearchJob pathSearch) {
|
|
+ this.queuingManager.checkLastSearchResult(pathSearch);
|
|
+ pathSearch.cleanup();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setSearchResult(PathSearchJobNavigationEntity pathSearch) {
|
|
+ this.queuingManager.checkLastSearchResult(pathSearch);
|
|
+ SearchCacheEntry entry = pathSearch.getCacheEntryValue();
|
|
+ if(entry != null && entry.didSearchSucceed()) {
|
|
+ synchronized(this.searchCache) {
|
|
+ UUID key = pathSearch.getCacheEntryKey();
|
|
+ this.searchCache.put(key, entry);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setSearchResult(PathSearchJobNavigationPosition pathSearch) {
|
|
+ this.queuingManager.checkLastSearchResult(pathSearch);
|
|
+ SearchCacheEntryPosition entry = pathSearch.getCacheEntryValue();
|
|
+ if(entry != null && entry.didSearchSucceed()) {
|
|
+ synchronized(this.positionSearchCache) {
|
|
+ PositionPathSearchType key = pathSearch.getCacheEntryKey();
|
|
+ this.positionSearchCache.put(key, entry);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public PathEntity a(double d0, double d1, double d2) {
|
|
+ return this.a(PositionPathSearchType.ANYOTHER, d0, d1, d2);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean a(PositionPathSearchType type, double d0, double d1, double d2, double d3) {
|
|
+ PathEntity pathentity = this.a(type, (double) MathHelper.floor(d0), (double) ((int) d1), (double) MathHelper.floor(d2));
|
|
+
|
|
+ return this.a(pathentity, d3);
|
|
+ }
|
|
+
|
|
+ public void cleanUpExpiredSearches() {
|
|
+ if(++this.cleanUpDelay > 100) {
|
|
+ this.cleanUpDelay = 0;
|
|
+ synchronized(this.searchCache) {
|
|
+ Iterator<Entry<UUID, SearchCacheEntry>> iter = this.searchCache.entrySet().iterator();
|
|
+ while(iter.hasNext()) {
|
|
+ Entry<UUID, SearchCacheEntry> entry = iter.next();
|
|
+ if(entry.getValue().hasExpired()) {
|
|
+ iter.remove();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ synchronized(this.positionSearchCache) {
|
|
+ Iterator<Entry<PositionPathSearchType, SearchCacheEntryPosition>> iter2 = this.positionSearchCache.entrySet().iterator();
|
|
+ while(iter2.hasNext()) {
|
|
+ Entry<PositionPathSearchType, SearchCacheEntryPosition> entry = iter2.next();
|
|
+ if(entry.getValue().hasExpired()) {
|
|
+ iter2.remove();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public PathEntity a(Entity entity) {
|
|
+ if(!this.offloadSearches() || this.a.f(entity) < minimumDistanceForOffloadingSquared) {
|
|
+ return super.a(entity);
|
|
+ }
|
|
+ if(!this.l()) {
|
|
+ return null;
|
|
+ }
|
|
+ SearchCacheEntry entry = null;
|
|
+ UUID id = entity.getUniqueID();
|
|
+ synchronized(this.searchCache) {
|
|
+ if(this.searchCache.containsKey(id)) {
|
|
+ entry = this.searchCache.get(id);
|
|
+ }
|
|
+ }
|
|
+ PathEntity resultPath = null;
|
|
+ if(entry != null) {
|
|
+ resultPath = entry.getAdjustedPathEntity();
|
|
+ if(!entry.isStillValid()) {
|
|
+ this.issueSearch(entity, this.d(), this.j, this.k, this.l, this.m);
|
|
+ }
|
|
+ }
|
|
+ if(entry == null && !this.queuingManager.hasAsyncSearchIssued()) {
|
|
+ resultPath = super.a(entity);
|
|
+ if(resultPath != null) {
|
|
+ entry = new SearchCacheEntryEntity(this.a, entity, resultPath);
|
|
+ synchronized(this.searchCache) {
|
|
+ SearchCacheEntry oldEntry = this.searchCache.put(id, entry);
|
|
+ if(oldEntry != null) {
|
|
+ oldEntry.cleanup();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return resultPath;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public PathEntity a(PositionPathSearchType type, double d0, double d1, double d2) {
|
|
+ if(!this.offloadSearches() || this.a.e(d0, d1, d2) < minimumDistanceForOffloadingSquared) {
|
|
+ return super.a(d0, d1, d2);
|
|
+ }
|
|
+ if(!this.l()) {
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+ int x = MathHelper.floor(d0);
|
|
+ int y = (int) d1;
|
|
+ int z = MathHelper.floor(d2);
|
|
+
|
|
+ SearchCacheEntryPosition entry = null;
|
|
+ synchronized(this.positionSearchCache) {
|
|
+ if(this.positionSearchCache.containsKey(type)) {
|
|
+ entry = this.positionSearchCache.get(type);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ PathEntity resultPath = null;
|
|
+ if(entry != null) {
|
|
+ resultPath = entry.getAdjustedPathEntity();
|
|
+ if(!entry.isStillValid()) {
|
|
+ this.issueSearch(type, x, y, z, this.d(), this.j, this.k, this.l, this.m);
|
|
+ }
|
|
+ }
|
|
+ if(entry == null && !this.queuingManager.hasAsyncSearchIssued()) {
|
|
+ resultPath = super.a(d0, d1, d2);
|
|
+ if(resultPath != null) {
|
|
+ entry = new SearchCacheEntryPosition(this.a, x, y, z, resultPath);
|
|
+ synchronized(this.positionSearchCache) {
|
|
+ SearchCacheEntry oldEntry = this.positionSearchCache.put(type, entry);
|
|
+ if(oldEntry != null) {
|
|
+ oldEntry.cleanup();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return resultPath;
|
|
+ }
|
|
+
|
|
+ private boolean offloadSearches() {
|
|
+ return true;
|
|
+ //return Migot.getConfig().isPathSearchOffloadedFor(this.b);
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/frozenorb/pathsearch/AsyncPathfinder.java b/src/main/java/net/frozenorb/pathsearch/AsyncPathfinder.java
|
|
new file mode 100644
|
|
index 000000000..4a6b9e471
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/frozenorb/pathsearch/AsyncPathfinder.java
|
|
@@ -0,0 +1,21 @@
|
|
+package net.frozenorb.pathsearch;
|
|
+
|
|
+import net.minecraft.server.Entity;
|
|
+import net.minecraft.server.IBlockAccess;
|
|
+import net.minecraft.server.PathPoint;
|
|
+import net.minecraft.server.Pathfinder;
|
|
+
|
|
+public class AsyncPathfinder extends Pathfinder {
|
|
+
|
|
+ private IBlockAccess iblockaccess;
|
|
+
|
|
+ public AsyncPathfinder(IBlockAccess iblockaccess, boolean flag, boolean flag1, boolean flag2, boolean flag3) {
|
|
+ super(iblockaccess, flag, flag1, flag2, flag3);
|
|
+ this.iblockaccess = iblockaccess;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int a(Entity entity, int i, int j, int k, PathPoint pathpoint) {
|
|
+ return this.a(this.iblockaccess, entity, i, j, k, pathpoint);
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/frozenorb/pathsearch/PathSearchThrottlerThread.java b/src/main/java/net/frozenorb/pathsearch/PathSearchThrottlerThread.java
|
|
new file mode 100644
|
|
index 000000000..53f011b14
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/frozenorb/pathsearch/PathSearchThrottlerThread.java
|
|
@@ -0,0 +1,105 @@
|
|
+package net.frozenorb.pathsearch;
|
|
+
|
|
+import java.util.HashSet;
|
|
+import java.util.Iterator;
|
|
+import java.util.LinkedHashMap;
|
|
+import java.util.Map.Entry;
|
|
+import java.util.concurrent.ExecutionException;
|
|
+import java.util.concurrent.FutureTask;
|
|
+import java.util.concurrent.LinkedBlockingQueue;
|
|
+import java.util.concurrent.ThreadPoolExecutor;
|
|
+import java.util.concurrent.TimeUnit;
|
|
+
|
|
+import net.frozenorb.NamePriorityThreadFactory;
|
|
+import net.frozenorb.pathsearch.jobs.PathSearchJob;
|
|
+
|
|
+public class PathSearchThrottlerThread extends ThreadPoolExecutor {
|
|
+
|
|
+ private int queueLimit;
|
|
+ private LinkedHashMap<PathSearchJob, PathSearchJob> filter;
|
|
+ private HashSet<Integer> activeSearchHashes;
|
|
+ private static PathSearchThrottlerThread instance;
|
|
+
|
|
+ public PathSearchThrottlerThread(int poolSize) {
|
|
+ super(poolSize, poolSize, 1L, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>(), new NamePriorityThreadFactory(Thread.MIN_PRIORITY, "mSpigot_PathFinder"));
|
|
+ instance = this;
|
|
+ adjustPoolSize(poolSize);
|
|
+ this.filter = new LinkedHashMap<PathSearchJob, PathSearchJob>();
|
|
+ this.activeSearchHashes = new HashSet<Integer>();
|
|
+ }
|
|
+
|
|
+ public boolean queuePathSearch(PathSearchJob newJob) {
|
|
+ boolean jobHasBeenQueued = false;
|
|
+ if(newJob != null) {
|
|
+ synchronized(this.filter) {
|
|
+ if(this.filter.containsKey(newJob) || this.filter.size() < 1000) {
|
|
+ jobHasBeenQueued = true;
|
|
+ PathSearchJob previousJob = this.filter.put(newJob, newJob);
|
|
+ if(previousJob != null) {
|
|
+ previousJob.cancel();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ if(!jobHasBeenQueued) {
|
|
+ newJob.cancel();
|
|
+ }
|
|
+ }
|
|
+ PathSearchJob jobToExecute = null;
|
|
+ synchronized(this.filter) {
|
|
+ Iterator<Entry<PathSearchJob, PathSearchJob>> iter = this.filter.entrySet().iterator();
|
|
+ while(iter.hasNext() && this.getQueue().size() < this.queueLimit) {
|
|
+ jobToExecute = iter.next().getValue();
|
|
+ if(!this.activeSearchHashes.contains(jobToExecute.getSearchHash())) {
|
|
+ iter.remove();
|
|
+ if(jobToExecute != null) {
|
|
+ this.activeSearchHashes.add(jobToExecute.getSearchHash());
|
|
+ this.submit(jobToExecute);
|
|
+ }
|
|
+ if(newJob != null) {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return jobHasBeenQueued;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void shutdown() {
|
|
+ this.getQueue().clear();
|
|
+ super.shutdown();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void afterExecute(Runnable runnable, Throwable throwable) {
|
|
+ super.afterExecute(runnable, throwable);
|
|
+ if(runnable instanceof FutureTask) {
|
|
+ FutureTask<PathSearchJob> task = (FutureTask<PathSearchJob>) runnable;
|
|
+ PathSearchJob job = null;
|
|
+ try {
|
|
+ job = task.get();
|
|
+ } catch (InterruptedException e) {
|
|
+ } catch (ExecutionException e) {
|
|
+ }
|
|
+ if(job != null) {
|
|
+ synchronized(this.filter) {
|
|
+ this.activeSearchHashes.remove(job.getSearchHash());
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ this.queuePathSearch(null);
|
|
+ }
|
|
+
|
|
+ public static void adjustPoolSize(int size) {
|
|
+ if(instance != null) {
|
|
+ if(size > instance.getMaximumPoolSize()) {
|
|
+ instance.setMaximumPoolSize(size);
|
|
+ instance.setCorePoolSize(size);
|
|
+ } else if(size < instance.getMaximumPoolSize()) {
|
|
+ instance.setCorePoolSize(size);
|
|
+ instance.setMaximumPoolSize(size);
|
|
+ }
|
|
+ instance.queueLimit = size * 8;
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/frozenorb/pathsearch/PositionPathSearchType.java b/src/main/java/net/frozenorb/pathsearch/PositionPathSearchType.java
|
|
new file mode 100644
|
|
index 000000000..d7c9a1e9b
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/frozenorb/pathsearch/PositionPathSearchType.java
|
|
@@ -0,0 +1,16 @@
|
|
+package net.frozenorb.pathsearch;
|
|
+
|
|
+public enum PositionPathSearchType {
|
|
+ ANYOTHER,
|
|
+ AVOIDPLAYER,
|
|
+ FLEESUN,
|
|
+ JUMPONBLOCK,
|
|
+ MOVEINDOORS,
|
|
+ MOVETHROUGHVILLAGE,
|
|
+ MOVETOWARDSRESTRICTION,
|
|
+ MOVETOWARDSTARGET,
|
|
+ PANIC,
|
|
+ PLAY,
|
|
+ RANDOMSTROLL,
|
|
+ TAME;
|
|
+}
|
|
diff --git a/src/main/java/net/frozenorb/pathsearch/cache/SearchCacheEntry.java b/src/main/java/net/frozenorb/pathsearch/cache/SearchCacheEntry.java
|
|
new file mode 100644
|
|
index 000000000..7d5e62a02
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/frozenorb/pathsearch/cache/SearchCacheEntry.java
|
|
@@ -0,0 +1,81 @@
|
|
+package net.frozenorb.pathsearch.cache;
|
|
+
|
|
+import net.minecraft.server.Entity;
|
|
+import net.minecraft.server.EntityInsentient;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
+import net.minecraft.server.PathEntity;
|
|
+import net.minecraft.server.PathPoint;
|
|
+
|
|
+import org.bukkit.util.BlockVector;
|
|
+
|
|
+public class SearchCacheEntry {
|
|
+ protected long tick;
|
|
+ protected BlockVector positionStart;
|
|
+ protected BlockVector positionTarget;
|
|
+ protected EntityInsentient entity;
|
|
+ private PathEntity path;
|
|
+
|
|
+ public SearchCacheEntry(EntityInsentient entity, PathEntity path) {
|
|
+ this.entity = entity;
|
|
+ this.positionStart = this.getEntityPosition(this.entity);
|
|
+ this.path = path;
|
|
+ this.tick = this.getCurrentTick();
|
|
+ }
|
|
+
|
|
+ protected int getCurrentTick() {
|
|
+ return MinecraftServer.getServer().al();
|
|
+ }
|
|
+
|
|
+ protected BlockVector getEntityPosition(Entity entity) {
|
|
+ return new BlockVector(entity.locX, entity.locY, entity.locZ);
|
|
+ }
|
|
+
|
|
+ protected BlockVector getTargetPosition(int x, int y, int z) {
|
|
+ return new BlockVector(x, y, z);
|
|
+ }
|
|
+
|
|
+ public boolean isStillValid() {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ public PathEntity getPathEntity() {
|
|
+ return this.path;
|
|
+ }
|
|
+
|
|
+ public boolean hasExpired() {
|
|
+ return !this.entity.isAlive() || (this.getCurrentTick() - this.tick) > 200;
|
|
+ }
|
|
+
|
|
+ public boolean didSearchSucceed() {
|
|
+ return this.path != null;
|
|
+ }
|
|
+
|
|
+ public boolean shouldBeRefreshed() {
|
|
+ return (this.getCurrentTick() - this.tick) > 5;
|
|
+ }
|
|
+
|
|
+ public PathEntity getAdjustedPathEntity() {
|
|
+ if(this.path != null && (this.path.e() < this.path.d() - 1)) {
|
|
+ PathPoint pathpoint = this.path.a(this.path.e());
|
|
+ double currentDist = this.entity.e(pathpoint.a, pathpoint.b, pathpoint.c);
|
|
+ while(this.path.e() < this.path.d() - 1) {
|
|
+ pathpoint = this.path.a(this.path.e() + 1);
|
|
+ double nextDist = this.entity.e(pathpoint.a, pathpoint.b, pathpoint.c);
|
|
+ if(nextDist < currentDist) {
|
|
+ currentDist = nextDist;
|
|
+ this.path.a();
|
|
+ } else {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return this.path;
|
|
+ }
|
|
+
|
|
+ public void cleanup() {
|
|
+ this.positionStart = null;
|
|
+ this.positionTarget = null;
|
|
+ this.entity = null;
|
|
+ this.path = null;
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/frozenorb/pathsearch/cache/SearchCacheEntryEntity.java b/src/main/java/net/frozenorb/pathsearch/cache/SearchCacheEntryEntity.java
|
|
new file mode 100644
|
|
index 000000000..d0f98af71
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/frozenorb/pathsearch/cache/SearchCacheEntryEntity.java
|
|
@@ -0,0 +1,37 @@
|
|
+package net.frozenorb.pathsearch.cache;
|
|
+
|
|
+import org.bukkit.util.BlockVector;
|
|
+
|
|
+import net.minecraft.server.Entity;
|
|
+import net.minecraft.server.EntityInsentient;
|
|
+import net.minecraft.server.PathEntity;
|
|
+
|
|
+public class SearchCacheEntryEntity extends SearchCacheEntry {
|
|
+
|
|
+ private Entity target;
|
|
+
|
|
+ public SearchCacheEntryEntity(EntityInsentient entity, Entity target, PathEntity path) {
|
|
+ super(entity, path);
|
|
+ this.target = target;
|
|
+ this.positionTarget = this.getEntityPosition(this.target);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isStillValid() {
|
|
+ if(this.getCurrentTick() - this.tick > 20) {
|
|
+ return false;
|
|
+ }
|
|
+ BlockVector bvStart = this.getEntityPosition(this.entity);
|
|
+ BlockVector bvTarget = this.getEntityPosition(this.target);
|
|
+ if(!bvStart.equals(this.positionStart) || !bvTarget.equals(this.positionTarget)) {
|
|
+ return false;
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void cleanup() {
|
|
+ super.cleanup();
|
|
+ this.target = null;
|
|
+ }
|
|
+}
|
|
\ No newline at end of file
|
|
diff --git a/src/main/java/net/frozenorb/pathsearch/cache/SearchCacheEntryPosition.java b/src/main/java/net/frozenorb/pathsearch/cache/SearchCacheEntryPosition.java
|
|
new file mode 100644
|
|
index 000000000..c3c314956
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/frozenorb/pathsearch/cache/SearchCacheEntryPosition.java
|
|
@@ -0,0 +1,31 @@
|
|
+package net.frozenorb.pathsearch.cache;
|
|
+
|
|
+import net.minecraft.server.Entity;
|
|
+import net.minecraft.server.EntityInsentient;
|
|
+import net.minecraft.server.PathEntity;
|
|
+
|
|
+import org.bukkit.util.BlockVector;
|
|
+
|
|
+public class SearchCacheEntryPosition extends SearchCacheEntry {
|
|
+
|
|
+ public SearchCacheEntryPosition(EntityInsentient entity, int x, int y, int z, PathEntity path) {
|
|
+ super(entity, path);
|
|
+ this.positionTarget = this.getTargetPosition(x, y, z);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isStillValid() {
|
|
+ if(this.getCurrentTick() - this.tick > 20) {
|
|
+ return false;
|
|
+ }
|
|
+ BlockVector bvStart = this.getEntityPosition(this.entity);
|
|
+ if(!bvStart.equals(this.positionStart)) {
|
|
+ return false;
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ public boolean targetEquals(BlockVector bv) {
|
|
+ return this.positionTarget.equals(bv);
|
|
+ }
|
|
+}
|
|
\ No newline at end of file
|
|
diff --git a/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchJob.java b/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchJob.java
|
|
new file mode 100644
|
|
index 000000000..bc33d1555
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchJob.java
|
|
@@ -0,0 +1,75 @@
|
|
+package net.frozenorb.pathsearch.jobs;
|
|
+
|
|
+import java.util.UUID;
|
|
+import java.util.concurrent.Callable;
|
|
+
|
|
+import net.frozenorb.WeakChunkCache;
|
|
+import net.frozenorb.pathsearch.cache.SearchCacheEntry;
|
|
+import net.minecraft.server.ChunkCache;
|
|
+import net.minecraft.server.EntityCreature;
|
|
+import net.minecraft.server.EntityInsentient;
|
|
+import net.minecraft.server.MathHelper;
|
|
+import net.minecraft.server.PathEntity;
|
|
+import net.minecraft.server.World;
|
|
+
|
|
+public abstract class PathSearchJob implements Callable<PathSearchJob> {
|
|
+
|
|
+ protected EntityInsentient entity;
|
|
+ protected WeakChunkCache chunkCache;
|
|
+ protected boolean issued;
|
|
+ protected float range;
|
|
+ protected boolean b1, b2, b3, b4;
|
|
+ protected PathEntity pathEntity;
|
|
+ protected int hash;
|
|
+
|
|
+ public PathSearchJob(EntityInsentient entity, float range, boolean b1, boolean b2, boolean b3, boolean b4) {
|
|
+ this.entity = entity;
|
|
+ this.range = range;
|
|
+ this.b1 = b1;
|
|
+ this.b2 = b2;
|
|
+ this.b3 = b3;
|
|
+ this.b4 = b4;
|
|
+ this.issued = false;
|
|
+ this.hash = entity.getUniqueID().hashCode();
|
|
+ this.createChunkCache();
|
|
+ }
|
|
+
|
|
+ private void createChunkCache() {
|
|
+ int x = MathHelper.floor(this.entity.locX);
|
|
+ int y = MathHelper.floor(this.entity.locY);
|
|
+ int z = MathHelper.floor(this.entity.locZ);
|
|
+ int radius = (int) (this.range + 8.0F);
|
|
+ int xMinor = x - radius;
|
|
+ int yMinor = y - radius;
|
|
+ int zMinor = z - radius;
|
|
+ int xMajor = x + radius;
|
|
+ int yMajor = y + radius;
|
|
+ int zMajor = z + radius;
|
|
+ this.chunkCache = new WeakChunkCache(this.entity.world, xMinor, yMinor, zMinor, xMajor, yMajor, zMajor, 0);
|
|
+ }
|
|
+
|
|
+ public void cleanup() {
|
|
+ this.entity = null;
|
|
+ this.chunkCache = null;
|
|
+ this.pathEntity = null;
|
|
+ }
|
|
+
|
|
+ public int getSearchHash() {
|
|
+ return this.hash;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int hashCode() {
|
|
+ return this.hash;
|
|
+ }
|
|
+
|
|
+ public abstract Object getCacheEntryKey();
|
|
+
|
|
+ public abstract SearchCacheEntry getCacheEntryValue();
|
|
+
|
|
+ public abstract void cancel();
|
|
+
|
|
+ protected boolean isEntityStillValid() {
|
|
+ return this.entity != null && this.entity.valid && this.entity.isAlive();
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchJobEntity.java b/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchJobEntity.java
|
|
new file mode 100644
|
|
index 000000000..e834c0d89
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchJobEntity.java
|
|
@@ -0,0 +1,62 @@
|
|
+package net.frozenorb.pathsearch.jobs;
|
|
+
|
|
+import java.util.UUID;
|
|
+
|
|
+import net.frozenorb.pathsearch.AsyncPathfinder;
|
|
+import net.frozenorb.pathsearch.cache.SearchCacheEntry;
|
|
+import net.frozenorb.pathsearch.cache.SearchCacheEntryEntity;
|
|
+import net.minecraft.server.Entity;
|
|
+import net.minecraft.server.EntityCreature;
|
|
+import net.minecraft.server.PathEntity;
|
|
+
|
|
+public class PathSearchJobEntity extends PathSearchJob {
|
|
+
|
|
+ private Entity target;
|
|
+
|
|
+ public PathSearchJobEntity(EntityCreature entity, Entity target, float range, boolean b1, boolean b2, boolean b3, boolean b4) {
|
|
+ super(entity, range, b1, b2, b3, b4);
|
|
+ this.target = target;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public PathSearchJob call() throws Exception {
|
|
+ if(!this.isEntityStillValid()) {
|
|
+ this.cancel();
|
|
+ } else if(!this.issued) {
|
|
+ this.issued = true;
|
|
+ this.pathEntity = (new AsyncPathfinder(this.chunkCache, this.b1, this.b2, this.b3, this.b4)).a(entity, this.target, this.range);
|
|
+ ((EntityCreature) this.entity).setSearchResult(this, this.target, this.pathEntity);
|
|
+ this.cleanup();
|
|
+ }
|
|
+ return this;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void cleanup() {
|
|
+ super.cleanup();
|
|
+ this.target = null;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Object getCacheEntryKey() {
|
|
+ return this.entity.getUniqueID();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public SearchCacheEntry getCacheEntryValue() {
|
|
+ return new SearchCacheEntryEntity(this.entity, this.target, this.pathEntity);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void cancel() {
|
|
+ ((EntityCreature) this.entity).cancelSearch(this);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean equals(Object o) {
|
|
+ if(o == null || !(o instanceof PathSearchJobEntity)) {
|
|
+ return false;
|
|
+ }
|
|
+ return this.getSearchHash() == ((PathSearchJobEntity)o).getSearchHash();
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchJobNavigationEntity.java b/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchJobNavigationEntity.java
|
|
new file mode 100644
|
|
index 000000000..7b6b7ea25
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchJobNavigationEntity.java
|
|
@@ -0,0 +1,63 @@
|
|
+package net.frozenorb.pathsearch.jobs;
|
|
+
|
|
+import java.util.UUID;
|
|
+
|
|
+import net.frozenorb.pathsearch.AsyncPathfinder;
|
|
+import net.frozenorb.pathsearch.cache.SearchCacheEntry;
|
|
+import net.frozenorb.pathsearch.cache.SearchCacheEntryEntity;
|
|
+
|
|
+import net.minecraft.server.ChunkCache;
|
|
+import net.minecraft.server.Entity;
|
|
+import net.minecraft.server.EntityCreature;
|
|
+import net.minecraft.server.EntityInsentient;
|
|
+import net.minecraft.server.PathEntity;
|
|
+
|
|
+public class PathSearchJobNavigationEntity extends PathSearchJob {
|
|
+
|
|
+ private Entity target;
|
|
+
|
|
+ public PathSearchJobNavigationEntity(EntityInsentient entity, Entity target, float range, boolean b1, boolean b2, boolean b3, boolean b4) {
|
|
+ super(entity, range, b1, b2, b3, b4);
|
|
+ this.target = target;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public PathSearchJob call() throws Exception {
|
|
+ if(!this.isEntityStillValid()) {
|
|
+ this.cancel();
|
|
+ } else if(!this.issued) {
|
|
+ this.issued = true;
|
|
+ this.pathEntity = (new AsyncPathfinder(this.chunkCache, this.b1, this.b2, this.b3, this.b4)).a(entity, this.target, this.range);
|
|
+ this.entity.getNavigation().setSearchResult(this);
|
|
+ this.cleanup();
|
|
+ }
|
|
+ return this;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void cleanup() {
|
|
+ super.cleanup();
|
|
+ this.target = null;
|
|
+ }
|
|
+
|
|
+ public UUID getCacheEntryKey() {
|
|
+ return this.target.getUniqueID();
|
|
+ }
|
|
+
|
|
+ public SearchCacheEntry getCacheEntryValue() {
|
|
+ return new SearchCacheEntryEntity(this.entity, this.target, this.pathEntity);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void cancel() {
|
|
+ this.entity.getNavigation().cancelSearch(this);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean equals(Object o) {
|
|
+ if(o == null || !(o instanceof PathSearchJobNavigationEntity)) {
|
|
+ return false;
|
|
+ }
|
|
+ return this.getSearchHash() == ((PathSearchJobNavigationEntity)o).getSearchHash();
|
|
+ }
|
|
+}
|
|
\ No newline at end of file
|
|
diff --git a/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchJobNavigationPosition.java b/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchJobNavigationPosition.java
|
|
new file mode 100644
|
|
index 000000000..7d37724a7
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchJobNavigationPosition.java
|
|
@@ -0,0 +1,68 @@
|
|
+package net.frozenorb.pathsearch.jobs;
|
|
+
|
|
+import net.frozenorb.pathsearch.AsyncPathfinder;
|
|
+import net.frozenorb.pathsearch.PositionPathSearchType;
|
|
+import net.frozenorb.pathsearch.cache.SearchCacheEntryPosition;
|
|
+import net.minecraft.server.ChunkCache;
|
|
+import net.minecraft.server.EntityCreature;
|
|
+import net.minecraft.server.EntityInsentient;
|
|
+import net.minecraft.server.PathEntity;
|
|
+
|
|
+public class PathSearchJobNavigationPosition extends PathSearchJob {
|
|
+
|
|
+ private int x, y, z;
|
|
+ private PositionPathSearchType type;
|
|
+
|
|
+ public PathSearchJobNavigationPosition(PositionPathSearchType type, EntityInsentient entity, int x, int y, int z, float range, boolean b1, boolean b2, boolean b3, boolean b4) {
|
|
+ super(entity, range, b1, b2, b3, b4);
|
|
+ this.type = type;
|
|
+ this.x = x;
|
|
+ this.y = y;
|
|
+ this.z = z;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public PathSearchJob call() throws Exception {
|
|
+ if(!this.isEntityStillValid()) {
|
|
+ this.cancel();
|
|
+ } else if(!this.issued) {
|
|
+ this.issued = true;
|
|
+ this.pathEntity = (new AsyncPathfinder(this.chunkCache, this.b1, this.b2, this.b3, this.b4)).a(entity, this.x, this.y, this.z, this.range);
|
|
+ this.entity.getNavigation().setSearchResult(this);
|
|
+ this.cleanup();
|
|
+ }
|
|
+ return this;
|
|
+ }
|
|
+
|
|
+ public PositionPathSearchType getCacheEntryKey() {
|
|
+ return this.type;
|
|
+ }
|
|
+
|
|
+ public SearchCacheEntryPosition getCacheEntryValue() {
|
|
+ return new SearchCacheEntryPosition(this.entity, this.x, this.y, this.z, this.pathEntity);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int hashCode() {
|
|
+ return this.type.hashCode() ^
|
|
+ (this.getSearchHash() << 4);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean equals(Object o) {
|
|
+ if(o == null || !(o instanceof PathSearchJobNavigationPosition)) {
|
|
+ return false;
|
|
+ }
|
|
+ PathSearchJobNavigationPosition other = (PathSearchJobNavigationPosition) o;
|
|
+
|
|
+ return this.type.equals(
|
|
+ other.type) &&
|
|
+ this.getSearchHash() ==
|
|
+ other.getSearchHash();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void cancel() {
|
|
+ this.entity.getNavigation().cancelSearch(this);
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchJobPosition.java b/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchJobPosition.java
|
|
new file mode 100644
|
|
index 000000000..f7106eaa3
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchJobPosition.java
|
|
@@ -0,0 +1,68 @@
|
|
+package net.frozenorb.pathsearch.jobs;
|
|
+
|
|
+import net.frozenorb.pathsearch.AsyncPathfinder;
|
|
+import net.frozenorb.pathsearch.PositionPathSearchType;
|
|
+import net.frozenorb.pathsearch.cache.SearchCacheEntry;
|
|
+import net.frozenorb.pathsearch.cache.SearchCacheEntryPosition;
|
|
+import net.minecraft.server.EntityCreature;
|
|
+import net.minecraft.server.PathEntity;
|
|
+import net.minecraft.server.Pathfinder;
|
|
+
|
|
+public class PathSearchJobPosition extends PathSearchJob {
|
|
+
|
|
+ private int x, y, z;
|
|
+ private PositionPathSearchType type;
|
|
+
|
|
+ public PathSearchJobPosition(EntityCreature entity, int x, int y, int z, float range, boolean b1, boolean b2, boolean b3, boolean b4) {
|
|
+ super(entity, range, b1, b2, b3, b4);
|
|
+ this.type = PositionPathSearchType.ANYOTHER;
|
|
+ this.x = x;
|
|
+ this.y = y;
|
|
+ this.z = z;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public PathSearchJob call() throws Exception {
|
|
+ if(!this.isEntityStillValid()) {
|
|
+ this.cancel();
|
|
+ } else if(!this.issued) {
|
|
+ this.issued = true;
|
|
+ this.pathEntity = (new AsyncPathfinder(this.chunkCache, this.b1, this.b2, this.b3, this.b4)).a(entity, this.x, this.y, this.z, this.range);
|
|
+ ((EntityCreature)this.entity).setSearchResult(this, this.pathEntity);
|
|
+ this.cleanup();
|
|
+ }
|
|
+ return this;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public Object getCacheEntryKey() {
|
|
+ return this.type;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public SearchCacheEntry getCacheEntryValue() {
|
|
+ return new SearchCacheEntryPosition(this.entity, this.x, this.y, this.z, this.pathEntity);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int hashCode() {
|
|
+ return this.type.hashCode() ^ (this.getSearchHash() << 4);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean equals(Object o) {
|
|
+ if(o == null || !(o instanceof PathSearchJobPosition)) {
|
|
+ return false;
|
|
+ }
|
|
+ PathSearchJobPosition other = (PathSearchJobPosition) o;
|
|
+
|
|
+ return this.type.equals(
|
|
+ other.type) &&
|
|
+ this.getSearchHash() == other.getSearchHash();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void cancel() {
|
|
+ ((EntityCreature) this.entity).cancelSearch(this);
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchQueuingManager.java b/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchQueuingManager.java
|
|
new file mode 100644
|
|
index 000000000..cd6828655
|
|
--- /dev/null
|
|
+++ b/src/main/java/net/frozenorb/pathsearch/jobs/PathSearchQueuingManager.java
|
|
@@ -0,0 +1,28 @@
|
|
+package net.frozenorb.pathsearch.jobs;
|
|
+
|
|
+import net.frozenorb.ThreadingManager;
|
|
+
|
|
+public class PathSearchQueuingManager {
|
|
+
|
|
+ private PathSearchJob lastQueuedJob;
|
|
+
|
|
+ public PathSearchQueuingManager() {
|
|
+ this.lastQueuedJob = null;
|
|
+ }
|
|
+
|
|
+ public synchronized boolean hasAsyncSearchIssued() {
|
|
+ return this.lastQueuedJob != null;
|
|
+ }
|
|
+
|
|
+ public synchronized void queueSearch(PathSearchJob job) {
|
|
+ if(ThreadingManager.queuePathSearch(job)) {
|
|
+ this.lastQueuedJob = job;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public synchronized void checkLastSearchResult(PathSearchJob pathSearch) {
|
|
+ if(this.lastQueuedJob == pathSearch) {
|
|
+ this.lastQueuedJob = null;
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
|
index 204e4f8c4..c31c59294 100644
|
|
--- a/src/main/java/net/minecraft/server/Entity.java
|
|
+++ b/src/main/java/net/minecraft/server/Entity.java
|
|
@@ -920,9 +920,15 @@ public abstract class Entity {
|
|
}
|
|
|
|
public boolean P() {
|
|
- return this.world.a(this.boundingBox.grow(-0.10000000149011612D, -0.4000000059604645D, -0.10000000149011612D), Material.LAVA);
|
|
+ // Poweruser start
|
|
+ return this.P(this.world);
|
|
}
|
|
|
|
+ public boolean P(IBlockAccess iblockaccess) {
|
|
+ return this.world.a(this.boundingBox.grow(-0.10000000149011612D, -0.4000000059604645D, -0.10000000149011612D), Material.LAVA, iblockaccess);
|
|
+ }
|
|
+ // Poweruser end
|
|
+
|
|
public void a(float f, float f1, float f2) {
|
|
float f3 = f * f + f1 * f1;
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/EntityCreature.java b/src/main/java/net/minecraft/server/EntityCreature.java
|
|
index 6960b0580..3810671e6 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityCreature.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityCreature.java
|
|
@@ -8,6 +8,13 @@ import org.bukkit.event.entity.EntityTargetEvent;
|
|
import org.bukkit.event.entity.EntityUnleashEvent;
|
|
// CraftBukkit end
|
|
|
|
+// Poweruser start
|
|
+import net.frozenorb.pathsearch.jobs.PathSearchJob;
|
|
+import net.frozenorb.pathsearch.jobs.PathSearchJobEntity;
|
|
+import net.frozenorb.pathsearch.jobs.PathSearchJobPosition;
|
|
+import net.frozenorb.pathsearch.jobs.PathSearchQueuingManager;
|
|
+// Poweruser end
|
|
+
|
|
public abstract class EntityCreature extends EntityInsentient {
|
|
|
|
public static final UUID h = UUID.fromString("E199AD21-BA8A-4C53-8D13-6182D5C69D3A");
|
|
@@ -21,6 +28,41 @@ public abstract class EntityCreature extends EntityInsentient {
|
|
private PathfinderGoal bs = new PathfinderGoalMoveTowardsRestriction(this, 1.0D);
|
|
private boolean bt;
|
|
|
|
+ // Poweruser start
|
|
+ private PathSearchQueuingManager queuingManager = new PathSearchQueuingManager();
|
|
+ private boolean searchIssued = false;
|
|
+ private PathEntity returnedPathEntity;
|
|
+
|
|
+ public boolean isSearchingForAPath() {
|
|
+ return this.queuingManager.hasAsyncSearchIssued();
|
|
+ }
|
|
+
|
|
+ public void cancelSearch(PathSearchJob pathSearch) {
|
|
+ this.queuingManager.checkLastSearchResult(pathSearch);
|
|
+ pathSearch.cleanup();
|
|
+ }
|
|
+
|
|
+ private void issueSearch(int x, int y, int z, float range) {
|
|
+ this.queuingManager.queueSearch(new PathSearchJobPosition(this, x, y, z, range, true, false, false, true));
|
|
+ }
|
|
+
|
|
+ private void issueSearch(Entity target, float range) {
|
|
+ this.queuingManager.queueSearch(new PathSearchJobEntity(this, target, range, true, false, false, true));
|
|
+ }
|
|
+
|
|
+ public void setSearchResult(PathSearchJobEntity pathSearchJobEntity, Entity target, PathEntity pathentity) {
|
|
+ this.queuingManager.checkLastSearchResult(pathSearchJobEntity);
|
|
+ if(this.target != null && this.target.equals(target)) {
|
|
+ this.returnedPathEntity = pathentity;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void setSearchResult(PathSearchJobPosition pathSearchJobPosition, PathEntity pathentity) {
|
|
+ this.queuingManager.checkLastSearchResult(pathSearchJobPosition);
|
|
+ this.returnedPathEntity = pathentity;
|
|
+ }
|
|
+ // Poweruser end
|
|
+
|
|
public EntityCreature(World world) {
|
|
super(world);
|
|
}
|
|
@@ -58,7 +100,8 @@ public abstract class EntityCreature extends EntityInsentient {
|
|
// CraftBukkit end
|
|
|
|
if (this.target != null) {
|
|
- this.pathEntity = this.world.findPath(this, this.target, f11, true, false, false, true);
|
|
+ //this.pathEntity = this.world.findPath(this, this.target, f11, true, false, false, true);
|
|
+ this.issueSearch(this.target, f11); // Poweruser
|
|
}
|
|
} else if (this.target.isAlive()) {
|
|
float f1 = this.target.e((Entity) this);
|
|
@@ -86,8 +129,17 @@ public abstract class EntityCreature extends EntityInsentient {
|
|
}
|
|
|
|
this.world.methodProfiler.b();
|
|
+
|
|
+ // Poweruser start
|
|
+ if(this.returnedPathEntity != null) {
|
|
+ this.pathEntity = this.returnedPathEntity;
|
|
+ this.returnedPathEntity = null;
|
|
+ }
|
|
+ // Poweruser end
|
|
+
|
|
if (!this.bn && this.target != null && (this.pathEntity == null || this.random.nextInt(20) == 0)) {
|
|
- this.pathEntity = this.world.findPath(this, this.target, f11, true, false, false, true);
|
|
+ //this.pathEntity = this.world.findPath(this, this.target, f11, true, false, false, true);
|
|
+ this.issueSearch(this.target, f11); // Poweruser
|
|
} else if (!this.bn && (this.pathEntity == null && this.random.nextInt(180) == 0 || this.random.nextInt(120) == 0 || this.bo > 0) && this.aU < 100) {
|
|
this.bQ();
|
|
}
|
|
@@ -190,7 +242,8 @@ public abstract class EntityCreature extends EntityInsentient {
|
|
}
|
|
|
|
if (flag) {
|
|
- this.pathEntity = this.world.a(this, i, j, k, 10.0F, true, false, false, true);
|
|
+ //this.pathEntity = this.world.a(this, i, j, k, 10.0F, true, false, false, true);
|
|
+ this.issueSearch(i, j, k, 10.0F); // Poweruser
|
|
}
|
|
|
|
this.world.methodProfiler.b();
|
|
diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java
|
|
index ccc86bbeb..2cb337986 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityInsentient.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityInsentient.java
|
|
@@ -11,6 +11,10 @@ import org.bukkit.event.entity.EntityUnleashEvent;
|
|
import org.bukkit.event.entity.EntityUnleashEvent.UnleashReason;
|
|
// CraftBukkit end
|
|
|
|
+// Poweruser start
|
|
+import net.frozenorb.pathsearch.AsyncNavigation;
|
|
+// Poweruser end
|
|
+
|
|
public abstract class EntityInsentient extends EntityLiving {
|
|
|
|
public int a_;
|
|
@@ -43,7 +47,7 @@ public abstract class EntityInsentient extends EntityLiving {
|
|
this.moveController = new ControllerMove(this);
|
|
this.bm = new ControllerJump(this);
|
|
this.bn = new EntityAIBodyControl(this);
|
|
- this.navigation = new Navigation(this, world);
|
|
+ this.navigation = new AsyncNavigation(this, world); // Poweruser
|
|
this.bq = new EntitySenses(this);
|
|
|
|
for (int i = 0; i < this.dropChances.length; ++i) {
|
|
@@ -417,6 +421,7 @@ public abstract class EntityInsentient extends EntityLiving {
|
|
|
|
protected void bn() {
|
|
++this.aU;
|
|
+ this.navigation.cleanUpExpiredSearches(); // Poweruser
|
|
this.world.methodProfiler.a("checkDespawn");
|
|
this.w();
|
|
this.world.methodProfiler.b();
|
|
diff --git a/src/main/java/net/minecraft/server/EntitySilverfish.java b/src/main/java/net/minecraft/server/EntitySilverfish.java
|
|
index ac5714f02..0881e251e 100644
|
|
--- a/src/main/java/net/minecraft/server/EntitySilverfish.java
|
|
+++ b/src/main/java/net/minecraft/server/EntitySilverfish.java
|
|
@@ -120,7 +120,7 @@ public class EntitySilverfish extends EntityMonster {
|
|
}
|
|
}
|
|
|
|
- if (this.target == null && !this.bS()) {
|
|
+ if (this.target == null && !this.bS() && !this.isSearchingForAPath()) { // Poweruser
|
|
i = MathHelper.floor(this.locX);
|
|
j = MathHelper.floor(this.locY + 0.5D);
|
|
k = MathHelper.floor(this.locZ);
|
|
@@ -141,7 +141,7 @@ public class EntitySilverfish extends EntityMonster {
|
|
} else {
|
|
this.bQ();
|
|
}
|
|
- } else if (this.target != null && !this.bS()) {
|
|
+ } else if (this.target != null && !this.bS() && !this.isSearchingForAPath()) { // Poweruser
|
|
this.target = null;
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/EntityWolf.java b/src/main/java/net/minecraft/server/EntityWolf.java
|
|
index 8f1ebf2eb..aed649652 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityWolf.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityWolf.java
|
|
@@ -110,7 +110,7 @@ public class EntityWolf extends EntityTameableAnimal {
|
|
|
|
public void e() {
|
|
super.e();
|
|
- if (!this.world.isStatic && this.bs && !this.bt && !this.bS() && this.onGround) {
|
|
+ if (!this.world.isStatic && this.bs && !this.bt && !this.bS() && this.onGround && !this.isSearchingForAPath()) { // Poweruser
|
|
this.bt = true;
|
|
this.bu = 0.0F;
|
|
this.bv = 0.0F;
|
|
diff --git a/src/main/java/net/minecraft/server/Navigation.java b/src/main/java/net/minecraft/server/Navigation.java
|
|
index 7002621b1..e5cd99c26 100644
|
|
--- a/src/main/java/net/minecraft/server/Navigation.java
|
|
+++ b/src/main/java/net/minecraft/server/Navigation.java
|
|
@@ -1,9 +1,16 @@
|
|
package net.minecraft.server;
|
|
|
|
+// Poweruser start
|
|
+import net.frozenorb.pathsearch.PositionPathSearchType;
|
|
+import net.frozenorb.pathsearch.jobs.PathSearchJob;
|
|
+import net.frozenorb.pathsearch.jobs.PathSearchJobNavigationEntity;
|
|
+import net.frozenorb.pathsearch.jobs.PathSearchJobNavigationPosition;
|
|
+//Poweruser end
|
|
+
|
|
public class Navigation {
|
|
|
|
- private EntityInsentient a;
|
|
- private World b;
|
|
+ protected EntityInsentient a; // Poweruser - private -> protected
|
|
+ protected World b; // Poweruser - private -> protected
|
|
private PathEntity c;
|
|
private double d;
|
|
private AttributeInstance e;
|
|
@@ -11,10 +18,28 @@ public class Navigation {
|
|
private int g;
|
|
private int h;
|
|
private Vec3D i = Vec3D.a(0.0D, 0.0D, 0.0D);
|
|
- private boolean j = true;
|
|
- private boolean k;
|
|
- private boolean l;
|
|
- private boolean m;
|
|
+ protected boolean j = true; // Poweruser - private -> protected
|
|
+ protected boolean k; // Poweruser - private -> protected
|
|
+ protected boolean l; // Poweruser - private -> protected
|
|
+ protected boolean m; // Poweruser - private -> protected
|
|
+
|
|
+ // Poweruser start
|
|
+ public void setSearchResult(PathSearchJobNavigationEntity pathSearch) { }
|
|
+
|
|
+ public void setSearchResult(PathSearchJobNavigationPosition pathSearch) { }
|
|
+
|
|
+ public PathEntity a(PositionPathSearchType type, double d0, double d1, double d2) {
|
|
+ return this.a(d0, d1, d2);
|
|
+ }
|
|
+
|
|
+ public boolean a(PositionPathSearchType type, double d0, double d1, double d2, double d3) {
|
|
+ return this.a(d0, d1, d2, d3);
|
|
+ }
|
|
+
|
|
+ public void cleanUpExpiredSearches() { }
|
|
+
|
|
+ public void cancelSearch(PathSearchJob pathSearch) { }
|
|
+ // Poweruser end
|
|
|
|
public Navigation(EntityInsentient entityinsentient, World world) {
|
|
this.a = entityinsentient;
|
|
@@ -205,7 +230,7 @@ public class Navigation {
|
|
}
|
|
}
|
|
|
|
- private boolean l() {
|
|
+ protected boolean l() { // Poweruser - private -> protected
|
|
return this.a.onGround || this.m && this.m() || this.a.am() && this.a instanceof EntityZombie && this.a.vehicle instanceof EntityChicken;
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/Pathfinder.java b/src/main/java/net/minecraft/server/Pathfinder.java
|
|
index de9593976..2181fdad3 100644
|
|
--- a/src/main/java/net/minecraft/server/Pathfinder.java
|
|
+++ b/src/main/java/net/minecraft/server/Pathfinder.java
|
|
@@ -200,12 +200,22 @@ public class Pathfinder {
|
|
}
|
|
|
|
public static int a(Entity entity, int i, int j, int k, PathPoint pathpoint, boolean flag, boolean flag1, boolean flag2) {
|
|
+ // Poweruser start
|
|
+ return a(entity.world, entity, i, j, k, pathpoint, flag, flag1, flag2);
|
|
+ }
|
|
+
|
|
+ public int a(IBlockAccess blockaccess, Entity entity, int i, int j, int k, PathPoint pathpoint) {
|
|
+ return a(blockaccess, entity, i, j, k, pathpoint, this.g, this.f, this.e);
|
|
+ }
|
|
+
|
|
+ public static int a(IBlockAccess blockaccess, Entity entity, int i, int j, int k, PathPoint pathpoint, boolean flag, boolean flag1, boolean flag2) {
|
|
+ // Poweruser end
|
|
boolean flag3 = false;
|
|
|
|
for (int l = i; l < i + pathpoint.a; ++l) {
|
|
for (int i1 = j; i1 < j + pathpoint.b; ++i1) {
|
|
for (int j1 = k; j1 < k + pathpoint.c; ++j1) {
|
|
- Block block = entity.world.getType(l, i1, j1);
|
|
+ Block block = blockaccess.getType(l, i1, j1); // Poweruser - entity.world -> blockaccess
|
|
|
|
if (block.getMaterial() != Material.AIR) {
|
|
if (block == Blocks.TRAP_DOOR) {
|
|
@@ -224,12 +234,12 @@ public class Pathfinder {
|
|
|
|
int k1 = block.b();
|
|
|
|
- if (entity.world.getType(l, i1, j1).b() == 9) {
|
|
+ if (k1 == 9) { // Poweruser
|
|
int l1 = MathHelper.floor(entity.locX);
|
|
int i2 = MathHelper.floor(entity.locY);
|
|
int j2 = MathHelper.floor(entity.locZ);
|
|
|
|
- if (entity.world.getType(l1, i2, j2).b() != 9 && entity.world.getType(l1, i2 - 1, j2).b() != 9) {
|
|
+ if (blockaccess.getType(l1, i2, j2).b() != 9 && blockaccess.getType(l1, i2 - 1, j2).b() != 9) { // Poweruser - entity.world -> blockaccess
|
|
return -3;
|
|
}
|
|
} else if (!block.b(entity.world, l, i1, j1) && (!flag1 || block != Blocks.WOODEN_DOOR)) {
|
|
@@ -247,7 +257,7 @@ public class Pathfinder {
|
|
return 0;
|
|
}
|
|
|
|
- if (!entity.P()) {
|
|
+ if (!entity.P(blockaccess)) { // Poweruser
|
|
return -2;
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalAvoidPlayer.java b/src/main/java/net/minecraft/server/PathfinderGoalAvoidPlayer.java
|
|
index e964925af..b27b2113c 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalAvoidPlayer.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalAvoidPlayer.java
|
|
@@ -51,7 +51,7 @@ public class PathfinderGoalAvoidPlayer extends PathfinderGoal {
|
|
} else if (this.e.e(vec3d.a, vec3d.b, vec3d.c) < this.e.f((Entity) this.b)) {
|
|
return false;
|
|
} else {
|
|
- this.g = this.h.a(vec3d.a, vec3d.b, vec3d.c);
|
|
+ this.g = this.h.a(net.frozenorb.pathsearch.PositionPathSearchType.AVOIDPLAYER, vec3d.a, vec3d.b, vec3d.c); // Poweruser
|
|
return this.g == null ? false : this.g.b(vec3d);
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalFleeSun.java b/src/main/java/net/minecraft/server/PathfinderGoalFleeSun.java
|
|
index 846214a4d..36de3b98e 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalFleeSun.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalFleeSun.java
|
|
@@ -44,7 +44,7 @@ public class PathfinderGoalFleeSun extends PathfinderGoal {
|
|
}
|
|
|
|
public void c() {
|
|
- this.a.getNavigation().a(this.b, this.c, this.d, this.e);
|
|
+ this.a.getNavigation().a(net.frozenorb.pathsearch.PositionPathSearchType.FLEESUN, this.b, this.c, this.d, this.e); // Poweruser
|
|
}
|
|
|
|
private Vec3D f() {
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalJumpOnBlock.java b/src/main/java/net/minecraft/server/PathfinderGoalJumpOnBlock.java
|
|
index e28f3f20e..23aa1a389 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalJumpOnBlock.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalJumpOnBlock.java
|
|
@@ -26,7 +26,7 @@ public class PathfinderGoalJumpOnBlock extends PathfinderGoal {
|
|
}
|
|
|
|
public void c() {
|
|
- this.a.getNavigation().a((double) ((float) this.f) + 0.5D, (double) (this.g + 1), (double) ((float) this.h) + 0.5D, this.b);
|
|
+ this.a.getNavigation().a(net.frozenorb.pathsearch.PositionPathSearchType.JUMPONBLOCK, (double) ((float) this.f) + 0.5D, (double) (this.g + 1), (double) ((float) this.h) + 0.5D, this.b); // Poweruser
|
|
this.c = 0;
|
|
this.d = 0;
|
|
this.e = this.a.aI().nextInt(this.a.aI().nextInt(1200) + 1200) + 1200;
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalMoveIndoors.java b/src/main/java/net/minecraft/server/PathfinderGoalMoveIndoors.java
|
|
index 06f2765d6..d2d90addd 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalMoveIndoors.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalMoveIndoors.java
|
|
@@ -47,10 +47,10 @@ public class PathfinderGoalMoveIndoors extends PathfinderGoal {
|
|
Vec3D vec3d = RandomPositionGenerator.a(this.a, 14, 3, Vec3D.a((double) this.b.getIndoorsX() + 0.5D, (double) this.b.getIndoorsY(), (double) this.b.getIndoorsZ() + 0.5D));
|
|
|
|
if (vec3d != null) {
|
|
- this.a.getNavigation().a(vec3d.a, vec3d.b, vec3d.c, 1.0D);
|
|
+ this.a.getNavigation().a(net.frozenorb.pathsearch.PositionPathSearchType.MOVEINDOORS, vec3d.a, vec3d.b, vec3d.c, 1.0D); // Poweruser
|
|
}
|
|
} else {
|
|
- this.a.getNavigation().a((double) this.b.getIndoorsX() + 0.5D, (double) this.b.getIndoorsY(), (double) this.b.getIndoorsZ() + 0.5D, 1.0D);
|
|
+ this.a.getNavigation().a(net.frozenorb.pathsearch.PositionPathSearchType.MOVEINDOORS, (double) this.b.getIndoorsX() + 0.5D, (double) this.b.getIndoorsY(), (double) this.b.getIndoorsZ() + 0.5D, 1.0D); // Poweruser
|
|
}
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalMoveThroughVillage.java b/src/main/java/net/minecraft/server/PathfinderGoalMoveThroughVillage.java
|
|
index f4ec2d44d..aa579a5ab 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalMoveThroughVillage.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalMoveThroughVillage.java
|
|
@@ -37,7 +37,7 @@ public class PathfinderGoalMoveThroughVillage extends PathfinderGoal {
|
|
boolean flag = this.a.getNavigation().c();
|
|
|
|
this.a.getNavigation().b(false);
|
|
- this.c = this.a.getNavigation().a((double) this.d.locX, (double) this.d.locY, (double) this.d.locZ);
|
|
+ this.c = this.a.getNavigation().a(net.frozenorb.pathsearch.PositionPathSearchType.MOVETHROUGHVILLAGE, (double) this.d.locX, (double) this.d.locY, (double) this.d.locZ); // Poweruser
|
|
this.a.getNavigation().b(flag);
|
|
if (this.c != null) {
|
|
return true;
|
|
@@ -48,7 +48,7 @@ public class PathfinderGoalMoveThroughVillage extends PathfinderGoal {
|
|
return false;
|
|
} else {
|
|
this.a.getNavigation().b(false);
|
|
- this.c = this.a.getNavigation().a(vec3d.a, vec3d.b, vec3d.c);
|
|
+ this.c = this.a.getNavigation().a(net.frozenorb.pathsearch.PositionPathSearchType.MOVETHROUGHVILLAGE, vec3d.a, vec3d.b, vec3d.c); // Poweruser
|
|
this.a.getNavigation().b(flag);
|
|
return this.c != null;
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalMoveTowardsRestriction.java b/src/main/java/net/minecraft/server/PathfinderGoalMoveTowardsRestriction.java
|
|
index 69a940e5d..4dcf7c22c 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalMoveTowardsRestriction.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalMoveTowardsRestriction.java
|
|
@@ -37,6 +37,6 @@ public class PathfinderGoalMoveTowardsRestriction extends PathfinderGoal {
|
|
}
|
|
|
|
public void c() {
|
|
- this.a.getNavigation().a(this.b, this.c, this.d, this.e);
|
|
+ this.a.getNavigation().a(net.frozenorb.pathsearch.PositionPathSearchType.MOVETOWARDSRESTRICTION, this.b, this.c, this.d, this.e); // Poweruser
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalMoveTowardsTarget.java b/src/main/java/net/minecraft/server/PathfinderGoalMoveTowardsTarget.java
|
|
index 28c6252c8..c75bc76ca 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalMoveTowardsTarget.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalMoveTowardsTarget.java
|
|
@@ -46,6 +46,6 @@ public class PathfinderGoalMoveTowardsTarget extends PathfinderGoal {
|
|
}
|
|
|
|
public void c() {
|
|
- this.a.getNavigation().a(this.c, this.d, this.e, this.f);
|
|
+ this.a.getNavigation().a(net.frozenorb.pathsearch.PositionPathSearchType.MOVETOWARDSTARGET, this.c, this.d, this.e, this.f); // Poweruser
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalPanic.java b/src/main/java/net/minecraft/server/PathfinderGoalPanic.java
|
|
index 1b8608d0b..599d8673c 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalPanic.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalPanic.java
|
|
@@ -32,7 +32,7 @@ public class PathfinderGoalPanic extends PathfinderGoal {
|
|
}
|
|
|
|
public void c() {
|
|
- this.a.getNavigation().a(this.c, this.d, this.e, this.b);
|
|
+ this.a.getNavigation().a(net.frozenorb.pathsearch.PositionPathSearchType.PANIC, this.c, this.d, this.e, this.b); // Poweruser
|
|
}
|
|
|
|
public boolean b() {
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalPlay.java b/src/main/java/net/minecraft/server/PathfinderGoalPlay.java
|
|
index 8fba19a7f..53d191dc2 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalPlay.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalPlay.java
|
|
@@ -81,7 +81,7 @@ public class PathfinderGoalPlay extends PathfinderGoal {
|
|
return;
|
|
}
|
|
|
|
- this.a.getNavigation().a(vec3d.a, vec3d.b, vec3d.c, this.c);
|
|
+ this.a.getNavigation().a(net.frozenorb.pathsearch.PositionPathSearchType.PLAY, vec3d.a, vec3d.b, vec3d.c, this.c); // Poweruser
|
|
}
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalRandomStroll.java b/src/main/java/net/minecraft/server/PathfinderGoalRandomStroll.java
|
|
index 396997afe..c0c7580d4 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalRandomStroll.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalRandomStroll.java
|
|
@@ -38,6 +38,6 @@ public class PathfinderGoalRandomStroll extends PathfinderGoal {
|
|
}
|
|
|
|
public void c() {
|
|
- this.a.getNavigation().a(this.b, this.c, this.d, this.e);
|
|
+ this.a.getNavigation().a(net.frozenorb.pathsearch.PositionPathSearchType.RANDOMSTROLL, this.b, this.c, this.d, this.e); // Poweruser
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalTame.java b/src/main/java/net/minecraft/server/PathfinderGoalTame.java
|
|
index a13c63825..fa98af65b 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderGoalTame.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderGoalTame.java
|
|
@@ -32,7 +32,7 @@ public class PathfinderGoalTame extends PathfinderGoal {
|
|
}
|
|
|
|
public void c() {
|
|
- this.entity.getNavigation().a(this.c, this.d, this.e, this.b);
|
|
+ this.entity.getNavigation().a(net.frozenorb.pathsearch.PositionPathSearchType.TAME, this.c, this.d, this.e, this.b); // Poweruser
|
|
}
|
|
|
|
public boolean b() {
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
index 16eb99ccb..aa89f7b12 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -39,6 +39,7 @@ import org.bukkit.event.weather.ThunderChangeEvent;
|
|
|
|
// Poweruser start
|
|
import net.frozenorb.LightingUpdater;
|
|
+import net.frozenorb.WeakChunkCache;
|
|
// Poweruser end
|
|
|
|
public abstract class World implements IBlockAccess {
|
|
@@ -1908,6 +1909,12 @@ public abstract class World implements IBlockAccess {
|
|
}
|
|
|
|
public boolean a(AxisAlignedBB axisalignedbb, Material material) {
|
|
+ // Poweruser start
|
|
+ return this.a(axisalignedbb, material, this);
|
|
+ }
|
|
+
|
|
+ public boolean a(AxisAlignedBB axisalignedbb, Material material, IBlockAccess iblockaccess) {
|
|
+ // Poweruser end
|
|
int i = MathHelper.floor(axisalignedbb.a);
|
|
int j = MathHelper.floor(axisalignedbb.d + 1.0D);
|
|
int k = MathHelper.floor(axisalignedbb.b);
|
|
@@ -1918,7 +1925,7 @@ public abstract class World implements IBlockAccess {
|
|
for (int k1 = i; k1 < j; ++k1) {
|
|
for (int l1 = k; l1 < l; ++l1) {
|
|
for (int i2 = i1; i2 < j1; ++i2) {
|
|
- if (this.getType(k1, l1, i2).getMaterial() == material) {
|
|
+ if (iblockaccess.getType(k1, l1, i2).getMaterial() == material) { // Poweruser
|
|
return true;
|
|
}
|
|
}
|
|
@@ -2816,7 +2823,7 @@ public abstract class World implements IBlockAccess {
|
|
int l1 = i + l;
|
|
int i2 = j + l;
|
|
int j2 = k + l;
|
|
- ChunkCache chunkcache = new ChunkCache(this, i1, j1, k1, l1, i2, j2, 0);
|
|
+ WeakChunkCache chunkcache = new WeakChunkCache(this, i1, j1, k1, l1, i2, j2, 0); // Poweruser
|
|
PathEntity pathentity = (new Pathfinder(chunkcache, flag, flag1, flag2, flag3)).a(entity, entity1, f);
|
|
|
|
this.methodProfiler.b();
|
|
@@ -2835,7 +2842,7 @@ public abstract class World implements IBlockAccess {
|
|
int k2 = l + k1;
|
|
int l2 = i1 + k1;
|
|
int i3 = j1 + k1;
|
|
- ChunkCache chunkcache = new ChunkCache(this, l1, i2, j2, k2, l2, i3, 0);
|
|
+ WeakChunkCache chunkcache = new WeakChunkCache(this, l1, i2, j2, k2, l2, i3, 0); // Poweruser
|
|
PathEntity pathentity = (new Pathfinder(chunkcache, flag, flag1, flag2, flag3)).a(entity, i, j, k, f);
|
|
|
|
this.methodProfiler.b();
|
|
--
|
|
2.13.3
|
|
|