c5a10665b8
Spigot still maintains some partial implementation of "tick skipping", a practice in which the MinecraftServer.currentTick field is updated not by an increment of one per actual tick, but instead set to System.currentTimeMillis() / 50. This behaviour means that the tracked tick may "skip" a tick value in case a previous tick took more than the expected 50ms. To compensate for this in important paths, spigot/craftbukkit implements "wall-time". Instead of incrementing/decrementing ticks on block entities/entities by one for each call to their tick() method, they instead increment/decrement important values, like an ItemEntity's age or pickupDelay, by the difference of `currentTick - lastTick`, where `lastTick` is the value of `currentTick` during the last tick() call. These "fixes" however do not play nicely with minecraft's simulation distance as entities/block entities implementing the above behaviour would "catch up" their values when moving from a non-ticking chunk to a ticking one as their `lastTick` value remains stuck on the last tick in a ticking chunk and hence lead to a large "catch up" once ticked again. Paper completely removes the "tick skipping" behaviour (See patch "Further-improve-server-tick-loop"), making the above precautions completely unnecessary, which also rids paper of the previous described incompatibility with non-ticking chunks.
123 Zeilen
8.9 KiB
Diff
123 Zeilen
8.9 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
|
Date: Tue, 29 Mar 2022 13:46:23 -0700
|
|
Subject: [PATCH] Fire CauldronLevelChange on initial fill
|
|
|
|
Also don't fire level events or game events if stalactite
|
|
drip is cancelled
|
|
|
|
diff --git a/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java b/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java
|
|
index 9ebd5310ee358acd83123a30415d9f7eb6aa36d9..f301c20e808b77cb3fcffd9a7c8102928306456e 100644
|
|
--- a/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java
|
|
+++ b/src/main/java/net/minecraft/core/cauldron/CauldronInteraction.java
|
|
@@ -81,7 +81,7 @@ public interface CauldronInteraction {
|
|
if (potioncontents != null && potioncontents.is(Potions.WATER)) {
|
|
if (!world.isClientSide) {
|
|
// CraftBukkit start
|
|
- if (!LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, Blocks.WATER_CAULDRON.defaultBlockState(), entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY)) {
|
|
+ if (!LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, Blocks.WATER_CAULDRON.defaultBlockState(), entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY, false)) { // Paper - Call CauldronLevelChangeEvent
|
|
return ItemInteractionResult.SUCCESS;
|
|
}
|
|
// CraftBukkit end
|
|
@@ -136,7 +136,7 @@ public interface CauldronInteraction {
|
|
if (potioncontents != null && potioncontents.is(Potions.WATER)) {
|
|
if (!world.isClientSide) {
|
|
// CraftBukkit start
|
|
- if (!LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, iblockdata.cycle(LayeredCauldronBlock.LEVEL), entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY)) {
|
|
+ if (!LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, iblockdata.cycle(LayeredCauldronBlock.LEVEL), entityhuman, CauldronLevelChangeEvent.ChangeReason.BOTTLE_EMPTY, false)) { // Paper - Call CauldronLevelChangeEvent
|
|
return ItemInteractionResult.SUCCESS;
|
|
}
|
|
// CraftBukkit end
|
|
@@ -222,7 +222,7 @@ public interface CauldronInteraction {
|
|
} else {
|
|
if (!world.isClientSide) {
|
|
// CraftBukkit start
|
|
- if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.CAULDRON.defaultBlockState(), player, CauldronLevelChangeEvent.ChangeReason.BUCKET_FILL)) {
|
|
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.CAULDRON.defaultBlockState(), player, CauldronLevelChangeEvent.ChangeReason.BUCKET_FILL, false)) { // Paper - Call CauldronLevelChangeEvent
|
|
return ItemInteractionResult.SUCCESS;
|
|
}
|
|
// CraftBukkit end
|
|
@@ -243,7 +243,7 @@ public interface CauldronInteraction {
|
|
static ItemInteractionResult emptyBucket(Level world, BlockPos pos, Player player, InteractionHand hand, ItemStack stack, BlockState state, SoundEvent soundEvent) {
|
|
if (!world.isClientSide) {
|
|
// CraftBukkit start
|
|
- if (!LayeredCauldronBlock.changeLevel(state, world, pos, state, player, CauldronLevelChangeEvent.ChangeReason.BUCKET_EMPTY)) {
|
|
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, state, player, CauldronLevelChangeEvent.ChangeReason.BUCKET_EMPTY, false)) { // Paper - Call CauldronLevelChangeEvent
|
|
return ItemInteractionResult.SUCCESS;
|
|
}
|
|
// CraftBukkit end
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/CauldronBlock.java b/src/main/java/net/minecraft/world/level/block/CauldronBlock.java
|
|
index 8d5ad9848d9652b4fd7179c425c47a683ee169ef..c9968934f4ecaa8d81e545f279b3001c7b1ce545 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/CauldronBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/CauldronBlock.java
|
|
@@ -44,9 +44,19 @@ public class CauldronBlock extends AbstractCauldronBlock {
|
|
public void handlePrecipitation(BlockState state, Level world, BlockPos pos, Biome.Precipitation precipitation) {
|
|
if (CauldronBlock.shouldHandlePrecipitation(world, precipitation)) {
|
|
if (precipitation == Biome.Precipitation.RAIN) {
|
|
+ // Paper start - Call CauldronLevelChangeEvent
|
|
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.WATER_CAULDRON.defaultBlockState(), null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL, false)) { // avoid duplicate game event
|
|
+ return;
|
|
+ }
|
|
+ // Paper end - Call CauldronLevelChangeEvent
|
|
world.setBlockAndUpdate(pos, Blocks.WATER_CAULDRON.defaultBlockState());
|
|
world.gameEvent((Entity) null, (Holder) GameEvent.BLOCK_CHANGE, pos);
|
|
} else if (precipitation == Biome.Precipitation.SNOW) {
|
|
+ // Paper start - Call CauldronLevelChangeEvent
|
|
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.POWDER_SNOW_CAULDRON.defaultBlockState(), null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL, false)) { // avoid duplicate game event
|
|
+ return;
|
|
+ }
|
|
+ // Paper end - Call CauldronLevelChangeEvent
|
|
world.setBlockAndUpdate(pos, Blocks.POWDER_SNOW_CAULDRON.defaultBlockState());
|
|
world.gameEvent((Entity) null, (Holder) GameEvent.BLOCK_CHANGE, pos);
|
|
}
|
|
@@ -65,11 +75,19 @@ public class CauldronBlock extends AbstractCauldronBlock {
|
|
|
|
if (fluid == Fluids.WATER) {
|
|
iblockdata1 = Blocks.WATER_CAULDRON.defaultBlockState();
|
|
- LayeredCauldronBlock.changeLevel(state, world, pos, iblockdata1, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL); // CraftBukkit
|
|
+ // Paper start - Call CauldronLevelChangeEvent; don't send level event or game event if cancelled
|
|
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, iblockdata1, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) { // CraftBukkit
|
|
+ return;
|
|
+ }
|
|
+ // Paper end - Call CauldronLevelChangeEvent
|
|
world.levelEvent(1047, pos, 0);
|
|
} else if (fluid == Fluids.LAVA) {
|
|
iblockdata1 = Blocks.LAVA_CAULDRON.defaultBlockState();
|
|
- LayeredCauldronBlock.changeLevel(state, world, pos, iblockdata1, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL); // CraftBukkit
|
|
+ // Paper start - Call CauldronLevelChangeEvent; don't send level event or game event if cancelled
|
|
+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, iblockdata1, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) { // CraftBukkit
|
|
+ return;
|
|
+ }
|
|
+ // Paper end - Call CauldronLevelChangeEvent
|
|
world.levelEvent(1046, pos, 0);
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
|
|
index 7c67efa6e344870b764eb39d5508190349e2e911..b222ac8e5b966c515be2aca86083f5640853cd29 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
|
|
@@ -102,7 +102,13 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
|
|
}
|
|
|
|
// CraftBukkit start
|
|
- public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, Entity entity, CauldronLevelChangeEvent.ChangeReason reason) {
|
|
+ // Paper start - Call CauldronLevelChangeEvent
|
|
+ public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, @javax.annotation.Nullable Entity entity, CauldronLevelChangeEvent.ChangeReason reason) { // Paper - entity is nullable
|
|
+ return changeLevel(iblockdata, world, blockposition, newBlock, entity, reason, true);
|
|
+ }
|
|
+
|
|
+ public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, @javax.annotation.Nullable Entity entity, CauldronLevelChangeEvent.ChangeReason reason, boolean sendGameEvent) { // Paper - entity is nullable
|
|
+ // Paper end - Call CauldronLevelChangeEvent
|
|
CraftBlockState newState = CraftBlockStates.getBlockState(world, blockposition);
|
|
newState.setData(newBlock);
|
|
|
|
@@ -115,7 +121,7 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
|
|
return false;
|
|
}
|
|
newState.update(true);
|
|
- world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(newBlock));
|
|
+ if (sendGameEvent) world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(newBlock)); // Paper - Call CauldronLevelChangeEvent
|
|
return true;
|
|
}
|
|
// CraftBukkit end
|