diff --git a/src/main/java/com/hbm/entity/item/EntityDeliveryDrone.java b/src/main/java/com/hbm/entity/item/EntityDeliveryDrone.java
index d26e96767..1d3e9674b 100644
--- a/src/main/java/com/hbm/entity/item/EntityDeliveryDrone.java
+++ b/src/main/java/com/hbm/entity/item/EntityDeliveryDrone.java
@@ -7,6 +7,7 @@ import com.hbm.inventory.fluid.Fluids;
import com.hbm.items.ModItems;
import com.hbm.main.MainRegistry;
+import com.hbm.util.ChunkShapeHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
@@ -20,13 +21,13 @@ import net.minecraftforge.common.ForgeChunkManager.Ticket;
import net.minecraftforge.common.ForgeChunkManager.Type;
public class EntityDeliveryDrone extends EntityDroneBase implements IInventory, IChunkLoader {
-
+
protected ItemStack[] slots = new ItemStack[this.getSizeInventory()];
public FluidStack fluid;
-
+
protected boolean chunkLoading = false;
private Ticket loaderTicket;
-
+
public EntityDeliveryDrone(World world) {
super(world);
}
@@ -60,32 +61,22 @@ public class EntityDeliveryDrone extends EntityDroneBase implements IInventory,
super.entityInit();
this.dataWatcher.addObject(11, new Byte((byte) 0));
}
-
- public EntityDeliveryDrone setChunkLoading() {
+
+ public void setChunkLoading() {
init(ForgeChunkManager.requestTicket(MainRegistry.instance, worldObj, Type.ENTITY));
this.chunkLoading = true;
- return this;
}
- @Override
- public void onUpdate() {
-
- if(!worldObj.isRemote) {
- loadNeighboringChunks((int)Math.floor(posX / 16D), (int)Math.floor(posZ / 16D));
- }
-
- super.onUpdate();
- }
@Override
public double getSpeed() {
return this.dataWatcher.getWatchableObjectByte(11) == 1 ? 0.375 * 3 : 0.375;
}
-
+
@Override
protected void writeEntityToNBT(NBTTagCompound nbt) {
super.writeEntityToNBT(nbt);
-
+
NBTTagList nbttaglist = new NBTTagList();
for(int i = 0; i < this.slots.length; ++i) {
@@ -98,7 +89,7 @@ public class EntityDeliveryDrone extends EntityDroneBase implements IInventory,
}
nbt.setTag("Items", nbttaglist);
-
+
if(fluid != null) {
nbt.setInteger("fluidType", fluid.type.getID());
nbt.setInteger("fluidAmount", fluid.fill);
@@ -111,7 +102,7 @@ public class EntityDeliveryDrone extends EntityDroneBase implements IInventory,
@Override
protected void readEntityFromNBT(NBTTagCompound nbt) {
super.readEntityFromNBT(nbt);
-
+
NBTTagList nbttaglist = nbt.getTagList("Items", 10);
this.slots = new ItemStack[this.getSizeInventory()];
@@ -123,14 +114,14 @@ public class EntityDeliveryDrone extends EntityDroneBase implements IInventory,
this.slots[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
}
}
-
+
if(nbt.hasKey("fluidType")) {
FluidType type = Fluids.fromNameCompat(nbt.getString("fluidType"));
if(type != Fluids.NONE) {
nbt.removeTag(nbt.getString("fluidType"));
} else
type = Fluids.fromID(nbt.getInteger("fluidType"));
-
+
this.fluid = new FluidStack(type, nbt.getInteger("fluidAmount"));
}
@@ -142,7 +133,7 @@ public class EntityDeliveryDrone extends EntityDroneBase implements IInventory,
public ItemStack getStackInSlot(int slot) {
return slots[slot];
}
-
+
@Override
public ItemStack decrStackSize(int slot, int amount) {
if(this.slots[slot] != null) {
@@ -197,20 +188,23 @@ public class EntityDeliveryDrone extends EntityDroneBase implements IInventory,
@Override public void openInventory() { }
@Override public void closeInventory() { }
- public void loadNeighboringChunks(int newChunkX, int newChunkZ) {
+ @Override
+ protected void loadNeighboringChunks() {
if(!worldObj.isRemote && loaderTicket != null) {
clearChunkLoader();
- ForgeChunkManager.forceChunk(loaderTicket, new ChunkCoordIntPair(newChunkX, newChunkZ));
- ForgeChunkManager.forceChunk(loaderTicket, new ChunkCoordIntPair((int) Math.ceil((this.posX + this.motionX) / 16D), (int) Math.ceil((this.posZ + this.motionZ) / 16D)));
+ // This is the lowest padding that worked with my drone waypoint path. if they stop getting loaded crank up paddingSize
+ for (ChunkCoordIntPair chunk : ChunkShapeHelper.getChunksAlongLineSegment((int) this.posX, (int) this.posZ, (int) (this.posX + this.motionX), (int) (this.posZ + this.motionZ), 4)){
+ ForgeChunkManager.forceChunk(loaderTicket, chunk);
+ }
}
}
-
+
@Override
public void setDead() {
super.setDead();
this.clearChunkLoader();
}
-
+
public void clearChunkLoader() {
if(!worldObj.isRemote && loaderTicket != null) {
for(ChunkCoordIntPair chunk : loaderTicket.getChunkList()) {
@@ -227,7 +221,7 @@ public class EntityDeliveryDrone extends EntityDroneBase implements IInventory,
loaderTicket.bindEntity(this);
loaderTicket.getModData();
}
- ForgeChunkManager.forceChunk(loaderTicket, new ChunkCoordIntPair(chunkCoordX, chunkCoordZ));
+ this.loadNeighboringChunks();
}
}
}
diff --git a/src/main/java/com/hbm/entity/item/EntityDroneBase.java b/src/main/java/com/hbm/entity/item/EntityDroneBase.java
index b6e269869..cdd8c000b 100644
--- a/src/main/java/com/hbm/entity/item/EntityDroneBase.java
+++ b/src/main/java/com/hbm/entity/item/EntityDroneBase.java
@@ -9,7 +9,7 @@ import net.minecraft.util.Vec3;
import net.minecraft.world.World;
public abstract class EntityDroneBase extends Entity {
-
+
protected int turnProgress;
protected double syncPosX;
protected double syncPosY;
@@ -26,7 +26,7 @@ public abstract class EntityDroneBase extends Entity {
super(world);
this.setSize(1.5F, 2.0F);
}
-
+
public void setTarget(double x, double y, double z) {
this.targetX = x;
this.targetY = y;
@@ -49,7 +49,7 @@ public abstract class EntityDroneBase extends Entity {
if(attacker instanceof EntityPlayer) {
this.setDead();
}
-
+
return false;
}
@@ -62,7 +62,7 @@ public abstract class EntityDroneBase extends Entity {
protected void entityInit() {
this.dataWatcher.addObject(10, new Byte((byte) 0));
}
-
+
/**
* 0: Empty
* 1: Crate
@@ -71,14 +71,14 @@ public abstract class EntityDroneBase extends Entity {
public void setAppearance(int style) {
this.dataWatcher.updateObject(10, (byte) style);
}
-
+
public int getAppearance() {
return this.dataWatcher.getWatchableObjectByte(10);
}
-
+
@Override
public void onUpdate() {
-
+
if(worldObj.isRemote) {
if(this.turnProgress > 0) {
double interpX = this.posX + (this.syncPosX - this.posX) / (double) this.turnProgress;
@@ -99,12 +99,12 @@ public abstract class EntityDroneBase extends Entity {
this.motionX = 0;
this.motionY = 0;
this.motionZ = 0;
-
+
if(this.targetY != -1) {
-
+
Vec3 dist = Vec3.createVectorHelper(targetX - posX, targetY - posY, targetZ - posZ);
double speed = Math.min(getSpeed(), dist.lengthVector());
-
+
dist = dist.normalize();
this.motionX = dist.xCoord * speed;
this.motionY = dist.yCoord * speed;
@@ -113,21 +113,26 @@ public abstract class EntityDroneBase extends Entity {
if(isCollidedHorizontally){
motionY += 1;
}
+ this.loadNeighboringChunks();
this.moveEntity(motionX, motionY, motionZ);
}
+
+ super.onUpdate();
}
-
+
+ protected void loadNeighboringChunks() {}
+
public double getSpeed() {
return 0.125D;
}
-
+
@SideOnly(Side.CLIENT)
public void setVelocity(double motionX, double motionY, double motionZ) {
this.velocityX = this.motionX = motionX;
this.velocityY = this.motionY = motionY;
this.velocityZ = this.motionZ = motionZ;
}
-
+
@SideOnly(Side.CLIENT)
public void setPositionAndRotation2(double x, double y, double z, float yaw, float pitch, int theNumberThree) {
this.syncPosX = x;
@@ -138,7 +143,7 @@ public abstract class EntityDroneBase extends Entity {
this.motionY = this.velocityY;
this.motionZ = this.velocityZ;
}
-
+
@Override
protected void writeEntityToNBT(NBTTagCompound nbt) {
@@ -157,7 +162,7 @@ public abstract class EntityDroneBase extends Entity {
this.targetY = nbt.getDouble("tY");
this.targetZ = nbt.getDouble("tZ");
}
-
+
this.dataWatcher.updateObject(10, nbt.getByte("app"));
}
}
diff --git a/src/main/java/com/hbm/util/ChunkShapeHelper.java b/src/main/java/com/hbm/util/ChunkShapeHelper.java
new file mode 100644
index 000000000..6722d5422
--- /dev/null
+++ b/src/main/java/com/hbm/util/ChunkShapeHelper.java
@@ -0,0 +1,113 @@
+package com.hbm.util;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import net.minecraft.world.ChunkCoordIntPair;
+
+public class ChunkShapeHelper {
+
+
+ // Help what are projections
+ private static double pointSegmentDist(int x1, int z1, int x2, int z2, int px, int pz) {
+ int dx = x2 - x1;
+ int dz = z2 - z1;
+
+ // The segment is just a point
+ if (dx == 0 && dz == 0) {
+ // intellij is telling me that this is duplicated, but it would be more expensive to move it out of the if statements
+ return Math.sqrt((px - x1) * (px - x1) + (pz - z1) * (pz - z1));
+ }
+
+ // Calculate the projection t of point P onto the infinite line through A and B
+ double t = ((px - x1) * dx + (pz - z1) * dz) / (double) (dx * dx + dz * dz);
+
+
+ // Closest to point (x1, z1)
+ if (t < 0) {
+ return Math.sqrt((px - x1) * (px - x1) + (pz - z1) * (pz - z1));
+ } else if (t > 1) {
+ // Closest to point (x2, z2)
+ return Math.sqrt((px - x2) * (px - x2) + (pz - z2) * (pz - z2));
+ }
+ // Projection is within the segment
+
+ double projX = x1 + t * dx;
+ double projZ = z1 + t * dz;
+
+ // Magic math
+ return Math.sqrt((px - projX) * (px - projX) + (pz - projZ) * (pz - projZ));
+ }
+
+ // Loop through the corners of the box and check their distances (yes I know that this doest work with the endpoints very well, but fuck off ive done too much math today)
+ private static double boxLineDist(int lineX0, int lineZ0, int lineX1, int lineZ1, int boxX, int boxZ) {
+ double minDist = Double.MAX_VALUE;
+
+ int[][] corners = {{0, 0}, {0, 16}, {16, 0}, {16, 16}};
+ for (int[] corner : corners) {
+ minDist = Math.min(minDist, pointSegmentDist(lineX0, lineZ0, lineX1, lineZ1, boxX + corner[0], boxZ + corner[1]));
+ }
+
+ return minDist;
+ }
+
+ // 90% of this is Bresenham's Line Algorithm, and the other part is messy padding
+ // The xs and zs are the endpoints fo the line segment, and paddingSize is how many blocks away a chunk needs to be to not be included
+ // Dont give chunk coords
+ public static List getChunksAlongLineSegment(int x0, int z0, int x1, int z1, double paddingSize) {
+ int dx = Math.abs(x1 - x0);
+ int sx = x0 < x1 ? 1 : -1;
+ int dz = -Math.abs(z1 - z0);
+ int sz = z0 < z1 ? 1 : -1;
+ int error = dx + dz;
+
+ // Just store the original starting point because we fuck with it in the loop
+ int originalX = x0;
+ int originalZ = z0;
+
+ // The chunks we are returning
+ List out = new ArrayList<>();
+ // The chunks we have aready checked for their distance so we dont run it over and over
+ List checked = new ArrayList<>();
+
+ // Ahhh scary while true
+ while (true) {
+ // Add the current chunk coords, if they havent already been added
+ ChunkCoordIntPair coords = new ChunkCoordIntPair(x0 >> 4, z0 >> 4);
+ if (!out.contains(coords)) {
+ out.add(coords);
+ }
+
+ // My messy padding code: loop over each of the chunks next to the one we just added
+ int[][] corners = {{-1, -1}, {0, -1}, {1, -1}, {-1, 0}, {1, 0}, {-1, 1}, {0, 1}, {1, 1}};
+ for (int[] corner : corners) {
+
+ // If we already checked this one keep going
+ ChunkCoordIntPair cornerCoords = new ChunkCoordIntPair((x0 >> 4) + corner[0], (z0 >> 4) + corner[1]);
+ if (checked.contains(cornerCoords)) continue;
+ checked.add(cornerCoords);
+
+ // If this box isn't already added, and it is closer than paddingSize, then add it
+ if (!out.contains(cornerCoords) && boxLineDist(originalX, originalZ, x1, z1, cornerCoords.chunkXPos * 16, cornerCoords.chunkZPos * 16) < paddingSize) {
+ out.add(cornerCoords);
+ }
+ }
+
+ // Wikipedia take the wheel
+ int e2 = 2 * error;
+ if (e2 >= dz) {
+ if (x0 == x1) break;
+ error += dz;
+ x0 += sx;
+ }
+ if (e2 <= dx) {
+ if (z0 == z1) break;
+ error += dx;
+ z0 += sz;
+ }
+ }
+
+ return out;
+
+ }
+}