WIP chunk loading fix

This commit is contained in:
TheMode 2019-08-26 04:39:58 +02:00
parent b13a888170
commit 4b1fac6cd4
5 changed files with 104 additions and 83 deletions

View File

@ -369,10 +369,11 @@ public abstract class Entity implements Viewable, DataContainer {
synchronized (instance) {
instance.removeEntityFromChunk(this, lastChunk);
instance.addEntityToChunk(this, newChunk);
if (this instanceof Player)
((Player) this).onChunkChange(lastChunk, newChunk); // Refresh loaded chunk
// TODO compare with viewers and remove if too far away
}
if (this instanceof Player)
((Player) this).onChunkChange(lastChunk, newChunk); // Refresh loaded chunk
// TODO compare with viewers and remove if too far away
}
}
}

View File

@ -15,7 +15,7 @@ public abstract class LivingEntity extends Entity {
protected boolean canPickupItem;
protected boolean isDead;
protected float health;
private float health;
private float[] attributeValues = new float[Attribute.values().length];

View File

@ -17,10 +17,7 @@ import fr.themode.minestom.net.packet.client.ClientPlayPacket;
import fr.themode.minestom.net.packet.server.ServerPacket;
import fr.themode.minestom.net.packet.server.play.*;
import fr.themode.minestom.net.player.PlayerConnection;
import fr.themode.minestom.utils.BlockPosition;
import fr.themode.minestom.utils.ChunkUtils;
import fr.themode.minestom.utils.Position;
import fr.themode.minestom.utils.Vector;
import fr.themode.minestom.utils.*;
import fr.themode.minestom.world.Dimension;
import fr.themode.minestom.world.LevelType;
@ -51,8 +48,8 @@ public class Player extends LivingEntity {
instanceContainer = Main.getInstanceManager().createInstanceContainer();
instanceContainer.enableAutoChunkLoad(true);
instanceContainer.setChunkGenerator(chunkGeneratorDemo);
int loopStart = -3;
int loopEnd = 3;
int loopStart = -2;
int loopEnd = 2;
long time = System.currentTimeMillis();
for (int x = loopStart; x < loopEnd; x++)
for (int z = loopStart; z < loopEnd; z++) {
@ -144,8 +141,8 @@ public class Player extends LivingEntity {
});
setEventCallback(PlayerSpawnEvent.class, event -> {
System.out.println("SPAWN ");
setGameMode(GameMode.SURVIVAL);
System.out.println("SPAWN");
setGameMode(GameMode.CREATIVE);
teleport(new Position(0, 66, 0));
/*ChickenCreature chickenCreature = new ChickenCreature();
@ -173,7 +170,7 @@ public class Player extends LivingEntity {
teamsPacket.entities = new String[]{getUsername()};
sendPacketToViewersAndSelf(teamsPacket);
setAttribute(Attribute.MAX_HEALTH, 21);
setAttribute(Attribute.MAX_HEALTH, 40);
heal();
});
}
@ -356,7 +353,7 @@ public class Player extends LivingEntity {
animationPacket.entityId = getEntityId();
animationPacket.animation = AnimationPacket.Animation.TAKE_DAMAGE;
sendPacketToViewersAndSelf(animationPacket);
setHealth(health - amount);
setHealth(getHealth() - amount);
}
@Override
@ -426,60 +423,51 @@ public class Player extends LivingEntity {
protected void sendUpdateHealthPacket() {
UpdateHealthPacket updateHealthPacket = new UpdateHealthPacket();
updateHealthPacket.health = health;
updateHealthPacket.health = getHealth();
updateHealthPacket.food = food;
updateHealthPacket.foodSaturation = foodSaturation;
playerConnection.sendPacket(updateHealthPacket);
}
protected void onChunkChange(Chunk lastChunk, Chunk newChunk) {
long[] lastVisibleChunks = ChunkUtils.getVisibleChunks(new Position(16 * lastChunk.getChunkX(), 0, 16 * lastChunk.getChunkZ()));
long[] newVisibleChunks = ChunkUtils.getVisibleChunks(new Position(16 * newChunk.getChunkX(), 0, 16 * newChunk.getChunkZ()));
// Unload old chunks
for (int l = 0; l < lastVisibleChunks.length; l++) {
long lastVisibleChunk = lastVisibleChunks[l];
boolean contains = false;
for (int n = 0; n < newVisibleChunks.length; n++) {
long newVisibleChunk = newVisibleChunks[n];
if (newVisibleChunk == lastVisibleChunk) {
contains = true;
break;
}
}
if (!contains) {
int[] chunkPos = ChunkUtils.getChunkCoord(lastVisibleChunk);
UnloadChunkPacket unloadChunkPacket = new UnloadChunkPacket();
unloadChunkPacket.chunkX = chunkPos[0];
unloadChunkPacket.chunkZ = chunkPos[1];
playerConnection.sendPacket(unloadChunkPacket);
}
float dx = newChunk.getChunkX() - lastChunk.getChunkX();
float dz = newChunk.getChunkZ() - lastChunk.getChunkZ();
double distance = Math.sqrt(dx * dx + dz * dz);
boolean isFar = distance >= Main.CHUNK_VIEW_DISTANCE / 2;
if (isFar) {
updatePlayerPosition();
}
// Load new chunks
for (int n = 0; n < newVisibleChunks.length; n++) {
long newVisibleChunk = newVisibleChunks[n];
boolean contains = false;
for (int l = 0; l < lastVisibleChunks.length; l++) {
long lastVisibleChunk = lastVisibleChunks[l];
if (lastVisibleChunk == newVisibleChunk) {
contains = true;
break;
}
}
if (!contains) {
int[] chunkPos = ChunkUtils.getChunkCoord(newVisibleChunk);
instance.loadOptionalChunk(chunkPos[0], chunkPos[1], chunk -> {
if (chunk == null) {
return; // Cannot load chunk (autoload not enabled)
}
instance.sendChunk(this, chunk);
});
}
long[] lastVisibleChunks = ChunkUtils.getVisibleChunks(new Position(16 * lastChunk.getChunkX(), 0, 16 * lastChunk.getChunkZ()));
long[] updatedVisibleChunks = ChunkUtils.getVisibleChunks(new Position(16 * newChunk.getChunkX(), 0, 16 * newChunk.getChunkZ()));
int[] oldChunks = ArrayUtils.getDifferencesBetweenArray(lastVisibleChunks, updatedVisibleChunks);
int[] newChunks = ArrayUtils.getDifferencesBetweenArray(updatedVisibleChunks, lastVisibleChunks);
// Unload old chunks
for (int index : oldChunks) {
int[] chunkPos = ChunkUtils.getChunkCoord(lastVisibleChunks[index]);
UnloadChunkPacket unloadChunkPacket = new UnloadChunkPacket();
unloadChunkPacket.chunkX = chunkPos[0];
unloadChunkPacket.chunkZ = chunkPos[1];
playerConnection.sendPacket(unloadChunkPacket);
}
updateViewPosition(newChunk);
// Load new chunks
for (int i = 0; i < newChunks.length; i++) {
boolean isLast = i == newChunks.length - 1;
int index = newChunks[i];
int[] chunkPos = ChunkUtils.getChunkCoord(updatedVisibleChunks[index]);
instance.loadOptionalChunk(chunkPos[0], chunkPos[1], chunk -> {
if (chunk == null) {
return; // Cannot load chunk (autoload not enabled)
}
instance.sendChunk(this, chunk);
if (isFar && isLast)
updatePlayerPosition();
});
}
}
@Override
@ -489,13 +477,7 @@ public class Player extends LivingEntity {
super.teleport(position, () -> {
if (!instance.hasEnabledAutoChunkLoad() && isChunkUnloaded(position.getX(), position.getZ()))
return;
refreshPosition(position.getX(), position.getY(), position.getZ());
refreshView(position.getYaw(), position.getPitch());
PlayerPositionAndLookPacket positionAndLookPacket = new PlayerPositionAndLookPacket();
positionAndLookPacket.position = position;
positionAndLookPacket.flags = 0x00;
positionAndLookPacket.teleportId = 67;
playerConnection.sendPacket(positionAndLookPacket);
updatePlayerPosition();
if (callback != null)
callback.run();
});
@ -646,6 +628,14 @@ public class Player extends LivingEntity {
playerConnection.sendPacket(updateViewPositionPacket);
}
protected void updatePlayerPosition() {
PlayerPositionAndLookPacket positionAndLookPacket = new PlayerPositionAndLookPacket();
positionAndLookPacket.position = position;
positionAndLookPacket.flags = 0x00;
positionAndLookPacket.teleportId = 67;
playerConnection.sendPacket(positionAndLookPacket);
}
public void addPacketToQueue(ClientPlayPacket packet) {
this.packets.add(packet);
}

View File

@ -0,0 +1,50 @@
package fr.themode.minestom.utils;
public class ArrayUtils {
public static byte[] concenateByteArrays(byte[]... arrays) {
int totalLength = 0;
for (byte[] array : arrays) {
totalLength += array.length;
}
byte[] result = new byte[totalLength];
int startingPos = 0;
for (byte[] array : arrays) {
System.arraycopy(array, 0, result, startingPos, array.length);
}
return result;
}
/**
* @param a
* @param b
* @return an array containing a's indexes that aren't in b array
*/
public static int[] getDifferencesBetweenArray(long[] a, long[] b) {
int counter = 0;
int[] indexes = new int[Math.max(a.length, b.length)];
for (int i = 0; i < a.length; i++) {
long aValue = a[i];
boolean contains = false;
for (int n = 0; n < b.length; n++) {
long bValue = b[n];
if (bValue == aValue) {
contains = true;
break;
}
}
if (!contains) {
indexes[counter++] = i;
}
}
// Resize array
int[] result = new int[counter];
System.arraycopy(indexes, 0, result, 0, counter);
return result;
}
}

View File

@ -1,20 +0,0 @@
package fr.themode.minestom.utils;
public class ArraysUtils {
public static byte[] concenateByteArrays(byte[]... arrays) {
int totalLength = 0;
for (byte[] array : arrays) {
totalLength += array.length;
}
byte[] result = new byte[totalLength];
int startingPos = 0;
for (byte[] array : arrays) {
System.arraycopy(array, 0, result, startingPos, array.length);
}
return result;
}
}