Merge pull request #1981 from KellenHurrey/master

There i fixed chunkloading drones
This commit is contained in:
HbmMods 2025-03-12 09:07:22 +01:00 committed by GitHub
commit 2bdbfda243
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 155 additions and 43 deletions

View File

@ -7,6 +7,7 @@ import com.hbm.inventory.fluid.Fluids;
import com.hbm.items.ModItems; import com.hbm.items.ModItems;
import com.hbm.main.MainRegistry; import com.hbm.main.MainRegistry;
import com.hbm.util.ChunkShapeHelper;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory; import net.minecraft.inventory.IInventory;
@ -20,13 +21,13 @@ import net.minecraftforge.common.ForgeChunkManager.Ticket;
import net.minecraftforge.common.ForgeChunkManager.Type; import net.minecraftforge.common.ForgeChunkManager.Type;
public class EntityDeliveryDrone extends EntityDroneBase implements IInventory, IChunkLoader { public class EntityDeliveryDrone extends EntityDroneBase implements IInventory, IChunkLoader {
protected ItemStack[] slots = new ItemStack[this.getSizeInventory()]; protected ItemStack[] slots = new ItemStack[this.getSizeInventory()];
public FluidStack fluid; public FluidStack fluid;
protected boolean chunkLoading = false; protected boolean chunkLoading = false;
private Ticket loaderTicket; private Ticket loaderTicket;
public EntityDeliveryDrone(World world) { public EntityDeliveryDrone(World world) {
super(world); super(world);
} }
@ -60,32 +61,22 @@ public class EntityDeliveryDrone extends EntityDroneBase implements IInventory,
super.entityInit(); super.entityInit();
this.dataWatcher.addObject(11, new Byte((byte) 0)); this.dataWatcher.addObject(11, new Byte((byte) 0));
} }
public EntityDeliveryDrone setChunkLoading() { public void setChunkLoading() {
init(ForgeChunkManager.requestTicket(MainRegistry.instance, worldObj, Type.ENTITY)); init(ForgeChunkManager.requestTicket(MainRegistry.instance, worldObj, Type.ENTITY));
this.chunkLoading = true; 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 @Override
public double getSpeed() { public double getSpeed() {
return this.dataWatcher.getWatchableObjectByte(11) == 1 ? 0.375 * 3 : 0.375; return this.dataWatcher.getWatchableObjectByte(11) == 1 ? 0.375 * 3 : 0.375;
} }
@Override @Override
protected void writeEntityToNBT(NBTTagCompound nbt) { protected void writeEntityToNBT(NBTTagCompound nbt) {
super.writeEntityToNBT(nbt); super.writeEntityToNBT(nbt);
NBTTagList nbttaglist = new NBTTagList(); NBTTagList nbttaglist = new NBTTagList();
for(int i = 0; i < this.slots.length; ++i) { for(int i = 0; i < this.slots.length; ++i) {
@ -98,7 +89,7 @@ public class EntityDeliveryDrone extends EntityDroneBase implements IInventory,
} }
nbt.setTag("Items", nbttaglist); nbt.setTag("Items", nbttaglist);
if(fluid != null) { if(fluid != null) {
nbt.setInteger("fluidType", fluid.type.getID()); nbt.setInteger("fluidType", fluid.type.getID());
nbt.setInteger("fluidAmount", fluid.fill); nbt.setInteger("fluidAmount", fluid.fill);
@ -111,7 +102,7 @@ public class EntityDeliveryDrone extends EntityDroneBase implements IInventory,
@Override @Override
protected void readEntityFromNBT(NBTTagCompound nbt) { protected void readEntityFromNBT(NBTTagCompound nbt) {
super.readEntityFromNBT(nbt); super.readEntityFromNBT(nbt);
NBTTagList nbttaglist = nbt.getTagList("Items", 10); NBTTagList nbttaglist = nbt.getTagList("Items", 10);
this.slots = new ItemStack[this.getSizeInventory()]; this.slots = new ItemStack[this.getSizeInventory()];
@ -123,14 +114,14 @@ public class EntityDeliveryDrone extends EntityDroneBase implements IInventory,
this.slots[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1); this.slots[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
} }
} }
if(nbt.hasKey("fluidType")) { if(nbt.hasKey("fluidType")) {
FluidType type = Fluids.fromNameCompat(nbt.getString("fluidType")); FluidType type = Fluids.fromNameCompat(nbt.getString("fluidType"));
if(type != Fluids.NONE) { if(type != Fluids.NONE) {
nbt.removeTag(nbt.getString("fluidType")); nbt.removeTag(nbt.getString("fluidType"));
} else } else
type = Fluids.fromID(nbt.getInteger("fluidType")); type = Fluids.fromID(nbt.getInteger("fluidType"));
this.fluid = new FluidStack(type, nbt.getInteger("fluidAmount")); this.fluid = new FluidStack(type, nbt.getInteger("fluidAmount"));
} }
@ -142,7 +133,7 @@ public class EntityDeliveryDrone extends EntityDroneBase implements IInventory,
public ItemStack getStackInSlot(int slot) { public ItemStack getStackInSlot(int slot) {
return slots[slot]; return slots[slot];
} }
@Override @Override
public ItemStack decrStackSize(int slot, int amount) { public ItemStack decrStackSize(int slot, int amount) {
if(this.slots[slot] != null) { if(this.slots[slot] != null) {
@ -197,20 +188,23 @@ public class EntityDeliveryDrone extends EntityDroneBase implements IInventory,
@Override public void openInventory() { } @Override public void openInventory() { }
@Override public void closeInventory() { } @Override public void closeInventory() { }
public void loadNeighboringChunks(int newChunkX, int newChunkZ) { @Override
protected void loadNeighboringChunks() {
if(!worldObj.isRemote && loaderTicket != null) { if(!worldObj.isRemote && loaderTicket != null) {
clearChunkLoader(); clearChunkLoader();
ForgeChunkManager.forceChunk(loaderTicket, new ChunkCoordIntPair(newChunkX, newChunkZ)); // This is the lowest padding that worked with my drone waypoint path. if they stop getting loaded crank up paddingSize
ForgeChunkManager.forceChunk(loaderTicket, new ChunkCoordIntPair((int) Math.ceil((this.posX + this.motionX) / 16D), (int) Math.ceil((this.posZ + this.motionZ) / 16D))); 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 @Override
public void setDead() { public void setDead() {
super.setDead(); super.setDead();
this.clearChunkLoader(); this.clearChunkLoader();
} }
public void clearChunkLoader() { public void clearChunkLoader() {
if(!worldObj.isRemote && loaderTicket != null) { if(!worldObj.isRemote && loaderTicket != null) {
for(ChunkCoordIntPair chunk : loaderTicket.getChunkList()) { for(ChunkCoordIntPair chunk : loaderTicket.getChunkList()) {
@ -227,7 +221,7 @@ public class EntityDeliveryDrone extends EntityDroneBase implements IInventory,
loaderTicket.bindEntity(this); loaderTicket.bindEntity(this);
loaderTicket.getModData(); loaderTicket.getModData();
} }
ForgeChunkManager.forceChunk(loaderTicket, new ChunkCoordIntPair(chunkCoordX, chunkCoordZ)); this.loadNeighboringChunks();
} }
} }
} }

View File

@ -9,7 +9,7 @@ import net.minecraft.util.Vec3;
import net.minecraft.world.World; import net.minecraft.world.World;
public abstract class EntityDroneBase extends Entity { public abstract class EntityDroneBase extends Entity {
protected int turnProgress; protected int turnProgress;
protected double syncPosX; protected double syncPosX;
protected double syncPosY; protected double syncPosY;
@ -26,7 +26,7 @@ public abstract class EntityDroneBase extends Entity {
super(world); super(world);
this.setSize(1.5F, 2.0F); this.setSize(1.5F, 2.0F);
} }
public void setTarget(double x, double y, double z) { public void setTarget(double x, double y, double z) {
this.targetX = x; this.targetX = x;
this.targetY = y; this.targetY = y;
@ -49,7 +49,7 @@ public abstract class EntityDroneBase extends Entity {
if(attacker instanceof EntityPlayer) { if(attacker instanceof EntityPlayer) {
this.setDead(); this.setDead();
} }
return false; return false;
} }
@ -62,7 +62,7 @@ public abstract class EntityDroneBase extends Entity {
protected void entityInit() { protected void entityInit() {
this.dataWatcher.addObject(10, new Byte((byte) 0)); this.dataWatcher.addObject(10, new Byte((byte) 0));
} }
/** /**
* 0: Empty<br> * 0: Empty<br>
* 1: Crate<br> * 1: Crate<br>
@ -71,14 +71,14 @@ public abstract class EntityDroneBase extends Entity {
public void setAppearance(int style) { public void setAppearance(int style) {
this.dataWatcher.updateObject(10, (byte) style); this.dataWatcher.updateObject(10, (byte) style);
} }
public int getAppearance() { public int getAppearance() {
return this.dataWatcher.getWatchableObjectByte(10); return this.dataWatcher.getWatchableObjectByte(10);
} }
@Override @Override
public void onUpdate() { public void onUpdate() {
if(worldObj.isRemote) { if(worldObj.isRemote) {
if(this.turnProgress > 0) { if(this.turnProgress > 0) {
double interpX = this.posX + (this.syncPosX - this.posX) / (double) this.turnProgress; 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.motionX = 0;
this.motionY = 0; this.motionY = 0;
this.motionZ = 0; this.motionZ = 0;
if(this.targetY != -1) { if(this.targetY != -1) {
Vec3 dist = Vec3.createVectorHelper(targetX - posX, targetY - posY, targetZ - posZ); Vec3 dist = Vec3.createVectorHelper(targetX - posX, targetY - posY, targetZ - posZ);
double speed = Math.min(getSpeed(), dist.lengthVector()); double speed = Math.min(getSpeed(), dist.lengthVector());
dist = dist.normalize(); dist = dist.normalize();
this.motionX = dist.xCoord * speed; this.motionX = dist.xCoord * speed;
this.motionY = dist.yCoord * speed; this.motionY = dist.yCoord * speed;
@ -113,21 +113,26 @@ public abstract class EntityDroneBase extends Entity {
if(isCollidedHorizontally){ if(isCollidedHorizontally){
motionY += 1; motionY += 1;
} }
this.loadNeighboringChunks();
this.moveEntity(motionX, motionY, motionZ); this.moveEntity(motionX, motionY, motionZ);
} }
super.onUpdate();
} }
protected void loadNeighboringChunks() {}
public double getSpeed() { public double getSpeed() {
return 0.125D; return 0.125D;
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public void setVelocity(double motionX, double motionY, double motionZ) { public void setVelocity(double motionX, double motionY, double motionZ) {
this.velocityX = this.motionX = motionX; this.velocityX = this.motionX = motionX;
this.velocityY = this.motionY = motionY; this.velocityY = this.motionY = motionY;
this.velocityZ = this.motionZ = motionZ; this.velocityZ = this.motionZ = motionZ;
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public void setPositionAndRotation2(double x, double y, double z, float yaw, float pitch, int theNumberThree) { public void setPositionAndRotation2(double x, double y, double z, float yaw, float pitch, int theNumberThree) {
this.syncPosX = x; this.syncPosX = x;
@ -138,7 +143,7 @@ public abstract class EntityDroneBase extends Entity {
this.motionY = this.velocityY; this.motionY = this.velocityY;
this.motionZ = this.velocityZ; this.motionZ = this.velocityZ;
} }
@Override @Override
protected void writeEntityToNBT(NBTTagCompound nbt) { protected void writeEntityToNBT(NBTTagCompound nbt) {
@ -157,7 +162,7 @@ public abstract class EntityDroneBase extends Entity {
this.targetY = nbt.getDouble("tY"); this.targetY = nbt.getDouble("tY");
this.targetZ = nbt.getDouble("tZ"); this.targetZ = nbt.getDouble("tZ");
} }
this.dataWatcher.updateObject(10, nbt.getByte("app")); this.dataWatcher.updateObject(10, nbt.getByte("app"));
} }
} }

View File

@ -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<ChunkCoordIntPair> 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<ChunkCoordIntPair> out = new ArrayList<>();
// The chunks we have aready checked for their distance so we dont run it over and over
List<ChunkCoordIntPair> 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;
}
}