Block Entity Lifecycle fixes ()

- Fire client chunk unload event when the load distance is decreased.
  Fixes .
- Fire client chunk unload event before entities are cleared from the
  chunk to fix block entity unload event not firing.
  Clarify that block entity data is unreliable in the block entity load
  events.
  Fixes .

(cherry picked from commit 23a79c8a40)
This commit is contained in:
Technici4n 2022-12-23 17:34:09 +01:00 committed by modmuss50
parent 251d254ae1
commit 1b46dc7866
4 changed files with 19 additions and 1 deletions
fabric-lifecycle-events-v1/src
client/java/net/fabricmc/fabric
api/client/event/lifecycle/v1
mixin/event/lifecycle/client
main
java/net/fabricmc/fabric/api/event/lifecycle/v1
resources

View file

@ -34,6 +34,7 @@ public final class ClientBlockEntityEvents {
* Called when a BlockEntity is loaded into a ClientWorld.
*
* <p>When this event is called, the block entity is already in the world.
* However, its data might not be loaded yet, so don't rely on it.
*/
public static final Event<ClientBlockEntityEvents.Load> BLOCK_ENTITY_LOAD = EventFactory.createArrayBacked(ClientBlockEntityEvents.Load.class, callbacks -> (blockEntity, world) -> {
if (EventFactory.isProfilingEnabled()) {

View file

@ -58,8 +58,22 @@ public abstract class ClientChunkManagerMixin {
}
}
@Inject(method = "unload", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientChunkManager$ClientChunkMap;compareAndSet(ILnet/minecraft/world/chunk/WorldChunk;Lnet/minecraft/world/chunk/WorldChunk;)Lnet/minecraft/world/chunk/WorldChunk;", shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILEXCEPTION)
@Inject(method = "unload", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientChunkManager$ClientChunkMap;compareAndSet(ILnet/minecraft/world/chunk/WorldChunk;Lnet/minecraft/world/chunk/WorldChunk;)Lnet/minecraft/world/chunk/WorldChunk;"), locals = LocalCapture.CAPTURE_FAILEXCEPTION)
private void onChunkUnload(int chunkX, int chunkZ, CallbackInfo ci, int i, WorldChunk chunk) {
ClientChunkEvents.CHUNK_UNLOAD.invoker().onChunkUnload(this.world, chunk);
}
@Inject(
method = "updateLoadDistance",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/world/ClientChunkManager$ClientChunkMap.isInRadius(II)Z"
),
locals = LocalCapture.CAPTURE_FAILHARD
)
private void onUpdateLoadDistance(int loadDistance, CallbackInfo ci, int oldRadius, int newRadius, ClientChunkManager.ClientChunkMap clientChunkMap, int k, WorldChunk oldChunk, ChunkPos chunkPos) {
if (!clientChunkMap.isInRadius(chunkPos.x, chunkPos.z)) {
ClientChunkEvents.CHUNK_UNLOAD.invoker().onChunkUnload(this.world, oldChunk);
}
}
}

View file

@ -31,6 +31,7 @@ public final class ServerBlockEntityEvents {
* Called when an BlockEntity is loaded into a ServerWorld.
*
* <p>When this is event is called, the block entity is already in the world.
* However, its data might not be loaded yet, so don't rely on it.
*/
public static final Event<ServerBlockEntityEvents.Load> BLOCK_ENTITY_LOAD = EventFactory.createArrayBacked(ServerBlockEntityEvents.Load.class, callbacks -> (blockEntity, world) -> {
if (EventFactory.isProfilingEnabled()) {

View file

@ -1,3 +1,5 @@
accessWidener v2 named
accessible class net/minecraft/server/MinecraftServer$ResourceManagerHolder
accessible class net/minecraft/client/world/ClientChunkManager$ClientChunkMap
accessible method net/minecraft/client/world/ClientChunkManager$ClientChunkMap isInRadius (II)Z