Make EntityLiving call AI logic every tick again. Rework PathfinderGoalSelector logic. Adds UnsafeList for use in places where we use ArrayList and know we won't get index out of range errors. Added usage to World's tickEntities, Chunk's entitySlices to speed up searching for entities, and to PathfinderGoalSelector to speed up dealing with AI goals. Reworked logic in PathfinderGoalSelector with help from fullwall. This code no longer uses an extra ArrayList for setting up goals and only updates which goals should be run every other time it is called. Removed only calling PathfinderGoalSelector every other tick from EntityLiving as we now only setup new goals every other tick. This ensures existing goals run every tick to properly update mob movement.
110 lines
4.2 KiB
Java
110 lines
4.2 KiB
Java
package net.minecraft.server;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Iterator;
|
|
import org.bukkit.craftbukkit.util.UnsafeList; // CraftBukkit
|
|
|
|
public class PathfinderGoalSelector {
|
|
|
|
// CraftBukkit start - use UnsafeList, add boolean for picking goals
|
|
private UnsafeList a = new UnsafeList(16);
|
|
private UnsafeList b = new UnsafeList(16);
|
|
boolean oddCall = true;
|
|
// CraftBukkit end
|
|
|
|
public PathfinderGoalSelector() {}
|
|
|
|
public void a(int i, PathfinderGoal pathfindergoal) {
|
|
this.a.add(new PathfinderGoalSelectorItem(this, i, pathfindergoal));
|
|
}
|
|
|
|
public void a() {
|
|
//ArrayList arraylist = new ArrayList(); // CraftBukkit - removed usage
|
|
|
|
// CraftBukkit start - don't use iterators for private fields, only run every other call
|
|
if (oddCall) {
|
|
for (int i = 0; i < this.a.size(); i++) {
|
|
PathfinderGoalSelectorItem pathfindergoalselectoritem = (PathfinderGoalSelectorItem) this.a.unsafeGet(i); // CraftBukkit - use unsafeGet
|
|
boolean flag = this.b.contains(pathfindergoalselectoritem);
|
|
|
|
if (flag) {
|
|
if (this.a(pathfindergoalselectoritem) && pathfindergoalselectoritem.a.b()) {
|
|
continue;
|
|
}
|
|
|
|
pathfindergoalselectoritem.a.d();
|
|
this.b.remove(pathfindergoalselectoritem);
|
|
}
|
|
|
|
if (this.a(pathfindergoalselectoritem) && pathfindergoalselectoritem.a.a()) {
|
|
// CraftBukkit start - call method now
|
|
// arraylist.add(pathfindergoalselectoritem);
|
|
pathfindergoalselectoritem.a.c();
|
|
// CraftBukkit end
|
|
this.b.add(pathfindergoalselectoritem);
|
|
}
|
|
}
|
|
}
|
|
oddCall = !oddCall;
|
|
// CraftBukkit end
|
|
|
|
boolean flag1 = false;
|
|
|
|
// CraftBukkit start - removed usage of arraylist
|
|
/*if (flag1 && arraylist.size() > 0) {
|
|
System.out.println("Starting: ");
|
|
}*/
|
|
// CraftBukkit end
|
|
|
|
Iterator iterator1;
|
|
PathfinderGoalSelectorItem pathfindergoalselectoritem1;
|
|
|
|
// CraftBukkit start - removed usage of arraylist
|
|
/*for (iterator1 = arraylist.iterator(); iterator1.hasNext(); pathfindergoalselectoritem1.a.c()) {
|
|
pathfindergoalselectoritem1 = (PathfinderGoalSelectorItem) iterator1.next();
|
|
if (flag1) {
|
|
System.out.println(pathfindergoalselectoritem1.a.toString() + ", ");
|
|
}
|
|
}*/
|
|
// CraftBukkit end
|
|
|
|
if (flag1 && this.b.size() > 0) {
|
|
System.out.println("Running: ");
|
|
}
|
|
|
|
// CraftBukkit start - don't use iterators for private fields
|
|
for (int i = 0; i < this.b.size(); i++) {
|
|
pathfindergoalselectoritem1 = (PathfinderGoalSelectorItem) this.b.unsafeGet(i); // CraftBukkit - use unsafeGet
|
|
pathfindergoalselectoritem1.a.e();
|
|
if (flag1) {
|
|
System.out.println(pathfindergoalselectoritem1.a.toString());
|
|
}
|
|
}
|
|
// CraftBukkit end
|
|
}
|
|
|
|
private boolean a(PathfinderGoalSelectorItem pathfindergoalselectoritem) {
|
|
// CraftBukkit start - don't use iterators for private fields
|
|
for (int i = 0; i < this.a.size(); i++) {
|
|
PathfinderGoalSelectorItem pathfindergoalselectoritem1 = (PathfinderGoalSelectorItem) this.a.unsafeGet(i); // CraftBukkit - use unsafeGet
|
|
|
|
if (pathfindergoalselectoritem1 != pathfindergoalselectoritem) {
|
|
if (pathfindergoalselectoritem.b >= pathfindergoalselectoritem1.b) {
|
|
if (!this.a(pathfindergoalselectoritem, pathfindergoalselectoritem1) && this.b.contains(pathfindergoalselectoritem1)) { // CraftBukkit - switch order
|
|
return false;
|
|
}
|
|
} else if (!pathfindergoalselectoritem1.a.g() && this.b.contains(pathfindergoalselectoritem1)) { // CraftBukkit - switch order
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
// CraftBukkit end
|
|
|
|
return true;
|
|
}
|
|
|
|
private boolean a(PathfinderGoalSelectorItem pathfindergoalselectoritem, PathfinderGoalSelectorItem pathfindergoalselectoritem1) {
|
|
return (pathfindergoalselectoritem.a.h() & pathfindergoalselectoritem1.a.h()) == 0;
|
|
}
|
|
}
|