mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-11-04 23:53:01 +00:00
Reschedule block entities when chunks are loaded
Minecraft sometimes keeps chunks in-memory, but not actively loaded. If we schedule a block entity to be ticked and that chunk is is then transitioned to this partially-loaded state, then the block entity is never actually ticked. This is most visible with monitors. When a monitor's contents changes, if the monitor is not already marked as changed, we set it as changed and schedule a tick (see ServerMonitor). However, if the tick is dropped, we don't clear the changed flag, meaning subsequent changes don't requeue the monitor to be ticked, and so the monitor is never updated. We fix this by maintaining a list of block entities whose tick was dropped. If these block entities (or rather their owning chunk) is ever re-loaded, then we reschedule them to be ticked. An alternative approach here would be to add the scheduled tick directly to the LevelChunk. However, getting hold of the LevelChunk for unloaded blocks is quiet nasty, so I think best avoided. Fixes #1146. Fixes #1560 - I believe the second one is a duplicate, and I noticed too late :D.
This commit is contained in:
@@ -22,11 +22,15 @@ import dan200.computercraft.shared.turtle.blocks.TurtleBlockEntity;
|
||||
import dan200.computercraft.shared.util.CapabilityProvider;
|
||||
import dan200.computercraft.shared.util.SidedCapabilityProvider;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.CommandBlockEntity;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraftforge.event.*;
|
||||
import net.minecraftforge.event.entity.EntityJoinLevelEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingDropsEvent;
|
||||
import net.minecraftforge.event.level.ChunkEvent;
|
||||
import net.minecraftforge.event.level.ChunkTicketLevelUpdatedEvent;
|
||||
import net.minecraftforge.event.level.ChunkWatchEvent;
|
||||
import net.minecraftforge.event.server.ServerStartingEvent;
|
||||
import net.minecraftforge.event.server.ServerStoppedEvent;
|
||||
@@ -67,11 +71,23 @@ public class ForgeCommonHooks {
|
||||
CommandComputerCraft.register(event.getDispatcher());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onChunkUnload(ChunkEvent.Unload event) {
|
||||
if (event.getLevel() instanceof ServerLevel && event.getChunk() instanceof LevelChunk chunk) {
|
||||
CommonHooks.onServerChunkUnload(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onChunkWatch(ChunkWatchEvent.Watch event) {
|
||||
CommonHooks.onChunkWatch(event.getChunk(), event.getPlayer());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onChunkTicketLevelChanged(ChunkTicketLevelUpdatedEvent event) {
|
||||
CommonHooks.onChunkTicketLevelChanged(event.getLevel(), event.getChunkPos(), event.getOldTicketLevel(), event.getNewTicketLevel());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onAddReloadListeners(AddReloadListenerEvent event) {
|
||||
CommonHooks.onDatapackReload((id, listener) -> event.addListener(listener));
|
||||
|
||||
Reference in New Issue
Block a user