diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7454180f2..7f93135c4 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/patches/api/0006-Add-World-Instance-flag.patch b/patches/api/0006-Add-World-Instance-flag.patch index 5ab133729..aa23a16c5 100644 --- a/patches/api/0006-Add-World-Instance-flag.patch +++ b/patches/api/0006-Add-World-Instance-flag.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add World Instance flag diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 17d404d6d1a5b46b58d612fca38f17e71adee92e..8542f193fe7be07d47b26dd0434965f2c3cd1be9 100644 +index d3081d4445af73c2c7b23c5fc60861f184ac808e..415a137775f072d1aefa841b01b6bf7a5f97b6a3 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java -@@ -2664,6 +2664,11 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient +@@ -2663,6 +2663,11 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient */ public void setAutoSave(boolean value); diff --git a/patches/api/0010-Smooth-Teleports.patch b/patches/api/0010-Smooth-Teleports.patch index 504eddd08..2574d7dc8 100644 --- a/patches/api/0010-Smooth-Teleports.patch +++ b/patches/api/0010-Smooth-Teleports.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Smooth Teleports diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 087898a50909a40aabec09f1e52cefed6565ba4c..1ca7b2800dc57e4b617d8225e9c18f30952b993e 100644 +index ae61a39b25267b84fe0b8766e4b12d9b24b44ded..3a7d0900e7802c40377086ba8acec5a3f90a340d 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3169,6 +3169,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3437,6 +3437,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM String getClientBrandName(); // Paper end diff --git a/patches/api/0011-AntiXray-Bypass.patch b/patches/api/0011-AntiXray-Bypass.patch index 4d2889307..f996664df 100644 --- a/patches/api/0011-AntiXray-Bypass.patch +++ b/patches/api/0011-AntiXray-Bypass.patch @@ -5,17 +5,17 @@ Subject: [PATCH] AntiXray Bypass diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index d422017c54d49a5a6aaa5226162cb152c20183a9..702a1b611bb107ea134830446ee748ebf6328bca 100644 +index 3a7d0900e7802c40377086ba8acec5a3f90a340d..cd21d9a16b8d50d2cc3b13fa3621a6aa3a859955 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -2952,6 +2952,10 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -2949,6 +2949,10 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ - boolean hasResourcePack(); + public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ, double extra); + // Slice start + void toggleAntiXrayBypass(boolean bypass); + // Slice end + /** - * Gets a copy of this players profile - * @return The players profile object + * Spawns the particle (the number of times specified by count) + * at the target location. The position of each particle will be diff --git a/patches/api/0012-Add-PlayerPreChunkLoadEvent.patch b/patches/api/0012-Add-PlayerPreChunkLoadEvent.patch index b1400d43f..8c3151c68 100644 --- a/patches/api/0012-Add-PlayerPreChunkLoadEvent.patch +++ b/patches/api/0012-Add-PlayerPreChunkLoadEvent.patch @@ -81,10 +81,10 @@ index 0000000000000000000000000000000000000000..b5cc9538a70c7ce0b494d4878d51b521 +} \ No newline at end of file diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 8542f193fe7be07d47b26dd0434965f2c3cd1be9..ba2bc145caf408a81d6f7a69479298628ebf0cf0 100644 +index 415a137775f072d1aefa841b01b6bf7a5f97b6a3..ffd89e5e2039c0f1662236db112bbf25eabb0a17 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java -@@ -501,6 +501,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient +@@ -525,6 +525,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient //@Deprecated // Paper public boolean refreshChunk(int x, int z); diff --git a/patches/api/0013-Equipment-Packet-Caching.patch b/patches/api/0013-Equipment-Packet-Caching.patch index 29492e602..28ca9e6ba 100644 --- a/patches/api/0013-Equipment-Packet-Caching.patch +++ b/patches/api/0013-Equipment-Packet-Caching.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Equipment Packet Caching diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java -index 19e58e62ae442ef9be02ca7fa2f55e370a54afa4..94aafbc3a08dec7c66cef89de7a5283049a4bf05 100644 +index e68c71047b2bc1b456c380db25b3ff376852b4a9..181e605e97e3bdda119144ccc0413740cdfd6ee7 100644 --- a/src/main/java/org/bukkit/entity/LivingEntity.java +++ b/src/main/java/org/bukkit/entity/LivingEntity.java -@@ -1192,4 +1192,11 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource +@@ -1270,4 +1270,11 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource */ void setBodyYaw(float bodyYaw); // Paper end diff --git a/patches/api/0021-Non-saveable-entities.patch b/patches/api/0021-Non-saveable-entities.patch new file mode 100644 index 000000000..f8c44c990 --- /dev/null +++ b/patches/api/0021-Non-saveable-entities.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Cryptite +Date: Thu, 28 Dec 2023 09:11:49 -0600 +Subject: [PATCH] Non-saveable-entities + + +diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java +index 1d0fd7ff8449f815a7d980af0b378181ea8bf8d8..0b057d6be0d55c275867bd1cb98387bc3237d881 100644 +--- a/src/main/java/org/bukkit/entity/Entity.java ++++ b/src/main/java/org/bukkit/entity/Entity.java +@@ -1107,4 +1107,19 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent + */ + @NotNull String getScoreboardEntryName(); + // Paper end - entity scoreboard name ++ ++ // Slice start ++ /** ++ * Returns true if the entity can be saved. If false, the entity will never be serialized or saved. ++ */ ++ boolean isSaveable(); ++ ++ /** ++ * Sets whether the entity can be serialized and saved to disk. ++ * ++ * @param saveable the saveable status ++ * @see #isSaveable() ++ */ ++ void setSaveable(boolean saveable); ++ // Slice end + } diff --git a/patches/server/0001-Initial.patch b/patches/server/0001-Initial.patch new file mode 100644 index 000000000..e6434cc11 --- /dev/null +++ b/patches/server/0001-Initial.patch @@ -0,0 +1,2936 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Initial Source +Date: Thu, 28 Dec 2023 09:38:04 -0600 +Subject: [PATCH] Initial + + +diff --git a/src/main/java/net/minecraft/data/worldgen/BiomeDefaultFeatures.java b/src/main/java/net/minecraft/data/worldgen/BiomeDefaultFeatures.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b9b7d2e668d9f7f36ac3cf1e1716460c4ad5ed3a +--- /dev/null ++++ b/src/main/java/net/minecraft/data/worldgen/BiomeDefaultFeatures.java +@@ -0,0 +1,486 @@ ++package net.minecraft.data.worldgen; ++ ++import net.minecraft.data.worldgen.placement.AquaticPlacements; ++import net.minecraft.data.worldgen.placement.CavePlacements; ++import net.minecraft.data.worldgen.placement.MiscOverworldPlacements; ++import net.minecraft.data.worldgen.placement.OrePlacements; ++import net.minecraft.data.worldgen.placement.VegetationPlacements; ++import net.minecraft.world.entity.EntityType; ++import net.minecraft.world.entity.MobCategory; ++import net.minecraft.world.level.biome.BiomeGenerationSettings; ++import net.minecraft.world.level.biome.MobSpawnSettings; ++import net.minecraft.world.level.levelgen.GenerationStep; ++ ++public class BiomeDefaultFeatures { ++ public static void addDefaultCarversAndLakes(BiomeGenerationSettings.Builder builder) { ++ builder.addCarver(GenerationStep.Carving.AIR, Carvers.CAVE); ++ builder.addCarver(GenerationStep.Carving.AIR, Carvers.CAVE_EXTRA_UNDERGROUND); ++ builder.addCarver(GenerationStep.Carving.AIR, Carvers.CANYON); ++ builder.addFeature(GenerationStep.Decoration.LAKES, MiscOverworldPlacements.LAKE_LAVA_UNDERGROUND); ++ builder.addFeature(GenerationStep.Decoration.LAKES, MiscOverworldPlacements.LAKE_LAVA_SURFACE); ++ } ++ ++ public static void addDefaultMonsterRoom(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_STRUCTURES, CavePlacements.MONSTER_ROOM); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_STRUCTURES, CavePlacements.MONSTER_ROOM_DEEP); ++ } ++ ++ public static void addDefaultUndergroundVariety(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_DIRT); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_GRAVEL); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_GRANITE_UPPER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_GRANITE_LOWER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_DIORITE_UPPER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_DIORITE_LOWER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_ANDESITE_UPPER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_ANDESITE_LOWER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_TUFF); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, CavePlacements.GLOW_LICHEN); ++ } ++ ++ public static void addDripstone(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.LOCAL_MODIFICATIONS, CavePlacements.LARGE_DRIPSTONE); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_DECORATION, CavePlacements.DRIPSTONE_CLUSTER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_DECORATION, CavePlacements.POINTED_DRIPSTONE); ++ } ++ ++ public static void addSculk(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_DECORATION, CavePlacements.SCULK_VEIN); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_DECORATION, CavePlacements.SCULK_PATCH_DEEP_DARK); ++ } ++ ++ public static void addDefaultOres(BiomeGenerationSettings.Builder builder) { ++ addDefaultOres(builder, false); ++ } ++ ++ public static void addDefaultOres(BiomeGenerationSettings.Builder builder, boolean largeCopperOreBlob) { ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_COAL_UPPER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_COAL_LOWER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_IRON_UPPER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_IRON_MIDDLE); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_IRON_SMALL); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_GOLD); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_GOLD_LOWER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_REDSTONE); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_REDSTONE_LOWER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_DIAMOND); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_DIAMOND_MEDIUM); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_DIAMOND_LARGE); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_DIAMOND_BURIED); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_LAPIS); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_LAPIS_BURIED); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, largeCopperOreBlob ? OrePlacements.ORE_COPPER_LARGE : OrePlacements.ORE_COPPER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, CavePlacements.UNDERWATER_MAGMA); ++ } ++ ++ public static void addExtraGold(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_GOLD_EXTRA); ++ } ++ ++ public static void addExtraEmeralds(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_EMERALD); ++ } ++ ++ public static void addInfestedStone(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_DECORATION, OrePlacements.ORE_INFESTED); ++ } ++ ++ public static void addDefaultSoftDisks(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, MiscOverworldPlacements.DISK_SAND); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, MiscOverworldPlacements.DISK_CLAY); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, MiscOverworldPlacements.DISK_GRAVEL); ++ } ++ ++ public static void addSwampClayDisk(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, MiscOverworldPlacements.DISK_CLAY); ++ } ++ ++ public static void addMangroveSwampDisks(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, MiscOverworldPlacements.DISK_GRASS); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, MiscOverworldPlacements.DISK_CLAY); ++ } ++ ++ public static void addMossyStoneBlock(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.LOCAL_MODIFICATIONS, MiscOverworldPlacements.FOREST_ROCK); ++ } ++ ++ public static void addFerns(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_LARGE_FERN); ++ } ++ ++ public static void addRareBerryBushes(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_BERRY_RARE); ++ } ++ ++ public static void addCommonBerryBushes(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_BERRY_COMMON); ++ } ++ ++ public static void addLightBambooVegetation(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.BAMBOO_LIGHT); ++ } ++ ++ public static void addBambooVegetation(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.BAMBOO); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.BAMBOO_VEGETATION); ++ } ++ ++ public static void addTaigaTrees(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_TAIGA); ++ } ++ ++ public static void addGroveTrees(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_GROVE); ++ } ++ ++ public static void addWaterTrees(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_WATER); ++ } ++ ++ public static void addBirchTrees(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_BIRCH); ++ } ++ ++ public static void addOtherBirchTrees(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_BIRCH_AND_OAK); ++ } ++ ++ public static void addTallBirchTrees(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.BIRCH_TALL); ++ } ++ ++ public static void addSavannaTrees(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_SAVANNA); ++ } ++ ++ public static void addShatteredSavannaTrees(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_WINDSWEPT_SAVANNA); ++ } ++ ++ public static void addLushCavesVegetationFeatures(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, CavePlacements.LUSH_CAVES_CEILING_VEGETATION); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, CavePlacements.CAVE_VINES); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, CavePlacements.LUSH_CAVES_CLAY); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, CavePlacements.LUSH_CAVES_VEGETATION); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, CavePlacements.ROOTED_AZALEA_TREE); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, CavePlacements.SPORE_BLOSSOM); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, CavePlacements.CLASSIC_VINES); ++ } ++ ++ public static void addLushCavesSpecialOres(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, OrePlacements.ORE_CLAY); ++ } ++ ++ public static void addMountainTrees(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_WINDSWEPT_HILLS); ++ } ++ ++ public static void addMountainForestTrees(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_WINDSWEPT_FOREST); ++ } ++ ++ public static void addJungleTrees(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_JUNGLE); ++ } ++ ++ public static void addSparseJungleTrees(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_SPARSE_JUNGLE); ++ } ++ ++ public static void addBadlandsTrees(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_BADLANDS); ++ } ++ ++ public static void addSnowyTrees(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_SNOWY); ++ } ++ ++ public static void addJungleGrass(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_JUNGLE); ++ } ++ ++ public static void addSavannaGrass(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_TALL_GRASS); ++ } ++ ++ public static void addShatteredSavannaGrass(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_NORMAL); ++ } ++ ++ public static void addSavannaExtraGrass(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_SAVANNA); ++ } ++ ++ public static void addBadlandGrass(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_BADLANDS); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_DEAD_BUSH_BADLANDS); ++ } ++ ++ public static void addForestFlowers(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.FOREST_FLOWERS); ++ } ++ ++ public static void addForestGrass(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_FOREST); ++ } ++ ++ public static void addSwampVegetation(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_SWAMP); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.FLOWER_SWAMP); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_NORMAL); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_DEAD_BUSH); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_WATERLILY); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.BROWN_MUSHROOM_SWAMP); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.RED_MUSHROOM_SWAMP); ++ } ++ ++ public static void addMangroveSwampVegetation(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_MANGROVE); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_NORMAL); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_DEAD_BUSH); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_WATERLILY); ++ } ++ ++ public static void addMushroomFieldVegetation(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.MUSHROOM_ISLAND_VEGETATION); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.BROWN_MUSHROOM_TAIGA); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.RED_MUSHROOM_TAIGA); ++ } ++ ++ public static void addPlainVegetation(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_PLAINS); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.FLOWER_PLAINS); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_PLAIN); ++ } ++ ++ public static void addDesertVegetation(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_DEAD_BUSH_2); ++ } ++ ++ public static void addGiantTaigaVegetation(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_TAIGA); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_DEAD_BUSH); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.BROWN_MUSHROOM_OLD_GROWTH); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.RED_MUSHROOM_OLD_GROWTH); ++ } ++ ++ public static void addDefaultFlowers(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.FLOWER_DEFAULT); ++ } ++ ++ public static void addCherryGroveVegetation(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_PLAIN); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.FLOWER_CHERRY); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_CHERRY); ++ } ++ ++ public static void addMeadowVegetation(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_PLAIN); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.FLOWER_MEADOW); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_MEADOW); ++ } ++ ++ public static void addWarmFlowers(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.FLOWER_WARM); ++ } ++ ++ public static void addDefaultGrass(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_BADLANDS); ++ } ++ ++ public static void addTaigaGrass(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_GRASS_TAIGA_2); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.BROWN_MUSHROOM_TAIGA); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.RED_MUSHROOM_TAIGA); ++ } ++ ++ public static void addPlainGrass(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_TALL_GRASS_2); ++ } ++ ++ public static void addDefaultMushrooms(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.BROWN_MUSHROOM_NORMAL); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.RED_MUSHROOM_NORMAL); ++ } ++ ++ public static void addDefaultExtraVegetation(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_SUGAR_CANE); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_PUMPKIN); ++ } ++ ++ public static void addBadlandExtraVegetation(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_SUGAR_CANE_BADLANDS); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_PUMPKIN); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_CACTUS_DECORATED); ++ } ++ ++ public static void addJungleMelons(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_MELON); ++ } ++ ++ public static void addSparseJungleMelons(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_MELON_SPARSE); ++ } ++ ++ public static void addJungleVines(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.VINES); ++ } ++ ++ public static void addDesertExtraVegetation(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_SUGAR_CANE_DESERT); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_PUMPKIN); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_CACTUS_DESERT); ++ } ++ ++ public static void addSwampExtraVegetation(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_SUGAR_CANE_SWAMP); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_PUMPKIN); ++ } ++ ++ public static void addDesertExtraDecoration(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.SURFACE_STRUCTURES, MiscOverworldPlacements.DESERT_WELL); ++ } ++ ++ public static void addFossilDecoration(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_STRUCTURES, CavePlacements.FOSSIL_UPPER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_STRUCTURES, CavePlacements.FOSSIL_LOWER); ++ } ++ ++ public static void addColdOceanExtraVegetation(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, AquaticPlacements.KELP_COLD); ++ } ++ ++ public static void addDefaultSeagrass(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, AquaticPlacements.SEAGRASS_SIMPLE); ++ } ++ ++ public static void addLukeWarmKelp(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, AquaticPlacements.KELP_WARM); ++ } ++ ++ public static void addDefaultSprings(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.FLUID_SPRINGS, MiscOverworldPlacements.SPRING_WATER); ++ builder.addFeature(GenerationStep.Decoration.FLUID_SPRINGS, MiscOverworldPlacements.SPRING_LAVA); ++ } ++ ++ public static void addFrozenSprings(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.FLUID_SPRINGS, MiscOverworldPlacements.SPRING_LAVA_FROZEN); ++ } ++ ++ public static void addIcebergs(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.LOCAL_MODIFICATIONS, MiscOverworldPlacements.ICEBERG_PACKED); ++ builder.addFeature(GenerationStep.Decoration.LOCAL_MODIFICATIONS, MiscOverworldPlacements.ICEBERG_BLUE); ++ } ++ ++ public static void addBlueIce(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.SURFACE_STRUCTURES, MiscOverworldPlacements.BLUE_ICE); ++ } ++ ++ public static void addSurfaceFreezing(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.TOP_LAYER_MODIFICATION, MiscOverworldPlacements.FREEZE_TOP_LAYER); ++ } ++ ++ public static void addNetherDefaultOres(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_DECORATION, OrePlacements.ORE_GRAVEL_NETHER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_DECORATION, OrePlacements.ORE_BLACKSTONE); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_DECORATION, OrePlacements.ORE_GOLD_NETHER); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_DECORATION, OrePlacements.ORE_QUARTZ_NETHER); ++ addAncientDebris(builder); ++ } ++ ++ public static void addAncientDebris(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_DECORATION, OrePlacements.ORE_ANCIENT_DEBRIS_LARGE); ++ builder.addFeature(GenerationStep.Decoration.UNDERGROUND_DECORATION, OrePlacements.ORE_ANCIENT_DEBRIS_SMALL); ++ } ++ ++ public static void addDefaultCrystalFormations(BiomeGenerationSettings.Builder builder) { ++ builder.addFeature(GenerationStep.Decoration.LOCAL_MODIFICATIONS, CavePlacements.AMETHYST_GEODE); ++ } ++ ++ public static void farmAnimals(MobSpawnSettings.Builder builder) { ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.SHEEP, 12, 4, 4)); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.PIG, 10, 4, 4)); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.CHICKEN, 10, 4, 4)); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.COW, 8, 4, 4)); ++ } ++ ++ public static void caveSpawns(MobSpawnSettings.Builder builder) { ++ builder.addSpawn(MobCategory.AMBIENT, new MobSpawnSettings.SpawnerData(EntityType.BAT, 10, 8, 8)); ++ builder.addSpawn(MobCategory.UNDERGROUND_WATER_CREATURE, new MobSpawnSettings.SpawnerData(EntityType.GLOW_SQUID, 10, 4, 6)); ++ } ++ ++ public static void commonSpawns(MobSpawnSettings.Builder builder) { ++ caveSpawns(builder); ++ monsters(builder, 95, 5, 100, false); ++ } ++ ++ public static void oceanSpawns(MobSpawnSettings.Builder builder, int squidWeight, int squidMaxGroupSize, int codWeight) { ++ builder.addSpawn(MobCategory.WATER_CREATURE, new MobSpawnSettings.SpawnerData(EntityType.SQUID, squidWeight, 1, squidMaxGroupSize)); ++ builder.addSpawn(MobCategory.WATER_AMBIENT, new MobSpawnSettings.SpawnerData(EntityType.COD, codWeight, 3, 6)); ++ commonSpawns(builder); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.DROWNED, 5, 1, 1)); ++ } ++ ++ public static void warmOceanSpawns(MobSpawnSettings.Builder builder, int squidWeight, int squidMinGroupSize) { ++ builder.addSpawn(MobCategory.WATER_CREATURE, new MobSpawnSettings.SpawnerData(EntityType.SQUID, squidWeight, squidMinGroupSize, 4)); ++ builder.addSpawn(MobCategory.WATER_AMBIENT, new MobSpawnSettings.SpawnerData(EntityType.TROPICAL_FISH, 25, 8, 8)); ++ builder.addSpawn(MobCategory.WATER_CREATURE, new MobSpawnSettings.SpawnerData(EntityType.DOLPHIN, 2, 1, 2)); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.DROWNED, 5, 1, 1)); ++ commonSpawns(builder); ++ } ++ ++ public static void plainsSpawns(MobSpawnSettings.Builder builder) { ++ farmAnimals(builder); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.HORSE, 5, 2, 6)); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.DONKEY, 1, 1, 3)); ++ commonSpawns(builder); ++ } ++ ++ public static void snowySpawns(MobSpawnSettings.Builder builder) { ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.RABBIT, 10, 2, 3)); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.POLAR_BEAR, 1, 1, 2)); ++ caveSpawns(builder); ++ monsters(builder, 95, 5, 20, false); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.STRAY, 80, 4, 4)); ++ } ++ ++ public static void desertSpawns(MobSpawnSettings.Builder builder) { ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.RABBIT, 4, 2, 3)); ++ caveSpawns(builder); ++ monsters(builder, 19, 1, 100, false); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.HUSK, 80, 4, 4)); ++ } ++ ++ public static void dripstoneCavesSpawns(MobSpawnSettings.Builder builder) { ++ caveSpawns(builder); ++ int i = 95; ++ monsters(builder, 95, 5, 100, false); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.DROWNED, 95, 4, 4)); ++ } ++ ++ public static void monsters(MobSpawnSettings.Builder builder, int zombieWeight, int zombieVillagerWeight, int skeletonWeight, boolean drowned) { ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.SPIDER, 100, 4, 4)); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(drowned ? EntityType.DROWNED : EntityType.ZOMBIE, zombieWeight, 4, 4)); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.ZOMBIE_VILLAGER, zombieVillagerWeight, 1, 1)); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.SKELETON, skeletonWeight, 4, 4)); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.CREEPER, 100, 4, 4)); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.SLIME, 100, 4, 4)); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.ENDERMAN, 10, 1, 4)); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.WITCH, 5, 1, 1)); ++ } ++ ++ public static void mooshroomSpawns(MobSpawnSettings.Builder builder) { ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.MOOSHROOM, 8, 4, 8)); ++ caveSpawns(builder); ++ } ++ ++ public static void baseJungleSpawns(MobSpawnSettings.Builder builder) { ++ farmAnimals(builder); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.CHICKEN, 10, 4, 4)); ++ commonSpawns(builder); ++ } ++ ++ public static void endSpawns(MobSpawnSettings.Builder builder) { ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.ENDERMAN, 10, 4, 4)); ++ } ++} +diff --git a/src/main/java/net/minecraft/data/worldgen/biome/OverworldBiomes.java b/src/main/java/net/minecraft/data/worldgen/biome/OverworldBiomes.java +new file mode 100644 +index 0000000000000000000000000000000000000000..84aa56cbcaa5539b556f42eb284d3dd2e200e358 +--- /dev/null ++++ b/src/main/java/net/minecraft/data/worldgen/biome/OverworldBiomes.java +@@ -0,0 +1,705 @@ ++package net.minecraft.data.worldgen.biome; ++ ++import javax.annotation.Nullable; ++import net.minecraft.core.HolderGetter; ++import net.minecraft.data.worldgen.BiomeDefaultFeatures; ++import net.minecraft.data.worldgen.Carvers; ++import net.minecraft.data.worldgen.placement.AquaticPlacements; ++import net.minecraft.data.worldgen.placement.MiscOverworldPlacements; ++import net.minecraft.data.worldgen.placement.VegetationPlacements; ++import net.minecraft.sounds.Music; ++import net.minecraft.sounds.Musics; ++import net.minecraft.sounds.SoundEvents; ++import net.minecraft.util.Mth; ++import net.minecraft.world.entity.EntityType; ++import net.minecraft.world.entity.MobCategory; ++import net.minecraft.world.level.biome.AmbientMoodSettings; ++import net.minecraft.world.level.biome.Biome; ++import net.minecraft.world.level.biome.BiomeGenerationSettings; ++import net.minecraft.world.level.biome.BiomeSpecialEffects; ++import net.minecraft.world.level.biome.MobSpawnSettings; ++import net.minecraft.world.level.levelgen.GenerationStep; ++import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver; ++import net.minecraft.world.level.levelgen.placement.PlacedFeature; ++ ++public class OverworldBiomes { ++ protected static final int NORMAL_WATER_COLOR = 4159204; ++ protected static final int NORMAL_WATER_FOG_COLOR = 329011; ++ private static final int OVERWORLD_FOG_COLOR = 12638463; ++ @Nullable ++ private static final Music NORMAL_MUSIC = null; ++ ++ protected static int calculateSkyColor(float temperature) { ++ float f = temperature / 3.0F; ++ f = Mth.clamp(f, -1.0F, 1.0F); ++ return Mth.hsvToRgb(0.62222224F - f * 0.05F, 0.5F + f * 0.1F, 1.0F); ++ } ++ ++ private static Biome biome(boolean precipitation, float temperature, float downfall, MobSpawnSettings.Builder spawnSettings, BiomeGenerationSettings.Builder generationSettings, @Nullable Music music) { ++ return biome(precipitation, temperature, downfall, 4159204, 329011, (Integer)null, (Integer)null, spawnSettings, generationSettings, music); ++ } ++ ++ private static Biome biome(boolean precipitation, float temperature, float downfall, int waterColor, int waterFogColor, @Nullable Integer grassColor, @Nullable Integer foliageColor, MobSpawnSettings.Builder spawnSettings, BiomeGenerationSettings.Builder generationSettings, @Nullable Music music) { ++ BiomeSpecialEffects.Builder builder = (new BiomeSpecialEffects.Builder()).waterColor(waterColor).waterFogColor(waterFogColor).fogColor(12638463).skyColor(calculateSkyColor(temperature)).ambientMoodSound(AmbientMoodSettings.LEGACY_CAVE_SETTINGS).backgroundMusic(music); ++ if (grassColor != null) { ++ builder.grassColorOverride(grassColor); ++ } ++ ++ if (foliageColor != null) { ++ builder.foliageColorOverride(foliageColor); ++ } ++ ++ return (new Biome.BiomeBuilder()).hasPrecipitation(precipitation).temperature(temperature).downfall(downfall).specialEffects(builder.build()).mobSpawnSettings(spawnSettings.build()).generationSettings(generationSettings.build()).build(); ++ } ++ ++ private static void globalOverworldGeneration(BiomeGenerationSettings.Builder generationSettings) { ++ BiomeDefaultFeatures.addDefaultCarversAndLakes(generationSettings); ++ BiomeDefaultFeatures.addDefaultCrystalFormations(generationSettings); ++ BiomeDefaultFeatures.addDefaultMonsterRoom(generationSettings); ++ BiomeDefaultFeatures.addDefaultUndergroundVariety(generationSettings); ++ BiomeDefaultFeatures.addDefaultSprings(generationSettings); ++ BiomeDefaultFeatures.addSurfaceFreezing(generationSettings); ++ } ++ ++ public static Biome oldGrowthTaiga(HolderGetter featureLookup, HolderGetter> carverLookup, boolean spruce) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.farmAnimals(builder); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.WOLF, 8, 4, 4)); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.RABBIT, 4, 2, 3)); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.FOX, 8, 2, 4)); ++ if (spruce) { ++ BiomeDefaultFeatures.commonSpawns(builder); ++ } else { ++ BiomeDefaultFeatures.caveSpawns(builder); ++ BiomeDefaultFeatures.monsters(builder, 100, 25, 100, false); ++ } ++ ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ globalOverworldGeneration(builder2); ++ BiomeDefaultFeatures.addMossyStoneBlock(builder2); ++ BiomeDefaultFeatures.addFerns(builder2); ++ BiomeDefaultFeatures.addDefaultOres(builder2); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder2); ++ builder2.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, spruce ? VegetationPlacements.TREES_OLD_GROWTH_SPRUCE_TAIGA : VegetationPlacements.TREES_OLD_GROWTH_PINE_TAIGA); ++ BiomeDefaultFeatures.addDefaultFlowers(builder2); ++ BiomeDefaultFeatures.addGiantTaigaVegetation(builder2); ++ BiomeDefaultFeatures.addDefaultMushrooms(builder2); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder2); ++ BiomeDefaultFeatures.addCommonBerryBushes(builder2); ++ Music music = Musics.createGameMusic(SoundEvents.MUSIC_BIOME_OLD_GROWTH_TAIGA); ++ return biome(true, spruce ? 0.25F : 0.3F, 0.8F, builder, builder2, music); ++ } ++ ++ public static Biome sparseJungle(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.baseJungleSpawns(builder); ++ return baseJungle(featureLookup, carverLookup, 0.8F, false, true, false, builder, Musics.createGameMusic(SoundEvents.MUSIC_BIOME_SPARSE_JUNGLE)); ++ } ++ ++ public static Biome jungle(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.baseJungleSpawns(builder); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.PARROT, 40, 1, 2)).addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.OCELOT, 2, 1, 3)).addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.PANDA, 1, 1, 2)); ++ return baseJungle(featureLookup, carverLookup, 0.9F, false, false, true, builder, Musics.createGameMusic(SoundEvents.MUSIC_BIOME_JUNGLE)); ++ } ++ ++ public static Biome bambooJungle(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.baseJungleSpawns(builder); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.PARROT, 40, 1, 2)).addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.PANDA, 80, 1, 2)).addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.OCELOT, 2, 1, 1)); ++ return baseJungle(featureLookup, carverLookup, 0.9F, true, false, true, builder, Musics.createGameMusic(SoundEvents.MUSIC_BIOME_BAMBOO_JUNGLE)); ++ } ++ ++ private static Biome baseJungle(HolderGetter featureLookup, HolderGetter> carverLookup, float depth, boolean bamboo, boolean sparse, boolean unmodified, MobSpawnSettings.Builder spawnSettings, Music music) { ++ BiomeGenerationSettings.Builder builder = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ globalOverworldGeneration(builder); ++ BiomeDefaultFeatures.addDefaultOres(builder); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder); ++ if (bamboo) { ++ BiomeDefaultFeatures.addBambooVegetation(builder); ++ } else { ++ if (unmodified) { ++ BiomeDefaultFeatures.addLightBambooVegetation(builder); ++ } ++ ++ if (sparse) { ++ BiomeDefaultFeatures.addSparseJungleTrees(builder); ++ } else { ++ BiomeDefaultFeatures.addJungleTrees(builder); ++ } ++ } ++ ++ BiomeDefaultFeatures.addWarmFlowers(builder); ++ BiomeDefaultFeatures.addJungleGrass(builder); ++ BiomeDefaultFeatures.addDefaultMushrooms(builder); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder); ++ BiomeDefaultFeatures.addJungleVines(builder); ++ if (sparse) { ++ BiomeDefaultFeatures.addSparseJungleMelons(builder); ++ } else { ++ BiomeDefaultFeatures.addJungleMelons(builder); ++ } ++ ++ return biome(true, 0.95F, depth, spawnSettings, builder, music); ++ } ++ ++ public static Biome windsweptHills(HolderGetter featureLookup, HolderGetter> carverLookup, boolean forest) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.farmAnimals(builder); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.LLAMA, 5, 4, 6)); ++ BiomeDefaultFeatures.commonSpawns(builder); ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ globalOverworldGeneration(builder2); ++ BiomeDefaultFeatures.addDefaultOres(builder2); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder2); ++ if (forest) { ++ BiomeDefaultFeatures.addMountainForestTrees(builder2); ++ } else { ++ BiomeDefaultFeatures.addMountainTrees(builder2); ++ } ++ ++ BiomeDefaultFeatures.addDefaultFlowers(builder2); ++ BiomeDefaultFeatures.addDefaultGrass(builder2); ++ BiomeDefaultFeatures.addDefaultMushrooms(builder2); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder2); ++ BiomeDefaultFeatures.addExtraEmeralds(builder2); ++ BiomeDefaultFeatures.addInfestedStone(builder2); ++ return biome(true, 0.2F, 0.3F, builder, builder2, NORMAL_MUSIC); ++ } ++ ++ public static Biome desert(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.desertSpawns(builder); ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ BiomeDefaultFeatures.addFossilDecoration(builder2); ++ globalOverworldGeneration(builder2); ++ BiomeDefaultFeatures.addDefaultOres(builder2); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder2); ++ BiomeDefaultFeatures.addDefaultFlowers(builder2); ++ BiomeDefaultFeatures.addDefaultGrass(builder2); ++ BiomeDefaultFeatures.addDesertVegetation(builder2); ++ BiomeDefaultFeatures.addDefaultMushrooms(builder2); ++ BiomeDefaultFeatures.addDesertExtraVegetation(builder2); ++ BiomeDefaultFeatures.addDesertExtraDecoration(builder2); ++ return biome(false, 2.0F, 0.0F, builder, builder2, Musics.createGameMusic(SoundEvents.MUSIC_BIOME_DESERT)); ++ } ++ ++ public static Biome plains(HolderGetter featureLookup, HolderGetter> carverLookup, boolean sunflower, boolean snowy, boolean iceSpikes) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ globalOverworldGeneration(builder2); ++ if (snowy) { ++ builder.creatureGenerationProbability(0.07F); ++ BiomeDefaultFeatures.snowySpawns(builder); ++ if (iceSpikes) { ++ builder2.addFeature(GenerationStep.Decoration.SURFACE_STRUCTURES, MiscOverworldPlacements.ICE_SPIKE); ++ builder2.addFeature(GenerationStep.Decoration.SURFACE_STRUCTURES, MiscOverworldPlacements.ICE_PATCH); ++ } ++ } else { ++ BiomeDefaultFeatures.plainsSpawns(builder); ++ BiomeDefaultFeatures.addPlainGrass(builder2); ++ if (sunflower) { ++ builder2.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_SUNFLOWER); ++ } ++ } ++ ++ BiomeDefaultFeatures.addDefaultOres(builder2); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder2); ++ if (snowy) { ++ BiomeDefaultFeatures.addSnowyTrees(builder2); ++ BiomeDefaultFeatures.addDefaultFlowers(builder2); ++ BiomeDefaultFeatures.addDefaultGrass(builder2); ++ } else { ++ BiomeDefaultFeatures.addPlainVegetation(builder2); ++ } ++ ++ BiomeDefaultFeatures.addDefaultMushrooms(builder2); ++ if (sunflower) { ++ builder2.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_SUGAR_CANE); ++ builder2.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.PATCH_PUMPKIN); ++ } else { ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder2); ++ } ++ ++ float f = snowy ? 0.0F : 0.8F; ++ return biome(true, f, snowy ? 0.5F : 0.4F, builder, builder2, NORMAL_MUSIC); ++ } ++ ++ public static Biome mushroomFields(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.mooshroomSpawns(builder); ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ globalOverworldGeneration(builder2); ++ BiomeDefaultFeatures.addDefaultOres(builder2); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder2); ++ BiomeDefaultFeatures.addMushroomFieldVegetation(builder2); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder2); ++ return biome(true, 0.9F, 1.0F, builder, builder2, NORMAL_MUSIC); ++ } ++ ++ public static Biome savanna(HolderGetter featureLookup, HolderGetter> carverLookup, boolean windswept, boolean plateau) { ++ BiomeGenerationSettings.Builder builder = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ globalOverworldGeneration(builder); ++ if (!windswept) { ++ BiomeDefaultFeatures.addSavannaGrass(builder); ++ } ++ ++ BiomeDefaultFeatures.addDefaultOres(builder); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder); ++ if (windswept) { ++ BiomeDefaultFeatures.addShatteredSavannaTrees(builder); ++ BiomeDefaultFeatures.addDefaultFlowers(builder); ++ BiomeDefaultFeatures.addShatteredSavannaGrass(builder); ++ } else { ++ BiomeDefaultFeatures.addSavannaTrees(builder); ++ BiomeDefaultFeatures.addWarmFlowers(builder); ++ BiomeDefaultFeatures.addSavannaExtraGrass(builder); ++ } ++ ++ BiomeDefaultFeatures.addDefaultMushrooms(builder); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder); ++ MobSpawnSettings.Builder builder2 = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.farmAnimals(builder2); ++ builder2.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.HORSE, 1, 2, 6)).addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.DONKEY, 1, 1, 1)); ++ BiomeDefaultFeatures.commonSpawns(builder2); ++ if (plateau) { ++ builder2.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.LLAMA, 8, 4, 4)); ++ } ++ ++ return biome(false, 2.0F, 0.0F, builder2, builder, NORMAL_MUSIC); ++ } ++ ++ public static Biome badlands(HolderGetter featureLookup, HolderGetter> carverLookup, boolean plateau) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.commonSpawns(builder); ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ globalOverworldGeneration(builder2); ++ BiomeDefaultFeatures.addDefaultOres(builder2); ++ BiomeDefaultFeatures.addExtraGold(builder2); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder2); ++ if (plateau) { ++ BiomeDefaultFeatures.addBadlandsTrees(builder2); ++ } ++ ++ BiomeDefaultFeatures.addBadlandGrass(builder2); ++ BiomeDefaultFeatures.addDefaultMushrooms(builder2); ++ BiomeDefaultFeatures.addBadlandExtraVegetation(builder2); ++ return (new Biome.BiomeBuilder()).hasPrecipitation(false).temperature(2.0F).downfall(0.0F).specialEffects((new BiomeSpecialEffects.Builder()).waterColor(4159204).waterFogColor(329011).fogColor(12638463).skyColor(calculateSkyColor(2.0F)).foliageColorOverride(10387789).grassColorOverride(9470285).ambientMoodSound(AmbientMoodSettings.LEGACY_CAVE_SETTINGS).backgroundMusic(Musics.createGameMusic(SoundEvents.MUSIC_BIOME_BADLANDS)).build()).mobSpawnSettings(builder.build()).generationSettings(builder2.build()).build(); ++ } ++ ++ private static Biome baseOcean(MobSpawnSettings.Builder spawnSettings, int waterColor, int waterFogColor, BiomeGenerationSettings.Builder generationSettings) { ++ return biome(true, 0.5F, 0.5F, waterColor, waterFogColor, (Integer)null, (Integer)null, spawnSettings, generationSettings, NORMAL_MUSIC); ++ } ++ ++ private static BiomeGenerationSettings.Builder baseOceanGeneration(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ BiomeGenerationSettings.Builder builder = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ globalOverworldGeneration(builder); ++ BiomeDefaultFeatures.addDefaultOres(builder); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder); ++ BiomeDefaultFeatures.addWaterTrees(builder); ++ BiomeDefaultFeatures.addDefaultFlowers(builder); ++ BiomeDefaultFeatures.addDefaultGrass(builder); ++ BiomeDefaultFeatures.addDefaultMushrooms(builder); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder); ++ return builder; ++ } ++ ++ public static Biome coldOcean(HolderGetter featureLookup, HolderGetter> carverLookup, boolean deep) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.oceanSpawns(builder, 3, 4, 15); ++ builder.addSpawn(MobCategory.WATER_AMBIENT, new MobSpawnSettings.SpawnerData(EntityType.SALMON, 15, 1, 5)); ++ BiomeGenerationSettings.Builder builder2 = baseOceanGeneration(featureLookup, carverLookup); ++ builder2.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, deep ? AquaticPlacements.SEAGRASS_DEEP_COLD : AquaticPlacements.SEAGRASS_COLD); ++ BiomeDefaultFeatures.addDefaultSeagrass(builder2); ++ BiomeDefaultFeatures.addColdOceanExtraVegetation(builder2); ++ return baseOcean(builder, 4020182, 329011, builder2); ++ } ++ ++ public static Biome ocean(HolderGetter featureLookup, HolderGetter> carverLookup, boolean deep) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.oceanSpawns(builder, 1, 4, 10); ++ builder.addSpawn(MobCategory.WATER_CREATURE, new MobSpawnSettings.SpawnerData(EntityType.DOLPHIN, 1, 1, 2)); ++ BiomeGenerationSettings.Builder builder2 = baseOceanGeneration(featureLookup, carverLookup); ++ builder2.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, deep ? AquaticPlacements.SEAGRASS_DEEP : AquaticPlacements.SEAGRASS_NORMAL); ++ BiomeDefaultFeatures.addDefaultSeagrass(builder2); ++ BiomeDefaultFeatures.addColdOceanExtraVegetation(builder2); ++ return baseOcean(builder, 4159204, 329011, builder2); ++ } ++ ++ public static Biome lukeWarmOcean(HolderGetter featureLookup, HolderGetter> carverLookup, boolean deep) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ if (deep) { ++ BiomeDefaultFeatures.oceanSpawns(builder, 8, 4, 8); ++ } else { ++ BiomeDefaultFeatures.oceanSpawns(builder, 10, 2, 15); ++ } ++ ++ builder.addSpawn(MobCategory.WATER_AMBIENT, new MobSpawnSettings.SpawnerData(EntityType.PUFFERFISH, 5, 1, 3)).addSpawn(MobCategory.WATER_AMBIENT, new MobSpawnSettings.SpawnerData(EntityType.TROPICAL_FISH, 25, 8, 8)).addSpawn(MobCategory.WATER_CREATURE, new MobSpawnSettings.SpawnerData(EntityType.DOLPHIN, 2, 1, 2)); ++ BiomeGenerationSettings.Builder builder2 = baseOceanGeneration(featureLookup, carverLookup); ++ builder2.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, deep ? AquaticPlacements.SEAGRASS_DEEP_WARM : AquaticPlacements.SEAGRASS_WARM); ++ if (deep) { ++ BiomeDefaultFeatures.addDefaultSeagrass(builder2); ++ } ++ ++ BiomeDefaultFeatures.addLukeWarmKelp(builder2); ++ return baseOcean(builder, 4566514, 267827, builder2); ++ } ++ ++ public static Biome warmOcean(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ MobSpawnSettings.Builder builder = (new MobSpawnSettings.Builder()).addSpawn(MobCategory.WATER_AMBIENT, new MobSpawnSettings.SpawnerData(EntityType.PUFFERFISH, 15, 1, 3)); ++ BiomeDefaultFeatures.warmOceanSpawns(builder, 10, 4); ++ BiomeGenerationSettings.Builder builder2 = baseOceanGeneration(featureLookup, carverLookup).addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, AquaticPlacements.WARM_OCEAN_VEGETATION).addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, AquaticPlacements.SEAGRASS_WARM).addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, AquaticPlacements.SEA_PICKLE); ++ return baseOcean(builder, 4445678, 270131, builder2); ++ } ++ ++ public static Biome frozenOcean(HolderGetter featureLookup, HolderGetter> carverLookup, boolean deep) { ++ MobSpawnSettings.Builder builder = (new MobSpawnSettings.Builder()).addSpawn(MobCategory.WATER_CREATURE, new MobSpawnSettings.SpawnerData(EntityType.SQUID, 1, 1, 4)).addSpawn(MobCategory.WATER_AMBIENT, new MobSpawnSettings.SpawnerData(EntityType.SALMON, 15, 1, 5)).addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.POLAR_BEAR, 1, 1, 2)); ++ BiomeDefaultFeatures.commonSpawns(builder); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.DROWNED, 5, 1, 1)); ++ float f = deep ? 0.5F : 0.0F; ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ BiomeDefaultFeatures.addIcebergs(builder2); ++ globalOverworldGeneration(builder2); ++ BiomeDefaultFeatures.addBlueIce(builder2); ++ BiomeDefaultFeatures.addDefaultOres(builder2); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder2); ++ BiomeDefaultFeatures.addWaterTrees(builder2); ++ BiomeDefaultFeatures.addDefaultFlowers(builder2); ++ BiomeDefaultFeatures.addDefaultGrass(builder2); ++ BiomeDefaultFeatures.addDefaultMushrooms(builder2); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder2); ++ return (new Biome.BiomeBuilder()).hasPrecipitation(true).temperature(f).temperatureAdjustment(Biome.TemperatureModifier.FROZEN).downfall(0.5F).specialEffects((new BiomeSpecialEffects.Builder()).waterColor(3750089).waterFogColor(329011).fogColor(12638463).skyColor(calculateSkyColor(f)).ambientMoodSound(AmbientMoodSettings.LEGACY_CAVE_SETTINGS).build()).mobSpawnSettings(builder.build()).generationSettings(builder2.build()).build(); ++ } ++ ++ public static Biome forest(HolderGetter featureLookup, HolderGetter> carverLookup, boolean birch, boolean oldGrowth, boolean flower) { ++ BiomeGenerationSettings.Builder builder = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ globalOverworldGeneration(builder); ++ Music music; ++ if (flower) { ++ music = Musics.createGameMusic(SoundEvents.MUSIC_BIOME_FLOWER_FOREST); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.FLOWER_FOREST_FLOWERS); ++ } else { ++ music = Musics.createGameMusic(SoundEvents.MUSIC_BIOME_FOREST); ++ BiomeDefaultFeatures.addForestFlowers(builder); ++ } ++ ++ BiomeDefaultFeatures.addDefaultOres(builder); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder); ++ if (flower) { ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.TREES_FLOWER_FOREST); ++ builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.FLOWER_FLOWER_FOREST); ++ BiomeDefaultFeatures.addDefaultGrass(builder); ++ } else { ++ if (birch) { ++ if (oldGrowth) { ++ BiomeDefaultFeatures.addTallBirchTrees(builder); ++ } else { ++ BiomeDefaultFeatures.addBirchTrees(builder); ++ } ++ } else { ++ BiomeDefaultFeatures.addOtherBirchTrees(builder); ++ } ++ ++ BiomeDefaultFeatures.addDefaultFlowers(builder); ++ BiomeDefaultFeatures.addForestGrass(builder); ++ } ++ ++ BiomeDefaultFeatures.addDefaultMushrooms(builder); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder); ++ MobSpawnSettings.Builder builder2 = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.farmAnimals(builder2); ++ BiomeDefaultFeatures.commonSpawns(builder2); ++ if (flower) { ++ builder2.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.RABBIT, 4, 2, 3)); ++ } else if (!birch) { ++ builder2.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.WOLF, 5, 4, 4)); ++ } ++ ++ float f = birch ? 0.6F : 0.7F; ++ return biome(true, f, birch ? 0.6F : 0.8F, builder2, builder, music); ++ } ++ ++ public static Biome taiga(HolderGetter featureLookup, HolderGetter> carverLookup, boolean snowy) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.farmAnimals(builder); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.WOLF, 8, 4, 4)).addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.RABBIT, 4, 2, 3)).addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.FOX, 8, 2, 4)); ++ BiomeDefaultFeatures.commonSpawns(builder); ++ float f = snowy ? -0.5F : 0.25F; ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ globalOverworldGeneration(builder2); ++ BiomeDefaultFeatures.addFerns(builder2); ++ BiomeDefaultFeatures.addDefaultOres(builder2); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder2); ++ BiomeDefaultFeatures.addTaigaTrees(builder2); ++ BiomeDefaultFeatures.addDefaultFlowers(builder2); ++ BiomeDefaultFeatures.addTaigaGrass(builder2); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder2); ++ if (snowy) { ++ BiomeDefaultFeatures.addRareBerryBushes(builder2); ++ } else { ++ BiomeDefaultFeatures.addCommonBerryBushes(builder2); ++ } ++ ++ return biome(true, f, snowy ? 0.4F : 0.8F, snowy ? 4020182 : 4159204, 329011, (Integer)null, (Integer)null, builder, builder2, NORMAL_MUSIC); ++ } ++ ++ public static Biome darkForest(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.farmAnimals(builder); ++ BiomeDefaultFeatures.commonSpawns(builder); ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ globalOverworldGeneration(builder2); ++ builder2.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, VegetationPlacements.DARK_FOREST_VEGETATION); ++ BiomeDefaultFeatures.addForestFlowers(builder2); ++ BiomeDefaultFeatures.addDefaultOres(builder2); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder2); ++ BiomeDefaultFeatures.addDefaultFlowers(builder2); ++ BiomeDefaultFeatures.addForestGrass(builder2); ++ BiomeDefaultFeatures.addDefaultMushrooms(builder2); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder2); ++ Music music = Musics.createGameMusic(SoundEvents.MUSIC_BIOME_FOREST); ++ return (new Biome.BiomeBuilder()).hasPrecipitation(true).temperature(0.7F).downfall(0.8F).specialEffects((new BiomeSpecialEffects.Builder()).waterColor(4159204).waterFogColor(329011).fogColor(12638463).skyColor(calculateSkyColor(0.7F)).grassColorModifier(BiomeSpecialEffects.GrassColorModifier.DARK_FOREST).ambientMoodSound(AmbientMoodSettings.LEGACY_CAVE_SETTINGS).backgroundMusic(music).build()).mobSpawnSettings(builder.build()).generationSettings(builder2.build()).build(); ++ } ++ ++ public static Biome swamp(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.farmAnimals(builder); ++ BiomeDefaultFeatures.commonSpawns(builder); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.SLIME, 1, 1, 1)); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.FROG, 10, 2, 5)); ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ BiomeDefaultFeatures.addFossilDecoration(builder2); ++ globalOverworldGeneration(builder2); ++ BiomeDefaultFeatures.addDefaultOres(builder2); ++ BiomeDefaultFeatures.addSwampClayDisk(builder2); ++ BiomeDefaultFeatures.addSwampVegetation(builder2); ++ BiomeDefaultFeatures.addDefaultMushrooms(builder2); ++ BiomeDefaultFeatures.addSwampExtraVegetation(builder2); ++ builder2.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, AquaticPlacements.SEAGRASS_SWAMP); ++ Music music = Musics.createGameMusic(SoundEvents.MUSIC_BIOME_SWAMP); ++ return (new Biome.BiomeBuilder()).hasPrecipitation(true).temperature(0.8F).downfall(0.9F).specialEffects((new BiomeSpecialEffects.Builder()).waterColor(6388580).waterFogColor(2302743).fogColor(12638463).skyColor(calculateSkyColor(0.8F)).foliageColorOverride(6975545).grassColorModifier(BiomeSpecialEffects.GrassColorModifier.SWAMP).ambientMoodSound(AmbientMoodSettings.LEGACY_CAVE_SETTINGS).backgroundMusic(music).build()).mobSpawnSettings(builder.build()).generationSettings(builder2.build()).build(); ++ } ++ ++ public static Biome mangroveSwamp(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.commonSpawns(builder); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.SLIME, 1, 1, 1)); ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.FROG, 10, 2, 5)); ++ builder.addSpawn(MobCategory.WATER_AMBIENT, new MobSpawnSettings.SpawnerData(EntityType.TROPICAL_FISH, 25, 8, 8)); ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ BiomeDefaultFeatures.addFossilDecoration(builder2); ++ globalOverworldGeneration(builder2); ++ BiomeDefaultFeatures.addDefaultOres(builder2); ++ BiomeDefaultFeatures.addMangroveSwampDisks(builder2); ++ BiomeDefaultFeatures.addMangroveSwampVegetation(builder2); ++ builder2.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, AquaticPlacements.SEAGRASS_SWAMP); ++ Music music = Musics.createGameMusic(SoundEvents.MUSIC_BIOME_SWAMP); ++ return (new Biome.BiomeBuilder()).hasPrecipitation(true).temperature(0.8F).downfall(0.9F).specialEffects((new BiomeSpecialEffects.Builder()).waterColor(3832426).waterFogColor(5077600).fogColor(12638463).skyColor(calculateSkyColor(0.8F)).foliageColorOverride(9285927).grassColorModifier(BiomeSpecialEffects.GrassColorModifier.SWAMP).ambientMoodSound(AmbientMoodSettings.LEGACY_CAVE_SETTINGS).backgroundMusic(music).build()).mobSpawnSettings(builder.build()).generationSettings(builder2.build()).build(); ++ } ++ ++ public static Biome river(HolderGetter featureLookup, HolderGetter> carverLookup, boolean frozen) { ++ MobSpawnSettings.Builder builder = (new MobSpawnSettings.Builder()).addSpawn(MobCategory.WATER_CREATURE, new MobSpawnSettings.SpawnerData(EntityType.SQUID, 2, 1, 4)).addSpawn(MobCategory.WATER_AMBIENT, new MobSpawnSettings.SpawnerData(EntityType.SALMON, 5, 1, 5)); ++ BiomeDefaultFeatures.commonSpawns(builder); ++ builder.addSpawn(MobCategory.MONSTER, new MobSpawnSettings.SpawnerData(EntityType.DROWNED, frozen ? 1 : 100, 1, 1)); ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ globalOverworldGeneration(builder2); ++ BiomeDefaultFeatures.addDefaultOres(builder2); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder2); ++ BiomeDefaultFeatures.addWaterTrees(builder2); ++ BiomeDefaultFeatures.addDefaultFlowers(builder2); ++ BiomeDefaultFeatures.addDefaultGrass(builder2); ++ BiomeDefaultFeatures.addDefaultMushrooms(builder2); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder2); ++ if (!frozen) { ++ builder2.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, AquaticPlacements.SEAGRASS_RIVER); ++ } ++ ++ float f = frozen ? 0.0F : 0.5F; ++ return biome(true, f, 0.5F, frozen ? 3750089 : 4159204, 329011, (Integer)null, (Integer)null, builder, builder2, NORMAL_MUSIC); ++ } ++ ++ public static Biome beach(HolderGetter featureLookup, HolderGetter> carverLookup, boolean snowy, boolean stony) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ boolean bl = !stony && !snowy; ++ if (bl) { ++ builder.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.TURTLE, 5, 2, 5)); ++ } ++ ++ BiomeDefaultFeatures.commonSpawns(builder); ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ globalOverworldGeneration(builder2); ++ BiomeDefaultFeatures.addDefaultOres(builder2); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder2); ++ BiomeDefaultFeatures.addDefaultFlowers(builder2); ++ BiomeDefaultFeatures.addDefaultGrass(builder2); ++ BiomeDefaultFeatures.addDefaultMushrooms(builder2); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder2); ++ float f; ++ if (snowy) { ++ f = 0.05F; ++ } else if (stony) { ++ f = 0.2F; ++ } else { ++ f = 0.8F; ++ } ++ ++ return biome(true, f, bl ? 0.4F : 0.3F, snowy ? 4020182 : 4159204, 329011, (Integer)null, (Integer)null, builder, builder2, NORMAL_MUSIC); ++ } ++ ++ public static Biome theVoid(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ BiomeGenerationSettings.Builder builder = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ builder.addFeature(GenerationStep.Decoration.TOP_LAYER_MODIFICATION, MiscOverworldPlacements.VOID_START_PLATFORM); ++ return biome(false, 0.5F, 0.5F, new MobSpawnSettings.Builder(), builder, NORMAL_MUSIC); ++ } ++ ++ public static Biome meadowOrCherryGrove(HolderGetter featureLookup, HolderGetter> carverLookup, boolean cherryGrove) { ++ BiomeGenerationSettings.Builder builder = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ MobSpawnSettings.Builder builder2 = new MobSpawnSettings.Builder(); ++ builder2.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(cherryGrove ? EntityType.PIG : EntityType.DONKEY, 1, 1, 2)).addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.RABBIT, 2, 2, 6)).addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.SHEEP, 2, 2, 4)); ++ BiomeDefaultFeatures.commonSpawns(builder2); ++ globalOverworldGeneration(builder); ++ BiomeDefaultFeatures.addPlainGrass(builder); ++ BiomeDefaultFeatures.addDefaultOres(builder); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder); ++ if (cherryGrove) { ++ BiomeDefaultFeatures.addCherryGroveVegetation(builder); ++ } else { ++ BiomeDefaultFeatures.addMeadowVegetation(builder); ++ } ++ ++ BiomeDefaultFeatures.addExtraEmeralds(builder); ++ BiomeDefaultFeatures.addInfestedStone(builder); ++ Music music = Musics.createGameMusic(cherryGrove ? SoundEvents.MUSIC_BIOME_CHERRY_GROVE : SoundEvents.MUSIC_BIOME_MEADOW); ++ return cherryGrove ? biome(true, 0.5F, 0.8F, 6141935, 6141935, 11983713, 11983713, builder2, builder, music) : biome(true, 0.5F, 0.8F, 937679, 329011, (Integer)null, (Integer)null, builder2, builder, music); ++ } ++ ++ public static Biome frozenPeaks(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ BiomeGenerationSettings.Builder builder = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ MobSpawnSettings.Builder builder2 = new MobSpawnSettings.Builder(); ++ builder2.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.GOAT, 5, 1, 3)); ++ BiomeDefaultFeatures.commonSpawns(builder2); ++ globalOverworldGeneration(builder); ++ BiomeDefaultFeatures.addFrozenSprings(builder); ++ BiomeDefaultFeatures.addDefaultOres(builder); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder); ++ BiomeDefaultFeatures.addExtraEmeralds(builder); ++ BiomeDefaultFeatures.addInfestedStone(builder); ++ Music music = Musics.createGameMusic(SoundEvents.MUSIC_BIOME_FROZEN_PEAKS); ++ return biome(true, -0.7F, 0.9F, builder2, builder, music); ++ } ++ ++ public static Biome jaggedPeaks(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ BiomeGenerationSettings.Builder builder = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ MobSpawnSettings.Builder builder2 = new MobSpawnSettings.Builder(); ++ builder2.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.GOAT, 5, 1, 3)); ++ BiomeDefaultFeatures.commonSpawns(builder2); ++ globalOverworldGeneration(builder); ++ BiomeDefaultFeatures.addFrozenSprings(builder); ++ BiomeDefaultFeatures.addDefaultOres(builder); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder); ++ BiomeDefaultFeatures.addExtraEmeralds(builder); ++ BiomeDefaultFeatures.addInfestedStone(builder); ++ Music music = Musics.createGameMusic(SoundEvents.MUSIC_BIOME_JAGGED_PEAKS); ++ return biome(true, -0.7F, 0.9F, builder2, builder, music); ++ } ++ ++ public static Biome stonyPeaks(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ BiomeGenerationSettings.Builder builder = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ MobSpawnSettings.Builder builder2 = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.commonSpawns(builder2); ++ globalOverworldGeneration(builder); ++ BiomeDefaultFeatures.addDefaultOres(builder); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder); ++ BiomeDefaultFeatures.addExtraEmeralds(builder); ++ BiomeDefaultFeatures.addInfestedStone(builder); ++ Music music = Musics.createGameMusic(SoundEvents.MUSIC_BIOME_STONY_PEAKS); ++ return biome(true, 1.0F, 0.3F, builder2, builder, music); ++ } ++ ++ public static Biome snowySlopes(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ BiomeGenerationSettings.Builder builder = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ MobSpawnSettings.Builder builder2 = new MobSpawnSettings.Builder(); ++ builder2.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.RABBIT, 4, 2, 3)).addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.GOAT, 5, 1, 3)); ++ BiomeDefaultFeatures.commonSpawns(builder2); ++ globalOverworldGeneration(builder); ++ BiomeDefaultFeatures.addFrozenSprings(builder); ++ BiomeDefaultFeatures.addDefaultOres(builder); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder); ++ BiomeDefaultFeatures.addExtraEmeralds(builder); ++ BiomeDefaultFeatures.addInfestedStone(builder); ++ Music music = Musics.createGameMusic(SoundEvents.MUSIC_BIOME_SNOWY_SLOPES); ++ return biome(true, -0.3F, 0.9F, builder2, builder, music); ++ } ++ ++ public static Biome grove(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ BiomeGenerationSettings.Builder builder = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ MobSpawnSettings.Builder builder2 = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.farmAnimals(builder2); ++ builder2.addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.WOLF, 8, 4, 4)).addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.RABBIT, 4, 2, 3)).addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(EntityType.FOX, 8, 2, 4)); ++ BiomeDefaultFeatures.commonSpawns(builder2); ++ globalOverworldGeneration(builder); ++ BiomeDefaultFeatures.addFrozenSprings(builder); ++ BiomeDefaultFeatures.addDefaultOres(builder); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder); ++ BiomeDefaultFeatures.addGroveTrees(builder); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder); ++ BiomeDefaultFeatures.addExtraEmeralds(builder); ++ BiomeDefaultFeatures.addInfestedStone(builder); ++ Music music = Musics.createGameMusic(SoundEvents.MUSIC_BIOME_GROVE); ++ return biome(true, -0.2F, 0.8F, builder2, builder, music); ++ } ++ ++ public static Biome lushCaves(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ builder.addSpawn(MobCategory.AXOLOTLS, new MobSpawnSettings.SpawnerData(EntityType.AXOLOTL, 10, 4, 6)); ++ builder.addSpawn(MobCategory.WATER_AMBIENT, new MobSpawnSettings.SpawnerData(EntityType.TROPICAL_FISH, 25, 8, 8)); ++ BiomeDefaultFeatures.commonSpawns(builder); ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ globalOverworldGeneration(builder2); ++ BiomeDefaultFeatures.addPlainGrass(builder2); ++ BiomeDefaultFeatures.addDefaultOres(builder2); ++ BiomeDefaultFeatures.addLushCavesSpecialOres(builder2); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder2); ++ BiomeDefaultFeatures.addLushCavesVegetationFeatures(builder2); ++ Music music = Musics.createGameMusic(SoundEvents.MUSIC_BIOME_LUSH_CAVES); ++ return biome(true, 0.5F, 0.5F, builder, builder2, music); ++ } ++ ++ public static Biome dripstoneCaves(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeDefaultFeatures.dripstoneCavesSpawns(builder); ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ globalOverworldGeneration(builder2); ++ BiomeDefaultFeatures.addPlainGrass(builder2); ++ BiomeDefaultFeatures.addDefaultOres(builder2, true); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder2); ++ BiomeDefaultFeatures.addPlainVegetation(builder2); ++ BiomeDefaultFeatures.addDefaultMushrooms(builder2); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder2); ++ BiomeDefaultFeatures.addDripstone(builder2); ++ Music music = Musics.createGameMusic(SoundEvents.MUSIC_BIOME_DRIPSTONE_CAVES); ++ return biome(true, 0.8F, 0.4F, builder, builder2, music); ++ } ++ ++ public static Biome deepDark(HolderGetter featureLookup, HolderGetter> carverLookup) { ++ MobSpawnSettings.Builder builder = new MobSpawnSettings.Builder(); ++ BiomeGenerationSettings.Builder builder2 = new BiomeGenerationSettings.Builder(featureLookup, carverLookup); ++ builder2.addCarver(GenerationStep.Carving.AIR, Carvers.CAVE); ++ builder2.addCarver(GenerationStep.Carving.AIR, Carvers.CAVE_EXTRA_UNDERGROUND); ++ builder2.addCarver(GenerationStep.Carving.AIR, Carvers.CANYON); ++ BiomeDefaultFeatures.addDefaultCrystalFormations(builder2); ++ BiomeDefaultFeatures.addDefaultMonsterRoom(builder2); ++ BiomeDefaultFeatures.addDefaultUndergroundVariety(builder2); ++ BiomeDefaultFeatures.addSurfaceFreezing(builder2); ++ BiomeDefaultFeatures.addPlainGrass(builder2); ++ BiomeDefaultFeatures.addDefaultOres(builder2); ++ BiomeDefaultFeatures.addDefaultSoftDisks(builder2); ++ BiomeDefaultFeatures.addPlainVegetation(builder2); ++ BiomeDefaultFeatures.addDefaultMushrooms(builder2); ++ BiomeDefaultFeatures.addDefaultExtraVegetation(builder2); ++ BiomeDefaultFeatures.addSculk(builder2); ++ Music music = Musics.createGameMusic(SoundEvents.MUSIC_BIOME_DEEP_DARK); ++ return biome(true, 0.8F, 0.4F, builder, builder2, music); ++ } ++} +diff --git a/src/main/java/net/minecraft/data/worldgen/features/CaveFeatures.java b/src/main/java/net/minecraft/data/worldgen/features/CaveFeatures.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c1f4a722b57bdc1ee516951c9341b146eb0fb34e +--- /dev/null ++++ b/src/main/java/net/minecraft/data/worldgen/features/CaveFeatures.java +@@ -0,0 +1,128 @@ ++package net.minecraft.data.worldgen.features; ++ ++import java.util.List; ++import net.minecraft.core.Direction; ++import net.minecraft.core.Holder; ++import net.minecraft.core.HolderGetter; ++import net.minecraft.core.HolderSet; ++import net.minecraft.core.registries.Registries; ++import net.minecraft.data.worldgen.BootstapContext; ++import net.minecraft.data.worldgen.ProcessorLists; ++import net.minecraft.data.worldgen.placement.PlacementUtils; ++import net.minecraft.resources.ResourceKey; ++import net.minecraft.resources.ResourceLocation; ++import net.minecraft.tags.BlockTags; ++import net.minecraft.util.random.SimpleWeightedRandomList; ++import net.minecraft.util.valueproviders.ClampedNormalFloat; ++import net.minecraft.util.valueproviders.ConstantInt; ++import net.minecraft.util.valueproviders.IntProvider; ++import net.minecraft.util.valueproviders.UniformFloat; ++import net.minecraft.util.valueproviders.UniformInt; ++import net.minecraft.util.valueproviders.WeightedListInt; ++import net.minecraft.world.level.block.Block; ++import net.minecraft.world.level.block.Blocks; ++import net.minecraft.world.level.block.CaveVines; ++import net.minecraft.world.level.block.CaveVinesBlock; ++import net.minecraft.world.level.block.MultifaceBlock; ++import net.minecraft.world.level.block.SmallDripleafBlock; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.properties.BlockStateProperties; ++import net.minecraft.world.level.levelgen.GeodeBlockSettings; ++import net.minecraft.world.level.levelgen.GeodeCrackSettings; ++import net.minecraft.world.level.levelgen.GeodeLayerSettings; ++import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate; ++import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; ++import net.minecraft.world.level.levelgen.feature.Feature; ++import net.minecraft.world.level.levelgen.feature.FossilFeatureConfiguration; ++import net.minecraft.world.level.levelgen.feature.configurations.BlockColumnConfiguration; ++import net.minecraft.world.level.levelgen.feature.configurations.DripstoneClusterConfiguration; ++import net.minecraft.world.level.levelgen.feature.configurations.GeodeConfiguration; ++import net.minecraft.world.level.levelgen.feature.configurations.LargeDripstoneConfiguration; ++import net.minecraft.world.level.levelgen.feature.configurations.MultifaceGrowthConfiguration; ++import net.minecraft.world.level.levelgen.feature.configurations.PointedDripstoneConfiguration; ++import net.minecraft.world.level.levelgen.feature.configurations.RandomBooleanFeatureConfiguration; ++import net.minecraft.world.level.levelgen.feature.configurations.RootSystemConfiguration; ++import net.minecraft.world.level.levelgen.feature.configurations.SculkPatchConfiguration; ++import net.minecraft.world.level.levelgen.feature.configurations.SimpleBlockConfiguration; ++import net.minecraft.world.level.levelgen.feature.configurations.SimpleRandomFeatureConfiguration; ++import net.minecraft.world.level.levelgen.feature.configurations.UnderwaterMagmaConfiguration; ++import net.minecraft.world.level.levelgen.feature.configurations.VegetationPatchConfiguration; ++import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; ++import net.minecraft.world.level.levelgen.feature.stateproviders.RandomizedIntStateProvider; ++import net.minecraft.world.level.levelgen.feature.stateproviders.WeightedStateProvider; ++import net.minecraft.world.level.levelgen.placement.CaveSurface; ++import net.minecraft.world.level.levelgen.placement.EnvironmentScanPlacement; ++import net.minecraft.world.level.levelgen.placement.PlacedFeature; ++import net.minecraft.world.level.levelgen.placement.RandomOffsetPlacement; ++import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList; ++ ++public class CaveFeatures { ++ public static final ResourceKey> MONSTER_ROOM = FeatureUtils.createKey("monster_room"); ++ public static final ResourceKey> FOSSIL_COAL = FeatureUtils.createKey("fossil_coal"); ++ public static final ResourceKey> FOSSIL_DIAMONDS = FeatureUtils.createKey("fossil_diamonds"); ++ public static final ResourceKey> DRIPSTONE_CLUSTER = FeatureUtils.createKey("dripstone_cluster"); ++ public static final ResourceKey> LARGE_DRIPSTONE = FeatureUtils.createKey("large_dripstone"); ++ public static final ResourceKey> POINTED_DRIPSTONE = FeatureUtils.createKey("pointed_dripstone"); ++ public static final ResourceKey> UNDERWATER_MAGMA = FeatureUtils.createKey("underwater_magma"); ++ public static final ResourceKey> GLOW_LICHEN = FeatureUtils.createKey("glow_lichen"); ++ public static final ResourceKey> ROOTED_AZALEA_TREE = FeatureUtils.createKey("rooted_azalea_tree"); ++ public static final ResourceKey> CAVE_VINE = FeatureUtils.createKey("cave_vine"); ++ public static final ResourceKey> CAVE_VINE_IN_MOSS = FeatureUtils.createKey("cave_vine_in_moss"); ++ public static final ResourceKey> MOSS_VEGETATION = FeatureUtils.createKey("moss_vegetation"); ++ public static final ResourceKey> MOSS_PATCH = FeatureUtils.createKey("moss_patch"); ++ public static final ResourceKey> MOSS_PATCH_BONEMEAL = FeatureUtils.createKey("moss_patch_bonemeal"); ++ public static final ResourceKey> DRIPLEAF = FeatureUtils.createKey("dripleaf"); ++ public static final ResourceKey> CLAY_WITH_DRIPLEAVES = FeatureUtils.createKey("clay_with_dripleaves"); ++ public static final ResourceKey> CLAY_POOL_WITH_DRIPLEAVES = FeatureUtils.createKey("clay_pool_with_dripleaves"); ++ public static final ResourceKey> LUSH_CAVES_CLAY = FeatureUtils.createKey("lush_caves_clay"); ++ public static final ResourceKey> MOSS_PATCH_CEILING = FeatureUtils.createKey("moss_patch_ceiling"); ++ public static final ResourceKey> SPORE_BLOSSOM = FeatureUtils.createKey("spore_blossom"); ++ public static final ResourceKey> AMETHYST_GEODE = FeatureUtils.createKey("amethyst_geode"); ++ public static final ResourceKey> SCULK_PATCH_DEEP_DARK = FeatureUtils.createKey("sculk_patch_deep_dark"); ++ public static final ResourceKey> SCULK_PATCH_ANCIENT_CITY = FeatureUtils.createKey("sculk_patch_ancient_city"); ++ public static final ResourceKey> SCULK_VEIN = FeatureUtils.createKey("sculk_vein"); ++ ++ private static Holder makeDripleaf(Direction direction) { ++ return PlacementUtils.inlinePlaced(Feature.BLOCK_COLUMN, new BlockColumnConfiguration(List.of(BlockColumnConfiguration.layer(new WeightedListInt(SimpleWeightedRandomList.builder().add(UniformInt.of(0, 4), 2).add(ConstantInt.of(0), 1).build()), BlockStateProvider.simple(Blocks.BIG_DRIPLEAF_STEM.defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, direction))), BlockColumnConfiguration.layer(ConstantInt.of(1), BlockStateProvider.simple(Blocks.BIG_DRIPLEAF.defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, direction)))), Direction.UP, BlockPredicate.ONLY_IN_AIR_OR_WATER_PREDICATE, true)); ++ } ++ ++ private static Holder makeSmallDripleaf() { ++ return PlacementUtils.inlinePlaced(Feature.SIMPLE_BLOCK, new SimpleBlockConfiguration(new WeightedStateProvider(SimpleWeightedRandomList.builder().add(Blocks.SMALL_DRIPLEAF.defaultBlockState().setValue(SmallDripleafBlock.FACING, Direction.EAST), 1).add(Blocks.SMALL_DRIPLEAF.defaultBlockState().setValue(SmallDripleafBlock.FACING, Direction.WEST), 1).add(Blocks.SMALL_DRIPLEAF.defaultBlockState().setValue(SmallDripleafBlock.FACING, Direction.NORTH), 1).add(Blocks.SMALL_DRIPLEAF.defaultBlockState().setValue(SmallDripleafBlock.FACING, Direction.SOUTH), 1)))); ++ } ++ ++ public static void bootstrap(BootstapContext> featureRegisterable) { ++ HolderGetter> holderGetter = featureRegisterable.lookup(Registries.CONFIGURED_FEATURE); ++ HolderGetter holderGetter2 = featureRegisterable.lookup(Registries.PROCESSOR_LIST); ++ FeatureUtils.register(featureRegisterable, MONSTER_ROOM, Feature.MONSTER_ROOM); ++ List list = List.of(new ResourceLocation("fossil/spine_1"), new ResourceLocation("fossil/spine_2"), new ResourceLocation("fossil/spine_3"), new ResourceLocation("fossil/spine_4"), new ResourceLocation("fossil/skull_1"), new ResourceLocation("fossil/skull_2"), new ResourceLocation("fossil/skull_3"), new ResourceLocation("fossil/skull_4")); ++ List list2 = List.of(new ResourceLocation("fossil/spine_1_coal"), new ResourceLocation("fossil/spine_2_coal"), new ResourceLocation("fossil/spine_3_coal"), new ResourceLocation("fossil/spine_4_coal"), new ResourceLocation("fossil/skull_1_coal"), new ResourceLocation("fossil/skull_2_coal"), new ResourceLocation("fossil/skull_3_coal"), new ResourceLocation("fossil/skull_4_coal")); ++ Holder holder = holderGetter2.getOrThrow(ProcessorLists.FOSSIL_ROT); ++ FeatureUtils.register(featureRegisterable, FOSSIL_COAL, Feature.FOSSIL, new FossilFeatureConfiguration(list, list2, holder, holderGetter2.getOrThrow(ProcessorLists.FOSSIL_COAL), 4)); ++ FeatureUtils.register(featureRegisterable, FOSSIL_DIAMONDS, Feature.FOSSIL, new FossilFeatureConfiguration(list, list2, holder, holderGetter2.getOrThrow(ProcessorLists.FOSSIL_DIAMONDS), 4)); ++ FeatureUtils.register(featureRegisterable, DRIPSTONE_CLUSTER, Feature.DRIPSTONE_CLUSTER, new DripstoneClusterConfiguration(12, UniformInt.of(3, 6), UniformInt.of(2, 8), 1, 3, UniformInt.of(2, 4), UniformFloat.of(0.3F, 0.7F), ClampedNormalFloat.of(0.1F, 0.3F, 0.1F, 0.9F), 0.1F, 3, 8)); ++ FeatureUtils.register(featureRegisterable, LARGE_DRIPSTONE, Feature.LARGE_DRIPSTONE, new LargeDripstoneConfiguration(30, UniformInt.of(3, 19), UniformFloat.of(0.4F, 2.0F), 0.33F, UniformFloat.of(0.3F, 0.9F), UniformFloat.of(0.4F, 1.0F), UniformFloat.of(0.0F, 0.3F), 4, 0.6F)); ++ FeatureUtils.register(featureRegisterable, POINTED_DRIPSTONE, Feature.SIMPLE_RANDOM_SELECTOR, new SimpleRandomFeatureConfiguration(HolderSet.direct(PlacementUtils.inlinePlaced(Feature.POINTED_DRIPSTONE, new PointedDripstoneConfiguration(0.2F, 0.7F, 0.5F, 0.5F), EnvironmentScanPlacement.scanningFor(Direction.DOWN, BlockPredicate.solid(), BlockPredicate.ONLY_IN_AIR_OR_WATER_PREDICATE, 12), RandomOffsetPlacement.vertical(ConstantInt.of(1))), PlacementUtils.inlinePlaced(Feature.POINTED_DRIPSTONE, new PointedDripstoneConfiguration(0.2F, 0.7F, 0.5F, 0.5F), EnvironmentScanPlacement.scanningFor(Direction.UP, BlockPredicate.solid(), BlockPredicate.ONLY_IN_AIR_OR_WATER_PREDICATE, 12), RandomOffsetPlacement.vertical(ConstantInt.of(-1)))))); ++ FeatureUtils.register(featureRegisterable, UNDERWATER_MAGMA, Feature.UNDERWATER_MAGMA, new UnderwaterMagmaConfiguration(5, 1, 0.5F)); ++ MultifaceBlock multifaceBlock = (MultifaceBlock)Blocks.GLOW_LICHEN; ++ FeatureUtils.register(featureRegisterable, GLOW_LICHEN, Feature.MULTIFACE_GROWTH, new MultifaceGrowthConfiguration(multifaceBlock, 20, false, true, true, 0.5F, HolderSet.direct(Block::builtInRegistryHolder, Blocks.STONE, Blocks.ANDESITE, Blocks.DIORITE, Blocks.GRANITE, Blocks.DRIPSTONE_BLOCK, Blocks.CALCITE, Blocks.TUFF, Blocks.DEEPSLATE))); ++ FeatureUtils.register(featureRegisterable, ROOTED_AZALEA_TREE, Feature.ROOT_SYSTEM, new RootSystemConfiguration(PlacementUtils.inlinePlaced(holderGetter.getOrThrow(TreeFeatures.AZALEA_TREE)), 3, 3, BlockTags.AZALEA_ROOT_REPLACEABLE, BlockStateProvider.simple(Blocks.ROOTED_DIRT), 20, 100, 3, 2, BlockStateProvider.simple(Blocks.HANGING_ROOTS), 20, 2, BlockPredicate.allOf(BlockPredicate.anyOf(BlockPredicate.matchesBlocks(List.of(Blocks.AIR, Blocks.CAVE_AIR, Blocks.VOID_AIR)), BlockPredicate.matchesTag(BlockTags.REPLACEABLE_BY_TREES)), BlockPredicate.matchesTag(Direction.DOWN.getNormal(), BlockTags.AZALEA_GROWS_ON)))); ++ WeightedStateProvider weightedStateProvider = new WeightedStateProvider(SimpleWeightedRandomList.builder().add(Blocks.CAVE_VINES_PLANT.defaultBlockState(), 4).add(Blocks.CAVE_VINES_PLANT.defaultBlockState().setValue(CaveVines.BERRIES, Boolean.valueOf(true)), 1)); ++ RandomizedIntStateProvider randomizedIntStateProvider = new RandomizedIntStateProvider(new WeightedStateProvider(SimpleWeightedRandomList.builder().add(Blocks.CAVE_VINES.defaultBlockState(), 4).add(Blocks.CAVE_VINES.defaultBlockState().setValue(CaveVines.BERRIES, Boolean.valueOf(true)), 1)), CaveVinesBlock.AGE, UniformInt.of(23, 25)); ++ FeatureUtils.register(featureRegisterable, CAVE_VINE, Feature.BLOCK_COLUMN, new BlockColumnConfiguration(List.of(BlockColumnConfiguration.layer(new WeightedListInt(SimpleWeightedRandomList.builder().add(UniformInt.of(0, 19), 2).add(UniformInt.of(0, 2), 3).add(UniformInt.of(0, 6), 10).build()), weightedStateProvider), BlockColumnConfiguration.layer(ConstantInt.of(1), randomizedIntStateProvider)), Direction.DOWN, BlockPredicate.ONLY_IN_AIR_PREDICATE, true)); ++ FeatureUtils.register(featureRegisterable, CAVE_VINE_IN_MOSS, Feature.BLOCK_COLUMN, new BlockColumnConfiguration(List.of(BlockColumnConfiguration.layer(new WeightedListInt(SimpleWeightedRandomList.builder().add(UniformInt.of(0, 3), 5).add(UniformInt.of(1, 7), 1).build()), weightedStateProvider), BlockColumnConfiguration.layer(ConstantInt.of(1), randomizedIntStateProvider)), Direction.DOWN, BlockPredicate.ONLY_IN_AIR_PREDICATE, true)); ++ FeatureUtils.register(featureRegisterable, MOSS_VEGETATION, Feature.SIMPLE_BLOCK, new SimpleBlockConfiguration(new WeightedStateProvider(SimpleWeightedRandomList.builder().add(Blocks.FLOWERING_AZALEA.defaultBlockState(), 4).add(Blocks.AZALEA.defaultBlockState(), 7).add(Blocks.MOSS_CARPET.defaultBlockState(), 25).add(Blocks.SHORT_GRASS.defaultBlockState(), 50).add(Blocks.TALL_GRASS.defaultBlockState(), 10)))); ++ FeatureUtils.register(featureRegisterable, MOSS_PATCH, Feature.VEGETATION_PATCH, new VegetationPatchConfiguration(BlockTags.MOSS_REPLACEABLE, BlockStateProvider.simple(Blocks.MOSS_BLOCK), PlacementUtils.inlinePlaced(holderGetter.getOrThrow(MOSS_VEGETATION)), CaveSurface.FLOOR, ConstantInt.of(1), 0.0F, 5, 0.8F, UniformInt.of(4, 7), 0.3F)); ++ FeatureUtils.register(featureRegisterable, MOSS_PATCH_BONEMEAL, Feature.VEGETATION_PATCH, new VegetationPatchConfiguration(BlockTags.MOSS_REPLACEABLE, BlockStateProvider.simple(Blocks.MOSS_BLOCK), PlacementUtils.inlinePlaced(holderGetter.getOrThrow(MOSS_VEGETATION)), CaveSurface.FLOOR, ConstantInt.of(1), 0.0F, 5, 0.6F, UniformInt.of(1, 2), 0.75F)); ++ FeatureUtils.register(featureRegisterable, DRIPLEAF, Feature.SIMPLE_RANDOM_SELECTOR, new SimpleRandomFeatureConfiguration(HolderSet.direct(makeSmallDripleaf(), makeDripleaf(Direction.EAST), makeDripleaf(Direction.WEST), makeDripleaf(Direction.SOUTH), makeDripleaf(Direction.NORTH)))); ++ FeatureUtils.register(featureRegisterable, CLAY_WITH_DRIPLEAVES, Feature.VEGETATION_PATCH, new VegetationPatchConfiguration(BlockTags.LUSH_GROUND_REPLACEABLE, BlockStateProvider.simple(Blocks.CLAY), PlacementUtils.inlinePlaced(holderGetter.getOrThrow(DRIPLEAF)), CaveSurface.FLOOR, ConstantInt.of(3), 0.8F, 2, 0.05F, UniformInt.of(4, 7), 0.7F)); ++ FeatureUtils.register(featureRegisterable, CLAY_POOL_WITH_DRIPLEAVES, Feature.WATERLOGGED_VEGETATION_PATCH, new VegetationPatchConfiguration(BlockTags.LUSH_GROUND_REPLACEABLE, BlockStateProvider.simple(Blocks.CLAY), PlacementUtils.inlinePlaced(holderGetter.getOrThrow(DRIPLEAF)), CaveSurface.FLOOR, ConstantInt.of(3), 0.8F, 5, 0.1F, UniformInt.of(4, 7), 0.7F)); ++ FeatureUtils.register(featureRegisterable, LUSH_CAVES_CLAY, Feature.RANDOM_BOOLEAN_SELECTOR, new RandomBooleanFeatureConfiguration(PlacementUtils.inlinePlaced(holderGetter.getOrThrow(CLAY_WITH_DRIPLEAVES)), PlacementUtils.inlinePlaced(holderGetter.getOrThrow(CLAY_POOL_WITH_DRIPLEAVES)))); ++ FeatureUtils.register(featureRegisterable, MOSS_PATCH_CEILING, Feature.VEGETATION_PATCH, new VegetationPatchConfiguration(BlockTags.MOSS_REPLACEABLE, BlockStateProvider.simple(Blocks.MOSS_BLOCK), PlacementUtils.inlinePlaced(holderGetter.getOrThrow(CAVE_VINE_IN_MOSS)), CaveSurface.CEILING, UniformInt.of(1, 2), 0.0F, 5, 0.08F, UniformInt.of(4, 7), 0.3F)); ++ FeatureUtils.register(featureRegisterable, SPORE_BLOSSOM, Feature.SIMPLE_BLOCK, new SimpleBlockConfiguration(BlockStateProvider.simple(Blocks.SPORE_BLOSSOM))); ++ FeatureUtils.register(featureRegisterable, AMETHYST_GEODE, Feature.GEODE, new GeodeConfiguration(new GeodeBlockSettings(BlockStateProvider.simple(Blocks.AIR), BlockStateProvider.simple(Blocks.AMETHYST_BLOCK), BlockStateProvider.simple(Blocks.BUDDING_AMETHYST), BlockStateProvider.simple(Blocks.CALCITE), BlockStateProvider.simple(Blocks.SMOOTH_BASALT), List.of(Blocks.SMALL_AMETHYST_BUD.defaultBlockState(), Blocks.MEDIUM_AMETHYST_BUD.defaultBlockState(), Blocks.LARGE_AMETHYST_BUD.defaultBlockState(), Blocks.AMETHYST_CLUSTER.defaultBlockState()), BlockTags.FEATURES_CANNOT_REPLACE, BlockTags.GEODE_INVALID_BLOCKS), new GeodeLayerSettings(1.7D, 2.2D, 3.2D, 4.2D), new GeodeCrackSettings(0.95D, 2.0D, 2), 0.35D, 0.083D, true, UniformInt.of(4, 6), UniformInt.of(3, 4), UniformInt.of(1, 2), -16, 16, 0.05D, 1)); ++ FeatureUtils.register(featureRegisterable, SCULK_PATCH_DEEP_DARK, Feature.SCULK_PATCH, new SculkPatchConfiguration(10, 32, 64, 0, 1, ConstantInt.of(0), 0.5F)); ++ FeatureUtils.register(featureRegisterable, SCULK_PATCH_ANCIENT_CITY, Feature.SCULK_PATCH, new SculkPatchConfiguration(10, 32, 64, 0, 1, UniformInt.of(1, 3), 0.5F)); ++ MultifaceBlock multifaceBlock2 = (MultifaceBlock)Blocks.SCULK_VEIN; ++ FeatureUtils.register(featureRegisterable, SCULK_VEIN, Feature.MULTIFACE_GROWTH, new MultifaceGrowthConfiguration(multifaceBlock2, 20, true, true, true, 1.0F, HolderSet.direct(Block::builtInRegistryHolder, Blocks.STONE, Blocks.ANDESITE, Blocks.DIORITE, Blocks.GRANITE, Blocks.DRIPSTONE_BLOCK, Blocks.CALCITE, Blocks.TUFF, Blocks.DEEPSLATE))); ++ } ++} +diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java +new file mode 100644 +index 0000000000000000000000000000000000000000..5a8f850b447fc3a4bd0eb0c505bbdfc8be7115e8 +--- /dev/null ++++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java +@@ -0,0 +1,64 @@ ++package net.minecraft.network.protocol.game; ++ ++import com.google.common.collect.Lists; ++import com.mojang.datafixers.util.Pair; ++import java.util.List; ++import net.minecraft.network.FriendlyByteBuf; ++import net.minecraft.network.protocol.Packet; ++import net.minecraft.world.entity.EquipmentSlot; ++import net.minecraft.world.item.ItemStack; ++ ++public class ClientboundSetEquipmentPacket implements Packet { ++ private static final byte CONTINUE_MASK = -128; ++ private final int entity; ++ private final List> slots; ++ ++ public ClientboundSetEquipmentPacket(int id, List> equipmentList) { ++ this.entity = id; ++ this.slots = equipmentList; ++ } ++ ++ public ClientboundSetEquipmentPacket(FriendlyByteBuf buf) { ++ this.entity = buf.readVarInt(); ++ EquipmentSlot[] equipmentSlots = EquipmentSlot.values(); ++ this.slots = Lists.newArrayList(); ++ ++ int i; ++ do { ++ i = buf.readByte(); ++ EquipmentSlot equipmentSlot = equipmentSlots[i & 127]; ++ ItemStack itemStack = buf.readItem(); ++ this.slots.add(Pair.of(equipmentSlot, itemStack)); ++ } while((i & -128) != 0); ++ ++ } ++ ++ @Override ++ public void write(FriendlyByteBuf buf) { ++ buf.writeVarInt(this.entity); ++ int i = this.slots.size(); ++ ++ for(int j = 0; j < i; ++j) { ++ Pair pair = this.slots.get(j); ++ EquipmentSlot equipmentSlot = pair.getFirst(); ++ boolean bl = j != i - 1; ++ int k = equipmentSlot.ordinal(); ++ buf.writeByte(bl ? k | -128 : k); ++ buf.writeItem(pair.getSecond()); ++ } ++ ++ } ++ ++ @Override ++ public void handle(ClientGamePacketListener listener) { ++ listener.handleSetEquipment(this); ++ } ++ ++ public int getEntity() { ++ return this.entity; ++ } ++ ++ public List> getSlots() { ++ return this.slots; ++ } ++} +diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/WardenAi.java b/src/main/java/net/minecraft/world/entity/monster/warden/WardenAi.java +new file mode 100644 +index 0000000000000000000000000000000000000000..03f16a5541de6bc95407aaa24741570c1993dc9e +--- /dev/null ++++ b/src/main/java/net/minecraft/world/entity/monster/warden/WardenAi.java +@@ -0,0 +1,156 @@ ++package net.minecraft.world.entity.monster.warden; ++ ++import com.google.common.collect.ImmutableList; ++import com.google.common.collect.ImmutableMap; ++import com.google.common.collect.ImmutableSet; ++import com.mojang.datafixers.util.Pair; ++import com.mojang.serialization.Dynamic; ++import java.util.List; ++import net.minecraft.core.BlockPos; ++import net.minecraft.util.Mth; ++import net.minecraft.util.Unit; ++import net.minecraft.world.entity.LivingEntity; ++import net.minecraft.world.entity.ai.Brain; ++import net.minecraft.world.entity.ai.attributes.Attributes; ++import net.minecraft.world.entity.ai.behavior.BehaviorControl; ++import net.minecraft.world.entity.ai.behavior.BlockPosTracker; ++import net.minecraft.world.entity.ai.behavior.DoNothing; ++import net.minecraft.world.entity.ai.behavior.GoToTargetLocation; ++import net.minecraft.world.entity.ai.behavior.LookAtTargetSink; ++import net.minecraft.world.entity.ai.behavior.MeleeAttack; ++import net.minecraft.world.entity.ai.behavior.MoveToTargetSink; ++import net.minecraft.world.entity.ai.behavior.RandomStroll; ++import net.minecraft.world.entity.ai.behavior.RunOne; ++import net.minecraft.world.entity.ai.behavior.SetEntityLookTarget; ++import net.minecraft.world.entity.ai.behavior.SetWalkTargetFromAttackTargetIfTargetOutOfReach; ++import net.minecraft.world.entity.ai.behavior.StopAttackingIfTargetInvalid; ++import net.minecraft.world.entity.ai.behavior.Swim; ++import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder; ++import net.minecraft.world.entity.ai.behavior.warden.Digging; ++import net.minecraft.world.entity.ai.behavior.warden.Emerging; ++import net.minecraft.world.entity.ai.behavior.warden.ForceUnmount; ++import net.minecraft.world.entity.ai.behavior.warden.Roar; ++import net.minecraft.world.entity.ai.behavior.warden.SetRoarTarget; ++import net.minecraft.world.entity.ai.behavior.warden.SetWardenLookTarget; ++import net.minecraft.world.entity.ai.behavior.warden.Sniffing; ++import net.minecraft.world.entity.ai.behavior.warden.SonicBoom; ++import net.minecraft.world.entity.ai.behavior.warden.TryToSniff; ++import net.minecraft.world.entity.ai.memory.MemoryModuleType; ++import net.minecraft.world.entity.ai.memory.MemoryStatus; ++import net.minecraft.world.entity.ai.sensing.Sensor; ++import net.minecraft.world.entity.ai.sensing.SensorType; ++import net.minecraft.world.entity.schedule.Activity; ++ ++public class WardenAi { ++ private static final float SPEED_MULTIPLIER_WHEN_IDLING = 0.5F; ++ private static final float SPEED_MULTIPLIER_WHEN_INVESTIGATING = 0.7F; ++ private static final float SPEED_MULTIPLIER_WHEN_FIGHTING = 1.2F; ++ private static final int MELEE_ATTACK_COOLDOWN = 18; ++ private static final int DIGGING_DURATION = Mth.ceil(100.0F); ++ public static final int EMERGE_DURATION = Mth.ceil(133.59999F); ++ public static final int ROAR_DURATION = Mth.ceil(84.0F); ++ private static final int SNIFFING_DURATION = Mth.ceil(83.2F); ++ public static final int DIGGING_COOLDOWN = 1200; ++ private static final int DISTURBANCE_LOCATION_EXPIRY_TIME = 100; ++ private static final List>> SENSOR_TYPES = List.of(SensorType.NEAREST_PLAYERS, SensorType.WARDEN_ENTITY_SENSOR); ++ private static final List> MEMORY_TYPES = List.of(MemoryModuleType.NEAREST_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_NEMESIS, MemoryModuleType.LOOK_TARGET, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.ATTACK_TARGET, MemoryModuleType.ATTACK_COOLING_DOWN, MemoryModuleType.NEAREST_ATTACKABLE, MemoryModuleType.ROAR_TARGET, MemoryModuleType.DISTURBANCE_LOCATION, MemoryModuleType.RECENT_PROJECTILE, MemoryModuleType.IS_SNIFFING, MemoryModuleType.IS_EMERGING, MemoryModuleType.ROAR_SOUND_DELAY, MemoryModuleType.DIG_COOLDOWN, MemoryModuleType.ROAR_SOUND_COOLDOWN, MemoryModuleType.SNIFF_COOLDOWN, MemoryModuleType.TOUCH_COOLDOWN, MemoryModuleType.VIBRATION_COOLDOWN, MemoryModuleType.SONIC_BOOM_COOLDOWN, MemoryModuleType.SONIC_BOOM_SOUND_COOLDOWN, MemoryModuleType.SONIC_BOOM_SOUND_DELAY); ++ private static final BehaviorControl DIG_COOLDOWN_SETTER = BehaviorBuilder.create((context) -> { ++ return context.group(context.registered(MemoryModuleType.DIG_COOLDOWN)).apply(context, (digCooldown) -> { ++ return (world, entity, time) -> { ++ if (context.tryGet(digCooldown).isPresent()) { ++ digCooldown.setWithExpiry(Unit.INSTANCE, 1200L); ++ } ++ ++ return true; ++ }; ++ }); ++ }); ++ ++ public static void updateActivity(Warden warden) { ++ warden.getBrain().setActiveActivityToFirstValid(ImmutableList.of(Activity.EMERGE, Activity.DIG, Activity.ROAR, Activity.FIGHT, Activity.INVESTIGATE, Activity.SNIFF, Activity.IDLE)); ++ } ++ ++ protected static Brain makeBrain(Warden warden, Dynamic dynamic) { ++ Brain.Provider provider = Brain.provider(MEMORY_TYPES, SENSOR_TYPES); ++ Brain brain = provider.makeBrain(dynamic); ++ initCoreActivity(brain); ++ initEmergeActivity(brain); ++ initDiggingActivity(brain); ++ initIdleActivity(brain); ++ initRoarActivity(brain); ++ initFightActivity(warden, brain); ++ initInvestigateActivity(brain); ++ initSniffingActivity(brain); ++ brain.setCoreActivities(ImmutableSet.of(Activity.CORE)); ++ brain.setDefaultActivity(Activity.IDLE); ++ brain.useDefaultActivity(); ++ return brain; ++ } ++ ++ private static void initCoreActivity(Brain brain) { ++ brain.addActivity(Activity.CORE, 0, ImmutableList.of(new Swim(0.8F), SetWardenLookTarget.create(), new LookAtTargetSink(45, 90), new MoveToTargetSink())); ++ } ++ ++ private static void initEmergeActivity(Brain brain) { ++ brain.addActivityAndRemoveMemoryWhenStopped(Activity.EMERGE, 5, ImmutableList.of(new Emerging<>(EMERGE_DURATION)), MemoryModuleType.IS_EMERGING); ++ } ++ ++ private static void initDiggingActivity(Brain brain) { ++ brain.addActivityWithConditions(Activity.DIG, ImmutableList.of(Pair.of(0, new ForceUnmount()), Pair.of(1, new Digging<>(DIGGING_DURATION))), ImmutableSet.of(Pair.of(MemoryModuleType.ROAR_TARGET, MemoryStatus.VALUE_ABSENT), Pair.of(MemoryModuleType.DIG_COOLDOWN, MemoryStatus.VALUE_ABSENT))); ++ } ++ ++ private static void initIdleActivity(Brain brain) { ++ brain.addActivity(Activity.IDLE, 10, ImmutableList.of(SetRoarTarget.create(Warden::getEntityAngryAt), TryToSniff.create(), new RunOne<>(ImmutableMap.of(MemoryModuleType.IS_SNIFFING, MemoryStatus.VALUE_ABSENT), ImmutableList.of(Pair.of(RandomStroll.stroll(0.5F), 2), Pair.of(new DoNothing(30, 60), 1))))); ++ } ++ ++ private static void initInvestigateActivity(Brain brain) { ++ brain.addActivityAndRemoveMemoryWhenStopped(Activity.INVESTIGATE, 5, ImmutableList.of(SetRoarTarget.create(Warden::getEntityAngryAt), GoToTargetLocation.create(MemoryModuleType.DISTURBANCE_LOCATION, 2, 0.7F)), MemoryModuleType.DISTURBANCE_LOCATION); ++ } ++ ++ private static void initSniffingActivity(Brain brain) { ++ brain.addActivityAndRemoveMemoryWhenStopped(Activity.SNIFF, 5, ImmutableList.of(SetRoarTarget.create(Warden::getEntityAngryAt), new Sniffing<>(SNIFFING_DURATION)), MemoryModuleType.IS_SNIFFING); ++ } ++ ++ private static void initRoarActivity(Brain brain) { ++ brain.addActivityAndRemoveMemoryWhenStopped(Activity.ROAR, 10, ImmutableList.of(new Roar()), MemoryModuleType.ROAR_TARGET); ++ } ++ ++ private static void initFightActivity(Warden warden, Brain brain) { ++ brain.addActivityAndRemoveMemoryWhenStopped(Activity.FIGHT, 10, ImmutableList.of(DIG_COOLDOWN_SETTER, StopAttackingIfTargetInvalid.create((entity) -> { ++ return !warden.getAngerLevel().isAngry() || !warden.canTargetEntity(entity); ++ }, WardenAi::onTargetInvalid, false), SetEntityLookTarget.create((entity) -> { ++ return isTarget(warden, entity); ++ }, (float)warden.getAttributeValue(Attributes.FOLLOW_RANGE)), SetWalkTargetFromAttackTargetIfTargetOutOfReach.create(1.2F), new SonicBoom(), MeleeAttack.create(18)), MemoryModuleType.ATTACK_TARGET); ++ } ++ ++ private static boolean isTarget(Warden warden, LivingEntity entity) { ++ return warden.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).filter((entityx) -> { ++ return entityx == entity; ++ }).isPresent(); ++ } ++ ++ private static void onTargetInvalid(Warden warden, LivingEntity suspect) { ++ if (!warden.canTargetEntity(suspect)) { ++ warden.clearAnger(suspect); ++ } ++ ++ setDigCooldown(warden); ++ } ++ ++ public static void setDigCooldown(LivingEntity warden) { ++ if (warden.getBrain().hasMemoryValue(MemoryModuleType.DIG_COOLDOWN)) { ++ warden.getBrain().setMemoryWithExpiry(MemoryModuleType.DIG_COOLDOWN, Unit.INSTANCE, 1200L); ++ } ++ ++ } ++ ++ public static void setDisturbanceLocation(Warden warden, BlockPos pos) { ++ if (warden.level().getWorldBorder().isWithinBounds(pos) && !warden.getEntityAngryAt().isPresent() && !warden.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).isPresent()) { ++ setDigCooldown(warden); ++ warden.getBrain().setMemoryWithExpiry(MemoryModuleType.SNIFF_COOLDOWN, Unit.INSTANCE, 100L); ++ warden.getBrain().setMemoryWithExpiry(MemoryModuleType.LOOK_TARGET, new BlockPosTracker(pos), 100L); ++ warden.getBrain().setMemoryWithExpiry(MemoryModuleType.DISTURBANCE_LOCATION, pos, 100L); ++ warden.getBrain().eraseMemory(MemoryModuleType.WALK_TARGET); ++ } ++ } ++} +diff --git a/src/main/java/net/minecraft/world/food/Foods.java b/src/main/java/net/minecraft/world/food/Foods.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b16d9e2eaa589f19c563ee70b1a56d67dbcdecb0 +--- /dev/null ++++ b/src/main/java/net/minecraft/world/food/Foods.java +@@ -0,0 +1,51 @@ ++package net.minecraft.world.food; ++ ++import net.minecraft.world.effect.MobEffectInstance; ++import net.minecraft.world.effect.MobEffects; ++ ++public class Foods { ++ public static final FoodProperties APPLE = (new FoodProperties.Builder()).nutrition(4).saturationMod(0.3F).build(); ++ public static final FoodProperties BAKED_POTATO = (new FoodProperties.Builder()).nutrition(5).saturationMod(0.6F).build(); ++ public static final FoodProperties BEEF = (new FoodProperties.Builder()).nutrition(3).saturationMod(0.3F).meat().build(); ++ public static final FoodProperties BEETROOT = (new FoodProperties.Builder()).nutrition(1).saturationMod(0.6F).build(); ++ public static final FoodProperties BEETROOT_SOUP = stew(6).build(); ++ public static final FoodProperties BREAD = (new FoodProperties.Builder()).nutrition(5).saturationMod(0.6F).build(); ++ public static final FoodProperties CARROT = (new FoodProperties.Builder()).nutrition(3).saturationMod(0.6F).build(); ++ public static final FoodProperties CHICKEN = (new FoodProperties.Builder()).nutrition(2).saturationMod(0.3F).effect(new MobEffectInstance(MobEffects.HUNGER, 600, 0), 0.3F).meat().build(); ++ public static final FoodProperties CHORUS_FRUIT = (new FoodProperties.Builder()).nutrition(4).saturationMod(0.3F).alwaysEat().build(); ++ public static final FoodProperties COD = (new FoodProperties.Builder()).nutrition(2).saturationMod(0.1F).build(); ++ public static final FoodProperties COOKED_BEEF = (new FoodProperties.Builder()).nutrition(8).saturationMod(0.8F).meat().build(); ++ public static final FoodProperties COOKED_CHICKEN = (new FoodProperties.Builder()).nutrition(6).saturationMod(0.6F).meat().build(); ++ public static final FoodProperties COOKED_COD = (new FoodProperties.Builder()).nutrition(5).saturationMod(0.6F).build(); ++ public static final FoodProperties COOKED_MUTTON = (new FoodProperties.Builder()).nutrition(6).saturationMod(0.8F).meat().build(); ++ public static final FoodProperties COOKED_PORKCHOP = (new FoodProperties.Builder()).nutrition(8).saturationMod(0.8F).meat().build(); ++ public static final FoodProperties COOKED_RABBIT = (new FoodProperties.Builder()).nutrition(5).saturationMod(0.6F).meat().build(); ++ public static final FoodProperties COOKED_SALMON = (new FoodProperties.Builder()).nutrition(6).saturationMod(0.8F).build(); ++ public static final FoodProperties COOKIE = (new FoodProperties.Builder()).nutrition(2).saturationMod(0.1F).build(); ++ public static final FoodProperties DRIED_KELP = (new FoodProperties.Builder()).nutrition(1).saturationMod(0.3F).fast().build(); ++ public static final FoodProperties ENCHANTED_GOLDEN_APPLE = (new FoodProperties.Builder()).nutrition(4).saturationMod(1.2F).effect(new MobEffectInstance(MobEffects.REGENERATION, 400, 1), 1.0F).effect(new MobEffectInstance(MobEffects.DAMAGE_RESISTANCE, 6000, 0), 1.0F).effect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, 6000, 0), 1.0F).effect(new MobEffectInstance(MobEffects.ABSORPTION, 2400, 3), 1.0F).alwaysEat().build(); ++ public static final FoodProperties GOLDEN_APPLE = (new FoodProperties.Builder()).nutrition(4).saturationMod(1.2F).effect(new MobEffectInstance(MobEffects.REGENERATION, 100, 1), 1.0F).effect(new MobEffectInstance(MobEffects.ABSORPTION, 2400, 0), 1.0F).alwaysEat().build(); ++ public static final FoodProperties GOLDEN_CARROT = (new FoodProperties.Builder()).nutrition(6).saturationMod(1.2F).build(); ++ public static final FoodProperties HONEY_BOTTLE = (new FoodProperties.Builder()).nutrition(6).saturationMod(0.1F).build(); ++ public static final FoodProperties MELON_SLICE = (new FoodProperties.Builder()).nutrition(2).saturationMod(0.3F).build(); ++ public static final FoodProperties MUSHROOM_STEW = stew(6).build(); ++ public static final FoodProperties MUTTON = (new FoodProperties.Builder()).nutrition(2).saturationMod(0.3F).meat().build(); ++ public static final FoodProperties POISONOUS_POTATO = (new FoodProperties.Builder()).nutrition(2).saturationMod(0.3F).effect(new MobEffectInstance(MobEffects.POISON, 100, 0), 0.6F).build(); ++ public static final FoodProperties PORKCHOP = (new FoodProperties.Builder()).nutrition(3).saturationMod(0.3F).meat().build(); ++ public static final FoodProperties POTATO = (new FoodProperties.Builder()).nutrition(1).saturationMod(0.3F).build(); ++ public static final FoodProperties PUFFERFISH = (new FoodProperties.Builder()).nutrition(1).saturationMod(0.1F).effect(new MobEffectInstance(MobEffects.POISON, 1200, 1), 1.0F).effect(new MobEffectInstance(MobEffects.HUNGER, 300, 2), 1.0F).effect(new MobEffectInstance(MobEffects.CONFUSION, 300, 0), 1.0F).build(); ++ public static final FoodProperties PUMPKIN_PIE = (new FoodProperties.Builder()).nutrition(8).saturationMod(0.3F).build(); ++ public static final FoodProperties RABBIT = (new FoodProperties.Builder()).nutrition(3).saturationMod(0.3F).meat().build(); ++ public static final FoodProperties RABBIT_STEW = stew(10).build(); ++ public static final FoodProperties ROTTEN_FLESH = (new FoodProperties.Builder()).nutrition(4).saturationMod(0.1F).effect(new MobEffectInstance(MobEffects.HUNGER, 600, 0), 0.8F).meat().build(); ++ public static final FoodProperties SALMON = (new FoodProperties.Builder()).nutrition(2).saturationMod(0.1F).build(); ++ public static final FoodProperties SPIDER_EYE = (new FoodProperties.Builder()).nutrition(2).saturationMod(0.8F).effect(new MobEffectInstance(MobEffects.POISON, 100, 0), 1.0F).build(); ++ public static final FoodProperties SUSPICIOUS_STEW = stew(6).alwaysEat().build(); ++ public static final FoodProperties SWEET_BERRIES = (new FoodProperties.Builder()).nutrition(2).saturationMod(0.1F).build(); ++ public static final FoodProperties GLOW_BERRIES = (new FoodProperties.Builder()).nutrition(2).saturationMod(0.1F).build(); ++ public static final FoodProperties TROPICAL_FISH = (new FoodProperties.Builder()).nutrition(1).saturationMod(0.1F).build(); ++ ++ private static FoodProperties.Builder stew(int hunger) { ++ return (new FoodProperties.Builder()).nutrition(hunger).saturationMod(0.6F); ++ } ++} +diff --git a/src/main/java/net/minecraft/world/level/biome/Biome.java b/src/main/java/net/minecraft/world/level/biome/Biome.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4f9187d9d640618c40a2fa528f36b845017b4777 +--- /dev/null ++++ b/src/main/java/net/minecraft/world/level/biome/Biome.java +@@ -0,0 +1,392 @@ ++package net.minecraft.world.level.biome; ++ ++import com.google.common.collect.ImmutableList; ++import com.mojang.serialization.Codec; ++import com.mojang.serialization.MapCodec; ++import com.mojang.serialization.codecs.RecordCodecBuilder; ++import it.unimi.dsi.fastutil.longs.Long2FloatLinkedOpenHashMap; ++import java.util.Optional; ++import javax.annotation.Nullable; ++import net.minecraft.Util; ++import net.minecraft.core.BlockPos; ++import net.minecraft.core.Holder; ++import net.minecraft.core.HolderSet; ++import net.minecraft.core.RegistryCodecs; ++import net.minecraft.core.registries.Registries; ++import net.minecraft.resources.RegistryFileCodec; ++import net.minecraft.sounds.Music; ++import net.minecraft.sounds.SoundEvent; ++import net.minecraft.util.Mth; ++import net.minecraft.util.StringRepresentable; ++import net.minecraft.world.level.FoliageColor; ++import net.minecraft.world.level.GrassColor; ++import net.minecraft.world.level.LevelReader; ++import net.minecraft.world.level.LightLayer; ++import net.minecraft.world.level.block.Blocks; ++import net.minecraft.world.level.block.LiquidBlock; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.levelgen.LegacyRandomSource; ++import net.minecraft.world.level.levelgen.WorldgenRandom; ++import net.minecraft.world.level.levelgen.synth.PerlinSimplexNoise; ++import net.minecraft.world.level.material.FluidState; ++import net.minecraft.world.level.material.Fluids; ++ ++public final class Biome { ++ public static final Codec DIRECT_CODEC = RecordCodecBuilder.create((instance) -> { ++ return instance.group(Biome.ClimateSettings.CODEC.forGetter((biome) -> { ++ return biome.climateSettings; ++ }), BiomeSpecialEffects.CODEC.fieldOf("effects").forGetter((biome) -> { ++ return biome.specialEffects; ++ }), BiomeGenerationSettings.CODEC.forGetter((biome) -> { ++ return biome.generationSettings; ++ }), MobSpawnSettings.CODEC.forGetter((biome) -> { ++ return biome.mobSettings; ++ })).apply(instance, Biome::new); ++ }); ++ public static final Codec NETWORK_CODEC = RecordCodecBuilder.create((instance) -> { ++ return instance.group(Biome.ClimateSettings.CODEC.forGetter((biome) -> { ++ return biome.climateSettings; ++ }), BiomeSpecialEffects.CODEC.fieldOf("effects").forGetter((biome) -> { ++ return biome.specialEffects; ++ })).apply(instance, (weather, effects) -> { ++ return new Biome(weather, effects, BiomeGenerationSettings.EMPTY, MobSpawnSettings.EMPTY); ++ }); ++ }); ++ public static final Codec> CODEC = RegistryFileCodec.create(Registries.BIOME, DIRECT_CODEC); ++ public static final Codec> LIST_CODEC = RegistryCodecs.homogeneousList(Registries.BIOME, DIRECT_CODEC); ++ private static final PerlinSimplexNoise TEMPERATURE_NOISE = new PerlinSimplexNoise(new WorldgenRandom(new LegacyRandomSource(1234L)), ImmutableList.of(0)); ++ static final PerlinSimplexNoise FROZEN_TEMPERATURE_NOISE = new PerlinSimplexNoise(new WorldgenRandom(new LegacyRandomSource(3456L)), ImmutableList.of(-2, -1, 0)); ++ /** @deprecated */ ++ @Deprecated( ++ forRemoval = true ++ ) ++ public static final PerlinSimplexNoise BIOME_INFO_NOISE = new PerlinSimplexNoise(new WorldgenRandom(new LegacyRandomSource(2345L)), ImmutableList.of(0)); ++ private static final int TEMPERATURE_CACHE_SIZE = 1024; ++ public final Biome.ClimateSettings climateSettings; ++ private final BiomeGenerationSettings generationSettings; ++ private final MobSpawnSettings mobSettings; ++ private final BiomeSpecialEffects specialEffects; ++ private final ThreadLocal temperatureCache = ThreadLocal.withInitial(() -> { ++ return Util.make(() -> { ++ Long2FloatLinkedOpenHashMap long2FloatLinkedOpenHashMap = new Long2FloatLinkedOpenHashMap(1024, 0.25F) { ++ protected void rehash(int i) { ++ } ++ }; ++ long2FloatLinkedOpenHashMap.defaultReturnValue(Float.NaN); ++ return long2FloatLinkedOpenHashMap; ++ }); ++ }); ++ ++ Biome(Biome.ClimateSettings weather, BiomeSpecialEffects effects, BiomeGenerationSettings generationSettings, MobSpawnSettings spawnSettings) { ++ this.climateSettings = weather; ++ this.generationSettings = generationSettings; ++ this.mobSettings = spawnSettings; ++ this.specialEffects = effects; ++ } ++ ++ public int getSkyColor() { ++ return this.specialEffects.getSkyColor(); ++ } ++ ++ public MobSpawnSettings getMobSettings() { ++ return this.mobSettings; ++ } ++ ++ public boolean hasPrecipitation() { ++ return this.climateSettings.hasPrecipitation(); ++ } ++ ++ public Biome.Precipitation getPrecipitationAt(BlockPos pos) { ++ if (!this.hasPrecipitation()) { ++ return Biome.Precipitation.NONE; ++ } else { ++ return this.coldEnoughToSnow(pos) ? Biome.Precipitation.SNOW : Biome.Precipitation.RAIN; ++ } ++ } ++ ++ private float getHeightAdjustedTemperature(BlockPos pos) { ++ float f = this.climateSettings.temperatureModifier.modifyTemperature(pos, this.getBaseTemperature()); ++ if (pos.getY() > 80) { ++ float g = (float)(TEMPERATURE_NOISE.getValue((double)((float)pos.getX() / 8.0F), (double)((float)pos.getZ() / 8.0F), false) * 8.0D); ++ return f - (g + (float)pos.getY() - 80.0F) * 0.05F / 40.0F; ++ } else { ++ return f; ++ } ++ } ++ ++ /** @deprecated */ ++ @Deprecated ++ public float getTemperature(BlockPos blockPos) { ++ long l = blockPos.asLong(); ++ Long2FloatLinkedOpenHashMap long2FloatLinkedOpenHashMap = this.temperatureCache.get(); ++ float f = long2FloatLinkedOpenHashMap.get(l); ++ if (!Float.isNaN(f)) { ++ return f; ++ } else { ++ float g = this.getHeightAdjustedTemperature(blockPos); ++ if (long2FloatLinkedOpenHashMap.size() == 1024) { ++ long2FloatLinkedOpenHashMap.removeFirstFloat(); ++ } ++ ++ long2FloatLinkedOpenHashMap.put(l, g); ++ return g; ++ } ++ } ++ ++ public boolean shouldFreeze(LevelReader world, BlockPos blockPos) { ++ return this.shouldFreeze(world, blockPos, true); ++ } ++ ++ public boolean shouldFreeze(LevelReader world, BlockPos pos, boolean doWaterCheck) { ++ if (this.warmEnoughToRain(pos)) { ++ return false; ++ } else { ++ if (pos.getY() >= world.getMinBuildHeight() && pos.getY() < world.getMaxBuildHeight() && world.getBrightness(LightLayer.BLOCK, pos) < 10) { ++ BlockState blockState = world.getBlockState(pos); ++ FluidState fluidState = world.getFluidState(pos); ++ if (fluidState.getType() == Fluids.WATER && blockState.getBlock() instanceof LiquidBlock) { ++ if (!doWaterCheck) { ++ return true; ++ } ++ ++ boolean bl = world.isWaterAt(pos.west()) && world.isWaterAt(pos.east()) && world.isWaterAt(pos.north()) && world.isWaterAt(pos.south()); ++ if (!bl) { ++ return true; ++ } ++ } ++ } ++ ++ return false; ++ } ++ } ++ ++ public boolean coldEnoughToSnow(BlockPos pos) { ++ return !this.warmEnoughToRain(pos); ++ } ++ ++ public boolean warmEnoughToRain(BlockPos pos) { ++ return this.getTemperature(pos) >= 0.15F; ++ } ++ ++ public boolean shouldMeltFrozenOceanIcebergSlightly(BlockPos pos) { ++ return this.getTemperature(pos) > 0.1F; ++ } ++ ++ public boolean shouldSnow(LevelReader world, BlockPos pos) { ++ if (this.warmEnoughToRain(pos)) { ++ return false; ++ } else { ++ if (pos.getY() >= world.getMinBuildHeight() && pos.getY() < world.getMaxBuildHeight() && world.getBrightness(LightLayer.BLOCK, pos) < 10) { ++ BlockState blockState = world.getBlockState(pos); ++ if ((blockState.isAir() || blockState.is(Blocks.SNOW)) && Blocks.SNOW.defaultBlockState().canSurvive(world, pos)) { ++ return true; ++ } ++ } ++ ++ return false; ++ } ++ } ++ ++ public BiomeGenerationSettings getGenerationSettings() { ++ return this.generationSettings; ++ } ++ ++ public int getFogColor() { ++ return this.specialEffects.getFogColor(); ++ } ++ ++ public int getGrassColor(double x, double z) { ++ int i = this.specialEffects.getGrassColorOverride().orElseGet(this::getGrassColorFromTexture); ++ return this.specialEffects.getGrassColorModifier().modifyColor(x, z, i); ++ } ++ ++ private int getGrassColorFromTexture() { ++ double d = (double)Mth.clamp(this.climateSettings.temperature, 0.0F, 1.0F); ++ double e = (double)Mth.clamp(this.climateSettings.downfall, 0.0F, 1.0F); ++ return GrassColor.get(d, e); ++ } ++ ++ public int getFoliageColor() { ++ return this.specialEffects.getFoliageColorOverride().orElseGet(this::getFoliageColorFromTexture); ++ } ++ ++ private int getFoliageColorFromTexture() { ++ double d = (double)Mth.clamp(this.climateSettings.temperature, 0.0F, 1.0F); ++ double e = (double)Mth.clamp(this.climateSettings.downfall, 0.0F, 1.0F); ++ return FoliageColor.get(d, e); ++ } ++ ++ public float getBaseTemperature() { ++ return this.climateSettings.temperature; ++ } ++ ++ public BiomeSpecialEffects getSpecialEffects() { ++ return this.specialEffects; ++ } ++ ++ public int getWaterColor() { ++ return this.specialEffects.getWaterColor(); ++ } ++ ++ public int getWaterFogColor() { ++ return this.specialEffects.getWaterFogColor(); ++ } ++ ++ public Optional getAmbientParticle() { ++ return this.specialEffects.getAmbientParticleSettings(); ++ } ++ ++ public Optional> getAmbientLoop() { ++ return this.specialEffects.getAmbientLoopSoundEvent(); ++ } ++ ++ public Optional getAmbientMood() { ++ return this.specialEffects.getAmbientMoodSettings(); ++ } ++ ++ public Optional getAmbientAdditions() { ++ return this.specialEffects.getAmbientAdditionsSettings(); ++ } ++ ++ public Optional getBackgroundMusic() { ++ return this.specialEffects.getBackgroundMusic(); ++ } ++ ++ public static class BiomeBuilder { ++ private boolean hasPrecipitation = true; ++ @Nullable ++ private Float temperature; ++ private Biome.TemperatureModifier temperatureModifier = Biome.TemperatureModifier.NONE; ++ @Nullable ++ private Float downfall; ++ @Nullable ++ private BiomeSpecialEffects specialEffects; ++ @Nullable ++ private MobSpawnSettings mobSpawnSettings; ++ @Nullable ++ private BiomeGenerationSettings generationSettings; ++ ++ public Biome.BiomeBuilder hasPrecipitation(boolean precipitation) { ++ this.hasPrecipitation = precipitation; ++ return this; ++ } ++ ++ public Biome.BiomeBuilder temperature(float temperature) { ++ this.temperature = temperature; ++ return this; ++ } ++ ++ public Biome.BiomeBuilder downfall(float downfall) { ++ this.downfall = downfall; ++ return this; ++ } ++ ++ public Biome.BiomeBuilder specialEffects(BiomeSpecialEffects effects) { ++ this.specialEffects = effects; ++ return this; ++ } ++ ++ public Biome.BiomeBuilder mobSpawnSettings(MobSpawnSettings spawnSettings) { ++ this.mobSpawnSettings = spawnSettings; ++ return this; ++ } ++ ++ public Biome.BiomeBuilder generationSettings(BiomeGenerationSettings generationSettings) { ++ this.generationSettings = generationSettings; ++ return this; ++ } ++ ++ public Biome.BiomeBuilder temperatureAdjustment(Biome.TemperatureModifier temperatureModifier) { ++ this.temperatureModifier = temperatureModifier; ++ return this; ++ } ++ ++ public Biome build() { ++ if (this.temperature != null && this.downfall != null && this.specialEffects != null && this.mobSpawnSettings != null && this.generationSettings != null) { ++ return new Biome(new Biome.ClimateSettings(this.hasPrecipitation, this.temperature, this.temperatureModifier, this.downfall), this.specialEffects, this.generationSettings, this.mobSpawnSettings); ++ } else { ++ throw new IllegalStateException("You are missing parameters to build a proper biome\n" + this); ++ } ++ } ++ ++ @Override ++ public String toString() { ++ return "BiomeBuilder{\nhasPrecipitation=" + this.hasPrecipitation + ",\ntemperature=" + this.temperature + ",\ntemperatureModifier=" + this.temperatureModifier + ",\ndownfall=" + this.downfall + ",\nspecialEffects=" + this.specialEffects + ",\nmobSpawnSettings=" + this.mobSpawnSettings + ",\ngenerationSettings=" + this.generationSettings + ",\n}"; ++ } ++ } ++ ++ public static record ClimateSettings(boolean hasPrecipitation, float temperature, Biome.TemperatureModifier temperatureModifier, float downfall) { ++ public static final MapCodec CODEC = RecordCodecBuilder.mapCodec((instance) -> { ++ return instance.group(Codec.BOOL.fieldOf("has_precipitation").forGetter((weather) -> { ++ return weather.hasPrecipitation; ++ }), Codec.FLOAT.fieldOf("temperature").forGetter((weather) -> { ++ return weather.temperature; ++ }), Biome.TemperatureModifier.CODEC.optionalFieldOf("temperature_modifier", Biome.TemperatureModifier.NONE).forGetter((weather) -> { ++ return weather.temperatureModifier; ++ }), Codec.FLOAT.fieldOf("downfall").forGetter((weather) -> { ++ return weather.downfall; ++ })).apply(instance, Biome.ClimateSettings::new); ++ }); ++ } ++ ++ public static enum Precipitation implements StringRepresentable { ++ NONE("none"), ++ RAIN("rain"), ++ SNOW("snow"); ++ ++ public static final Codec CODEC = StringRepresentable.fromEnum(Biome.Precipitation::values); ++ private final String name; ++ ++ private Precipitation(String name) { ++ this.name = name; ++ } ++ ++ @Override ++ public String getSerializedName() { ++ return this.name; ++ } ++ } ++ ++ public static enum TemperatureModifier implements StringRepresentable { ++ NONE("none") { ++ @Override ++ public float modifyTemperature(BlockPos pos, float temperature) { ++ return temperature; ++ } ++ }, ++ FROZEN("frozen") { ++ @Override ++ public float modifyTemperature(BlockPos pos, float temperature) { ++ double d = Biome.FROZEN_TEMPERATURE_NOISE.getValue((double)pos.getX() * 0.05D, (double)pos.getZ() * 0.05D, false) * 7.0D; ++ double e = Biome.BIOME_INFO_NOISE.getValue((double)pos.getX() * 0.2D, (double)pos.getZ() * 0.2D, false); ++ double f = d + e; ++ if (f < 0.3D) { ++ double g = Biome.BIOME_INFO_NOISE.getValue((double)pos.getX() * 0.09D, (double)pos.getZ() * 0.09D, false); ++ if (g < 0.8D) { ++ return 0.2F; ++ } ++ } ++ ++ return temperature; ++ } ++ }; ++ ++ private final String name; ++ public static final Codec CODEC = StringRepresentable.fromEnum(Biome.TemperatureModifier::values); ++ ++ public abstract float modifyTemperature(BlockPos pos, float temperature); ++ ++ TemperatureModifier(String name) { ++ this.name = name; ++ } ++ ++ public String getName() { ++ return this.name; ++ } ++ ++ @Override ++ public String getSerializedName() { ++ return this.name; ++ } ++ } ++} +diff --git a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ddca14f1224327a738415fb8b37398d8df0aa9c8 +--- /dev/null ++++ b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java +@@ -0,0 +1,175 @@ ++package net.minecraft.world.level.block; ++ ++import com.mojang.serialization.MapCodec; ++import javax.annotation.Nullable; ++import net.minecraft.core.BlockPos; ++import net.minecraft.core.Direction; ++import net.minecraft.core.particles.ParticleTypes; ++import net.minecraft.network.chat.Component; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.stats.Stats; ++import net.minecraft.util.RandomSource; ++import net.minecraft.world.InteractionHand; ++import net.minecraft.world.InteractionResult; ++import net.minecraft.world.SimpleMenuProvider; ++import net.minecraft.world.entity.monster.piglin.PiglinAi; ++import net.minecraft.world.entity.player.Player; ++import net.minecraft.world.inventory.ChestMenu; ++import net.minecraft.world.inventory.PlayerEnderChestContainer; ++import net.minecraft.world.item.context.BlockPlaceContext; ++import net.minecraft.world.level.BlockGetter; ++import net.minecraft.world.level.Level; ++import net.minecraft.world.level.LevelAccessor; ++import net.minecraft.world.level.block.entity.BlockEntity; ++import net.minecraft.world.level.block.entity.BlockEntityTicker; ++import net.minecraft.world.level.block.entity.BlockEntityType; ++import net.minecraft.world.level.block.entity.ChestBlockEntity; ++import net.minecraft.world.level.block.entity.EnderChestBlockEntity; ++import net.minecraft.world.level.block.state.BlockBehaviour; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.StateDefinition; ++import net.minecraft.world.level.block.state.properties.BlockStateProperties; ++import net.minecraft.world.level.block.state.properties.BooleanProperty; ++import net.minecraft.world.level.block.state.properties.DirectionProperty; ++import net.minecraft.world.level.material.FluidState; ++import net.minecraft.world.level.material.Fluids; ++import net.minecraft.world.level.pathfinder.PathComputationType; ++import net.minecraft.world.phys.BlockHitResult; ++import net.minecraft.world.phys.shapes.CollisionContext; ++import net.minecraft.world.phys.shapes.VoxelShape; ++ ++public class EnderChestBlock extends AbstractChestBlock implements SimpleWaterloggedBlock { ++ public static final MapCodec CODEC = simpleCodec(EnderChestBlock::new); ++ public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING; ++ public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; ++ protected static final VoxelShape SHAPE = Block.box(1.0D, 0.0D, 1.0D, 15.0D, 14.0D, 15.0D); ++ private static final Component CONTAINER_TITLE = Component.translatable("container.enderchest"); ++ ++ @Override ++ public MapCodec codec() { ++ return CODEC; ++ } ++ ++ protected EnderChestBlock(BlockBehaviour.Properties settings) { ++ super(settings, () -> { ++ return BlockEntityType.ENDER_CHEST; ++ }); ++ this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(WATERLOGGED, Boolean.valueOf(false))); ++ } ++ ++ @Override ++ public DoubleBlockCombiner.NeighborCombineResult combine(BlockState state, Level world, BlockPos pos, boolean ignoreBlocked) { ++ return DoubleBlockCombiner.Combiner::acceptNone; ++ } ++ ++ @Override ++ public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { ++ return SHAPE; ++ } ++ ++ @Override ++ public RenderShape getRenderShape(BlockState state) { ++ return RenderShape.ENTITYBLOCK_ANIMATED; ++ } ++ ++ @Override ++ public BlockState getStateForPlacement(BlockPlaceContext ctx) { ++ FluidState fluidState = ctx.getLevel().getFluidState(ctx.getClickedPos()); ++ return this.defaultBlockState().setValue(FACING, ctx.getHorizontalDirection().getOpposite()).setValue(WATERLOGGED, Boolean.valueOf(fluidState.getType() == Fluids.WATER)); ++ } ++ ++ @Override ++ public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { ++ PlayerEnderChestContainer playerEnderChestContainer = player.getEnderChestInventory(); ++ BlockEntity blockEntity = world.getBlockEntity(pos); ++ if (playerEnderChestContainer != null && blockEntity instanceof EnderChestBlockEntity) { ++ BlockPos blockPos = pos.above(); ++ if (world.getBlockState(blockPos).isRedstoneConductor(world, blockPos)) { ++ return InteractionResult.sidedSuccess(world.isClientSide); ++ } else if (world.isClientSide) { ++ return InteractionResult.SUCCESS; ++ } else { ++ EnderChestBlockEntity enderChestBlockEntity = (EnderChestBlockEntity)blockEntity; ++ playerEnderChestContainer.setActiveChest(enderChestBlockEntity); ++ player.openMenu(new SimpleMenuProvider((syncId, inventory, playerx) -> { ++ return ChestMenu.threeRows(syncId, inventory, playerEnderChestContainer); ++ }, CONTAINER_TITLE)); ++ player.awardStat(Stats.OPEN_ENDERCHEST); ++ PiglinAi.angerNearbyPiglins(player, true); ++ return InteractionResult.CONSUME; ++ } ++ } else { ++ return InteractionResult.sidedSuccess(world.isClientSide); ++ } ++ } ++ ++ @Override ++ public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { ++ return new EnderChestBlockEntity(pos, state); ++ } ++ ++ @Nullable ++ @Override ++ public BlockEntityTicker getTicker(Level world, BlockState state, BlockEntityType type) { ++ return world.isClientSide ? createTickerHelper(type, BlockEntityType.ENDER_CHEST, EnderChestBlockEntity::lidAnimateTick) : null; ++ } ++ ++ @Override ++ public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource random) { ++ for(int i = 0; i < 3; ++i) { ++ int j = random.nextInt(2) * 2 - 1; ++ int k = random.nextInt(2) * 2 - 1; ++ double d = (double)pos.getX() + 0.5D + 0.25D * (double)j; ++ double e = (double)((float)pos.getY() + random.nextFloat()); ++ double f = (double)pos.getZ() + 0.5D + 0.25D * (double)k; ++ double g = (double)(random.nextFloat() * (float)j); ++ double h = ((double)random.nextFloat() - 0.5D) * 0.125D; ++ double l = (double)(random.nextFloat() * (float)k); ++ world.addParticle(ParticleTypes.PORTAL, d, e, f, g, h, l); ++ } ++ ++ } ++ ++ @Override ++ public BlockState rotate(BlockState state, Rotation rotation) { ++ return state.setValue(FACING, rotation.rotate(state.getValue(FACING))); ++ } ++ ++ @Override ++ public BlockState mirror(BlockState state, Mirror mirror) { ++ return state.rotate(mirror.getRotation(state.getValue(FACING))); ++ } ++ ++ @Override ++ protected void createBlockStateDefinition(StateDefinition.Builder builder) { ++ builder.add(FACING, WATERLOGGED); ++ } ++ ++ @Override ++ public FluidState getFluidState(BlockState state) { ++ return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); ++ } ++ ++ @Override ++ public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { ++ if (state.getValue(WATERLOGGED)) { ++ world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); ++ } ++ ++ return super.updateShape(state, direction, neighborState, world, pos, neighborPos); ++ } ++ ++ @Override ++ public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { ++ return false; ++ } ++ ++ @Override ++ public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { ++ BlockEntity blockEntity = world.getBlockEntity(pos); ++ if (blockEntity instanceof EnderChestBlockEntity) { ++ ((EnderChestBlockEntity)blockEntity).recheckOpen(); ++ } ++ ++ } ++} +diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java +new file mode 100644 +index 0000000000000000000000000000000000000000..f945fae50983424091b58f83ed14f2e8f2621619 +--- /dev/null ++++ b/src/main/java/net/minecraft/world/level/levelgen/feature/GeodeFeature.java +@@ -0,0 +1,171 @@ ++package net.minecraft.world.level.levelgen.feature; ++ ++import com.google.common.collect.Lists; ++import com.mojang.datafixers.util.Pair; ++import com.mojang.serialization.Codec; ++import java.util.List; ++import java.util.function.Predicate; ++import net.minecraft.Util; ++import net.minecraft.core.BlockPos; ++import net.minecraft.core.Direction; ++import net.minecraft.tags.BlockTags; ++import net.minecraft.util.Mth; ++import net.minecraft.util.RandomSource; ++import net.minecraft.world.level.WorldGenLevel; ++import net.minecraft.world.level.block.Blocks; ++import net.minecraft.world.level.block.BuddingAmethystBlock; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.properties.BlockStateProperties; ++import net.minecraft.world.level.levelgen.GeodeBlockSettings; ++import net.minecraft.world.level.levelgen.GeodeCrackSettings; ++import net.minecraft.world.level.levelgen.GeodeLayerSettings; ++import net.minecraft.world.level.levelgen.LegacyRandomSource; ++import net.minecraft.world.level.levelgen.WorldgenRandom; ++import net.minecraft.world.level.levelgen.feature.configurations.GeodeConfiguration; ++import net.minecraft.world.level.levelgen.synth.NormalNoise; ++import net.minecraft.world.level.material.FluidState; ++ ++public class GeodeFeature extends Feature { ++ private static final Direction[] DIRECTIONS = Direction.values(); ++ ++ public GeodeFeature(Codec configCodec) { ++ super(configCodec); ++ } ++ ++ @Override ++ public boolean place(FeaturePlaceContext context) { ++ GeodeConfiguration geodeConfiguration = context.config(); ++ RandomSource randomSource = context.random(); ++ BlockPos blockPos = context.origin(); ++ WorldGenLevel worldGenLevel = context.level(); ++ int i = geodeConfiguration.minGenOffset; ++ int j = geodeConfiguration.maxGenOffset; ++ List> list = Lists.newLinkedList(); ++ int k = geodeConfiguration.distributionPoints.sample(randomSource); ++ WorldgenRandom worldgenRandom = new WorldgenRandom(new LegacyRandomSource(worldGenLevel.getSeed())); ++ NormalNoise normalNoise = NormalNoise.create(worldgenRandom, -4, 1.0D); ++ List list2 = Lists.newLinkedList(); ++ double d = (double)k / (double)geodeConfiguration.outerWallDistance.getMaxValue(); ++ GeodeLayerSettings geodeLayerSettings = geodeConfiguration.geodeLayerSettings; ++ GeodeBlockSettings geodeBlockSettings = geodeConfiguration.geodeBlockSettings; ++ GeodeCrackSettings geodeCrackSettings = geodeConfiguration.geodeCrackSettings; ++ double e = 1.0D / Math.sqrt(geodeLayerSettings.filling); ++ double f = 1.0D / Math.sqrt(geodeLayerSettings.innerLayer + d); ++ double g = 1.0D / Math.sqrt(geodeLayerSettings.middleLayer + d); ++ double h = 1.0D / Math.sqrt(geodeLayerSettings.outerLayer + d); ++ double l = 1.0D / Math.sqrt(geodeCrackSettings.baseCrackSize + randomSource.nextDouble() / 2.0D + (k > 3 ? d : 0.0D)); ++ boolean bl = (double)randomSource.nextFloat() < geodeCrackSettings.generateCrackChance; ++ int m = 0; ++ ++ for(int n = 0; n < k; ++n) { ++ int o = geodeConfiguration.outerWallDistance.sample(randomSource); ++ int p = geodeConfiguration.outerWallDistance.sample(randomSource); ++ int q = geodeConfiguration.outerWallDistance.sample(randomSource); ++ BlockPos blockPos2 = blockPos.offset(o, p, q); ++ BlockState blockState = worldGenLevel.getBlockState(blockPos2); ++ if (blockState.isAir() || blockState.is(BlockTags.GEODE_INVALID_BLOCKS)) { ++ ++m; ++ if (m > geodeConfiguration.invalidBlocksThreshold) { ++ return false; ++ } ++ } ++ ++ list.add(Pair.of(blockPos2, geodeConfiguration.pointOffset.sample(randomSource))); ++ } ++ ++ if (bl) { ++ int r = randomSource.nextInt(4); ++ int s = k * 2 + 1; ++ if (r == 0) { ++ list2.add(blockPos.offset(s, 7, 0)); ++ list2.add(blockPos.offset(s, 5, 0)); ++ list2.add(blockPos.offset(s, 1, 0)); ++ } else if (r == 1) { ++ list2.add(blockPos.offset(0, 7, s)); ++ list2.add(blockPos.offset(0, 5, s)); ++ list2.add(blockPos.offset(0, 1, s)); ++ } else if (r == 2) { ++ list2.add(blockPos.offset(s, 7, s)); ++ list2.add(blockPos.offset(s, 5, s)); ++ list2.add(blockPos.offset(s, 1, s)); ++ } else { ++ list2.add(blockPos.offset(0, 7, 0)); ++ list2.add(blockPos.offset(0, 5, 0)); ++ list2.add(blockPos.offset(0, 1, 0)); ++ } ++ } ++ ++ List list3 = Lists.newArrayList(); ++ Predicate predicate = isReplaceable(geodeConfiguration.geodeBlockSettings.cannotReplace); ++ ++ for(BlockPos blockPos3 : BlockPos.betweenClosed(blockPos.offset(i, i, i), blockPos.offset(j, j, j))) { ++ double t = normalNoise.getValue((double)blockPos3.getX(), (double)blockPos3.getY(), (double)blockPos3.getZ()) * geodeConfiguration.noiseMultiplier; ++ double u = 0.0D; ++ double v = 0.0D; ++ ++ for(Pair pair : list) { ++ u += Mth.invSqrt(blockPos3.distSqr(pair.getFirst()) + (double)pair.getSecond().intValue()) + t; ++ } ++ ++ for(BlockPos blockPos4 : list2) { ++ v += Mth.invSqrt(blockPos3.distSqr(blockPos4) + (double)geodeCrackSettings.crackPointOffset) + t; ++ } ++ ++ if (!(u < h)) { ++ if (bl && v >= l && u < e) { ++ this.safeSetBlock(worldGenLevel, blockPos3, Blocks.AIR.defaultBlockState(), predicate); ++ ++ for(Direction direction : DIRECTIONS) { ++ BlockPos blockPos5 = blockPos3.relative(direction); ++ FluidState fluidState = worldGenLevel.getFluidState(blockPos5); ++ if (!fluidState.isEmpty()) { ++ worldGenLevel.scheduleTick(blockPos5, fluidState.getType(), 0); ++ } ++ } ++ } else if (u >= e) { ++ this.safeSetBlock(worldGenLevel, blockPos3, geodeBlockSettings.fillingProvider.getState(randomSource, blockPos3), predicate); ++ } else if (u >= f) { ++ boolean bl2 = (double)randomSource.nextFloat() < geodeConfiguration.useAlternateLayer0Chance; ++ if (bl2) { ++ this.safeSetBlock(worldGenLevel, blockPos3, geodeBlockSettings.alternateInnerLayerProvider.getState(randomSource, blockPos3), predicate); ++ } else { ++ this.safeSetBlock(worldGenLevel, blockPos3, geodeBlockSettings.innerLayerProvider.getState(randomSource, blockPos3), predicate); ++ } ++ ++ if ((!geodeConfiguration.placementsRequireLayer0Alternate || bl2) && (double)randomSource.nextFloat() < geodeConfiguration.usePotentialPlacementsChance) { ++ list3.add(blockPos3.immutable()); ++ } ++ } else if (u >= g) { ++ this.safeSetBlock(worldGenLevel, blockPos3, geodeBlockSettings.middleLayerProvider.getState(randomSource, blockPos3), predicate); ++ } else if (u >= h) { ++ this.safeSetBlock(worldGenLevel, blockPos3, geodeBlockSettings.outerLayerProvider.getState(randomSource, blockPos3), predicate); ++ } ++ } ++ } ++ ++ List list4 = geodeBlockSettings.innerPlacements; ++ ++ for(BlockPos blockPos6 : list3) { ++ BlockState blockState2 = Util.getRandom(list4, randomSource); ++ ++ for(Direction direction2 : DIRECTIONS) { ++ if (blockState2.hasProperty(BlockStateProperties.FACING)) { ++ blockState2 = blockState2.setValue(BlockStateProperties.FACING, direction2); ++ } ++ ++ BlockPos blockPos7 = blockPos6.relative(direction2); ++ BlockState blockState3 = worldGenLevel.getBlockState(blockPos7); ++ if (blockState2.hasProperty(BlockStateProperties.WATERLOGGED)) { ++ blockState2 = blockState2.setValue(BlockStateProperties.WATERLOGGED, Boolean.valueOf(blockState3.getFluidState().isSource())); ++ } ++ ++ if (BuddingAmethystBlock.canClusterGrowAtState(blockState3)) { ++ this.safeSetBlock(worldGenLevel, blockPos7, blockState2, predicate); ++ break; ++ } ++ } ++ } ++ ++ return true; ++ } ++} +diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/MonsterRoomFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/MonsterRoomFeature.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7c252dd2bd314f06703ac9356410c52b21198d12 +--- /dev/null ++++ b/src/main/java/net/minecraft/world/level/levelgen/feature/MonsterRoomFeature.java +@@ -0,0 +1,134 @@ ++package net.minecraft.world.level.levelgen.feature; ++ ++import com.mojang.logging.LogUtils; ++import com.mojang.serialization.Codec; ++import java.util.function.Predicate; ++import net.minecraft.Util; ++import net.minecraft.core.BlockPos; ++import net.minecraft.core.Direction; ++import net.minecraft.tags.BlockTags; ++import net.minecraft.util.RandomSource; ++import net.minecraft.world.RandomizableContainer; ++import net.minecraft.world.entity.EntityType; ++import net.minecraft.world.level.WorldGenLevel; ++import net.minecraft.world.level.block.Blocks; ++import net.minecraft.world.level.block.entity.BlockEntity; ++import net.minecraft.world.level.block.entity.SpawnerBlockEntity; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; ++import net.minecraft.world.level.levelgen.structure.StructurePiece; ++import net.minecraft.world.level.storage.loot.BuiltInLootTables; ++import org.slf4j.Logger; ++ ++public class MonsterRoomFeature extends Feature { ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ private static final EntityType[] MOBS = new EntityType[]{EntityType.SKELETON, EntityType.ZOMBIE, EntityType.ZOMBIE, EntityType.SPIDER}; ++ private static final BlockState AIR = Blocks.CAVE_AIR.defaultBlockState(); ++ ++ public MonsterRoomFeature(Codec configCodec) { ++ super(configCodec); ++ } ++ ++ @Override ++ public boolean place(FeaturePlaceContext context) { ++ Predicate predicate = Feature.isReplaceable(BlockTags.FEATURES_CANNOT_REPLACE); ++ BlockPos blockPos = context.origin(); ++ RandomSource randomSource = context.random(); ++ WorldGenLevel worldGenLevel = context.level(); ++ int i = 3; ++ int j = randomSource.nextInt(2) + 2; ++ int k = -j - 1; ++ int l = j + 1; ++ int m = -1; ++ int n = 4; ++ int o = randomSource.nextInt(2) + 2; ++ int p = -o - 1; ++ int q = o + 1; ++ int r = 0; ++ ++ for(int s = k; s <= l; ++s) { ++ for(int t = -1; t <= 4; ++t) { ++ for(int u = p; u <= q; ++u) { ++ BlockPos blockPos2 = blockPos.offset(s, t, u); ++ boolean bl = worldGenLevel.getBlockState(blockPos2).isSolid(); ++ if (t == -1 && !bl) { ++ return false; ++ } ++ ++ if (t == 4 && !bl) { ++ return false; ++ } ++ ++ if ((s == k || s == l || u == p || u == q) && t == 0 && worldGenLevel.isEmptyBlock(blockPos2) && worldGenLevel.isEmptyBlock(blockPos2.above())) { ++ ++r; ++ } ++ } ++ } ++ } ++ ++ if (r >= 1 && r <= 5) { ++ for(int v = k; v <= l; ++v) { ++ for(int w = 3; w >= -1; --w) { ++ for(int x = p; x <= q; ++x) { ++ BlockPos blockPos3 = blockPos.offset(v, w, x); ++ BlockState blockState = worldGenLevel.getBlockState(blockPos3); ++ if (v != k && w != -1 && x != p && v != l && w != 4 && x != q) { ++ if (!blockState.is(Blocks.CHEST) && !blockState.is(Blocks.SPAWNER)) { ++ this.safeSetBlock(worldGenLevel, blockPos3, AIR, predicate); ++ } ++ } else if (blockPos3.getY() >= worldGenLevel.getMinBuildHeight() && !worldGenLevel.getBlockState(blockPos3.below()).isSolid()) { ++ worldGenLevel.setBlock(blockPos3, AIR, 2); ++ } else if (blockState.isSolid() && !blockState.is(Blocks.CHEST)) { ++ if (w == -1 && randomSource.nextInt(4) != 0) { ++ this.safeSetBlock(worldGenLevel, blockPos3, Blocks.MOSSY_COBBLESTONE.defaultBlockState(), predicate); ++ } else { ++ this.safeSetBlock(worldGenLevel, blockPos3, Blocks.COBBLESTONE.defaultBlockState(), predicate); ++ } ++ } ++ } ++ } ++ } ++ ++ for(int y = 0; y < 2; ++y) { ++ for(int z = 0; z < 3; ++z) { ++ int aa = blockPos.getX() + randomSource.nextInt(j * 2 + 1) - j; ++ int ab = blockPos.getY(); ++ int ac = blockPos.getZ() + randomSource.nextInt(o * 2 + 1) - o; ++ BlockPos blockPos4 = new BlockPos(aa, ab, ac); ++ if (worldGenLevel.isEmptyBlock(blockPos4)) { ++ int ad = 0; ++ ++ for(Direction direction : Direction.Plane.HORIZONTAL) { ++ if (worldGenLevel.getBlockState(blockPos4.relative(direction)).isSolid()) { ++ ++ad; ++ } ++ } ++ ++ if (ad == 1) { ++ this.safeSetBlock(worldGenLevel, blockPos4, StructurePiece.reorient(worldGenLevel, blockPos4, Blocks.CHEST.defaultBlockState()), predicate); ++ RandomizableContainer.setBlockEntityLootTable(worldGenLevel, randomSource, blockPos4, BuiltInLootTables.SIMPLE_DUNGEON); ++ break; ++ } ++ } ++ } ++ } ++ ++ this.safeSetBlock(worldGenLevel, blockPos, Blocks.SPAWNER.defaultBlockState(), predicate); ++ BlockEntity blockEntity = worldGenLevel.getBlockEntity(blockPos); ++ if (blockEntity instanceof SpawnerBlockEntity) { ++ SpawnerBlockEntity spawnerBlockEntity = (SpawnerBlockEntity)blockEntity; ++ spawnerBlockEntity.setEntityId(this.randomEntityId(randomSource), randomSource); ++ } else { ++ LOGGER.error("Failed to fetch mob spawner entity at ({}, {}, {})", blockPos.getX(), blockPos.getY(), blockPos.getZ()); ++ } ++ ++ return true; ++ } else { ++ return false; ++ } ++ } ++ ++ private EntityType randomEntityId(RandomSource random) { ++ return Util.getRandom(MOBS, random); ++ } ++} +diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/SculkPatchFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/SculkPatchFeature.java +new file mode 100644 +index 0000000000000000000000000000000000000000..f5aea54f81dcd3072e36ddf3c4c6ded848c2c540 +--- /dev/null ++++ b/src/main/java/net/minecraft/world/level/levelgen/feature/SculkPatchFeature.java +@@ -0,0 +1,75 @@ ++package net.minecraft.world.level.levelgen.feature; ++ ++import com.mojang.serialization.Codec; ++import net.minecraft.core.BlockPos; ++import net.minecraft.core.Direction; ++import net.minecraft.util.RandomSource; ++import net.minecraft.world.level.LevelAccessor; ++import net.minecraft.world.level.WorldGenLevel; ++import net.minecraft.world.level.block.Blocks; ++import net.minecraft.world.level.block.SculkBehaviour; ++import net.minecraft.world.level.block.SculkShriekerBlock; ++import net.minecraft.world.level.block.SculkSpreader; ++import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.levelgen.feature.configurations.SculkPatchConfiguration; ++ ++public class SculkPatchFeature extends Feature { ++ public SculkPatchFeature(Codec configCodec) { ++ super(configCodec); ++ } ++ ++ @Override ++ public boolean place(FeaturePlaceContext context) { ++ WorldGenLevel worldGenLevel = context.level(); ++ BlockPos blockPos = context.origin(); ++ if (!this.canSpreadFrom(worldGenLevel, blockPos)) { ++ return false; ++ } else { ++ SculkPatchConfiguration sculkPatchConfiguration = context.config(); ++ RandomSource randomSource = context.random(); ++ SculkSpreader sculkSpreader = SculkSpreader.createWorldGenSpreader(); ++ int i = sculkPatchConfiguration.spreadRounds() + sculkPatchConfiguration.growthRounds(); ++ ++ for(int j = 0; j < i; ++j) { ++ for(int k = 0; k < sculkPatchConfiguration.chargeCount(); ++k) { ++ sculkSpreader.addCursors(blockPos, sculkPatchConfiguration.amountPerCharge()); ++ } ++ ++ boolean bl = j < sculkPatchConfiguration.spreadRounds(); ++ ++ for(int l = 0; l < sculkPatchConfiguration.spreadAttempts(); ++l) { ++ sculkSpreader.updateCursors(worldGenLevel, blockPos, randomSource, bl); ++ } ++ ++ sculkSpreader.clear(); ++ } ++ ++ BlockPos blockPos2 = blockPos.below(); ++ if (randomSource.nextFloat() <= sculkPatchConfiguration.catalystChance() && worldGenLevel.getBlockState(blockPos2).isCollisionShapeFullBlock(worldGenLevel, blockPos2)) { ++ worldGenLevel.setBlock(blockPos, Blocks.SCULK_CATALYST.defaultBlockState(), 3); ++ } ++ ++ int m = sculkPatchConfiguration.extraRareGrowths().sample(randomSource); ++ ++ for(int n = 0; n < m; ++n) { ++ BlockPos blockPos3 = blockPos.offset(randomSource.nextInt(5) - 2, 0, randomSource.nextInt(5) - 2); ++ if (worldGenLevel.getBlockState(blockPos3).isAir() && worldGenLevel.getBlockState(blockPos3.below()).isFaceSturdy(worldGenLevel, blockPos3.below(), Direction.UP)) { ++ worldGenLevel.setBlock(blockPos3, Blocks.SCULK_SHRIEKER.defaultBlockState().setValue(SculkShriekerBlock.CAN_SUMMON, Boolean.valueOf(true)), 3); ++ } ++ } ++ ++ return true; ++ } ++ } ++ ++ private boolean canSpreadFrom(LevelAccessor world, BlockPos pos) { ++ BlockState blockState = world.getBlockState(pos); ++ if (blockState.getBlock() instanceof SculkBehaviour) { ++ return true; ++ } else { ++ return !blockState.isAir() && (!blockState.is(Blocks.WATER) || !blockState.getFluidState().isSource()) ? false : Direction.stream().map(pos::relative).anyMatch((pos2) -> { ++ return world.getBlockState(pos2).isCollisionShapeFullBlock(world, pos2); ++ }); ++ } ++ } ++} +diff --git a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d051e8c1db6b5c42b8df0be54d9d48ba0e7b0077 +--- /dev/null ++++ b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java +@@ -0,0 +1,129 @@ ++package net.minecraft.world.level.storage; ++ ++import com.google.common.collect.Maps; ++import com.mojang.datafixers.DataFixer; ++import com.mojang.logging.LogUtils; ++import java.io.DataInputStream; ++import java.io.File; ++import java.io.FileInputStream; ++import java.io.IOException; ++import java.io.PushbackInputStream; ++import java.util.Map; ++import java.util.function.Function; ++import javax.annotation.Nullable; ++import net.minecraft.SharedConstants; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.nbt.NbtAccounter; ++import net.minecraft.nbt.NbtIo; ++import net.minecraft.nbt.NbtUtils; ++import net.minecraft.util.datafix.DataFixTypes; ++import net.minecraft.world.level.saveddata.SavedData; ++import org.slf4j.Logger; ++ ++public class DimensionDataStorage { ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ public final Map cache = Maps.newHashMap(); ++ private final DataFixer fixerUpper; ++ private final File dataFolder; ++ ++ public DimensionDataStorage(File directory, DataFixer dataFixer) { ++ this.fixerUpper = dataFixer; ++ this.dataFolder = directory; ++ } ++ ++ private File getDataFile(String id) { ++ return new File(this.dataFolder, id + ".dat"); ++ } ++ ++ public T computeIfAbsent(SavedData.Factory type, String id) { ++ T savedData = this.get(type, id); ++ if (savedData != null) { ++ return savedData; ++ } else { ++ T savedData2 = type.constructor().get(); ++ this.set(id, savedData2); ++ return savedData2; ++ } ++ } ++ ++ @Nullable ++ public T get(SavedData.Factory type, String id) { ++ SavedData savedData = this.cache.get(id); ++ if (savedData == null && !this.cache.containsKey(id)) { ++ savedData = this.readSavedData(type.deserializer(), type.type(), id); ++ this.cache.put(id, savedData); ++ } ++ ++ return (T)savedData; ++ } ++ ++ @Nullable ++ public T readSavedData(Function readFunction, DataFixTypes dataFixTypes, String id) { ++ try { ++ File file = this.getDataFile(id); ++ if (file.exists()) { ++ CompoundTag compoundTag = this.readTagFromDisk(id, dataFixTypes, SharedConstants.getCurrentVersion().getDataVersion().getVersion()); ++ return readFunction.apply(compoundTag.getCompound("data")); ++ } ++ } catch (Exception var6) { ++ LOGGER.error("Error loading saved data: {}", id, var6); ++ } ++ ++ return (T)null; ++ } ++ ++ public void set(String id, SavedData state) { ++ this.cache.put(id, state); ++ } ++ ++ public CompoundTag readTagFromDisk(String id, DataFixTypes dataFixTypes, int currentSaveVersion) throws IOException { ++ File file = this.getDataFile(id); ++ ++ CompoundTag var9; ++ try ( ++ FileInputStream fileInputStream = new FileInputStream(file); ++ PushbackInputStream pushbackInputStream = new PushbackInputStream(fileInputStream, 2); ++ ) { ++ CompoundTag compoundTag; ++ if (this.isGzip(pushbackInputStream)) { ++ compoundTag = NbtIo.readCompressed(pushbackInputStream, NbtAccounter.unlimitedHeap()); ++ } else { ++ try (DataInputStream dataInputStream = new DataInputStream(pushbackInputStream)) { ++ compoundTag = NbtIo.read(dataInputStream); ++ } ++ } ++ ++ int i = NbtUtils.getDataVersion(compoundTag, 1343); ++ var9 = dataFixTypes.update(this.fixerUpper, compoundTag, i, currentSaveVersion); ++ } ++ ++ return var9; ++ } ++ ++ private boolean isGzip(PushbackInputStream stream) throws IOException { ++ byte[] bs = new byte[2]; ++ boolean bl = false; ++ int i = stream.read(bs, 0, 2); ++ if (i == 2) { ++ int j = (bs[1] & 255) << 8 | bs[0] & 255; ++ if (j == 35615) { ++ bl = true; ++ } ++ } ++ ++ if (i != 0) { ++ stream.unread(bs, 0, i); ++ } ++ ++ return bl; ++ } ++ ++ public void save() { ++ this.cache.forEach((id, state) -> { ++ if (state != null) { ++ state.save(this.getDataFile(id)); ++ } ++ ++ }); ++ } ++} +diff --git a/src/main/java/net/minecraft/world/scores/PlayerTeam.java b/src/main/java/net/minecraft/world/scores/PlayerTeam.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9464054912e19fc78dd965b71fce20a18564b351 +--- /dev/null ++++ b/src/main/java/net/minecraft/world/scores/PlayerTeam.java +@@ -0,0 +1,186 @@ ++package net.minecraft.world.scores; ++ ++import com.google.common.collect.Sets; ++import java.util.Collection; ++import java.util.Set; ++import javax.annotation.Nullable; ++import net.minecraft.ChatFormatting; ++import net.minecraft.network.chat.CommonComponents; ++import net.minecraft.network.chat.Component; ++import net.minecraft.network.chat.ComponentUtils; ++import net.minecraft.network.chat.HoverEvent; ++import net.minecraft.network.chat.MutableComponent; ++import net.minecraft.network.chat.Style; ++ ++public class PlayerTeam extends Team { ++ private static final int BIT_FRIENDLY_FIRE = 0; ++ private static final int BIT_SEE_INVISIBLES = 1; ++ private final Scoreboard scoreboard; ++ private final String name; ++ private final Set players = Sets.newHashSet(); ++ private Component displayName; ++ private Component playerPrefix = CommonComponents.EMPTY; ++ private Component playerSuffix = CommonComponents.EMPTY; ++ private boolean allowFriendlyFire = true; ++ private boolean seeFriendlyInvisibles = true; ++ private Team.Visibility nameTagVisibility = Team.Visibility.ALWAYS; ++ private Team.Visibility deathMessageVisibility = Team.Visibility.ALWAYS; ++ private ChatFormatting color = ChatFormatting.RESET; ++ private Team.CollisionRule collisionRule = Team.CollisionRule.ALWAYS; ++ private final Style displayNameStyle; ++ ++ public PlayerTeam(Scoreboard scoreboard, String name) { ++ this.scoreboard = scoreboard; ++ this.name = name; ++ this.displayName = Component.literal(name); ++ this.displayNameStyle = Style.EMPTY.withInsertion(name).withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.literal(name))); ++ } ++ ++ public Scoreboard getScoreboard() { ++ return this.scoreboard; ++ } ++ ++ @Override ++ public String getName() { ++ return this.name; ++ } ++ ++ public Component getDisplayName() { ++ return this.displayName; ++ } ++ ++ public MutableComponent getFormattedDisplayName() { ++ MutableComponent mutableComponent = ComponentUtils.wrapInSquareBrackets(this.displayName.copy().withStyle(this.displayNameStyle)); ++ ChatFormatting chatFormatting = this.getColor(); ++ if (chatFormatting != ChatFormatting.RESET) { ++ mutableComponent.withStyle(chatFormatting); ++ } ++ ++ return mutableComponent; ++ } ++ ++ public void setDisplayName(Component displayName) { ++ if (displayName == null) { ++ throw new IllegalArgumentException("Name cannot be null"); ++ } else { ++ this.displayName = displayName; ++ this.scoreboard.onTeamChanged(this); ++ } ++ } ++ ++ public void setPlayerPrefix(@Nullable Component prefix) { ++ this.playerPrefix = prefix == null ? CommonComponents.EMPTY : prefix; ++ this.scoreboard.onTeamChanged(this); ++ } ++ ++ public Component getPlayerPrefix() { ++ return this.playerPrefix; ++ } ++ ++ public void setPlayerSuffix(@Nullable Component suffix) { ++ this.playerSuffix = suffix == null ? CommonComponents.EMPTY : suffix; ++ this.scoreboard.onTeamChanged(this); ++ } ++ ++ public Component getPlayerSuffix() { ++ return this.playerSuffix; ++ } ++ ++ @Override ++ public Collection getPlayers() { ++ return this.players; ++ } ++ ++ @Override ++ public MutableComponent getFormattedName(Component name) { ++ MutableComponent mutableComponent = Component.empty().append(this.playerPrefix).append(name).append(this.playerSuffix); ++ ChatFormatting chatFormatting = this.getColor(); ++ if (chatFormatting != ChatFormatting.RESET) { ++ mutableComponent.withStyle(chatFormatting); ++ } ++ ++ return mutableComponent; ++ } ++ ++ public static MutableComponent formatNameForTeam(@Nullable Team team, Component name) { ++ return team == null ? name.copy() : team.getFormattedName(name); ++ } ++ ++ @Override ++ public boolean isAllowFriendlyFire() { ++ return this.allowFriendlyFire; ++ } ++ ++ public void setAllowFriendlyFire(boolean friendlyFire) { ++ this.allowFriendlyFire = friendlyFire; ++ this.scoreboard.onTeamChanged(this); ++ } ++ ++ @Override ++ public boolean canSeeFriendlyInvisibles() { ++ return this.seeFriendlyInvisibles; ++ } ++ ++ public void setSeeFriendlyInvisibles(boolean showFriendlyInvisible) { ++ this.seeFriendlyInvisibles = showFriendlyInvisible; ++ this.scoreboard.onTeamChanged(this); ++ } ++ ++ @Override ++ public Team.Visibility getNameTagVisibility() { ++ return this.nameTagVisibility; ++ } ++ ++ @Override ++ public Team.Visibility getDeathMessageVisibility() { ++ return this.deathMessageVisibility; ++ } ++ ++ public void setNameTagVisibility(Team.Visibility nameTagVisibilityRule) { ++ this.nameTagVisibility = nameTagVisibilityRule; ++ this.scoreboard.onTeamChanged(this); ++ } ++ ++ public void setDeathMessageVisibility(Team.Visibility deathMessageVisibilityRule) { ++ this.deathMessageVisibility = deathMessageVisibilityRule; ++ this.scoreboard.onTeamChanged(this); ++ } ++ ++ @Override ++ public Team.CollisionRule getCollisionRule() { ++ return this.collisionRule; ++ } ++ ++ public void setCollisionRule(Team.CollisionRule collisionRule) { ++ this.collisionRule = collisionRule; ++ this.scoreboard.onTeamChanged(this); ++ } ++ ++ public int packOptions() { ++ int i = 0; ++ if (this.isAllowFriendlyFire()) { ++ i |= 1; ++ } ++ ++ if (this.canSeeFriendlyInvisibles()) { ++ i |= 2; ++ } ++ ++ return i; ++ } ++ ++ public void unpackOptions(int flags) { ++ this.setAllowFriendlyFire((flags & 1) > 0); ++ this.setSeeFriendlyInvisibles((flags & 2) > 0); ++ } ++ ++ public void setColor(ChatFormatting color) { ++ this.color = color; ++ this.scoreboard.onTeamChanged(this); ++ } ++ ++ @Override ++ public ChatFormatting getColor() { ++ return this.color; ++ } ++} diff --git a/patches/server/0001-Build-Changes.patch b/patches/server/0002-Build-Changes.patch similarity index 88% rename from patches/server/0001-Build-Changes.patch rename to patches/server/0002-Build-Changes.patch index 674fe11f3..5904759c8 100644 --- a/patches/server/0001-Build-Changes.patch +++ b/patches/server/0002-Build-Changes.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Build Changes diff --git a/build.gradle.kts b/build.gradle.kts -index 79beac737c17412913983614bd478d33e3c6ed58..b049d50ba82d07f89a608333d4c9e84cfe631c09 100644 +index 58da26ad2f128ba0b66f86820f60853f4be352f0..f9df4ced9b313333102d5f76dff20841a789e53f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,8 +13,12 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { @@ -16,7 +16,7 @@ index 79beac737c17412913983614bd478d33e3c6ed58..b049d50ba82d07f89a608333d4c9e84c - implementation(project(":paper-mojangapi")) + // Slice start + implementation(project(":slice-api")) -+ implementation("io.papermc.paper:paper-mojangapi:1.19.2-R0.1-SNAPSHOT") { ++ implementation("io.papermc.paper:paper-mojangapi:1.20.4-R0.1-SNAPSHOT") { + exclude("io.papermc.paper", "paper-api") + } + // Slice end @@ -42,10 +42,10 @@ index 79beac737c17412913983614bd478d33e3c6ed58..b049d50ba82d07f89a608333d4c9e84c standardInput = System.`in` workingDir = rootProject.layout.projectDirectory diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 8f31413c939cc2b0454ad3d9a1b618dbae449d00..d91ad3622592ece58877f975cdcbf984e61219d7 100644 +index 34f19ac897a30c0c4e3ab406013fcca1c8b7db93..04c6357d24a095bcff40e267cd40920e3b3c3c5d 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1697,7 +1697,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop(); // CraftBukkit end + BlockState iblockdata1 = block.playerWillDestroy(this.level, pos, iblockdata, this.player); + level.pendingPlayerBlockEvents.put(pos, new Level.PendingBlockEvent(pos, this.player)); // Paper - block.playerWillDestroy(this.level, pos, iblockdata, this.player); boolean flag = this.level.removeBlock(pos, false); -@@ -447,6 +448,7 @@ public class ServerPlayerGameMode { + if (flag) { +@@ -446,6 +447,7 @@ public class ServerPlayerGameMode { // CraftBukkit start java.util.List itemsToDrop = this.level.captureDrops; // Paper - store current list this.level.captureDrops = null; // Paper - Remove this earlier so that we can actually drop stuff -+ this.level.pendingPlayerBlockEvents.remove(pos); // Paper ++ level.pendingPlayerBlockEvents.remove(pos); // Paper if (event.isDropItems()) { org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, state, this.player, itemsToDrop); // Paper - use stored ref } diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 4697df75fdee2023c41260bed211e3e3d90d2b9b..e30aaa502f5e98b5658a0dd78853e865cbf91f96 100644 +index de277d61b718fe07a87d75a2547bb1c7f8553aa1..625a852db818d95365ad7ae56e6b1de541bbdada 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -357,6 +357,7 @@ public final class ItemStack { +@@ -378,6 +378,7 @@ public final class ItemStack { CompoundTag oldData = this.getTagClone(); int oldCount = this.getCount(); ServerLevel world = (ServerLevel) context.getLevel(); @@ -37,10 +37,10 @@ index 4697df75fdee2023c41260bed211e3e3d90d2b9b..e30aaa502f5e98b5658a0dd78853e865 if (!(item instanceof BucketItem/* || item instanceof SolidBucketItem*/)) { // if not bucket // Paper - capture block states for snow buckets world.captureBlockStates = true; diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 763165618a47d9841bb8fc70651a4e80a2bbd67f..7c332c004f469fb47598121c3b828a484634b526 100644 +index fe62e872f0c989f612dcbfc58894bd1787345d25..465bbaeff36f4d03db40fcaf9b6ab98550316afb 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -184,6 +184,27 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -187,6 +187,27 @@ public abstract class Level implements LevelAccessor, AutoCloseable { public final Map explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions public java.util.ArrayDeque redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here @@ -68,7 +68,7 @@ index 763165618a47d9841bb8fc70651a4e80a2bbd67f..7c332c004f469fb47598121c3b828a48 // Paper start - fix and optimise world upgrading // copied from below public static ResourceKey getDimensionKey(DimensionType manager) { -@@ -1053,6 +1074,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1056,6 +1077,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable { if (!this.preventPoiUpdated) { this.onBlockStateChange(blockposition, iblockdata1, iblockdata2); } @@ -76,7 +76,7 @@ index 763165618a47d9841bb8fc70651a4e80a2bbd67f..7c332c004f469fb47598121c3b828a48 // CraftBukkit end } } -@@ -1074,6 +1096,17 @@ public abstract class Level implements LevelAccessor, AutoCloseable { +@@ -1077,6 +1099,17 @@ public abstract class Level implements LevelAccessor, AutoCloseable { if (iblockdata.isAir()) { return false; } else { @@ -95,10 +95,10 @@ index 763165618a47d9841bb8fc70651a4e80a2bbd67f..7c332c004f469fb47598121c3b828a48 // Paper start - while the above setAir method is named same and looks very similar // they are NOT used with same intent and the above should not fire this event. The above method is more of a BlockSetToAirEvent, diff --git a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java -index 030b38d5d5d2578d6ef482a239ef58787efa3b08..329053cf5c342747985f9079e87edc6f883bfa1e 100644 +index 81d2140351775ad55546af52eb635ccdc8509d89..0ed9f6ae968c06e63e1431ed1ce153dd1e90e908 100644 --- a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java +++ b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java -@@ -105,6 +105,15 @@ public class DoublePlantBlock extends BushBlock { +@@ -112,6 +112,15 @@ public class DoublePlantBlock extends BushBlock { BlockPos blockposition1 = pos.below(); BlockState iblockdata1 = world.getBlockState(blockposition1); @@ -115,10 +115,10 @@ index 030b38d5d5d2578d6ef482a239ef58787efa3b08..329053cf5c342747985f9079e87edc6f BlockState iblockdata2 = iblockdata1.getFluidState().is((Fluid) Fluids.WATER) ? Blocks.WATER.defaultBlockState() : Blocks.AIR.defaultBlockState(); diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -index e6a4a5898ffdcb2aa2bc01371a6d7dbc06d610ce..204f0cd86a318efb3545a24c0e25a2f9cb7b9f58 100644 +index 3ab8b99837b1d1faea722c598b0228b2780be8b1..45bd7b9e684f71d9186a33277e5772dc7e04e9da 100644 --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java -@@ -1175,11 +1175,22 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -1242,11 +1242,22 @@ public abstract class BlockBehaviour implements FeatureElement { BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); Direction[] aenumdirection = BlockBehaviour.UPDATE_SHAPE_ORDER; int k = aenumdirection.length; diff --git a/patches/server/0004-Add-provided-Material-to-getDrops.patch b/patches/server/0005-Add-provided-Material-to-getDrops.patch similarity index 85% rename from patches/server/0004-Add-provided-Material-to-getDrops.patch rename to patches/server/0005-Add-provided-Material-to-getDrops.patch index 11f6b9fe5..835a2cc7f 100644 --- a/patches/server/0004-Add-provided-Material-to-getDrops.patch +++ b/patches/server/0005-Add-provided-Material-to-getDrops.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add provided Material to getDrops diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -index cb2826852ea38850eb0c553ab3b626253fd8e7a2..a65f1362bcdb064f3213830e9c9c7f9966ce4623 100644 +index 5b0a5c6ba424eeeb071f362f4ffc856b50dd7b2f..6b764644493accf8b17773120b39cc0c0b7f39d0 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java -@@ -590,7 +590,18 @@ public class CraftBlock implements Block { +@@ -591,7 +591,18 @@ public class CraftBlock implements Block { @Override public Collection getDrops(ItemStack item, Entity entity) { @@ -28,7 +28,7 @@ index cb2826852ea38850eb0c553ab3b626253fd8e7a2..a65f1362bcdb064f3213830e9c9c7f99 net.minecraft.world.item.ItemStack nms = CraftItemStack.asNMSCopy(item); // Modelled off EntityHuman#hasBlock -@@ -601,6 +612,7 @@ public class CraftBlock implements Block { +@@ -602,6 +613,7 @@ public class CraftBlock implements Block { return Collections.emptyList(); } } diff --git a/patches/server/0005-Add-Player-to-SpongeAbsorbEvent.patch b/patches/server/0006-Add-Player-to-SpongeAbsorbEvent.patch similarity index 88% rename from patches/server/0005-Add-Player-to-SpongeAbsorbEvent.patch rename to patches/server/0006-Add-Player-to-SpongeAbsorbEvent.patch index 48813dc2b..44966eb96 100644 --- a/patches/server/0005-Add-Player-to-SpongeAbsorbEvent.patch +++ b/patches/server/0006-Add-Player-to-SpongeAbsorbEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Player to SpongeAbsorbEvent diff --git a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java -index d810f6bf9a8a354e5b8994e51ec3672428277dde..b5eb4718a96ab9abf700a156a23ec3e19757c9aa 100644 +index c4667bea0708d12e228ec2a4c84fcee7e48ca08c..ad2a9c6d91ebeda5bd9cffdf5471e19353348f65 100644 --- a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java -@@ -107,7 +107,8 @@ public class SpongeBlock extends Block { +@@ -114,7 +114,8 @@ public class SpongeBlock extends Block { if (!blocks.isEmpty()) { final org.bukkit.block.Block bblock = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); diff --git a/patches/server/0006-Add-World-Instance-flag.patch b/patches/server/0007-Add-World-Instance-flag.patch similarity index 84% rename from patches/server/0006-Add-World-Instance-flag.patch rename to patches/server/0007-Add-World-Instance-flag.patch index 65fe8833f..581be28c9 100644 --- a/patches/server/0006-Add-World-Instance-flag.patch +++ b/patches/server/0007-Add-World-Instance-flag.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add World Instance flag diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 584a768f2ce1c98a1de7749060c47f21721f9055..aad0d7662d530eaa9256de635401bbcde3263286 100644 +index 6041f1f5151f26d389f946d70f16e1de76db496b..a530dd1b15093803ffb87848f4c28dcf5da6476c 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -222,6 +222,7 @@ public class ServerLevel extends Level implements WorldGenLevel { +@@ -224,6 +224,7 @@ public class ServerLevel extends Level implements WorldGenLevel { public final UUID uuid; public boolean hasPhysicsEvent = true; // Paper public boolean hasEntityMoveEvent = false; // Paper @@ -17,10 +17,10 @@ index 584a768f2ce1c98a1de7749060c47f21721f9055..aad0d7662d530eaa9256de635401bbcd public static Throwable getAddToWorldStackTrace(Entity entity) { final Throwable thr = new Throwable(entity + " Added to world at " + new java.util.Date()); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 746f88db6b78b3c8ec372bfaacb26ec98f3b1163..b2b729c520f6b5dadc4d7bb72135c6da40d94b38 100644 +index 38d842bc0fb7d9c39a3673983a643248e9563fe2..7727a4322155c9b208f097bec751368c01671a07 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -1288,6 +1288,18 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1301,6 +1301,18 @@ public class CraftWorld extends CraftRegionAccessor implements World { this.world.noSave = !value; } diff --git a/patches/server/0007-Add-PlayerData-Events.patch b/patches/server/0008-Add-PlayerData-Events.patch similarity index 89% rename from patches/server/0007-Add-PlayerData-Events.patch rename to patches/server/0008-Add-PlayerData-Events.patch index 93d7532f9..5f939417c 100644 --- a/patches/server/0007-Add-PlayerData-Events.patch +++ b/patches/server/0008-Add-PlayerData-Events.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerData Events diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index 1d32eb837517f2b949613498b1a68c8b1edf0b9a..a31ea11234da240e56bbfd14725dd76295c8f338 100644 +index 4f00c2e8d6ff3a03a334542f699c5e35bfd03ce8..f31fc572413c2e1350adca3691316ac6b0d66fef 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -602,6 +602,8 @@ public class ServerPlayerGameMode { +@@ -603,6 +603,8 @@ public class ServerPlayerGameMode { enuminteractionresult1 = stack.useOn(itemactioncontext); } @@ -45,18 +45,18 @@ index 9bb8d4d7be6a937980aa653db82be084d066a563..9838435fbc31cfbba487d1e62ec5d2e7 private static ResourceLocation getKey(Stat stat) { diff --git a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java -index 36af81f0957d17e170d229059c66f4eb4539dfeb..e8d324a32838b69255ce48b1c03e47cd9e201da6 100644 +index b3a90d6ef0e17c236e0b3c46e2d0012671afdaa7..bb22635a8dc7d4e2030f50da62983119520a0b91 100644 --- a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java +++ b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java -@@ -33,6 +33,7 @@ public class PlayerDataStorage { +@@ -36,6 +36,7 @@ public class PlayerDataStorage { public void save(Player player) { if (org.spigotmc.SpigotConfig.disablePlayerDataSaving) return; // Spigot + if (!new com.destroystokyo.paper.event.player.PlayerSaveDataEvent((org.bukkit.entity.Player) player.getBukkitEntity()).callEvent()) return; // Slice try { CompoundTag nbttagcompound = player.saveWithoutId(new CompoundTag()); - File file = File.createTempFile(player.getStringUUID() + "-", ".dat", this.playerDir); -@@ -52,32 +53,40 @@ public class PlayerDataStorage { + Path path = this.playerDir.toPath(); +@@ -56,33 +57,41 @@ public class PlayerDataStorage { public CompoundTag load(Player player) { CompoundTag nbttagcompound = null; @@ -95,14 +95,14 @@ index 36af81f0957d17e170d229059c66f4eb4539dfeb..e8d324a32838b69255ce48b1c03e47cd + // Spigot End - if (file.exists() && file.isFile()) { -- nbttagcompound = NbtIo.readCompressed(file); +- nbttagcompound = NbtIo.readCompressed(file.toPath(), NbtAccounter.unlimitedHeap()); - } - // Spigot Start - if ( usingWrongFile ) - { - file.renameTo( new File( file.getPath() + ".offline-read" ) ); + if (file.exists() && file.isFile()) { -+ nbttagcompound = NbtIo.readCompressed(file); ++ nbttagcompound = NbtIo.readCompressed(file.toPath(), NbtAccounter.unlimitedHeap()); + } + // Spigot Start + if (usingWrongFile) { @@ -115,7 +115,9 @@ index 36af81f0957d17e170d229059c66f4eb4539dfeb..e8d324a32838b69255ce48b1c03e47cd - // Spigot End - } catch (Exception exception) { - PlayerDataStorage.LOGGER.warn("Failed to load player data for {}", player.getName().getString()); -+ // Slice end - } +- } ++ } // Slice end ++ if (nbttagcompound != null) { + // CraftBukkit start diff --git a/patches/server/0008-Add-PlayerGetRespawnLocationEvent.patch b/patches/server/0009-Add-PlayerGetRespawnLocationEvent.patch similarity index 97% rename from patches/server/0008-Add-PlayerGetRespawnLocationEvent.patch rename to patches/server/0009-Add-PlayerGetRespawnLocationEvent.patch index bd06ff2b5..42f88f7f8 100644 --- a/patches/server/0008-Add-PlayerGetRespawnLocationEvent.patch +++ b/patches/server/0009-Add-PlayerGetRespawnLocationEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add PlayerGetRespawnLocationEvent diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 33abcf12b4426572b74ca4c813e4392c823494bc..3caf0774537a02d8ceeb9a5cf113bee290f1aef6 100644 +index e98a455b6bca9d094d0da323bddd7b3f2c07bb23..6977fb1024db3e709e5c83215bf886e7c04d5326 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -869,49 +869,57 @@ public abstract class PlayerList { +@@ -867,49 +867,57 @@ public abstract class PlayerList { // CraftBukkit start - fire PlayerRespawnEvent if (location == null) { diff --git a/patches/server/0009-Set-multiple-team-settings-at-once.patch b/patches/server/0010-Set-multiple-team-settings-at-once.patch similarity index 98% rename from patches/server/0009-Set-multiple-team-settings-at-once.patch rename to patches/server/0010-Set-multiple-team-settings-at-once.patch index 26591b623..3aa58fcfe 100644 --- a/patches/server/0009-Set-multiple-team-settings-at-once.patch +++ b/patches/server/0010-Set-multiple-team-settings-at-once.patch @@ -106,7 +106,7 @@ index 9464054912e19fc78dd965b71fce20a18564b351..1624a0f8ea211a4c43fd01612674ca50 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java -index 9c3520524cfb903da6a5401760394ec1b49a1825..a6809c3104d4a8fce89eb5056b445ae0517bf9a0 100644 +index fd86c1d43cccd036f60cb270b56fd33f95707720..9d81ae52f55db1c330ebe2daa2d4008ee9b845c3 100644 --- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java +++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java @@ -341,6 +341,37 @@ final class CraftTeam extends CraftScoreboardComponent implements Team { diff --git a/patches/server/0010-Smooth-Teleports.patch b/patches/server/0011-Smooth-Teleports.patch similarity index 86% rename from patches/server/0010-Smooth-Teleports.patch rename to patches/server/0011-Smooth-Teleports.patch index 5076438db..6655eea06 100644 --- a/patches/server/0010-Smooth-Teleports.patch +++ b/patches/server/0011-Smooth-Teleports.patch @@ -5,11 +5,11 @@ Subject: [PATCH] Smooth Teleports diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index f71a4a8307fb092d33545e12d253e0b80c884168..7f09801b4afd426d75c16dee88c31e1a16108fc1 100644 +index 0eb3384df396508c3d26d1e155cd0e6d64251346..1c3e41c9c849c6ba9fa4a8cd6950f99c28ceff92 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -274,6 +274,7 @@ public class ServerPlayer extends Player { - public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper +@@ -281,6 +281,7 @@ public class ServerPlayer extends Player { + public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper public @Nullable String clientBrandName = null; // Paper - Brand name public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - there are a lot of changes to do if we change all methods leading to the event + public boolean smoothWorldTeleport; // Slice @@ -17,10 +17,10 @@ index f71a4a8307fb092d33545e12d253e0b80c884168..7f09801b4afd426d75c16dee88c31e1a // Paper start - replace player chunk loader private final java.util.concurrent.atomic.AtomicReference viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1)); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 3caf0774537a02d8ceeb9a5cf113bee290f1aef6..98290d00c4f472afa5d6db4d6bfd99c30086ceb0 100644 +index 6977fb1024db3e709e5c83215bf886e7c04d5326..2d6a0e30e47e4df22fd9aba1aca0f1f0d03740d2 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -955,10 +955,10 @@ public abstract class PlayerList { +@@ -953,10 +953,10 @@ public abstract class PlayerList { ServerLevel worldserver2 = entityplayer1.serverLevel(); LevelData worlddata = worldserver2.getLevelData(); @@ -34,10 +34,10 @@ index 3caf0774537a02d8ceeb9a5cf113bee290f1aef6..98290d00c4f472afa5d6db4d6bfd99c3 entityplayer1.connection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); entityplayer1.connection.send(new ClientboundSetExperiencePacket(entityplayer1.experienceProgress, entityplayer1.totalExperience, entityplayer1.experienceLevel)); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 00bae5df87bcc1c75d4e2f430241579d3be82c11..eaaf8b52b72ad688f8df772b574a84c9ee8f8be8 100644 +index 2ec8b8f65661001716d1cb34dcc21cda7286e5d7..16734cf6cb5203a9d40be56672a698b761f8ce8a 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -1246,6 +1246,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -1267,6 +1267,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Paper end } diff --git a/patches/server/0011-Ignore-durability-changes-for-equipment-updates.patch b/patches/server/0012-Ignore-durability-changes-for-equipment-updates.patch similarity index 83% rename from patches/server/0011-Ignore-durability-changes-for-equipment-updates.patch rename to patches/server/0012-Ignore-durability-changes-for-equipment-updates.patch index 384787122..8c111ba93 100644 --- a/patches/server/0011-Ignore-durability-changes-for-equipment-updates.patch +++ b/patches/server/0012-Ignore-durability-changes-for-equipment-updates.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Ignore durability changes for equipment updates diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index a76eb3d051db0229ed088b71c92ff3f131449007..d5fe77692292055f71766546d2f283440cccd7d6 100644 +index bc908b75cb99536df658281ae7f8b4eeedbbedc9..edfd68dd73deb703efc6e7164a2af0cb8744a0bd 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3161,7 +3161,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3166,7 +3166,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } public boolean equipmentHasChanged(ItemStack stack, ItemStack stack2) { diff --git a/patches/server/0012-Disable-Azalea-generation.patch b/patches/server/0013-Disable-Azalea-generation.patch similarity index 92% rename from patches/server/0012-Disable-Azalea-generation.patch rename to patches/server/0013-Disable-Azalea-generation.patch index f6a15f331..6d4ad7d94 100644 --- a/patches/server/0012-Disable-Azalea-generation.patch +++ b/patches/server/0013-Disable-Azalea-generation.patch @@ -18,15 +18,15 @@ index b9b7d2e668d9f7f36ac3cf1e1716460c4ad5ed3a..9fdd765b65777a1a82b54326bc7ad152 builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, CavePlacements.CLASSIC_VINES); } diff --git a/src/main/java/net/minecraft/data/worldgen/features/CaveFeatures.java b/src/main/java/net/minecraft/data/worldgen/features/CaveFeatures.java -index 3d899e4dbb96f64279485bbd5b708df88ddbfe8f..89f33b92dc8cfa22d1e1edbda1a31179743979e8 100644 +index c1f4a722b57bdc1ee516951c9341b146eb0fb34e..9d81f1e3e64edfcd5e8a2885dda3187386941cb8 100644 --- a/src/main/java/net/minecraft/data/worldgen/features/CaveFeatures.java +++ b/src/main/java/net/minecraft/data/worldgen/features/CaveFeatures.java @@ -110,7 +110,7 @@ public class CaveFeatures { RandomizedIntStateProvider randomizedIntStateProvider = new RandomizedIntStateProvider(new WeightedStateProvider(SimpleWeightedRandomList.builder().add(Blocks.CAVE_VINES.defaultBlockState(), 4).add(Blocks.CAVE_VINES.defaultBlockState().setValue(CaveVines.BERRIES, Boolean.valueOf(true)), 1)), CaveVinesBlock.AGE, UniformInt.of(23, 25)); FeatureUtils.register(featureRegisterable, CAVE_VINE, Feature.BLOCK_COLUMN, new BlockColumnConfiguration(List.of(BlockColumnConfiguration.layer(new WeightedListInt(SimpleWeightedRandomList.builder().add(UniformInt.of(0, 19), 2).add(UniformInt.of(0, 2), 3).add(UniformInt.of(0, 6), 10).build()), weightedStateProvider), BlockColumnConfiguration.layer(ConstantInt.of(1), randomizedIntStateProvider)), Direction.DOWN, BlockPredicate.ONLY_IN_AIR_PREDICATE, true)); FeatureUtils.register(featureRegisterable, CAVE_VINE_IN_MOSS, Feature.BLOCK_COLUMN, new BlockColumnConfiguration(List.of(BlockColumnConfiguration.layer(new WeightedListInt(SimpleWeightedRandomList.builder().add(UniformInt.of(0, 3), 5).add(UniformInt.of(1, 7), 1).build()), weightedStateProvider), BlockColumnConfiguration.layer(ConstantInt.of(1), randomizedIntStateProvider)), Direction.DOWN, BlockPredicate.ONLY_IN_AIR_PREDICATE, true)); -- FeatureUtils.register(featureRegisterable, MOSS_VEGETATION, Feature.SIMPLE_BLOCK, new SimpleBlockConfiguration(new WeightedStateProvider(SimpleWeightedRandomList.builder().add(Blocks.FLOWERING_AZALEA.defaultBlockState(), 4).add(Blocks.AZALEA.defaultBlockState(), 7).add(Blocks.MOSS_CARPET.defaultBlockState(), 25).add(Blocks.GRASS.defaultBlockState(), 50).add(Blocks.TALL_GRASS.defaultBlockState(), 10)))); -+ FeatureUtils.register(featureRegisterable, MOSS_VEGETATION, Feature.SIMPLE_BLOCK, new SimpleBlockConfiguration(new WeightedStateProvider(SimpleWeightedRandomList.builder().add(Blocks.MOSS_CARPET.defaultBlockState(), 25).add(Blocks.GRASS.defaultBlockState(), 50).add(Blocks.TALL_GRASS.defaultBlockState(), 10)))); +- FeatureUtils.register(featureRegisterable, MOSS_VEGETATION, Feature.SIMPLE_BLOCK, new SimpleBlockConfiguration(new WeightedStateProvider(SimpleWeightedRandomList.builder().add(Blocks.FLOWERING_AZALEA.defaultBlockState(), 4).add(Blocks.AZALEA.defaultBlockState(), 7).add(Blocks.MOSS_CARPET.defaultBlockState(), 25).add(Blocks.SHORT_GRASS.defaultBlockState(), 50).add(Blocks.TALL_GRASS.defaultBlockState(), 10)))); ++ FeatureUtils.register(featureRegisterable, MOSS_VEGETATION, Feature.SIMPLE_BLOCK, new SimpleBlockConfiguration(new WeightedStateProvider(SimpleWeightedRandomList.builder().add(Blocks.MOSS_CARPET.defaultBlockState(), 25).add(Blocks.SHORT_GRASS.defaultBlockState(), 50).add(Blocks.TALL_GRASS.defaultBlockState(), 10)))); FeatureUtils.register(featureRegisterable, MOSS_PATCH, Feature.VEGETATION_PATCH, new VegetationPatchConfiguration(BlockTags.MOSS_REPLACEABLE, BlockStateProvider.simple(Blocks.MOSS_BLOCK), PlacementUtils.inlinePlaced(holderGetter.getOrThrow(MOSS_VEGETATION)), CaveSurface.FLOOR, ConstantInt.of(1), 0.0F, 5, 0.8F, UniformInt.of(4, 7), 0.3F)); FeatureUtils.register(featureRegisterable, MOSS_PATCH_BONEMEAL, Feature.VEGETATION_PATCH, new VegetationPatchConfiguration(BlockTags.MOSS_REPLACEABLE, BlockStateProvider.simple(Blocks.MOSS_BLOCK), PlacementUtils.inlinePlaced(holderGetter.getOrThrow(MOSS_VEGETATION)), CaveSurface.FLOOR, ConstantInt.of(1), 0.0F, 5, 0.6F, UniformInt.of(1, 2), 0.75F)); FeatureUtils.register(featureRegisterable, DRIPLEAF, Feature.SIMPLE_RANDOM_SELECTOR, new SimpleRandomFeatureConfiguration(HolderSet.direct(makeSmallDripleaf(), makeDripleaf(Direction.EAST), makeDripleaf(Direction.WEST), makeDripleaf(Direction.SOUTH), makeDripleaf(Direction.NORTH)))); diff --git a/patches/server/0013-AntiXray-Bypass.patch b/patches/server/0014-AntiXray-Bypass.patch similarity index 76% rename from patches/server/0013-AntiXray-Bypass.patch rename to patches/server/0014-AntiXray-Bypass.patch index 2c89da1f8..1d3e43590 100644 --- a/patches/server/0013-AntiXray-Bypass.patch +++ b/patches/server/0014-AntiXray-Bypass.patch @@ -5,10 +5,10 @@ Subject: [PATCH] AntiXray Bypass diff --git a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java -index 42fdce97d99618a53f2e9c51804ff2205b574f69..7e8d58e3481be2d7ebbe5fe388d61932479e7721 100644 +index e7fe98ea30ae6d0baea3ec1f9f98a89502a49a12..7e2651aa63cc9ddbe28fb9ecbc5188358d52e607 100644 --- a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java +++ b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java -@@ -165,6 +165,7 @@ public final class ChunkPacketBlockControllerAntiXray extends ChunkPacketBlockCo +@@ -169,6 +169,7 @@ public final class ChunkPacketBlockControllerAntiXray extends ChunkPacketBlockCo @Override public boolean shouldModify(ServerPlayer player, LevelChunk chunk) { @@ -17,18 +17,18 @@ index 42fdce97d99618a53f2e9c51804ff2205b574f69..7e8d58e3481be2d7ebbe5fe388d61932 } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index eaaf8b52b72ad688f8df772b574a84c9ee8f8be8..4e4b77587aaa19d69fad9d15e97330b55ea97a8e 100644 +index 16734cf6cb5203a9d40be56672a698b761f8ce8a..7af85d92f87a645b35ffcb1ebf934b7fcfe0ec7b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -198,6 +198,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -193,6 +193,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + public org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus; // Paper - more resource pack API private static final boolean DISABLE_CHANNEL_LIMIT = System.getProperty("paper.disableChannelLimit") != null; // Paper - add a flag to disable the channel limit - private long lastSaveTime; - // Paper end + private long lastSaveTime; // Paper - getLastPlayed replacement API + private boolean antiXrayBypass; // Slice public CraftPlayer(CraftServer server, ServerPlayer entity) { super(server, entity); -@@ -2835,6 +2836,17 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2924,6 +2925,17 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end diff --git a/patches/server/0014-Add-PlayerPreChunkLoadEvent.patch b/patches/server/0015-Add-PlayerPreChunkLoadEvent.patch similarity index 91% rename from patches/server/0014-Add-PlayerPreChunkLoadEvent.patch rename to patches/server/0015-Add-PlayerPreChunkLoadEvent.patch index 15877624f..049132cd1 100644 --- a/patches/server/0014-Add-PlayerPreChunkLoadEvent.patch +++ b/patches/server/0015-Add-PlayerPreChunkLoadEvent.patch @@ -18,10 +18,10 @@ index 1b090f1e79b996e52097afc49c1cec85936653e6..5185bcbf5363fa2c7e2b0226706cc66d private static final byte CHUNK_TICKET_STAGE_NONE = 0; private static final byte CHUNK_TICKET_STAGE_LOADING = 1; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index b2b729c520f6b5dadc4d7bb72135c6da40d94b38..11f516e89a6d219033464b774e32dc59632fd5b2 100644 +index 7727a4322155c9b208f097bec751368c01671a07..88507e50e1fd0e9e8bfb124d0162db15e0d046a5 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -530,6 +530,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -538,6 +538,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { return true; } diff --git a/patches/server/0015-Allow-opening-covered-chests.patch b/patches/server/0016-Allow-opening-covered-chests.patch similarity index 87% rename from patches/server/0015-Allow-opening-covered-chests.patch rename to patches/server/0016-Allow-opening-covered-chests.patch index c74886c42..b0e974d13 100644 --- a/patches/server/0015-Allow-opening-covered-chests.patch +++ b/patches/server/0016-Allow-opening-covered-chests.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Allow opening covered chests diff --git a/src/main/java/net/minecraft/world/level/block/ChestBlock.java b/src/main/java/net/minecraft/world/level/block/ChestBlock.java -index 5e22d175b1048a58802cdf64ac70a8b56329e915..0f15e574b5c0cc8648bc1c0a12f1c72aa8653724 100644 +index 9804ee2020e5cef23d3f5174d153fc149e611503..8baeb4cb4a6e24e8099a0a98779dc50073d5d0b4 100644 --- a/src/main/java/net/minecraft/world/level/block/ChestBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ChestBlock.java -@@ -355,9 +355,10 @@ public class ChestBlock extends AbstractChestBlock implements +@@ -358,9 +358,10 @@ public class ChestBlock extends AbstractChestBlock implements } private static boolean isBlockedChestByBlock(BlockGetter world, BlockPos pos) { @@ -23,10 +23,10 @@ index 5e22d175b1048a58802cdf64ac70a8b56329e915..0f15e574b5c0cc8648bc1c0a12f1c72a private static boolean isCatSittingOnChest(LevelAccessor world, BlockPos pos) { diff --git a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java -index 7385e91f32f070e86a4e0fd3d214f55d832c7979..4911b099f865b9202286f51087e5c00ffeaa95a5 100644 +index ddca14f1224327a738415fb8b37398d8df0aa9c8..cfd9bfd30d4b1787dacc95215e823603537131fd 100644 --- a/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java +++ b/src/main/java/net/minecraft/world/level/block/EnderChestBlock.java -@@ -76,10 +76,10 @@ public class EnderChestBlock extends AbstractChestBlock i +@@ -83,10 +83,10 @@ public class EnderChestBlock extends AbstractChestBlock i PlayerEnderChestContainer playerEnderChestContainer = player.getEnderChestInventory(); BlockEntity blockEntity = world.getBlockEntity(pos); if (playerEnderChestContainer != null && blockEntity instanceof EnderChestBlockEntity) { diff --git a/patches/server/0016-Don-t-send-fire-packets-if-player-has-FR.patch b/patches/server/0017-Don-t-send-fire-packets-if-player-has-FR.patch similarity index 83% rename from patches/server/0016-Don-t-send-fire-packets-if-player-has-FR.patch rename to patches/server/0017-Don-t-send-fire-packets-if-player-has-FR.patch index edc4c9cf1..b9a8bcd30 100644 --- a/patches/server/0016-Don-t-send-fire-packets-if-player-has-FR.patch +++ b/patches/server/0017-Don-t-send-fire-packets-if-player-has-FR.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Don't send fire packets if player has FR diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 1e05fca2a2ba6e2c0b641b6e27585520889cd8a6..067bfc5414ad69916624aa635e475b6cac8517df 100644 +index 0c46a4aeafd03fbbfd590b0362d41bf2b1d5ca74..91fc0da2cc01c24f9d69ef008a8f6a79c6eaaa5e 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -868,7 +868,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -872,7 +872,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.checkBelowWorld(); if (!this.level().isClientSide) { diff --git a/patches/server/0017-Allow-access-to-LightEngine.patch b/patches/server/0018-Allow-access-to-LightEngine.patch similarity index 81% rename from patches/server/0017-Allow-access-to-LightEngine.patch rename to patches/server/0018-Allow-access-to-LightEngine.patch index 68ada773a..fcf1adc64 100644 --- a/patches/server/0017-Allow-access-to-LightEngine.patch +++ b/patches/server/0018-Allow-access-to-LightEngine.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Allow access to LightEngine diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index caa73632aee15583c6b6ed12a668c8f49b794708..f4b82c5506308aacba10a421afc284913a04099b 100644 +index d9cd497bc1b654030ff1a597f038b6a881df9f6b..4407f04904af9b17987ce595cc8b6e9e129ccec7 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -436,7 +436,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -435,7 +435,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider // Paper end - rewrite player chunk loader } diff --git a/patches/server/0018-Disable-geode-and-monsterspawners-generation.patch b/patches/server/0019-Disable-geode-and-monsterspawners-generation.patch similarity index 100% rename from patches/server/0018-Disable-geode-and-monsterspawners-generation.patch rename to patches/server/0019-Disable-geode-and-monsterspawners-generation.patch diff --git a/patches/server/0019-Set-Mutton-nutrition-equal-to-beef.patch b/patches/server/0020-Set-Mutton-nutrition-equal-to-beef.patch similarity index 100% rename from patches/server/0019-Set-Mutton-nutrition-equal-to-beef.patch rename to patches/server/0020-Set-Mutton-nutrition-equal-to-beef.patch diff --git a/patches/server/0021-Add-Force-Crit-to-PlayerPreAttackEntityEvent.patch b/patches/server/0022-Add-Force-Crit-to-PlayerPreAttackEntityEvent.patch similarity index 57% rename from patches/server/0021-Add-Force-Crit-to-PlayerPreAttackEntityEvent.patch rename to patches/server/0022-Add-Force-Crit-to-PlayerPreAttackEntityEvent.patch index 913c8c9f2..42185c37c 100644 --- a/patches/server/0021-Add-Force-Crit-to-PlayerPreAttackEntityEvent.patch +++ b/patches/server/0022-Add-Force-Crit-to-PlayerPreAttackEntityEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Force Crit to PlayerPreAttackEntityEvent diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index d58b4c0dbe651b5068212e5f14dce3164ee520f5..32d6615ea73c1c149049d16dfd1b395621ad634b 100644 +index 3e597833b57377b855505b8a0f2744801c791f90..04a68a4f0c642984bd2b95bfb0d7d2bd887d18f0 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -1283,10 +1283,11 @@ public abstract class Player extends LivingEntity { +@@ -1278,10 +1278,11 @@ public abstract class Player extends LivingEntity { flag1 = true; } @@ -23,31 +23,3 @@ index d58b4c0dbe651b5068212e5f14dce3164ee520f5..32d6615ea73c1c149049d16dfd1b3956 if (flag2) { f *= 1.5F; } -@@ -2413,27 +2414,6 @@ public abstract class Player extends LivingEntity { - this.lastDeathLocation = lastDeathPos; - } - -- @Override -- public float getHurtDir() { -- return this.hurtDir; -- } -- -- @Override -- public void animateHurt(float yaw) { -- super.animateHurt(yaw); -- this.hurtDir = yaw; -- } -- -- @Override -- public boolean canSprint() { -- return true; -- } -- -- @Override -- protected float getFlyingSpeed() { -- return this.abilities.flying && !this.isPassenger() ? (this.isSprinting() ? this.abilities.getFlyingSpeed() * 2.0F : this.abilities.getFlyingSpeed()) : (this.isSprinting() ? 0.025999999F : 0.02F); -- } -- - public static enum BedSleepingProblem { - - NOT_POSSIBLE_HERE, NOT_POSSIBLE_NOW(Component.translatable("block.minecraft.bed.no_sleep")), TOO_FAR_AWAY(Component.translatable("block.minecraft.bed.too_far_away")), OBSTRUCTED(Component.translatable("block.minecraft.bed.obstructed")), OTHER_PROBLEM, NOT_SAFE(Component.translatable("block.minecraft.bed.not_safe")); diff --git a/patches/server/0022-Add-Preventing-KB-Bonus-to-PlayerPreAttackEntityEven.patch b/patches/server/0023-Add-Preventing-KB-Bonus-to-PlayerPreAttackEntityEven.patch similarity index 88% rename from patches/server/0022-Add-Preventing-KB-Bonus-to-PlayerPreAttackEntityEven.patch rename to patches/server/0023-Add-Preventing-KB-Bonus-to-PlayerPreAttackEntityEven.patch index 9ef459d39..0c361efa3 100644 --- a/patches/server/0022-Add-Preventing-KB-Bonus-to-PlayerPreAttackEntityEven.patch +++ b/patches/server/0023-Add-Preventing-KB-Bonus-to-PlayerPreAttackEntityEven.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add Preventing KB Bonus to PlayerPreAttackEntityEvent diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index 32d6615ea73c1c149049d16dfd1b395621ad634b..0325086157b846da7da0ca291fd33c55fc91f229 100644 +index 04a68a4f0c642984bd2b95bfb0d7d2bd887d18f0..c12b9b70d093217c9c796663341edcfa7fd29932 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -1275,7 +1275,11 @@ public abstract class Player extends LivingEntity { +@@ -1270,7 +1270,11 @@ public abstract class Player extends LivingEntity { boolean flag = f2 > 0.9F; boolean flag1 = false; byte b0 = 0; diff --git a/patches/server/0023-noEntityCollisions-for-Entity.patch b/patches/server/0024-noEntityCollisions-for-Entity.patch similarity index 71% rename from patches/server/0023-noEntityCollisions-for-Entity.patch rename to patches/server/0024-noEntityCollisions-for-Entity.patch index 1a0da9142..fa9953e6c 100644 --- a/patches/server/0023-noEntityCollisions-for-Entity.patch +++ b/patches/server/0024-noEntityCollisions-for-Entity.patch @@ -5,22 +5,23 @@ Subject: [PATCH] noEntityCollisions for Entity diff --git a/src/main/java/io/papermc/paper/util/CollisionUtil.java b/src/main/java/io/papermc/paper/util/CollisionUtil.java -index bfb1de19f53d5d7c7b65e25a606fabfa416706b3..63262cc017b15b076f27143309b3e38c48289261 100644 +index ee0331a6bc40cdde08d926fd8eb1dc642630c2e5..d1094f6a61976a81f400ab5b2b604f9608209b28 100644 --- a/src/main/java/io/papermc/paper/util/CollisionUtil.java +++ b/src/main/java/io/papermc/paper/util/CollisionUtil.java -@@ -1777,6 +1777,7 @@ public final class CollisionUtil { - +@@ -1753,7 +1753,7 @@ public final class CollisionUtil { public static boolean getEntityHardCollisions(final CollisionGetter getter, final Entity entity, AABB aabb, final List into, final int collisionFlags, final Predicate predicate) { -+ if (entity != null && entity.noEntityCollisions) return false; // Slice final boolean checkOnly = (collisionFlags & COLLISION_FLAG_CHECK_ONLY) != 0; - if (!(getter instanceof EntityGetter entityGetter)) { +- if (!(getter instanceof EntityGetter entityGetter)) { ++ if ((entity != null && entity.noEntityCollisions) || !(getter instanceof EntityGetter entityGetter)) { return false; + } + diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 067bfc5414ad69916624aa635e475b6cac8517df..c2e0a83819a0ea553f1206d364a111c7c127bc18 100644 +index 91fc0da2cc01c24f9d69ef008a8f6a79c6eaaa5e..25c28dd37e729627739c91e929c208f6aa2539c0 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -453,6 +453,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -457,6 +457,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S * Overriding this field will cause memory leaks. */ private final boolean hardCollides; diff --git a/patches/server/0024-Do-not-freeze-MappedRegistry.patch b/patches/server/0025-Do-not-freeze-MappedRegistry.patch similarity index 87% rename from patches/server/0024-Do-not-freeze-MappedRegistry.patch rename to patches/server/0025-Do-not-freeze-MappedRegistry.patch index a10b5a8f0..52fdebd91 100644 --- a/patches/server/0024-Do-not-freeze-MappedRegistry.patch +++ b/patches/server/0025-Do-not-freeze-MappedRegistry.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Do not freeze MappedRegistry diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java -index 26b92e27de1f079ab8440538c65377ed80e8b6ef..2a52ba73849b3f1f86ab4a5c41fcaf65ad452e41 100644 +index 742af4feb3986ca7d8f5ed136b556a41cbe0722f..d8fd0627b781e4b66ad0882304ec417fbb5c9b20 100644 --- a/src/main/java/net/minecraft/core/MappedRegistry.java +++ b/src/main/java/net/minecraft/core/MappedRegistry.java -@@ -337,7 +337,7 @@ public class MappedRegistry implements WritableRegistry { +@@ -334,7 +334,7 @@ public class MappedRegistry implements WritableRegistry { if (this.frozen) { return this; } else { @@ -17,7 +17,7 @@ index 26b92e27de1f079ab8440538c65377ed80e8b6ef..2a52ba73849b3f1f86ab4a5c41fcaf65 this.byValue.forEach((value, entry) -> { entry.bindValue(value); }); -@@ -364,14 +364,16 @@ public class MappedRegistry implements WritableRegistry { +@@ -361,14 +361,16 @@ public class MappedRegistry implements WritableRegistry { @Override public Holder.Reference createIntrusiveHolder(T value) { diff --git a/patches/server/0025-Add-jackson.patch b/patches/server/0026-Add-jackson.patch similarity index 89% rename from patches/server/0025-Add-jackson.patch rename to patches/server/0026-Add-jackson.patch index 042d7084a..81755dd6c 100644 --- a/patches/server/0025-Add-jackson.patch +++ b/patches/server/0026-Add-jackson.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Add jackson diff --git a/build.gradle.kts b/build.gradle.kts -index 2e1cea360bb6ff85eb8da54237bc407653eb91f6..475cbb6120655419fc7dc51292e6beedfe778656 100644 +index f9df4ced9b313333102d5f76dff20841a789e53f..1d78ff5def3357c4b4fed3e6b66f092c237c1a0b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,6 +19,13 @@ dependencies { diff --git a/patches/server/0026-Maybe-can-t-tostring.patch b/patches/server/0027-Maybe-can-t-tostring.patch similarity index 86% rename from patches/server/0026-Maybe-can-t-tostring.patch rename to patches/server/0027-Maybe-can-t-tostring.patch index edac1b435..ee735380a 100644 --- a/patches/server/0026-Maybe-can-t-tostring.patch +++ b/patches/server/0027-Maybe-can-t-tostring.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Maybe can't tostring? diff --git a/src/main/java/net/minecraft/nbt/CompoundTag.java b/src/main/java/net/minecraft/nbt/CompoundTag.java -index 84fc2adf591f02a14862f7c1cd645c2efde55c3d..f088d316aac7626204cff330f90468d89ac3581b 100644 +index e464ada187fd1f15efef29a0e5033aeb0c688059..b2e800c653ba423e40de734218a8e4a020069076 100644 --- a/src/main/java/net/minecraft/nbt/CompoundTag.java +++ b/src/main/java/net/minecraft/nbt/CompoundTag.java -@@ -503,6 +503,9 @@ public class CompoundTag implements Tag { +@@ -507,6 +507,9 @@ public class CompoundTag implements Tag { @Override public CompoundTag copy() { // Paper start - reduce memory footprint of NBTTagCompound @@ -19,10 +19,10 @@ index 84fc2adf591f02a14862f7c1cd645c2efde55c3d..f088d316aac7626204cff330f90468d8 java.util.Iterator> iterator = (this.tags instanceof it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap) ? ((it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap)this.tags).object2ObjectEntrySet().fastIterator() : this.tags.entrySet().iterator(); while (iterator.hasNext()) { diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index e30aaa502f5e98b5658a0dd78853e865cbf91f96..c9cd6d3a3678ec38fbfb9ca3975d2ddbe2ce2881 100644 +index 625a852db818d95365ad7ae56e6b1de541bbdada..f721dd923711d65338820642dfca89ab8022e9a5 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -742,7 +742,11 @@ public final class ItemStack { +@@ -765,7 +765,11 @@ public final class ItemStack { itemstack.setPopTime(this.getPopTime()); if (this.tag != null) { diff --git a/patches/server/0027-Allow-inventory-clicks-in-Spectator.patch b/patches/server/0028-Allow-inventory-clicks-in-Spectator.patch similarity index 88% rename from patches/server/0027-Allow-inventory-clicks-in-Spectator.patch rename to patches/server/0028-Allow-inventory-clicks-in-Spectator.patch index 73043b9a4..61456b2b8 100644 --- a/patches/server/0027-Allow-inventory-clicks-in-Spectator.patch +++ b/patches/server/0028-Allow-inventory-clicks-in-Spectator.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Allow inventory clicks in Spectator diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 8bd243a8d5a4be54f907af2b02e96ea833cee62f..e93738332eaef720abb303b382f902c95aa87d72 100644 +index 30ccbab1586a656e0ae41d7406525fb02d9e025b..31f6914f1b254aa568801e94a0d523f2aa2ad65c 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2873,7 +2873,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2876,7 +2876,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl if (this.player.isImmobile()) return; // CraftBukkit this.player.resetLastActionTime(); if (this.player.containerMenu.containerId == packet.getContainerId() && this.player.containerMenu.stillValid(this.player)) { // CraftBukkit diff --git a/patches/server/0028-Packet-obfuscation-and-reduction.patch b/patches/server/0029-Packet-obfuscation-and-reduction.patch similarity index 92% rename from patches/server/0028-Packet-obfuscation-and-reduction.patch rename to patches/server/0029-Packet-obfuscation-and-reduction.patch index e70b385a5..45aa1706f 100644 --- a/patches/server/0028-Packet-obfuscation-and-reduction.patch +++ b/patches/server/0029-Packet-obfuscation-and-reduction.patch @@ -144,10 +144,10 @@ index 35674f92a67f93382103c2766df4b678ba5c862f..97dbcb6f527bd5c567e77200d7f6cbc1 if (this.entity instanceof LivingEntity) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index c2e0a83819a0ea553f1206d364a111c7c127bc18..6f60cadb034de8bbe52351a100916879ca98d977 100644 +index 25c28dd37e729627739c91e929c208f6aa2539c0..34f3ddb22febc0aea7d3059b2cbbd84554fd03b4 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -3334,7 +3334,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { +@@ -3384,7 +3384,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S this.entityData.markDirty(Entity.DATA_AIR_SUPPLY_ID); return; } @@ -157,10 +157,10 @@ index c2e0a83819a0ea553f1206d364a111c7c127bc18..6f60cadb034de8bbe52351a100916879 } diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index d5fe77692292055f71766546d2f283440cccd7d6..1625dea60a5880b04b34d36732370e65ab86e528 100644 +index edfd68dd73deb703efc6e7164a2af0cb8744a0bd..3c453de303422f96abf3aa67fa23523dd71327cb 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3161,7 +3161,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3166,7 +3166,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } public boolean equipmentHasChanged(ItemStack stack, ItemStack stack2) { @@ -170,10 +170,10 @@ index d5fe77692292055f71766546d2f283440cccd7d6..1625dea60a5880b04b34d36732370e65 private void handleHandSwap(Map equipmentChanges) { diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java -index a969ced38fb6cdc4e27f5a4430a4ec98279d9525..69968dff14c08a37a723ecd39c75f6981353df09 100644 +index c12b9b70d093217c9c796663341edcfa7fd29932..88873231244f3d6e36a3e0aae957cb3af2048b8d 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -649,7 +649,7 @@ public abstract class Player extends LivingEntity { +@@ -644,7 +644,7 @@ public abstract class Player extends LivingEntity { public void increaseScore(int score) { int j = this.getScore(); @@ -183,10 +183,10 @@ index a969ced38fb6cdc4e27f5a4430a4ec98279d9525..69968dff14c08a37a723ecd39c75f698 public void startAutoSpinAttack(int riptideTicks) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 4e4b77587aaa19d69fad9d15e97330b55ea97a8e..3634519803bb755fa0fde91500223c365a1b8ca1 100644 +index 7af85d92f87a645b35ffcb1ebf934b7fcfe0ec7b..c46cb9bbc1b7e8f6febb2ea93082d7d90ed78867 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2599,7 +2599,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2727,7 +2727,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.sendHealthUpdate(); } } diff --git a/patches/server/0029-Long-distance-tracking.patch b/patches/server/0030-Long-distance-tracking.patch similarity index 90% rename from patches/server/0029-Long-distance-tracking.patch rename to patches/server/0030-Long-distance-tracking.patch index 5120c7107..be7f33c8f 100644 --- a/patches/server/0029-Long-distance-tracking.patch +++ b/patches/server/0030-Long-distance-tracking.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Long distance tracking diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index f4b82c5506308aacba10a421afc284913a04099b..3ad804d7f5b018757a218547e25b9bf53ecfa78d 100644 +index 4407f04904af9b17987ce595cc8b6e9e129ccec7..2d97c4445bd172a901c8dcf144b03081e0679468 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1422,6 +1422,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -1421,6 +1421,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider Vec3 vec3d = player.position().subtract(this.entity.position()); int i = ChunkMap.this.getPlayerViewDistance(player); double d0 = (double) Math.min(this.getEffectiveRange(), i * 16); @@ -17,10 +17,10 @@ index f4b82c5506308aacba10a421afc284913a04099b..3ad804d7f5b018757a218547e25b9bf5 double d2 = d0 * d0; boolean flag = d1 <= d2 && this.entity.broadcastToPlayer(player) && ChunkMap.this.isChunkTracked(player, this.entity.chunkPosition().x, this.entity.chunkPosition().z); diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index 7f09801b4afd426d75c16dee88c31e1a16108fc1..702ca0b220e5f81702c3cc8e7b4797be22de9235 100644 +index 1c3e41c9c849c6ba9fa4a8cd6950f99c28ceff92..7a9805d6c4335092bbabb68b3678a8e78b7d406f 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -275,6 +275,7 @@ public class ServerPlayer extends Player { +@@ -282,6 +282,7 @@ public class ServerPlayer extends Player { public @Nullable String clientBrandName = null; // Paper - Brand name public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - there are a lot of changes to do if we change all methods leading to the event public boolean smoothWorldTeleport; // Slice @@ -28,7 +28,7 @@ index 7f09801b4afd426d75c16dee88c31e1a16108fc1..702ca0b220e5f81702c3cc8e7b4797be // Paper start - replace player chunk loader private final java.util.concurrent.atomic.AtomicReference viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1)); -@@ -2657,4 +2658,18 @@ public class ServerPlayer extends Player { +@@ -2757,4 +2758,18 @@ public class ServerPlayer extends Player { return (CraftPlayer) super.getBukkitEntity(); } // CraftBukkit end @@ -48,7 +48,7 @@ index 7f09801b4afd426d75c16dee88c31e1a16108fc1..702ca0b220e5f81702c3cc8e7b4797be + // Slice end } diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java -index f9b8e2bc039f1a37e47f84909c8785f3ef530284..bfa02a3698a347c55f0fff351ac24e831403cb56 100644 +index 1cf6d4f854d89c515e48e1fb365eb95ff9340765..6dab8b76bef3c97936fc337e813bcb60c7f2026d 100644 --- a/src/main/java/org/spigotmc/SpigotWorldConfig.java +++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java @@ -271,6 +271,7 @@ public class SpigotWorldConfig diff --git a/patches/server/0038-Non-saveable-entities.patch b/patches/server/0038-Non-saveable-entities.patch new file mode 100644 index 000000000..87d6d5f8a --- /dev/null +++ b/patches/server/0038-Non-saveable-entities.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Cryptite +Date: Sat, 21 Oct 2023 11:27:52 -0500 +Subject: [PATCH] Non-saveable entities + + +diff --git a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java +index 7e8dc9e8f381abfdcce2746edc93122d623622d1..303e5ed4d5cf2a64b998656bfd189f19f8c8fcde 100644 +--- a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java ++++ b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java +@@ -118,7 +118,7 @@ public final class ChunkEntitySlices { + // removed by us below + continue; + } +- if (entity.shouldBeSaved()) { ++ if (entity.shouldBeSaved() || !entity.saveable) { // Slice + entity.setRemoved(Entity.RemovalReason.UNLOADED_TO_CHUNK); + if (entity.isVehicle()) { + // we cannot assume that these entities are contained within this chunk, because entities can +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index 34f3ddb22febc0aea7d3059b2cbbd84554fd03b4..a6db17c51d6b8e58936e52e7f6cbe07dcebd5418 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -422,6 +422,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S + private UUID originWorld; + public boolean freezeLocked = false; // Paper - Freeze Tick Lock API + public boolean fixedPose = false; // Paper ++ public boolean saveable = true; // Slice + + public void setOrigin(@javax.annotation.Nonnull Location location) { + this.origin = location.toVector(); +@@ -4819,7 +4820,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S + + @Override + public boolean shouldBeSaved() { +- return this.removalReason != null && !this.removalReason.shouldSave() ? false : (this.isPassenger() ? false : !this.isVehicle() || !this.hasAnyPlayerPassengers()); // Paper - rewrite chunk system - it should check if the entity has ANY player passengers ++ return this.saveable && this.removalReason != null && !this.removalReason.shouldSave() ? false : (this.isPassenger() ? false : !this.isVehicle() || !this.hasAnyPlayerPassengers()); // Paper - rewrite chunk system - it should check if the entity has ANY player passengers // Slice - add saveable check + } + + @Override +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +index 1c3e1153d08b59d29b3613fc3b50a4780aa7a3ac..19c56ef79cacfb6d65dea5741d9ce71998c1eacc 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +@@ -1227,4 +1227,16 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { + return this.getHandle().getScoreboardName(); + } + // Paper end - entity scoreboard name ++ ++ // Slice start ++ @Override ++ public boolean isSaveable() { ++ return this.entity.saveable; ++ } ++ ++ @Override ++ public void setSaveable(boolean saveable) { ++ this.entity.saveable = saveable; ++ } ++ // Slice end + } diff --git a/patches/server/0040-Disable-sending-Entity-Movement-Packets.patch b/patches/server/0040-Disable-sending-Entity-Movement-Packets.patch new file mode 100644 index 000000000..384be094e --- /dev/null +++ b/patches/server/0040-Disable-sending-Entity-Movement-Packets.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Cryptite +Date: Wed, 25 Oct 2023 17:05:29 -0500 +Subject: [PATCH] Disable sending Entity Movement Packets + + +diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java +index 97dbcb6f527bd5c567e77200d7f6cbc1abb15792..fa4e0bcf752693c34aff8b53aea3eeaa65834fc1 100644 +--- a/src/main/java/net/minecraft/server/level/ServerEntity.java ++++ b/src/main/java/net/minecraft/server/level/ServerEntity.java +@@ -151,7 +151,7 @@ public class ServerEntity { + boolean flag = Math.abs(i - this.yRotp) >= 1 || Math.abs(j - this.xRotp) >= 1; + + if (flag) { +- this.broadcast.accept(new ClientboundMoveEntityPacket.Rot(this.entity.getId(), (byte) i, (byte) j, this.entity.onGround())); ++ if (entity.sendMovementPackets) this.broadcast.accept(new ClientboundMoveEntityPacket.Rot(this.entity.getId(), (byte) i, (byte) j, this.entity.onGround())); // Slice + this.yRotp = i; + this.xRotp = j; + } +@@ -180,14 +180,14 @@ public class ServerEntity { + if (!flag6 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.onGround()&& !(io.papermc.paper.configuration.GlobalConfiguration.get().collisions.sendFullPosForHardCollidingEntities && this.entity.hardCollides())) { // Paper - send full pos for hard colliding entities to prevent collision problems due to desync + if ((!flag2 || !flag3) && !(this.entity instanceof AbstractArrow)) { + if (flag2) { +- packet1 = new ClientboundMoveEntityPacket.Pos(this.entity.getId(), (short) ((int) k), (short) ((int) l), (short) ((int) i1), this.entity.onGround()); ++ if (entity.sendMovementPackets) packet1 = new ClientboundMoveEntityPacket.Pos(this.entity.getId(), (short) ((int) k), (short) ((int) l), (short) ((int) i1), this.entity.onGround()); // Slice + flag4 = true; + } else if (flag3) { +- packet1 = new ClientboundMoveEntityPacket.Rot(this.entity.getId(), (byte) i, (byte) j, this.entity.onGround()); ++ if (entity.sendMovementPackets) packet1 = new ClientboundMoveEntityPacket.Rot(this.entity.getId(), (byte) i, (byte) j, this.entity.onGround()); // Slice + flag5 = true; + } + } else { +- packet1 = new ClientboundMoveEntityPacket.PosRot(this.entity.getId(), (short) ((int) k), (short) ((int) l), (short) ((int) i1), (byte) i, (byte) j, this.entity.onGround()); ++ if (entity.sendMovementPackets) packet1 = new ClientboundMoveEntityPacket.PosRot(this.entity.getId(), (short) ((int) k), (short) ((int) l), (short) ((int) i1), (byte) i, (byte) j, this.entity.onGround()); // Slice + flag4 = true; + flag5 = true; + } +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index a6db17c51d6b8e58936e52e7f6cbe07dcebd5418..1c75f943055b27d435ba36275fa7cd704e7a7b1a 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -423,6 +423,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S + public boolean freezeLocked = false; // Paper - Freeze Tick Lock API + public boolean fixedPose = false; // Paper + public boolean saveable = true; // Slice ++ public boolean sendMovementPackets = true; // Slice + + public void setOrigin(@javax.annotation.Nonnull Location location) { + this.origin = location.toVector(); diff --git a/patches/server/0041-Player-spawnsOwnMobs.patch b/patches/server/0041-Player-spawnsOwnMobs.patch new file mode 100644 index 000000000..b9e6ac1d0 --- /dev/null +++ b/patches/server/0041-Player-spawnsOwnMobs.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Cryptite +Date: Thu, 7 Dec 2023 08:48:41 -0600 +Subject: [PATCH] Player spawnsOwnMobs + + +diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +index 44ada45d9bf2d9b48e5de1c3cb1a855902f3884b..9c5be1f0fd4d6cb62e7bc7faa8fa4c4e5879ab4e 100644 +--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java ++++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +@@ -557,7 +557,7 @@ public class ServerChunkCache extends ChunkSource { + // Paper start - optimise chunk tick iteration + ChunkMap playerChunkMap = this.chunkMap; + for (ServerPlayer player : this.level.players) { +- if (!player.affectsSpawning || player.isSpectator()) { ++ if (!player.affectsSpawning || player.isSpectator() || player.spawnsOwnMobs) { + playerChunkMap.playerMobSpawnMap.remove(player); + player.playerNaturallySpawnedEvent = null; + player.lastEntitySpawnRadiusSquared = -1.0; +diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java +index 88873231244f3d6e36a3e0aae957cb3af2048b8d..a0b6df7d86345f8a7269ca9cfcec6717b213adfd 100644 +--- a/src/main/java/net/minecraft/world/entity/player/Player.java ++++ b/src/main/java/net/minecraft/world/entity/player/Player.java +@@ -184,6 +184,8 @@ public abstract class Player extends LivingEntity { + public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; + // Paper end + ++ public boolean spawnsOwnMobs = false; // Slice ++ + // CraftBukkit start + public boolean fauxSleeping; + public int oldLevel = -1; diff --git a/patches/server/0042-Set-location-on-a-Custom-Inventory.patch b/patches/server/0042-Set-location-on-a-Custom-Inventory.patch new file mode 100644 index 000000000..0e7d27783 --- /dev/null +++ b/patches/server/0042-Set-location-on-a-Custom-Inventory.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Cryptite +Date: Fri, 8 Dec 2023 08:02:07 -0600 +Subject: [PATCH] Set location on a Custom Inventory + + +diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java +index da1c1fe0faf6819b15a81d6ad53370948e5f984f..84eff85e98484c9701e203bb1fa61435ee88bab4 100644 +--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java ++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java +@@ -69,6 +69,14 @@ public class CraftInventoryCustom extends CraftInventory { + } + // Paper end + ++ // Slice start ++ public void setLocation(Location location) { ++ if (this.inventory instanceof MinecraftInventory minecraftInventory) { ++ minecraftInventory.location = location; ++ } ++ } ++ // Slice end ++ + static class MinecraftInventory implements Container { + private final NonNullList items; + private int maxStack = MAX_STACK; +@@ -77,6 +85,7 @@ public class CraftInventoryCustom extends CraftInventory { + private final net.kyori.adventure.text.Component adventure$title; // Paper + private InventoryType type; + private final InventoryHolder owner; ++ private Location location; // Slice + + // Paper start + public MinecraftInventory(InventoryHolder owner, InventoryType type, net.kyori.adventure.text.Component title) { +@@ -239,7 +248,7 @@ public class CraftInventoryCustom extends CraftInventory { + + @Override + public Location getLocation() { +- return null; ++ return location; + } + + // Paper start diff --git a/patches/server/0043-Affinity-Test.patch b/patches/server/0043-Affinity-Test.patch new file mode 100644 index 000000000..52e8853a1 --- /dev/null +++ b/patches/server/0043-Affinity-Test.patch @@ -0,0 +1,20 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Cryptite +Date: Mon, 11 Dec 2023 11:09:16 -0600 +Subject: [PATCH] Affinity Test + + +diff --git a/build.gradle.kts b/build.gradle.kts +index 1d78ff5def3357c4b4fed3e6b66f092c237c1a0b..aff13fbe60cc6970227f86a1d451d88f71f1b346 100644 +--- a/build.gradle.kts ++++ b/build.gradle.kts +@@ -26,6 +26,9 @@ dependencies { + implementation("com.fasterxml.jackson.core:jackson-annotations:2.13.0") + // Slice end + ++ // https://mvnrepository.com/artifact/net.openhft/Java-Thread-Affinity ++ implementation("net.openhft:affinity:3.23.3") ++ + // Paper start + implementation("org.jline:jline-terminal-jansi:3.21.0") + implementation("net.minecrell:terminalconsoleappender:1.3.0")