diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch index cced43f51..bb40e18cf 100644 --- a/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch +++ b/purpur-server/minecraft-patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -109,6 +109,45 @@ skeletonHorse.setAge(0); skeletonHorse.setPos(blockPos.getX(), blockPos.getY(), blockPos.getZ()); this.addFreshEntity(skeletonHorse, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); // CraftBukkit +@@ -986,9 +_,35 @@ + if (blockState.is(Blocks.SNOW)) { + int layersValue = blockState.getValue(SnowLayerBlock.LAYERS); + if (layersValue < Math.min(_int, 8)) { +- BlockState blockState1 = blockState.setValue(SnowLayerBlock.LAYERS, Integer.valueOf(layersValue + 1)); +- Block.pushEntitiesUp(blockState, blockState1, this, heightmapPos); +- org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, heightmapPos, blockState1, null); // CraftBukkit ++ // Purpur start - Smooth snow accumulation ++ boolean canSnow = true; ++ // Ensure snow doesn't get more than N layers taller than its neighbors ++ // We only need to check blocks that are taller than the minimum step height ++ if (layersValue >= org.purpurmc.purpur.PurpurConfig.smoothSnowAccumulationStep && org.purpurmc.purpur.PurpurConfig.smoothSnowAccumulationStep > 0) { ++ int layersValueMin = layersValue - org.purpurmc.purpur.PurpurConfig.smoothSnowAccumulationStep; ++ for (Direction direction : Direction.Plane.HORIZONTAL) { ++ BlockPos blockPosNeighbor = heightmapPos.relative(direction); ++ BlockState blockStateNeighbor = this.getBlockState(blockPosNeighbor); ++ if (blockStateNeighbor.is(Blocks.SNOW)) { ++ // Special check for snow layers, if neighbors are too short, don't accumulate ++ int layersValueNeighbor = blockStateNeighbor.getValue(SnowLayerBlock.LAYERS); ++ if (layersValueNeighbor <= layersValueMin) { ++ canSnow = false; ++ break; ++ } ++ } else if (!Block.isFaceFull(blockStateNeighbor.getCollisionShape(this, blockPosNeighbor), direction.getOpposite())) { ++ // Since our layer is tall enough already, if we have a non-full neighbor block, don't accumulate ++ canSnow = false; ++ break; ++ } ++ } ++ } ++ if (canSnow) { ++ BlockState blockState1 = blockState.setValue(SnowLayerBlock.LAYERS, Integer.valueOf(layersValue + 1)); ++ Block.pushEntitiesUp(blockState, blockState1, this, heightmapPos); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, heightmapPos, blockState1, null); // CraftBukkit ++ } ++ // Purpur end - Smooth snow accumulation + } + } else { + org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, heightmapPos, Blocks.SNOW.defaultBlockState(), null); // CraftBukkit @@ -1009,7 +_,7 @@ pointOfInterestType -> pointOfInterestType.is(PoiTypes.LIGHTNING_ROD), blockPos -> blockPos.getY() == this.getHeight(Heightmap.Types.WORLD_SURFACE, blockPos.getX(), blockPos.getZ()) - 1, diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java index c4cce5eb0..338154a80 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java @@ -332,6 +332,7 @@ public class PurpurConfig { public static boolean cryingObsidianValidForPortalFrame = false; public static int beeInsideBeeHive = 3; public static boolean anvilCumulativeCost = true; + public static int smoothSnowAccumulationStep = 0; public static int lightningRodRange = 128; public static Set grindstoneIgnoredEnchants = new HashSet<>(); public static boolean grindstoneRemoveAttributes = false; @@ -375,6 +376,16 @@ public class PurpurConfig { cryingObsidianValidForPortalFrame = getBoolean("settings.blocks.crying_obsidian.valid-for-portal-frame", cryingObsidianValidForPortalFrame); beeInsideBeeHive = getInt("settings.blocks.beehive.max-bees-inside", beeInsideBeeHive); anvilCumulativeCost = getBoolean("settings.blocks.anvil.cumulative-cost", anvilCumulativeCost); + smoothSnowAccumulationStep = getInt("settings.blocks.snow.smooth-accumulation-step", smoothSnowAccumulationStep); + if (smoothSnowAccumulationStep > 7) { + smoothSnowAccumulationStep = 7; + log(Level.WARNING, "blocks.snow.smooth-accumulation-step is set to above maximum allowed value of 7"); + log(Level.WARNING, "Using value of 7 to prevent issues"); + } else if (smoothSnowAccumulationStep < 0) { + smoothSnowAccumulationStep = 0; + log(Level.WARNING, "blocks.snow.smooth-accumulation-step is set to below minimum allowed value of 0"); + log(Level.WARNING, "Using value of 0 to prevent issues"); + } lightningRodRange = getInt("settings.blocks.lightning_rod.range", lightningRodRange); ArrayList defaultCurses = new ArrayList<>(){{ add("minecraft:binding_curse");