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.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();
}
}
}

View File

@ -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<br>
* 1: Crate<br>
@ -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"));
}
}

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;
}
}