mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-01 05:58:00 +01:00
Replaced player viewableChunks set interaction to the Chunk class (Viewable support)
This commit is contained in:
parent
737cf24ace
commit
97a1141583
@ -40,8 +40,8 @@ import java.util.function.Consumer;
|
||||
|
||||
public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
|
||||
private static Map<Integer, Entity> entityById = new ConcurrentHashMap<>();
|
||||
private static AtomicInteger lastEntityId = new AtomicInteger();
|
||||
private static final Map<Integer, Entity> entityById = new ConcurrentHashMap<>();
|
||||
private static final AtomicInteger lastEntityId = new AtomicInteger();
|
||||
|
||||
// Metadata
|
||||
protected static final byte METADATA_BYTE = 0;
|
||||
@ -63,7 +63,8 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
protected float cacheX, cacheY, cacheZ; // Used to synchronize with #getPosition
|
||||
protected float lastYaw, lastPitch;
|
||||
protected float cacheYaw, cachePitch;
|
||||
private int id;
|
||||
// Synchronization
|
||||
private static final long SYNCHRONIZATION_DELAY = 1500; // In ms
|
||||
|
||||
private BoundingBox boundingBox;
|
||||
|
||||
@ -74,22 +75,20 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
protected float eyeHeight;
|
||||
|
||||
private boolean autoViewable;
|
||||
private Set<Player> viewers = new CopyOnWriteArraySet<>();
|
||||
private final int id;
|
||||
private Data data;
|
||||
private Set<Entity> passengers = new CopyOnWriteArraySet<>();
|
||||
private final Set<Player> viewers = new CopyOnWriteArraySet<>();
|
||||
|
||||
protected UUID uuid;
|
||||
private boolean isActive; // False if entity has only been instanced without being added somewhere
|
||||
private boolean removed;
|
||||
private boolean shouldRemove;
|
||||
private long scheduledRemoveTime;
|
||||
private EntityType entityType;
|
||||
private final Set<Entity> passengers = new CopyOnWriteArraySet<>();
|
||||
private long lastUpdate;
|
||||
private Map<Class<? extends Event>, List<EventCallback>> eventCallbacks = new ConcurrentHashMap<>();
|
||||
private final EntityType entityType;
|
||||
protected long lastVelocityUpdateTime; // Reset velocity to 0 after countdown
|
||||
|
||||
// Synchronization
|
||||
private long synchronizationDelay = 1500; // In ms
|
||||
private final Map<Class<? extends Event>, List<EventCallback>> eventCallbacks = new ConcurrentHashMap<>();
|
||||
private long lastSynchronizationTime;
|
||||
|
||||
// Metadata
|
||||
@ -215,9 +214,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
};
|
||||
|
||||
if (instance.hasEnabledAutoChunkLoad()) {
|
||||
instance.loadChunk(position, chunk -> {
|
||||
runnable.run();
|
||||
});
|
||||
instance.loadChunk(position, chunk -> runnable.run());
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
@ -289,7 +286,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
if (!result)
|
||||
return false;
|
||||
player.viewableEntities.add(this);
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -497,7 +494,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
}
|
||||
|
||||
// Scheduled synchronization
|
||||
if (time - lastSynchronizationTime >= synchronizationDelay) {
|
||||
if (time - lastSynchronizationTime >= SYNCHRONIZATION_DELAY) {
|
||||
lastSynchronizationTime = time;
|
||||
sendSynchronization();
|
||||
}
|
||||
@ -1210,9 +1207,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
protected void sendMetadataIndex(int index) {
|
||||
EntityMetaDataPacket metaDataPacket = new EntityMetaDataPacket();
|
||||
metaDataPacket.entityId = getEntityId();
|
||||
metaDataPacket.consumer = packet -> {
|
||||
fillMetadataIndex(packet, index);
|
||||
};
|
||||
metaDataPacket.consumer = packet -> fillMetadataIndex(packet, index);
|
||||
|
||||
sendPacketToViewersAndSelf(metaDataPacket);
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
|
||||
private String username;
|
||||
protected PlayerConnection playerConnection;
|
||||
private ConcurrentLinkedQueue<ClientPlayPacket> packets = new ConcurrentLinkedQueue<>();
|
||||
protected final Set<Entity> viewableEntities = new CopyOnWriteArraySet<>();
|
||||
|
||||
private int latency;
|
||||
private ColoredText displayName;
|
||||
@ -69,19 +69,17 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
|
||||
private DimensionType dimensionType;
|
||||
private GameMode gameMode;
|
||||
private LevelType levelType;
|
||||
protected final Set<Chunk> viewableChunks = new CopyOnWriteArraySet<>();
|
||||
private int teleportId = 0;
|
||||
|
||||
protected boolean onGround;
|
||||
|
||||
protected Set<Entity> viewableEntities = new CopyOnWriteArraySet<>();
|
||||
protected Set<Chunk> viewableChunks = new CopyOnWriteArraySet<>();
|
||||
|
||||
private PlayerSettings settings;
|
||||
private final ConcurrentLinkedQueue<ClientPlayPacket> packets = new ConcurrentLinkedQueue<>();
|
||||
private final LevelType levelType;
|
||||
private final PlayerSettings settings;
|
||||
private float exp;
|
||||
private int level;
|
||||
|
||||
private PlayerInventory inventory;
|
||||
private final PlayerInventory inventory;
|
||||
private Inventory openInventory;
|
||||
// Used internally to allow the closing of inventory within the inventory listener
|
||||
private boolean didCloseInventory;
|
||||
@ -128,10 +126,10 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
private float walkingSpeed = 0.1f;
|
||||
|
||||
// Statistics
|
||||
private Map<PlayerStatistic, Integer> statisticValueMap = new Hashtable<>();
|
||||
private final Map<PlayerStatistic, Integer> statisticValueMap = new Hashtable<>();
|
||||
|
||||
// Vehicle
|
||||
private PlayerVehicleInformation vehicleInformation = new PlayerVehicleInformation();
|
||||
private final PlayerVehicleInformation vehicleInformation = new PlayerVehicleInformation();
|
||||
|
||||
// Tick related
|
||||
private final PlayerTickEvent playerTickEvent = new PlayerTickEvent(this);
|
||||
@ -364,7 +362,7 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
final boolean positionChanged = position.getX() != lastX || position.getY() != lastY || position.getZ() != lastZ;
|
||||
final boolean viewChanged = position.getYaw() != lastYaw || position.getPitch() != lastPitch;
|
||||
if (!getViewers().isEmpty() && (positionChanged || viewChanged)) {
|
||||
ServerPacket updatePacket = null;
|
||||
ServerPacket updatePacket;
|
||||
ServerPacket optionalUpdatePacket = null;
|
||||
if (positionChanged && viewChanged) {
|
||||
EntityPositionAndRotationPacket entityPositionAndRotationPacket = new EntityPositionAndRotationPacket();
|
||||
@ -393,7 +391,8 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
lastY = position.getY();
|
||||
lastZ = position.getZ();
|
||||
updatePacket = entityPositionPacket;
|
||||
} else if (viewChanged) {
|
||||
} else {
|
||||
// View changed
|
||||
EntityRotationPacket entityRotationPacket = new EntityRotationPacket();
|
||||
entityRotationPacket.entityId = getEntityId();
|
||||
entityRotationPacket.yaw = position.getYaw();
|
||||
@ -412,13 +411,13 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
optionalUpdatePacket = entityHeadLookPacket;
|
||||
}
|
||||
|
||||
if (updatePacket != null) {
|
||||
if (optionalUpdatePacket != null) {
|
||||
sendPacketsToViewers(updatePacket, optionalUpdatePacket);
|
||||
} else {
|
||||
sendPacketToViewers(updatePacket);
|
||||
}
|
||||
// Send the update packet
|
||||
if (optionalUpdatePacket != null) {
|
||||
sendPacketsToViewers(updatePacket, optionalUpdatePacket);
|
||||
} else {
|
||||
sendPacketToViewers(updatePacket);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -513,7 +512,7 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
|
||||
PlayerConnection viewerConnection = player.getPlayerConnection();
|
||||
showPlayer(viewerConnection);
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -540,7 +539,6 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
for (Chunk viewableChunk : viewableChunks) {
|
||||
viewableChunk.removeViewer(this);
|
||||
}
|
||||
viewableChunks.clear();
|
||||
|
||||
if (this.instance != null) {
|
||||
final DimensionType instanceDimensionType = instance.getDimensionType();
|
||||
@ -552,13 +550,12 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
final int length = visibleChunks.length;
|
||||
|
||||
AtomicInteger counter = new AtomicInteger(0);
|
||||
for (int i = 0; i < length; i++) {
|
||||
final int[] chunkPos = ChunkUtils.getChunkCoord(visibleChunks[i]);
|
||||
for (long visibleChunk : visibleChunks) {
|
||||
final int[] chunkPos = ChunkUtils.getChunkCoord(visibleChunk);
|
||||
final int chunkX = chunkPos[0];
|
||||
final int chunkZ = chunkPos[1];
|
||||
Consumer<Chunk> callback = (chunk) -> {
|
||||
if (chunk != null) {
|
||||
viewableChunks.add(chunk);
|
||||
chunk.addViewer(this);
|
||||
if (chunk.getChunkX() == Math.floorDiv((int) getPosition().getX(), 16) && chunk.getChunkZ() == Math.floorDiv((int) getPosition().getZ(), 16))
|
||||
updateViewPosition(chunk);
|
||||
@ -827,7 +824,7 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
/**
|
||||
* Update the internal field and send the appropriate {@link EntityMetaDataPacket}
|
||||
*
|
||||
* @param additionalHearts the count of additional heartss
|
||||
* @param additionalHearts the count of additional hearts
|
||||
*/
|
||||
public void setAdditionalHearts(float additionalHearts) {
|
||||
this.additionalHearts = additionalHearts;
|
||||
@ -958,7 +955,7 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
playerConnection.sendPacket(addPlayerPacket);
|
||||
|
||||
for (Player viewer : getViewers()) {
|
||||
PlayerConnection connection = viewer.getPlayerConnection();
|
||||
final PlayerConnection connection = viewer.getPlayerConnection();
|
||||
|
||||
connection.sendPacket(removePlayerPacket);
|
||||
connection.sendPacket(destroyEntitiesPacket);
|
||||
@ -970,16 +967,6 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
teleport(getPosition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to update the internal skin field
|
||||
*
|
||||
* @param skin the player skin
|
||||
* @see #setSkin(PlayerSkin) instead
|
||||
*/
|
||||
protected void refreshSkin(PlayerSkin skin) {
|
||||
this.skin = skin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the player has the respawn screen enabled or disabled
|
||||
*
|
||||
@ -1202,9 +1189,9 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
*/
|
||||
protected void onChunkChange(Chunk newChunk) {
|
||||
final long[] lastVisibleChunks = new long[viewableChunks.size()];
|
||||
Chunk[] lastViewableChunks = viewableChunks.toArray(new Chunk[0]);
|
||||
final Chunk[] lastViewableChunks = viewableChunks.toArray(new Chunk[0]);
|
||||
for (int i = 0; i < lastViewableChunks.length; i++) {
|
||||
Chunk lastViewableChunk = lastViewableChunks[i];
|
||||
final Chunk lastViewableChunk = lastViewableChunks[i];
|
||||
lastVisibleChunks[i] = ChunkUtils.getChunkIndex(lastViewableChunk.getChunkX(), lastViewableChunk.getChunkZ());
|
||||
}
|
||||
final long[] updatedVisibleChunks = ChunkUtils.getChunksInRange(new Position(16 * newChunk.getChunkX(), 0, 16 * newChunk.getChunkZ()), getChunkRange());
|
||||
@ -1219,8 +1206,7 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
unloadChunkPacket.chunkZ = chunkPos[1];
|
||||
playerConnection.sendPacket(unloadChunkPacket);
|
||||
|
||||
Chunk chunk = instance.getChunk(chunkPos[0], chunkPos[1]);
|
||||
viewableChunks.remove(chunk);
|
||||
final Chunk chunk = instance.getChunk(chunkPos[0], chunkPos[1]);
|
||||
if (chunk != null)
|
||||
chunk.removeViewer(this);
|
||||
}
|
||||
@ -1228,15 +1214,13 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
updateViewPosition(newChunk);
|
||||
|
||||
// Load new chunks
|
||||
for (int i = 0; i < newChunks.length; i++) {
|
||||
final int index = newChunks[i];
|
||||
for (int index : newChunks) {
|
||||
final int[] chunkPos = ChunkUtils.getChunkCoord(updatedVisibleChunks[index]);
|
||||
instance.loadOptionalChunk(chunkPos[0], chunkPos[1], chunk -> {
|
||||
if (chunk == null) {
|
||||
// Cannot load chunk (auto load is not enabled)
|
||||
return;
|
||||
}
|
||||
this.viewableChunks.add(chunk);
|
||||
chunk.addViewer(this);
|
||||
});
|
||||
}
|
||||
@ -1541,11 +1525,14 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
|
||||
/**
|
||||
* Get the player viewable chunks
|
||||
* <p>
|
||||
* WARNING: adding or removing a chunk there will not load/unload it,
|
||||
* use {@link Chunk#addViewer(Player)} or {@link Chunk#removeViewer(Player)}
|
||||
*
|
||||
* @return an unmodifiable {@link Set} containing all the chunks that the player sees
|
||||
* @return a {@link Set} containing all the chunks that the player sees
|
||||
*/
|
||||
public Set<Chunk> getViewableChunks() {
|
||||
return Collections.unmodifiableSet(viewableChunks);
|
||||
return viewableChunks;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -286,6 +286,8 @@ public abstract class Chunk implements Viewable {
|
||||
|
||||
// Send the chunk data & light packets to the player
|
||||
sendChunk(player);
|
||||
// Add to the viewable chunks set
|
||||
player.getViewableChunks().add(this);
|
||||
|
||||
PlayerChunkLoadEvent playerChunkLoadEvent = new PlayerChunkLoadEvent(player, chunkX, chunkZ);
|
||||
player.callEvent(PlayerChunkLoadEvent.class, playerChunkLoadEvent);
|
||||
@ -297,6 +299,9 @@ public abstract class Chunk implements Viewable {
|
||||
public boolean removeViewer(Player player) {
|
||||
final boolean result = this.viewers.remove(player);
|
||||
|
||||
// Remove from the viewable chunks set
|
||||
player.getViewableChunks().remove(this);
|
||||
|
||||
PlayerChunkUnloadEvent playerChunkUnloadEvent = new PlayerChunkUnloadEvent(player, chunkX, chunkZ);
|
||||
player.callEvent(PlayerChunkUnloadEvent.class, playerChunkUnloadEvent);
|
||||
return result;
|
||||
|
Loading…
Reference in New Issue
Block a user