From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Thu, 6 Mar 2025 00:09:54 +0300 Subject: [PATCH] lithium: block_entity_ticking.sleeping diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java index 7aef92967cb8a662e644225a4122a544f3cff937..87837ab5ac16786db0b0ddd420b9f7cb797e5bbb 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -2439,7 +2439,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe CsvOutput csvOutput = CsvOutput.builder().addColumn("x").addColumn("y").addColumn("z").addColumn("type").build(output); for (TickingBlockEntity tickingBlockEntity : this.blockEntityTickers) { - BlockPos pos = tickingBlockEntity.getPos(); + BlockPos pos = getPosOrOrigin(tickingBlockEntity); // DivineMC - lithium: block_entity_ticking.sleeping csvOutput.writeRow(pos.getX(), pos.getY(), pos.getZ(), tickingBlockEntity.getType()); } } @@ -2494,6 +2494,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return this; } + // DivineMC start - lithium: block_entity_ticking.sleeping + private BlockPos getPosOrOrigin(TickingBlockEntity instance) { + BlockPos pos = instance.getPos(); + if (pos == null) { + return BlockPos.ZERO; + } + return pos; + } + // DivineMC end - lithium: block_entity_ticking.sleeping + @VisibleForTesting public String getWatchdogStats() { return String.format( diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java index 533b6d4c5238607818002f0b43ff71226c645886..9cde0f691e51072d02faf9df184030bf9675cb1a 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -1535,7 +1535,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl // Spigot end if (tickingBlockEntity.isRemoved()) { this.blockEntityTickers.markAsRemoved(this.tileTickPosition); // DivineMC - optimize block entity removals - Fix MC-117075 - } else if (runsNormally && this.shouldTickBlocksAt(tickingBlockEntity.getPos())) { + } else if (runsNormally && this.shouldTickBlockPosFilterNull(this, tickingBlockEntity.getPos())) { // DivineMC - lithium: block_entity_ticking.sleeping tickingBlockEntity.tick(); // DivineMC start - Parallel world ticking ++tickedEntities; @@ -1553,6 +1553,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl this.spigotConfig.currentPrimedTnt = 0; // Spigot } + // DivineMC start - lithium: block_entity_ticking.sleeping + private boolean shouldTickBlockPosFilterNull(Level instance, BlockPos pos) { + if (pos == null) { + return false; + } + return instance.shouldTickBlocksAt(pos); + } + // DivineMC end - lithium: block_entity_ticking.sleeping + public void guardEntityTick(Consumer consumerEntity, T entity) { try { consumerEntity.accept(entity); diff --git a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java index 947b2911a71768c43180ca8dcaaacd6ce93b3f55..c8c56a4a8872d4b2a437506322f97ccdc5a9dc87 100644 --- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java @@ -39,7 +39,7 @@ import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; -public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntity implements WorldlyContainer, RecipeCraftingHolder, StackedContentsCompatible { +public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntity implements WorldlyContainer, RecipeCraftingHolder, StackedContentsCompatible, net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity { // DivineMC - lithium: block_entity_ticking.sleeping protected static final int SLOT_INPUT = 0; protected static final int SLOT_FUEL = 1; protected static final int SLOT_RESULT = 2; @@ -101,6 +101,38 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit private final RecipeManager.CachedCheck quickCheck; public final RecipeType recipeType; // Paper - cook speed multiplier API public double cookSpeedMultiplier = 1.0; // Paper - cook speed multiplier API + // DivineMC start - lithium: block_entity_ticking.sleeping + private net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper = null; + private TickingBlockEntity sleepingTicker = null; + + @Override + public net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper lithium$getTickWrapper() { + return tickWrapper; + } + + @Override + public void lithium$setTickWrapper(net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper) { + this.tickWrapper = tickWrapper; + this.lithium$setSleepingTicker(null); + } + + @Override + public TickingBlockEntity lithium$getSleepingTicker() { + return sleepingTicker; + } + + @Override + public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) { + this.sleepingTicker = sleepingTicker; + } + + @Override + public void lithium$handleSetChanged() { + if (this.isSleeping() && this.level != null && !this.level.isClientSide) { + this.wakeUpNow(); + } + } + // DivineMC end - lithium: block_entity_ticking.sleeping protected AbstractFurnaceBlockEntity(BlockEntityType type, BlockPos pos, BlockState blockState, RecipeType recipeType) { super(type, pos, blockState); @@ -167,6 +199,11 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit this.cookSpeedMultiplier = tag.getDouble("Paper.CookSpeedMultiplier"); } // Paper end - cook speed multiplier API + // DivineMC start - lithium: block_entity_ticking.sleeping + if (this.isSleeping() && this.level != null && !this.level.isClientSide) { + this.wakeUpNow(); + } + // DivineMC end - lithium: block_entity_ticking.sleeping } @Override @@ -291,7 +328,16 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit } if (usedLavaFromUnderneath) furnace.items.set(1, ItemStack.EMPTY); // Purpur - Furnace uses lava from underneath + furnace.checkSleep(state); // DivineMC - lithium: block_entity_ticking.sleeping + } + + // DivineMC start - lithium: block_entity_ticking.sleeping + private void checkSleep(BlockState state) { + if (!this.isLit() && this.cookingTimer == 0 && (state.is(Blocks.FURNACE) || state.is(Blocks.BLAST_FURNACE) || state.is(Blocks.SMOKER)) && this.level != null) { + this.lithium$startSleeping(); + } } + // DivineMC end - lithium: block_entity_ticking.sleeping private static boolean canBurn( RegistryAccess registryAccess, diff --git a/net/minecraft/world/level/block/entity/BlockEntity.java b/net/minecraft/world/level/block/entity/BlockEntity.java index 3fd0f42618e5c2c683335d1d3e0bb74c6d32ef66..5e0dbe39c8df0147a067b775455f3b73b2906363 100644 --- a/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/net/minecraft/world/level/block/entity/BlockEntity.java @@ -39,6 +39,7 @@ public abstract class BlockEntity { protected boolean remove; private BlockState blockState; private DataComponentMap components = DataComponentMap.EMPTY; + public void lithium$handleSetChanged() { } // DivineMC - lithium: block_entity_ticking.sleeping public BlockEntity(BlockEntityType type, BlockPos pos, BlockState blockState) { this.type = type; diff --git a/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java index 94f9477e78600eded6eecc4c961576501001d187..3c82874cc490bc8e29bb44abcc4b0893cfebf00b 100644 --- a/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java @@ -24,7 +24,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.BrewingStandBlock; import net.minecraft.world.level.block.state.BlockState; -public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements WorldlyContainer { +public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements WorldlyContainer, net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity { // DivineMC - lithium: block_entity_ticking.sleeping private static final int INGREDIENT_SLOT = 3; private static final int FUEL_SLOT = 4; private static final int[] SLOTS_FOR_UP = new int[]{3}; @@ -40,6 +40,44 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements private boolean[] lastPotionCount; private Item ingredient; public int fuel; + // DivineMC start - lithium: block_entity_ticking.sleeping + private net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper = null; + private TickingBlockEntity sleepingTicker = null; + + @Override + public net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper lithium$getTickWrapper() { + return tickWrapper; + } + + @Override + public void lithium$setTickWrapper(net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper) { + this.tickWrapper = tickWrapper; + this.lithium$setSleepingTicker(null); + } + + @Override + public TickingBlockEntity lithium$getSleepingTicker() { + return sleepingTicker; + } + + @Override + public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) { + this.sleepingTicker = sleepingTicker; + } + + private void checkSleep(BlockState state) { + if (this.brewTime == 0 && state.is(net.minecraft.world.level.block.Blocks.BREWING_STAND) && this.level != null) { + this.lithium$startSleeping(); + } + } + + @Override + public void lithium$handleSetChanged() { + if (this.isSleeping() && this.level != null && !this.level.isClientSide) { + this.wakeUpNow(); + } + } + // DivineMC end - lithium: block_entity_ticking.sleeping protected final ContainerData dataAccess = new ContainerData() { @Override public int get(int index) { @@ -128,6 +166,7 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements } public static void serverTick(Level level, BlockPos pos, BlockState state, BrewingStandBlockEntity blockEntity) { + blockEntity.checkSleep(state); // DivineMC - lithium: block_entity_ticking.sleeping ItemStack itemStack = blockEntity.items.get(4); if (blockEntity.fuel <= 0 && itemStack.is(ItemTags.BREWING_FUEL)) { // CraftBukkit start @@ -145,6 +184,7 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements itemStack.shrink(1); } // CraftBukkit end + blockEntity.wakeUpNow(); // DivineMC - lithium: block_entity_ticking.sleeping setChanged(level, pos, state); } @@ -160,6 +200,7 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements blockEntity.brewTime = 0; } + blockEntity.wakeUpNow(); // DivineMC - lithium: block_entity_ticking.sleeping setChanged(level, pos, state); } else if (isBrewable && blockEntity.fuel > 0) { blockEntity.fuel--; @@ -172,6 +213,7 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements blockEntity.brewTime = event.getBrewingTime(); // 400 -> event.getTotalBrewTime() // Paper - use brewing time from event // CraftBukkit end blockEntity.ingredient = itemStack1.getItem(); + blockEntity.wakeUpNow(); // DivineMC - lithium: block_entity_ticking.sleeping setChanged(level, pos, state); } @@ -278,6 +320,11 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements } this.fuel = tag.getByte("Fuel"); + // DivineMC start - lithium: block_entity_ticking.sleeping + if (this.isSleeping() && this.level != null && !this.level.isClientSide()) { + this.wakeUpNow(); + } + // DivineMC end - lithium: block_entity_ticking.sleeping } @Override diff --git a/net/minecraft/world/level/block/entity/CampfireBlockEntity.java b/net/minecraft/world/level/block/entity/CampfireBlockEntity.java index 2811ecb7624877b6b04896811f1d1626d716dad6..dcf92ac304c0d54c8371ce63eeb4942a67e3796e 100644 --- a/net/minecraft/world/level/block/entity/CampfireBlockEntity.java +++ b/net/minecraft/world/level/block/entity/CampfireBlockEntity.java @@ -30,13 +30,50 @@ import net.minecraft.world.level.block.CampfireBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.gameevent.GameEvent; -public class CampfireBlockEntity extends BlockEntity implements Clearable { +public class CampfireBlockEntity extends BlockEntity implements Clearable, net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity { // DivineMC - lithium: block_entity_ticking.sleeping private static final int BURN_COOL_SPEED = 2; private static final int NUM_SLOTS = 4; private final NonNullList items = NonNullList.withSize(4, ItemStack.EMPTY); public final int[] cookingProgress = new int[4]; public final int[] cookingTime = new int[4]; public final boolean[] stopCooking = new boolean[4]; // Paper - Add more Campfire API + // DivineMC start - lithium: block_entity_ticking.sleeping + private net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper = null; + private TickingBlockEntity sleepingTicker = null; + + @Override + public net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper lithium$getTickWrapper() { + return tickWrapper; + } + + @Override + public void lithium$setTickWrapper(net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper) { + this.tickWrapper = tickWrapper; + this.lithium$setSleepingTicker(null); + } + + @Override + public TickingBlockEntity lithium$getSleepingTicker() { + return sleepingTicker; + } + + @Override + public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) { + this.sleepingTicker = sleepingTicker; + } + + private static void trySleepLit(CampfireBlockEntity campfireBlockEntity, boolean bl) { + if (!bl) { + campfireBlockEntity.lithium$startSleeping(); + } + } + + private static void trySleepUnlit(CampfireBlockEntity campfire, boolean hadProgress) { + if (!hadProgress) { + campfire.lithium$startSleeping(); + } + } + // DivineMC end - lithium: block_entity_ticking.sleeping public CampfireBlockEntity(BlockPos pos, BlockState blockState) { super(BlockEntityType.CAMPFIRE, pos, blockState); @@ -62,8 +99,14 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { SingleRecipeInput singleRecipeInput = new SingleRecipeInput(itemStack); // Paper start - add recipe to cook events final var optionalCookingRecipe = check.getRecipeFor(singleRecipeInput, level); + // DivineMC start - lithium: block_entity_ticking.sleeping + final boolean finalFlag = flag; ItemStack itemStack1 = optionalCookingRecipe - .map(recipe -> recipe.value().assemble(singleRecipeInput, level.registryAccess())) + .map(recipe -> { + trySleepLit(campfire, finalFlag); // Canvas + return recipe.value().assemble(singleRecipeInput, level.registryAccess()); + }) + // DivineMC end - lithium: block_entity_ticking.sleeping .orElse(itemStack); // Paper end - add recipe to cook events if (itemStack1.isItemEnabled(level.enabledFeatures())) { @@ -79,6 +122,7 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { ); if (!blockCookEvent.callEvent()) { + trySleepLit(campfire, flag); // DivineMC - lithium: block_entity_ticking.sleeping return; } @@ -104,6 +148,8 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { if (flag) { setChanged(level, pos, state); } + + trySleepLit(campfire, flag); // DivineMC - lithium: block_entity_ticking.sleeping } public static void cooldownTick(Level level, BlockPos pos, BlockState state, CampfireBlockEntity blockEntity) { @@ -119,6 +165,8 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { if (flag) { setChanged(level, pos, state); } + + trySleepUnlit(blockEntity, flag); // DivineMC - lithium: block_entity_ticking.sleeping } public static void particleTick(Level level, BlockPos pos, BlockState state, CampfireBlockEntity blockEntity) { @@ -175,6 +223,8 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { System.arraycopy(cookingState, 0, this.stopCooking, 0, Math.min(this.stopCooking.length, abyte.length)); } // Paper end - Add more Campfire API + + this.wakeUpNow(); // DivineMC - lithium: block_entity_ticking.sleeping } @Override @@ -224,6 +274,7 @@ public class CampfireBlockEntity extends BlockEntity implements Clearable { this.cookingTime[i] = event.getTotalCookTime(); // i -> event.getTotalCookTime() // CraftBukkit end this.cookingProgress[i] = 0; + this.wakeUpNow(); // DivineMC - lithium: block_entity_ticking.sleeping this.items.set(i, stack.consumeAndReturn(1, entity)); level.gameEvent(GameEvent.BLOCK_CHANGE, this.getBlockPos(), GameEvent.Context.of(entity, this.getBlockState())); this.markUpdated(); diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java index a0ee6ad6e7a6791605191d20d742e16cc9857a60..627af05bbfc3ed60fb22bfeb1b7c79c09cf4f442 100644 --- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -28,7 +28,7 @@ import net.minecraft.world.level.block.HopperBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.AABB; -public class HopperBlockEntity extends RandomizableContainerBlockEntity implements Hopper { +public class HopperBlockEntity extends RandomizableContainerBlockEntity implements Hopper, net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity { // DivineMC - lithium: block_entity_ticking.sleeping public static final int MOVE_ITEM_SPEED = 8; public static final int HOPPER_CONTAINER_SIZE = 5; private static final int[][] CACHED_SLOTS = new int[54][]; @@ -36,6 +36,51 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen public int cooldownTime = -1; private long tickedGameTime; private Direction facing; + // DivineMC start - lithium: block_entity_ticking.sleeping + private net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper = null; + private TickingBlockEntity sleepingTicker = null; + + @Override + public net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper lithium$getTickWrapper() { + return tickWrapper; + } + + @Override + public void lithium$setTickWrapper(net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper) { + this.tickWrapper = tickWrapper; + this.lithium$setSleepingTicker(null); + } + + @Override + public TickingBlockEntity lithium$getSleepingTicker() { + return sleepingTicker; + } + + @Override + public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) { + this.sleepingTicker = sleepingTicker; + } + + @Override + public boolean lithium$startSleeping() { + if (this.isSleeping()) { + return false; + } + + net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper = this.lithium$getTickWrapper(); + if (tickWrapper != null) { + this.lithium$setSleepingTicker(tickWrapper.ticker); + tickWrapper.rebind(net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity.SLEEPING_BLOCK_ENTITY_TICKER); + + // Set the last tick time to max value, so other hoppers transferring into this hopper will set it to 7gt + // cooldown. Then when waking up, we make sure to not tick this hopper in the same gametick. + // This makes the observable hopper cooldown not be different from vanilla. + this.tickedGameTime = Long.MAX_VALUE; + return true; + } + return false; + } + // DivineMC end - lithium: block_entity_ticking.sleeping // CraftBukkit start - add fields and methods public List transaction = new java.util.ArrayList<>(); @@ -160,6 +205,14 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen } } + // DivineMC start - lithium: block_entity_ticking.sleeping + if (!(blockEntity).isOnCooldown() && + !(blockEntity).isSleeping() && + !state.getValue(HopperBlock.ENABLED)) { + (blockEntity).lithium$startSleeping(); + } + // DivineMC end - lithium: block_entity_ticking.sleeping + return false; } } @@ -586,6 +639,17 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen } public void setCooldown(int cooldownTime) { + // DivineMC start - lithium: block_entity_ticking.sleeping + if (cooldownTime == 7) { + if (this.tickedGameTime == Long.MAX_VALUE) { + this.sleepOnlyCurrentTick(); + } else { + this.wakeUpNow(); + } + } else if (cooldownTime > 0 && this.sleepingTicker != null) { + this.wakeUpNow(); + } + // DivineMC end - lithium: block_entity_ticking.sleeping this.cooldownTime = cooldownTime; } diff --git a/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java index a2ae4b47d742e7fb9809cfc4575517c06400ec61..e92863af578bb472a692482be3dddc1cc658f930 100644 --- a/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java +++ b/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java @@ -32,7 +32,7 @@ import net.minecraft.world.level.material.PushReaction; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; -public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity implements WorldlyContainer { +public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity implements WorldlyContainer, net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity { // DivineMC - lithium: block_entity_ticking.sleeping public static final int COLUMNS = 9; public static final int ROWS = 3; public static final int CONTAINER_SIZE = 27; @@ -48,6 +48,30 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl private float progressOld; @Nullable private final DyeColor color; + // DivineMC start - lithium: block_entity_ticking.sleeping + private net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper = null; + private TickingBlockEntity sleepingTicker = null; + + @Override + public net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper lithium$getTickWrapper() { + return tickWrapper; + } + + @Override + public void lithium$setTickWrapper(net.minecraft.world.level.chunk.LevelChunk.RebindableTickingBlockEntityWrapper tickWrapper) { + this.tickWrapper = tickWrapper; + } + + @Override + public TickingBlockEntity lithium$getSleepingTicker() { + return sleepingTicker; + } + + @Override + public void lithium$setSleepingTicker(TickingBlockEntity sleepingTicker) { + this.sleepingTicker = sleepingTicker; + } + // DivineMC end - lithium: block_entity_ticking.sleeping // CraftBukkit start - add fields and methods public List transaction = new java.util.ArrayList<>(); @@ -129,6 +153,12 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl doNeighborUpdates(level, pos, state); } } + + // DivineMC start - lithium: block_entity_ticking.sleeping + if (this.animationStatus == ShulkerBoxBlockEntity.AnimationStatus.CLOSED && this.progressOld == 0.0f && this.progress == 0.0f) { + this.lithium$startSleeping(); + } + // DivineMC end - lithium: block_entity_ticking.sleeping } public ShulkerBoxBlockEntity.AnimationStatus getAnimationStatus() { @@ -169,6 +199,7 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl @Override public boolean triggerEvent(int id, int type) { + if (this.sleepingTicker != null) this.wakeUpNow(); // DivineMC - lithium: block_entity_ticking.sleeping if (id == 1) { this.openCount = type; if (type == 0) { diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java index 1cdff5ee25e6ef66e6aae221e61eee7829b213ed..7a76396e7dedd886ce56dd6a578f6e64d8553abe 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java @@ -883,12 +883,22 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p (pos, ticker1) -> { TickingBlockEntity tickingBlockEntity = this.createTicker(blockEntity, ticker); if (ticker1 != null) { + // DivineMC start - lithium: block_entity_ticking.sleeping + if (blockEntity instanceof net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity sleepingBlockEntity) { + sleepingBlockEntity.lithium$setTickWrapper(ticker1); + } + // DivineMC end - lithium: block_entity_ticking.sleeping ticker1.rebind(tickingBlockEntity); return (LevelChunk.RebindableTickingBlockEntityWrapper)ticker1; } else if (this.isInLevel()) { LevelChunk.RebindableTickingBlockEntityWrapper rebindableTickingBlockEntityWrapper = new LevelChunk.RebindableTickingBlockEntityWrapper( tickingBlockEntity ); + // DivineMC start - lithium: block_entity_ticking.sleeping + if (blockEntity instanceof net.caffeinemc.mods.lithium.common.block.entity.SleepingBlockEntity sleepingBlockEntity) { + sleepingBlockEntity.lithium$setTickWrapper(rebindableTickingBlockEntityWrapper); + } + // DivineMC end - lithium: block_entity_ticking.sleeping this.level.addBlockEntityTicker(rebindableTickingBlockEntityWrapper); return rebindableTickingBlockEntityWrapper; } else {