From b1ab1d513d9368e6c34576e262128d6459fe6845 Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Sat, 3 Aug 2024 18:42:30 -0400 Subject: [PATCH 001/125] Add warning for wrong mob category in biomes (#1383) --- .../neoforge/server/ServerLifecycleHooks.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/java/net/neoforged/neoforge/server/ServerLifecycleHooks.java b/src/main/java/net/neoforged/neoforge/server/ServerLifecycleHooks.java index b41d0554af..4fa7de3f9a 100644 --- a/src/main/java/net/neoforged/neoforge/server/ServerLifecycleHooks.java +++ b/src/main/java/net/neoforged/neoforge/server/ServerLifecycleHooks.java @@ -19,13 +19,16 @@ import net.minecraft.core.RegistrationInfo; import net.minecraft.core.Registry; import net.minecraft.core.RegistryAccess; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.gametest.framework.GameTestServer; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; import net.minecraft.world.entity.SpawnPlacements; import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Biomes; import net.minecraft.world.level.biome.MobSpawnSettings; import net.minecraft.world.level.storage.LevelResource; import net.neoforged.fml.config.ConfigTracker; @@ -186,6 +189,23 @@ private static void runModifiers(final MinecraftServer server) { entitiesWithoutPlacements.add(data.type); }); }); + + for (MobCategory mobCategory : mobSettings.getSpawnerTypes()) { + for (MobSpawnSettings.SpawnerData spawnerData : mobSettings.getMobs(mobCategory).unwrap()) { + if (spawnerData.type.getCategory() != mobCategory) { + // Ignore vanilla bugged entries to reduce unneeded logging. See https://bugs.mojang.com/browse/MC-1788 for the Ocelot/Jungle vanilla bug. + boolean isVanillaBug = spawnerData.type == EntityType.OCELOT && (biomeHolder.is(Biomes.JUNGLE) || biomeHolder.is(Biomes.BAMBOO_JUNGLE)); + if (!isVanillaBug) { + LOGGER.warn("Detected {} that was registered with {} mob category but was added under {} mob category for {} biome! " + + "Mobs should be added to biomes under the same mob category that the mob was registered as to prevent mob cap spawning issues.", + BuiltInRegistries.ENTITY_TYPE.getKey(spawnerData.type), + spawnerData.type.getCategory(), + mobCategory, + biomeHolder.getKey().location()); + } + } + } + } }); // Rebuild the indexed feature list registries.registryOrThrow(Registries.LEVEL_STEM).forEach(levelStem -> { From 4bd040dfb0bb97113ce02bca8604fb5cc105a317 Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Sun, 4 Aug 2024 11:39:48 -0400 Subject: [PATCH 002/125] rename slimeball tag, melee tools adjustment, and fix entries for some biome and food tags (#1372) --- .../resources/assets/c/lang/en_us.json | 2 +- .../data/c/tags/item/foods/fruit.json | 1 + .../data/c/tags/item/foods/golden.json | 3 +-- .../data/c/tags/item/foods/vegetable.json | 1 - .../data/c/tags/item/slime_balls.json | 13 ++++++++++++ .../data/c/tags/item/slimeballs.json | 9 --------- .../data/c/tags/item/tools/melee_weapon.json | 20 +------------------ .../worldgen/biome/is_cold/overworld.json | 5 +++++ .../common/TagConventionLogWarning.java | 3 ++- .../net/neoforged/neoforge/common/Tags.java | 10 +++++++++- .../internal/NeoForgeBiomeTagsProvider.java | 5 +++++ .../internal/NeoForgeItemTagsProvider.java | 15 ++++++-------- .../internal/NeoForgeLanguageProvider.java | 2 +- 13 files changed, 45 insertions(+), 44 deletions(-) create mode 100644 src/generated/resources/data/c/tags/item/slime_balls.json delete mode 100644 src/generated/resources/data/c/tags/item/slimeballs.json diff --git a/src/generated/resources/assets/c/lang/en_us.json b/src/generated/resources/assets/c/lang/en_us.json index d2de27a0da..4c75679674 100644 --- a/src/generated/resources/assets/c/lang/en_us.json +++ b/src/generated/resources/assets/c/lang/en_us.json @@ -312,7 +312,7 @@ "tag.item.c.seeds.pumpkin": "Pumpkin Seeds", "tag.item.c.seeds.wheat": "Wheat Seeds", "tag.item.c.shulker_boxes": "Shulker Boxes", - "tag.item.c.slimeballs": "Slimeballs", + "tag.item.c.slime_balls": "Slimeballs", "tag.item.c.stones": "Stones", "tag.item.c.storage_blocks": "Storage Blocks", "tag.item.c.storage_blocks.bone_meal": "Bone Meal Storage Blocks", diff --git a/src/generated/resources/data/c/tags/item/foods/fruit.json b/src/generated/resources/data/c/tags/item/foods/fruit.json index 9860c9bbb8..d8703e8edf 100644 --- a/src/generated/resources/data/c/tags/item/foods/fruit.json +++ b/src/generated/resources/data/c/tags/item/foods/fruit.json @@ -3,6 +3,7 @@ "minecraft:apple", "minecraft:golden_apple", "minecraft:enchanted_golden_apple", + "minecraft:melon_slice", { "id": "#c:foods/fruits", "required": false diff --git a/src/generated/resources/data/c/tags/item/foods/golden.json b/src/generated/resources/data/c/tags/item/foods/golden.json index 109e7d6001..da323315a3 100644 --- a/src/generated/resources/data/c/tags/item/foods/golden.json +++ b/src/generated/resources/data/c/tags/item/foods/golden.json @@ -2,7 +2,6 @@ "values": [ "minecraft:golden_apple", "minecraft:enchanted_golden_apple", - "minecraft:golden_carrot", - "minecraft:glistering_melon_slice" + "minecraft:golden_carrot" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/foods/vegetable.json b/src/generated/resources/data/c/tags/item/foods/vegetable.json index e1bc7cfb0b..c6ae447d59 100644 --- a/src/generated/resources/data/c/tags/item/foods/vegetable.json +++ b/src/generated/resources/data/c/tags/item/foods/vegetable.json @@ -3,7 +3,6 @@ "minecraft:carrot", "minecraft:golden_carrot", "minecraft:potato", - "minecraft:melon_slice", "minecraft:beetroot", { "id": "#c:foods/vegetables", diff --git a/src/generated/resources/data/c/tags/item/slime_balls.json b/src/generated/resources/data/c/tags/item/slime_balls.json new file mode 100644 index 0000000000..c5d2c7d82d --- /dev/null +++ b/src/generated/resources/data/c/tags/item/slime_balls.json @@ -0,0 +1,13 @@ +{ + "values": [ + "minecraft:slime_ball", + { + "id": "#c:slimeballs", + "required": false + }, + { + "id": "#forge:slime_balls", + "required": false + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/slimeballs.json b/src/generated/resources/data/c/tags/item/slimeballs.json deleted file mode 100644 index e81d459385..0000000000 --- a/src/generated/resources/data/c/tags/item/slimeballs.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "values": [ - "minecraft:slime_ball", - { - "id": "#forge:slimeballs", - "required": false - } - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/tools/melee_weapon.json b/src/generated/resources/data/c/tags/item/tools/melee_weapon.json index abed055f16..1b166a3b4a 100644 --- a/src/generated/resources/data/c/tags/item/tools/melee_weapon.json +++ b/src/generated/resources/data/c/tags/item/tools/melee_weapon.json @@ -13,24 +13,6 @@ "minecraft:golden_axe", "minecraft:iron_axe", "minecraft:diamond_axe", - "minecraft:netherite_axe", - "minecraft:wooden_pickaxe", - "minecraft:stone_pickaxe", - "minecraft:golden_pickaxe", - "minecraft:iron_pickaxe", - "minecraft:diamond_pickaxe", - "minecraft:netherite_pickaxe", - "minecraft:wooden_shovel", - "minecraft:stone_shovel", - "minecraft:golden_shovel", - "minecraft:iron_shovel", - "minecraft:diamond_shovel", - "minecraft:netherite_shovel", - "minecraft:wooden_hoe", - "minecraft:stone_hoe", - "minecraft:golden_hoe", - "minecraft:iron_hoe", - "minecraft:diamond_hoe", - "minecraft:netherite_hoe" + "minecraft:netherite_axe" ] } \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/worldgen/biome/is_cold/overworld.json b/src/generated/resources/data/c/tags/worldgen/biome/is_cold/overworld.json index 8151c7e470..67e6574044 100644 --- a/src/generated/resources/data/c/tags/worldgen/biome/is_cold/overworld.json +++ b/src/generated/resources/data/c/tags/worldgen/biome/is_cold/overworld.json @@ -2,12 +2,17 @@ "values": [ "minecraft:taiga", "minecraft:old_growth_pine_taiga", + "minecraft:old_growth_spruce_taiga", + "minecraft:windswept_hills", + "minecraft:windswept_gravelly_hills", + "minecraft:windswept_forest", "minecraft:snowy_plains", "minecraft:ice_spikes", "minecraft:grove", "minecraft:snowy_slopes", "minecraft:jagged_peaks", "minecraft:frozen_peaks", + "minecraft:stony_shore", "minecraft:snowy_beach", "minecraft:snowy_taiga", "minecraft:frozen_river", diff --git a/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java b/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java index 2c5e86ff0e..aa9e51f6e6 100644 --- a/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java +++ b/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java @@ -333,7 +333,8 @@ public enum LogWarningMode { createForgeMapEntry(Registries.ITEM, "seeds/pumpkin", Tags.Items.SEEDS_PUMPKIN), createForgeMapEntry(Registries.ITEM, "seeds/wheat", Tags.Items.SEEDS_WHEAT), createForgeMapEntry(Registries.ITEM, "shears", Tags.Items.TOOLS_SHEAR), - createForgeMapEntry(Registries.ITEM, "slimeballs", Tags.Items.SLIMEBALLS), + createForgeMapEntry(Registries.ITEM, "slimeballs", Tags.Items.SLIME_BALLS), + createMapEntry(Registries.ITEM, "c", "slimeballs", Tags.Items.SLIME_BALLS), createForgeMapEntry(Registries.ITEM, "stone", Tags.Items.STONES), createForgeMapEntry(Registries.ITEM, "storage_blocks", Tags.Items.STORAGE_BLOCKS), createForgeMapEntry(Registries.ITEM, "storage_blocks/amethyst", "storage_blocks/amethyst"), diff --git a/src/main/java/net/neoforged/neoforge/common/Tags.java b/src/main/java/net/neoforged/neoforge/common/Tags.java index f008d0cb02..a7982f2ae0 100644 --- a/src/main/java/net/neoforged/neoforge/common/Tags.java +++ b/src/main/java/net/neoforged/neoforge/common/Tags.java @@ -560,6 +560,13 @@ public static class Items { * Block tag equivalent is {@link BlockTags#SHULKER_BOXES} */ public static final TagKey SHULKER_BOXES = tag("shulker_boxes"); + public static final TagKey SLIME_BALLS = tag("slime_balls"); + /** + * Please use properly named {@link Tags.Items#SLIME_BALLS} tag and field instead + *

+ * TODO: Remove in 1.21.1 + */ + @Deprecated(since = "1.21") public static final TagKey SLIMEBALLS = tag("slimeballs"); /** * Natural stone-like blocks that can be used as a base ingredient in recipes that takes stone. @@ -679,7 +686,8 @@ public static class Items { public static final TagKey TOOLS_MACE = tag("tools/mace"); /** * A tag containing melee-based weapons for recipes and loot tables. - * Tools are considered melee if they contain an {@link net.minecraft.world.entity.ai.attributes.Attributes#ATTACK_DAMAGE} attribute. + * Tools are considered melee if they are intentionally intended to be used for melee attack as a primary purpose. + * (In other words, Pickaxes are not melee weapons as they are not intended to be a weapon as a primary purpose) * Do not use this tag for determining a tool's behavior in-code. * Please use {@link ItemAbilities} instead for what action a tool can do. * diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBiomeTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBiomeTagsProvider.java index 0257d959f6..e1bf5dc121 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBiomeTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBiomeTagsProvider.java @@ -61,12 +61,17 @@ protected void addTags(HolderLookup.Provider lookupProvider) { tag(Tags.Biomes.IS_COLD_OVERWORLD) .add(Biomes.TAIGA) .add(Biomes.OLD_GROWTH_PINE_TAIGA) + .add(Biomes.OLD_GROWTH_SPRUCE_TAIGA) + .add(Biomes.WINDSWEPT_HILLS) + .add(Biomes.WINDSWEPT_GRAVELLY_HILLS) + .add(Biomes.WINDSWEPT_FOREST) .add(Biomes.SNOWY_PLAINS) .add(Biomes.ICE_SPIKES) .add(Biomes.GROVE) .add(Biomes.SNOWY_SLOPES) .add(Biomes.JAGGED_PEAKS) .add(Biomes.FROZEN_PEAKS) + .add(Biomes.STONY_SHORE) .add(Biomes.SNOWY_BEACH) .add(Biomes.SNOWY_TAIGA) .add(Biomes.FROZEN_RIVER) diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java index cc3cb415d3..197cfb5892 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java @@ -101,8 +101,8 @@ public void addTags(HolderLookup.Provider lookupProvider) { copy(Tags.Blocks.FENCES_NETHER_BRICK, Tags.Items.FENCES_NETHER_BRICK); copy(Tags.Blocks.FENCES_WOODEN, Tags.Items.FENCES_WOODEN); tag(Tags.Items.FERTILIZERS).add(Items.BONE_MEAL); - tag(Tags.Items.FOODS_FRUIT).add(Items.APPLE, Items.GOLDEN_APPLE, Items.ENCHANTED_GOLDEN_APPLE); - tag(Tags.Items.FOODS_VEGETABLE).add(Items.CARROT, Items.GOLDEN_CARROT, Items.POTATO, Items.MELON_SLICE, Items.BEETROOT); + tag(Tags.Items.FOODS_FRUIT).add(Items.APPLE, Items.GOLDEN_APPLE, Items.ENCHANTED_GOLDEN_APPLE).add(Items.MELON_SLICE); + tag(Tags.Items.FOODS_VEGETABLE).add(Items.CARROT, Items.GOLDEN_CARROT, Items.POTATO, Items.BEETROOT); tag(Tags.Items.FOODS_BERRY).add(Items.SWEET_BERRIES, Items.GLOW_BERRIES); tag(Tags.Items.FOODS_BREAD).add(Items.BREAD); tag(Tags.Items.FOODS_COOKIE).add(Items.COOKIE); @@ -112,7 +112,7 @@ public void addTags(HolderLookup.Provider lookupProvider) { tag(Tags.Items.FOODS_COOKED_FISH).add(Items.COOKED_COD, Items.COOKED_SALMON); tag(Tags.Items.FOODS_SOUP).add(Items.BEETROOT_SOUP, Items.MUSHROOM_STEW, Items.RABBIT_STEW, Items.SUSPICIOUS_STEW); tag(Tags.Items.FOODS_CANDY); - tag(Tags.Items.FOODS_GOLDEN).add(Items.GOLDEN_APPLE).add(Items.ENCHANTED_GOLDEN_APPLE).add(Items.GOLDEN_CARROT).add(Items.GLISTERING_MELON_SLICE); + tag(Tags.Items.FOODS_GOLDEN).add(Items.GOLDEN_APPLE).add(Items.ENCHANTED_GOLDEN_APPLE).add(Items.GOLDEN_CARROT); tag(Tags.Items.FOODS_EDIBLE_WHEN_PLACED).add(Items.CAKE); tag(Tags.Items.FOODS_FOOD_POISONING).add(Items.POISONOUS_POTATO, Items.PUFFERFISH, Items.SPIDER_EYE, Items.CHICKEN, Items.ROTTEN_FLESH); tag(Tags.Items.FOODS) @@ -204,7 +204,7 @@ public void addTags(HolderLookup.Provider lookupProvider) { tag(Tags.Items.SEEDS_MELON).add(Items.MELON_SEEDS); tag(Tags.Items.SEEDS_PUMPKIN).add(Items.PUMPKIN_SEEDS); tag(Tags.Items.SEEDS_WHEAT).add(Items.WHEAT_SEEDS); - tag(Tags.Items.SLIMEBALLS).add(Items.SLIME_BALL); + tag(Tags.Items.SLIME_BALLS).add(Items.SLIME_BALL).addOptionalTag(Tags.Items.SLIMEBALLS); tag(Tags.Items.SHULKER_BOXES) .add(Items.SHULKER_BOX).add(Items.WHITE_SHULKER_BOX).add(Items.ORANGE_SHULKER_BOX) .add(Items.MAGENTA_SHULKER_BOX).add(Items.LIGHT_BLUE_SHULKER_BOX).add(Items.YELLOW_SHULKER_BOX) @@ -250,10 +250,7 @@ public void addTags(HolderLookup.Provider lookupProvider) { tag(Tags.Items.MELEE_WEAPON_TOOLS).add( Items.MACE, Items.TRIDENT, Items.WOODEN_SWORD, Items.STONE_SWORD, Items.GOLDEN_SWORD, Items.IRON_SWORD, Items.DIAMOND_SWORD, Items.NETHERITE_SWORD, - Items.WOODEN_AXE, Items.STONE_AXE, Items.GOLDEN_AXE, Items.IRON_AXE, Items.DIAMOND_AXE, Items.NETHERITE_AXE, - Items.WOODEN_PICKAXE, Items.STONE_PICKAXE, Items.GOLDEN_PICKAXE, Items.IRON_PICKAXE, Items.DIAMOND_PICKAXE, Items.NETHERITE_PICKAXE, - Items.WOODEN_SHOVEL, Items.STONE_SHOVEL, Items.GOLDEN_SHOVEL, Items.IRON_SHOVEL, Items.DIAMOND_SHOVEL, Items.NETHERITE_SHOVEL, - Items.WOODEN_HOE, Items.STONE_HOE, Items.GOLDEN_HOE, Items.IRON_HOE, Items.DIAMOND_HOE, Items.NETHERITE_HOE); + Items.WOODEN_AXE, Items.STONE_AXE, Items.GOLDEN_AXE, Items.IRON_AXE, Items.DIAMOND_AXE, Items.NETHERITE_AXE); tag(Tags.Items.RANGED_WEAPON_TOOLS).add(Items.BOW, Items.CROSSBOW, Items.TRIDENT); tag(Tags.Items.TOOLS) .addTags(ItemTags.AXES, ItemTags.HOES, ItemTags.PICKAXES, ItemTags.SHOVELS, ItemTags.SWORDS) @@ -361,7 +358,7 @@ public void addTags(HolderLookup.Provider lookupProvider) { tagWithOptionalLegacy(Tags.Items.SEEDS_MELON); tagWithOptionalLegacy(Tags.Items.SEEDS_PUMPKIN); tagWithOptionalLegacy(Tags.Items.SEEDS_WHEAT); - tagWithOptionalLegacy(Tags.Items.SLIMEBALLS); + tagWithOptionalLegacy(Tags.Items.SLIME_BALLS); tagWithOptionalLegacy(Tags.Items.STRINGS); tag(Tags.Items.TOOLS_SHEAR).addOptionalTag(ResourceLocation.fromNamespaceAndPath("forge", "shears")); tag(Tags.Items.TOOLS_SPEAR).addOptionalTag(ResourceLocation.fromNamespaceAndPath("forge", "tools/tridents")); diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java index 3549bb43d1..8b712f2a2a 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java @@ -284,7 +284,7 @@ protected void addTranslations() { add(Tags.Items.SEEDS_PUMPKIN, "Pumpkin Seeds"); add(Tags.Items.SEEDS_WHEAT, "Wheat Seeds"); add(Tags.Items.SHULKER_BOXES, "Shulker Boxes"); - add(Tags.Items.SLIMEBALLS, "Slimeballs"); + add(Tags.Items.SLIME_BALLS, "Slimeballs"); add(Tags.Items.STONES, "Stones"); add(Tags.Items.STORAGE_BLOCKS, "Storage Blocks"); add(Tags.Items.STORAGE_BLOCKS_BONE_MEAL, "Bone Meal Storage Blocks"); From 3702a4de04fb600f1e98ec2777bc5b1b40d5248d Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Sun, 4 Aug 2024 15:48:33 -0400 Subject: [PATCH 003/125] Fill deprecated Slimeball tag with entry again (#1417) --- src/generated/resources/assets/c/lang/en_us.json | 1 + src/generated/resources/data/c/tags/item/slimeballs.json | 5 +++++ .../common/data/internal/NeoForgeItemTagsProvider.java | 1 + .../common/data/internal/NeoForgeLanguageProvider.java | 1 + 4 files changed, 8 insertions(+) create mode 100644 src/generated/resources/data/c/tags/item/slimeballs.json diff --git a/src/generated/resources/assets/c/lang/en_us.json b/src/generated/resources/assets/c/lang/en_us.json index 4c75679674..0854e0535a 100644 --- a/src/generated/resources/assets/c/lang/en_us.json +++ b/src/generated/resources/assets/c/lang/en_us.json @@ -313,6 +313,7 @@ "tag.item.c.seeds.wheat": "Wheat Seeds", "tag.item.c.shulker_boxes": "Shulker Boxes", "tag.item.c.slime_balls": "Slimeballs", + "tag.item.c.slimeballs": "Slimeballs", "tag.item.c.stones": "Stones", "tag.item.c.storage_blocks": "Storage Blocks", "tag.item.c.storage_blocks.bone_meal": "Bone Meal Storage Blocks", diff --git a/src/generated/resources/data/c/tags/item/slimeballs.json b/src/generated/resources/data/c/tags/item/slimeballs.json new file mode 100644 index 0000000000..533c25d916 --- /dev/null +++ b/src/generated/resources/data/c/tags/item/slimeballs.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:slime_ball" + ] +} \ No newline at end of file diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java index 197cfb5892..a01e03124f 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java @@ -204,6 +204,7 @@ public void addTags(HolderLookup.Provider lookupProvider) { tag(Tags.Items.SEEDS_MELON).add(Items.MELON_SEEDS); tag(Tags.Items.SEEDS_PUMPKIN).add(Items.PUMPKIN_SEEDS); tag(Tags.Items.SEEDS_WHEAT).add(Items.WHEAT_SEEDS); + tag(Tags.Items.SLIMEBALLS).add(Items.SLIME_BALL); // Deprecated tag(Tags.Items.SLIME_BALLS).add(Items.SLIME_BALL).addOptionalTag(Tags.Items.SLIMEBALLS); tag(Tags.Items.SHULKER_BOXES) .add(Items.SHULKER_BOX).add(Items.WHITE_SHULKER_BOX).add(Items.ORANGE_SHULKER_BOX) diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java index 8b712f2a2a..e6b399d3e1 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java @@ -285,6 +285,7 @@ protected void addTranslations() { add(Tags.Items.SEEDS_WHEAT, "Wheat Seeds"); add(Tags.Items.SHULKER_BOXES, "Shulker Boxes"); add(Tags.Items.SLIME_BALLS, "Slimeballs"); + add(Tags.Items.SLIMEBALLS, "Slimeballs"); add(Tags.Items.STONES, "Stones"); add(Tags.Items.STORAGE_BLOCKS, "Storage Blocks"); add(Tags.Items.STORAGE_BLOCKS_BONE_MEAL, "Bone Meal Storage Blocks"); From bf8a757de1db3d5a976bc6e49bce5a4f62594bbd Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 4 Aug 2024 16:19:25 -0400 Subject: [PATCH 004/125] Implement hashCode() on Ingredient.ItemValue (#1413) --- .../world/item/crafting/Ingredient.java.patch | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/patches/net/minecraft/world/item/crafting/Ingredient.java.patch b/patches/net/minecraft/world/item/crafting/Ingredient.java.patch index 083a8348b9..9699025400 100644 --- a/patches/net/minecraft/world/item/crafting/Ingredient.java.patch +++ b/patches/net/minecraft/world/item/crafting/Ingredient.java.patch @@ -178,6 +178,19 @@ @Override public boolean equals(Object p_301316_) { +@@ -156,6 +_,12 @@ + : ingredient$itemvalue.item.getItem().equals(this.item.getItem()) && ingredient$itemvalue.item.getCount() == this.item.getCount(); + } + ++ // Neo: Add a hashCode() implementation that matches equals() ++ @Override ++ public int hashCode() { ++ return 31 * item.getItem().hashCode() + item.getCount(); ++ } ++ + @Override + public Collection getItems() { + return Collections.singleton(this.item); @@ -163,10 +_,11 @@ } From e9c463382e0cf75e8f825cb31e86cec6d9898810 Mon Sep 17 00:00:00 2001 From: dhyces <10985914+dhyces@users.noreply.github.com> Date: Sat, 13 Jul 2024 10:51:03 -0700 Subject: [PATCH 005/125] Create patches --- .../data/recipes/RecipeProvider.java.patch | 23 ++++++++++++++----- .../packs/BundleRecipeProvider.java.patch | 11 +++++++++ .../packs/VanillaRecipeProvider.java.patch | 11 +++++++++ .../data/internal/NeoForgeRecipeProvider.java | 4 ++-- .../debug/crafting/IngredientTests.java | 9 ++++---- .../neoforge/oldtest/DataGeneratorTest.java | 2 +- 6 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 patches/net/minecraft/data/recipes/packs/BundleRecipeProvider.java.patch create mode 100644 patches/net/minecraft/data/recipes/packs/VanillaRecipeProvider.java.patch diff --git a/patches/net/minecraft/data/recipes/RecipeProvider.java.patch b/patches/net/minecraft/data/recipes/RecipeProvider.java.patch index ca88e83bd0..90486182e2 100644 --- a/patches/net/minecraft/data/recipes/RecipeProvider.java.patch +++ b/patches/net/minecraft/data/recipes/RecipeProvider.java.patch @@ -23,21 +23,32 @@ RecipeProvider.this.advancementPathProvider.json(p_311794_.id()) ) ); -@@ -113,12 +_,16 @@ +@@ -107,18 +_,22 @@ + public Advancement.Builder advancement() { + return Advancement.Builder.recipeAdvancement().parent(RecipeBuilder.ROOT_RECIPE_ADVANCEMENT); + } +- } ++ }, p_324248_ + ); + return CompletableFuture.allOf(list.toArray(CompletableFuture[]::new)); } protected CompletableFuture buildAdvancement(CachedOutput p_253674_, HolderLookup.Provider p_323646_, AdvancementHolder p_301116_) { - return DataProvider.saveStable(p_253674_, p_323646_, Advancement.CODEC, p_301116_.value(), this.advancementPathProvider.json(p_301116_.id())); +- } +- +- protected abstract void buildRecipes(RecipeOutput p_301172_); +- +- protected static void generateForEnabledBlockFamilies(RecipeOutput p_301146_, FeatureFlagSet p_251836_) { + return buildAdvancement(p_253674_, p_323646_, p_301116_, new net.neoforged.neoforge.common.conditions.ICondition[0]); + } + + protected CompletableFuture buildAdvancement(CachedOutput p_253674_, HolderLookup.Provider p_323646_, AdvancementHolder p_301116_, net.neoforged.neoforge.common.conditions.ICondition... conditions) { + return DataProvider.saveStable(p_253674_, p_323646_, Advancement.CONDITIONAL_CODEC, Optional.of(new net.neoforged.neoforge.common.conditions.WithConditions<>(p_301116_.value(), conditions)), this.advancementPathProvider.json(p_301116_.id())); - } - - protected abstract void buildRecipes(RecipeOutput p_301172_); - -- protected static void generateForEnabledBlockFamilies(RecipeOutput p_301146_, FeatureFlagSet p_251836_) { ++ } ++ ++ protected abstract void buildRecipes(RecipeOutput p_301172_, HolderLookup.Provider holderLookup); ++ + protected void generateForEnabledBlockFamilies(RecipeOutput p_301146_, FeatureFlagSet p_251836_) { BlockFamilies.getAllFamilies().filter(BlockFamily::shouldGenerateRecipe).forEach(p_313461_ -> generateRecipes(p_301146_, p_313461_, p_251836_)); } diff --git a/patches/net/minecraft/data/recipes/packs/BundleRecipeProvider.java.patch b/patches/net/minecraft/data/recipes/packs/BundleRecipeProvider.java.patch new file mode 100644 index 0000000000..70e3ec0593 --- /dev/null +++ b/patches/net/minecraft/data/recipes/packs/BundleRecipeProvider.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/data/recipes/packs/BundleRecipeProvider.java ++++ b/net/minecraft/data/recipes/packs/BundleRecipeProvider.java +@@ -15,7 +_,7 @@ + } + + @Override +- protected void buildRecipes(RecipeOutput p_301031_) { ++ protected void buildRecipes(RecipeOutput p_301031_, HolderLookup.Provider holderLookup) { + ShapedRecipeBuilder.shaped(RecipeCategory.TOOLS, Items.BUNDLE) + .define('#', Items.RABBIT_HIDE) + .define('-', Items.STRING) diff --git a/patches/net/minecraft/data/recipes/packs/VanillaRecipeProvider.java.patch b/patches/net/minecraft/data/recipes/packs/VanillaRecipeProvider.java.patch new file mode 100644 index 0000000000..a6c3c6dedc --- /dev/null +++ b/patches/net/minecraft/data/recipes/packs/VanillaRecipeProvider.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/data/recipes/packs/VanillaRecipeProvider.java ++++ b/net/minecraft/data/recipes/packs/VanillaRecipeProvider.java +@@ -81,7 +_,7 @@ + } + + @Override +- protected void buildRecipes(RecipeOutput p_301191_) { ++ protected void buildRecipes(RecipeOutput p_301191_, HolderLookup.Provider holderLookup) { + generateForEnabledBlockFamilies(p_301191_, FeatureFlagSet.of(FeatureFlags.VANILLA)); + planksFromLog(p_301191_, Blocks.ACACIA_PLANKS, ItemTags.ACACIA_LOGS, 4); + planksFromLogs(p_301191_, Blocks.BIRCH_PLANKS, ItemTags.BIRCH_LOGS, 4); diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeRecipeProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeRecipeProvider.java index cfbefe02f5..af0edbffc8 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeRecipeProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeRecipeProvider.java @@ -64,7 +64,7 @@ private void replace(ItemLike item, TagKey tag) { } @Override - protected void buildRecipes(RecipeOutput recipeOutput) { + protected void buildRecipes(RecipeOutput recipeOutput, HolderLookup.Provider holderLookup) { replace(Items.STICK, Tags.Items.RODS_WOODEN); replace(Items.GOLD_INGOT, Tags.Items.INGOTS_GOLD); replace(Items.GOLD_NUGGET, Tags.Items.NUGGETS_GOLD); @@ -113,7 +113,7 @@ public void accept(ResourceLocation id, Recipe recipe, @Nullable AdvancementH public Advancement.Builder advancement() { return recipeOutput.advancement(); } - }); + }, holderLookup); } @Nullable diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java index a81f369bcf..8cd64716ae 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java @@ -18,6 +18,7 @@ import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementHolder; import net.minecraft.core.FrontAndTop; +import net.minecraft.core.HolderLookup; import net.minecraft.core.NonNullList; import net.minecraft.core.component.DataComponents; import net.minecraft.core.registries.Registries; @@ -74,7 +75,7 @@ public class IngredientTests { static void blockTagIngredient(final DynamicTest test, final RegistrationHelper reg) { reg.addProvider(event -> new RecipeProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override - protected void buildRecipes(RecipeOutput output) { + protected void buildRecipes(RecipeOutput output, HolderLookup.Provider holderLookup) { ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, Items.MUD) .requires(new TestEnabledIngredient(new BlockTagIngredient(BlockTags.CONVERTABLE_TO_MUD).toVanilla(), test.framework(), test.id()).toVanilla()) .requires(Items.WATER_BUCKET) @@ -105,7 +106,7 @@ protected void buildRecipes(RecipeOutput output) { static void partialNBTIngredient(final DynamicTest test, final RegistrationHelper reg) { reg.addProvider(event -> new RecipeProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override - protected void buildRecipes(RecipeOutput output) { + protected void buildRecipes(RecipeOutput output, HolderLookup.Provider holderLookup) { ShapedRecipeBuilder.shaped(RecipeCategory.MISC, Items.ALLIUM) .pattern("IDE") .define('I', new TestEnabledIngredient( @@ -151,7 +152,7 @@ protected void buildRecipes(RecipeOutput output) { static void strictNBTIngredient(final DynamicTest test, final RegistrationHelper reg) { reg.addProvider(event -> new RecipeProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override - protected void buildRecipes(RecipeOutput output) { + protected void buildRecipes(RecipeOutput output, HolderLookup.Provider holderLookup) { ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, Items.ACACIA_BOAT) .requires(new TestEnabledIngredient( DataComponentIngredient.of(true, DataComponents.DAMAGE, 4, Items.DIAMOND_PICKAXE), @@ -342,7 +343,7 @@ public static ShapelessRecipeBuilder shapeless(RecipeCategory category, ItemLike static void testSizedIngredient(final DynamicTest test, final RegistrationHelper reg) { reg.addProvider(event -> new RecipeProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override - protected void buildRecipes(RecipeOutput output) { + protected void buildRecipes(RecipeOutput output, HolderLookup.Provider holderLookup) { CompressedShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, Items.CHERRY_FENCE) .requires(new TestEnabledIngredient( Ingredient.of(Items.DIAMOND_PICKAXE), diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java index 0ba5be5f57..bc6e32e0b7 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java @@ -200,7 +200,7 @@ public Recipes(PackOutput gen, CompletableFuture lookupPr } @Override - protected void buildRecipes(RecipeOutput consumer) { + protected void buildRecipes(RecipeOutput consumer, HolderLookup.Provider holderLookup) { // conditional recipe ShapedRecipeBuilder.shaped(RecipeCategory.BUILDING_BLOCKS, Blocks.DIAMOND_BLOCK, 64) .pattern("XXX") From a3f2e3083f8b13518758be495bae02af72c51f87 Mon Sep 17 00:00:00 2001 From: dhyces <10985914+dhyces@users.noreply.github.com> Date: Sat, 13 Jul 2024 15:57:16 -0700 Subject: [PATCH 006/125] Make it less of a breaking change --- .../minecraft/data/recipes/RecipeProvider.java.patch | 8 ++++++-- .../recipes/packs/BundleRecipeProvider.java.patch | 11 ----------- .../recipes/packs/VanillaRecipeProvider.java.patch | 11 ----------- .../common/data/internal/NeoForgeRecipeProvider.java | 4 ++-- .../neoforge/debug/crafting/IngredientTests.java | 8 ++++---- .../neoforged/neoforge/oldtest/DataGeneratorTest.java | 2 +- 6 files changed, 13 insertions(+), 31 deletions(-) delete mode 100644 patches/net/minecraft/data/recipes/packs/BundleRecipeProvider.java.patch delete mode 100644 patches/net/minecraft/data/recipes/packs/VanillaRecipeProvider.java.patch diff --git a/patches/net/minecraft/data/recipes/RecipeProvider.java.patch b/patches/net/minecraft/data/recipes/RecipeProvider.java.patch index 90486182e2..b9d2ae0ca9 100644 --- a/patches/net/minecraft/data/recipes/RecipeProvider.java.patch +++ b/patches/net/minecraft/data/recipes/RecipeProvider.java.patch @@ -23,7 +23,7 @@ RecipeProvider.this.advancementPathProvider.json(p_311794_.id()) ) ); -@@ -107,18 +_,22 @@ +@@ -107,18 +_,26 @@ public Advancement.Builder advancement() { return Advancement.Builder.recipeAdvancement().parent(RecipeBuilder.ROOT_RECIPE_ADVANCEMENT); } @@ -47,7 +47,11 @@ + return DataProvider.saveStable(p_253674_, p_323646_, Advancement.CONDITIONAL_CODEC, Optional.of(new net.neoforged.neoforge.common.conditions.WithConditions<>(p_301116_.value(), conditions)), this.advancementPathProvider.json(p_301116_.id())); + } + -+ protected abstract void buildRecipes(RecipeOutput p_301172_, HolderLookup.Provider holderLookup); ++ protected void buildRecipes(RecipeOutput recipeOutput, HolderLookup.Provider holderLookup) { ++ buildRecipes(recipeOutput); ++ } ++ ++ protected void buildRecipes(RecipeOutput p_301172_) {} + + protected void generateForEnabledBlockFamilies(RecipeOutput p_301146_, FeatureFlagSet p_251836_) { BlockFamilies.getAllFamilies().filter(BlockFamily::shouldGenerateRecipe).forEach(p_313461_ -> generateRecipes(p_301146_, p_313461_, p_251836_)); diff --git a/patches/net/minecraft/data/recipes/packs/BundleRecipeProvider.java.patch b/patches/net/minecraft/data/recipes/packs/BundleRecipeProvider.java.patch deleted file mode 100644 index 70e3ec0593..0000000000 --- a/patches/net/minecraft/data/recipes/packs/BundleRecipeProvider.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/data/recipes/packs/BundleRecipeProvider.java -+++ b/net/minecraft/data/recipes/packs/BundleRecipeProvider.java -@@ -15,7 +_,7 @@ - } - - @Override -- protected void buildRecipes(RecipeOutput p_301031_) { -+ protected void buildRecipes(RecipeOutput p_301031_, HolderLookup.Provider holderLookup) { - ShapedRecipeBuilder.shaped(RecipeCategory.TOOLS, Items.BUNDLE) - .define('#', Items.RABBIT_HIDE) - .define('-', Items.STRING) diff --git a/patches/net/minecraft/data/recipes/packs/VanillaRecipeProvider.java.patch b/patches/net/minecraft/data/recipes/packs/VanillaRecipeProvider.java.patch deleted file mode 100644 index a6c3c6dedc..0000000000 --- a/patches/net/minecraft/data/recipes/packs/VanillaRecipeProvider.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/data/recipes/packs/VanillaRecipeProvider.java -+++ b/net/minecraft/data/recipes/packs/VanillaRecipeProvider.java -@@ -81,7 +_,7 @@ - } - - @Override -- protected void buildRecipes(RecipeOutput p_301191_) { -+ protected void buildRecipes(RecipeOutput p_301191_, HolderLookup.Provider holderLookup) { - generateForEnabledBlockFamilies(p_301191_, FeatureFlagSet.of(FeatureFlags.VANILLA)); - planksFromLog(p_301191_, Blocks.ACACIA_PLANKS, ItemTags.ACACIA_LOGS, 4); - planksFromLogs(p_301191_, Blocks.BIRCH_PLANKS, ItemTags.BIRCH_LOGS, 4); diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeRecipeProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeRecipeProvider.java index af0edbffc8..cfbefe02f5 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeRecipeProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeRecipeProvider.java @@ -64,7 +64,7 @@ private void replace(ItemLike item, TagKey tag) { } @Override - protected void buildRecipes(RecipeOutput recipeOutput, HolderLookup.Provider holderLookup) { + protected void buildRecipes(RecipeOutput recipeOutput) { replace(Items.STICK, Tags.Items.RODS_WOODEN); replace(Items.GOLD_INGOT, Tags.Items.INGOTS_GOLD); replace(Items.GOLD_NUGGET, Tags.Items.NUGGETS_GOLD); @@ -113,7 +113,7 @@ public void accept(ResourceLocation id, Recipe recipe, @Nullable AdvancementH public Advancement.Builder advancement() { return recipeOutput.advancement(); } - }, holderLookup); + }); } @Nullable diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java index 8cd64716ae..d3e1fdffd7 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java @@ -75,7 +75,7 @@ public class IngredientTests { static void blockTagIngredient(final DynamicTest test, final RegistrationHelper reg) { reg.addProvider(event -> new RecipeProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override - protected void buildRecipes(RecipeOutput output, HolderLookup.Provider holderLookup) { + protected void buildRecipes(RecipeOutput output) { ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, Items.MUD) .requires(new TestEnabledIngredient(new BlockTagIngredient(BlockTags.CONVERTABLE_TO_MUD).toVanilla(), test.framework(), test.id()).toVanilla()) .requires(Items.WATER_BUCKET) @@ -106,7 +106,7 @@ protected void buildRecipes(RecipeOutput output, HolderLookup.Provider holderLoo static void partialNBTIngredient(final DynamicTest test, final RegistrationHelper reg) { reg.addProvider(event -> new RecipeProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override - protected void buildRecipes(RecipeOutput output, HolderLookup.Provider holderLookup) { + protected void buildRecipes(RecipeOutput output) { ShapedRecipeBuilder.shaped(RecipeCategory.MISC, Items.ALLIUM) .pattern("IDE") .define('I', new TestEnabledIngredient( @@ -152,7 +152,7 @@ protected void buildRecipes(RecipeOutput output, HolderLookup.Provider holderLoo static void strictNBTIngredient(final DynamicTest test, final RegistrationHelper reg) { reg.addProvider(event -> new RecipeProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override - protected void buildRecipes(RecipeOutput output, HolderLookup.Provider holderLookup) { + protected void buildRecipes(RecipeOutput output) { ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, Items.ACACIA_BOAT) .requires(new TestEnabledIngredient( DataComponentIngredient.of(true, DataComponents.DAMAGE, 4, Items.DIAMOND_PICKAXE), @@ -343,7 +343,7 @@ public static ShapelessRecipeBuilder shapeless(RecipeCategory category, ItemLike static void testSizedIngredient(final DynamicTest test, final RegistrationHelper reg) { reg.addProvider(event -> new RecipeProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { @Override - protected void buildRecipes(RecipeOutput output, HolderLookup.Provider holderLookup) { + protected void buildRecipes(RecipeOutput output) { CompressedShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, Items.CHERRY_FENCE) .requires(new TestEnabledIngredient( Ingredient.of(Items.DIAMOND_PICKAXE), diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java index bc6e32e0b7..0ba5be5f57 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java @@ -200,7 +200,7 @@ public Recipes(PackOutput gen, CompletableFuture lookupPr } @Override - protected void buildRecipes(RecipeOutput consumer, HolderLookup.Provider holderLookup) { + protected void buildRecipes(RecipeOutput consumer) { // conditional recipe ShapedRecipeBuilder.shaped(RecipeCategory.BUILDING_BLOCKS, Blocks.DIAMOND_BLOCK, 64) .pattern("XXX") From 79d03d146eb7fef6bec33989e18114422f8246da Mon Sep 17 00:00:00 2001 From: dhyces <10985914+dhyces@users.noreply.github.com> Date: Sat, 13 Jul 2024 15:57:57 -0700 Subject: [PATCH 007/125] Apply formatting --- .../net/neoforged/neoforge/debug/crafting/IngredientTests.java | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java index d3e1fdffd7..a81f369bcf 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/crafting/IngredientTests.java @@ -18,7 +18,6 @@ import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementHolder; import net.minecraft.core.FrontAndTop; -import net.minecraft.core.HolderLookup; import net.minecraft.core.NonNullList; import net.minecraft.core.component.DataComponents; import net.minecraft.core.registries.Registries; From 901d060111f6c9a69aad536ffcffbcbe83e1a74c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20J=C3=A4ger?= Date: Mon, 5 Aug 2024 12:29:18 +0200 Subject: [PATCH 008/125] Use the real buffer data (#1276) --- .../neoforged/neoforge/common/util/FriendlyByteBufUtil.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/neoforged/neoforge/common/util/FriendlyByteBufUtil.java b/src/main/java/net/neoforged/neoforge/common/util/FriendlyByteBufUtil.java index 2a7c32f214..99ef8c8b17 100644 --- a/src/main/java/net/neoforged/neoforge/common/util/FriendlyByteBufUtil.java +++ b/src/main/java/net/neoforged/neoforge/common/util/FriendlyByteBufUtil.java @@ -31,7 +31,10 @@ public static byte[] writeCustomData(Consumer dataWrite final RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.buffer(), registryAccess, ConnectionType.NEOFORGE); try { dataWriter.accept(buf); - return buf.array(); + buf.readerIndex(0); + final byte[] data = new byte[buf.readableBytes()]; + buf.readBytes(data); + return data; } finally { buf.release(); } From a00270c9d560e76171b487de6869e098fa322e30 Mon Sep 17 00:00:00 2001 From: Su5eD <51261569+Su5eD@users.noreply.github.com> Date: Mon, 5 Aug 2024 13:46:58 +0200 Subject: [PATCH 009/125] Update FML to allow sorting of `IDependencyLocator`s (#1410) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 89c730e095..667bff0378 100644 --- a/gradle.properties +++ b/gradle.properties @@ -30,7 +30,7 @@ jetbrains_annotations_version=24.0.1 slf4j_api_version=2.0.7 apache_maven_artifact_version=3.8.5 jarjar_version=0.4.1 -fancy_mod_loader_version=4.0.21 +fancy_mod_loader_version=4.0.23 mojang_logging_version=1.1.1 log4j_version=2.22.1 guava_version=31.1.2-jre From 682a61837aa240b0c1585de950803caffd267dbc Mon Sep 17 00:00:00 2001 From: NeoForged Localizations Date: Mon, 5 Aug 2024 22:35:44 +0800 Subject: [PATCH 010/125] New Crowdin updates (#1378) --- .../resources/assets/neoforge/lang/cs_cz.json | 315 ++++++++++++++++++ .../resources/assets/neoforge/lang/da_dk.json | 23 +- .../resources/assets/neoforge/lang/de_de.json | 29 +- .../resources/assets/neoforge/lang/en_gb.json | 23 +- .../resources/assets/neoforge/lang/eo_uy.json | 23 +- .../resources/assets/neoforge/lang/es_es.json | 23 +- .../resources/assets/neoforge/lang/et_ee.json | 23 +- .../resources/assets/neoforge/lang/fr_fr.json | 23 +- .../resources/assets/neoforge/lang/hu_hu.json | 23 +- .../resources/assets/neoforge/lang/it_it.json | 23 +- .../resources/assets/neoforge/lang/ja_jp.json | 23 +- .../resources/assets/neoforge/lang/ko_kr.json | 23 +- .../resources/assets/neoforge/lang/nl_nl.json | 23 +- .../resources/assets/neoforge/lang/pl_pl.json | 23 +- .../resources/assets/neoforge/lang/pt_br.json | 23 +- .../resources/assets/neoforge/lang/pt_pt.json | 23 +- .../resources/assets/neoforge/lang/ro_ro.json | 23 +- .../resources/assets/neoforge/lang/ru_ru.json | 23 +- .../resources/assets/neoforge/lang/sk_sk.json | 153 +++++---- .../resources/assets/neoforge/lang/tr_tr.json | 23 +- .../resources/assets/neoforge/lang/tt_ru.json | 23 +- .../resources/assets/neoforge/lang/uk_ua.json | 19 +- .../resources/assets/neoforge/lang/vi_vn.json | 23 +- .../resources/assets/neoforge/lang/zh_cn.json | 29 +- .../resources/assets/neoforge/lang/zh_hk.json | 23 +- 25 files changed, 816 insertions(+), 189 deletions(-) create mode 100644 src/main/resources/assets/neoforge/lang/cs_cz.json diff --git a/src/main/resources/assets/neoforge/lang/cs_cz.json b/src/main/resources/assets/neoforge/lang/cs_cz.json new file mode 100644 index 0000000000..75160c4ebe --- /dev/null +++ b/src/main/resources/assets/neoforge/lang/cs_cz.json @@ -0,0 +1,315 @@ +{ + "fml.menu.mods": "Módy", + "fml.menu.mods.title": "Módy", + "fml.menu.mods.normal": "Vypnuto", + "fml.menu.mods.search": "Hledat", + "fml.menu.mods.a_to_z": "A-Z", + "fml.menu.mods.z_to_a": "Z-A", + "fml.menu.mods.config": "Konfigurace", + "fml.menu.mods.openmodsfolder": "Otevřít složku s módy", + "fml.menu.modoptions": "Nastavení módů...", + "fml.menu.mods.info.version": "Verze: %1$s", + "fml.menu.mods.info.idstate": "ModID: %1$s Status: {1,lower}", + "fml.menu.mods.info.credits": "Poděkování: %1$s", + "fml.menu.mods.info.authors": "Autoři: %1$s", + "fml.menu.mods.info.displayurl": "Domovská stránka: %1$s", + "fml.menu.mods.info.license": "Licence: %1$s", + "fml.menu.mods.info.securejardisabled": "Bezpečné módové funkce jsou vypnuty, aktualizujte JDK", + "fml.menu.mods.info.signature": "Podepsání: %1$s", + "fml.menu.mods.info.signature.unsigned": "NEPODEPSANÝ", + "fml.menu.mods.info.trust": "Důvěra: %1$s", + "fml.menu.mods.info.trust.noauthority": "Žádné", + "fml.menu.mods.info.nochildmods": "Žádné pod-módy nebyly nalezeny", + "fml.menu.mods.info.childmods": "Pod-módy: %1$s", + "fml.menu.mods.info.updateavailable": "Dostupná aktualizace: %1$s", + "fml.menu.mods.info.changelogheader": "Seznam změn:", + "fml.menu.multiplayer.compatible": "Kompatibilní FML módovaný server\n{0,choice,1#1 mód|1<%1$s módy} přítomné", + "fml.menu.multiplayer.incompatible": "Nekompatibilní FML módovaný server", + "fml.menu.multiplayer.incompatible.extra": "Nekompatibilní FML módovaný server\n%1$s", + "fml.menu.multiplayer.truncated": "Data mohou být nepřesná kvůli limitu velikosti protokolu na přenášení dat.", + "fml.menu.multiplayer.vanilla": "Vanilla server", + "fml.menu.multiplayer.vanilla.incompatible": "Nekompatibilní Vanilla server", + "fml.menu.multiplayer.unknown": "Neznámý server %1$s", + "fml.menu.multiplayer.serveroutdated": "Verze sítě NeoForge serveru je zastaralá", + "fml.menu.multiplayer.clientoutdated": "Verze sítě NeoForge klienta je zastaralá", + "fml.menu.multiplayer.extraservermods": "Server obsahuje módy navíc které mohou být potřeba i na klientovi", + "fml.menu.multiplayer.modsincompatible": "Seznam módů na serveru není kompatibilní", + "fml.menu.multiplayer.networkincompatible": "Seznam zpráv sítě serveru není kompatibilní", + "fml.menu.multiplayer.missingdatapackregistries": "Chybí požadované registry datapacků: %1$s", + "fml.menu.branding": "%s (%s módů)", + "fml.menu.notification.title": "Oznámení při spuštění", + "fml.menu.accessdenied.title": "Přístup k serveru byl odepřen", + "fml.menu.accessdenied.message": "Fancy Mod Loader se nemohl připojit k serveru\nServer %1$s zakázal přístup s módy", + "fml.menu.backupfailed.title": "Záloha se nepovedla", + "fml.menu.backupfailed.message": "Nastala chyba při ukládání archivu %1$s\nProsím, opravte problém a zkuste to znovu", + "fml.button.open.file": "Otevřít %1$s", + "fml.button.open.log": "Otevřít log soubor", + "fml.button.open.crashreport": "Otevřít záznam o zhroucení", + "fml.button.open.mods.folder": "Otevřít složku s módy", + "fml.button.continue.launch": "Pokračovat do hlavního menu", + "fml.modmismatchscreen.missingmods.client": "Na vašem klientovi chybí tyto módy, nainstalujte je abyste se mohli připojit k serveru:", + "fml.modmismatchscreen.missingmods.server": "Na serveru chybí tyto módy, odstraňte je abyste se mohli připojit k serveru:", + "fml.modmismatchscreen.mismatchedmods": "Následující verze módů se neschodují. K připojení k serveru si nainstalujte shodné verze:", + "fml.modmismatchscreen.table.channelname": "Jméno kanálu", + "fml.modmismatchscreen.table.youneed": "Potřebujete", + "fml.modmismatchscreen.table.youhave": "Máte", + "fml.modmismatchscreen.table.serverhas": "Server má", + "fml.modmismatchscreen.additional": "[%1$s navíc, koukněte do latest.log pro celý seznam]", + "fml.modmismatchscreen.homepage": "Klikněte pro přesměrování na hlavní stránku módu", + "fml.modmismatchscreen.table.reason": "Důvod", + "fml.modmismatchscreen.table.visit.mod_page": "Otevřete stránku módu, který je zaregistrovaný na tento kanál: %s", + "fml.modmismatchscreen.simplifiedview": "Zjednodušený pohled", + "fml.resources.modresources": "Zdroje pro %1$s módové soubory", + "fml.resources.moddata": "Data pro %1$s módové soubory", + "loadwarning.neoforge.prbuild": "Tento NeoForge build byl vytvořen komunitním členem a proto je §c§lBEZ PODPORY§r", + "commands.neoforge.arguments.enum.invalid": "Enum konstanta musí být jedna z %1$s, nalezeno %2$s", + "commands.neoforge.dimensions.list": "Aktuálně registrované dimenze typu:", + "commands.neoforge.dump.success": "Nový soubor vytvořen s obsahem registru %s je na %s", + "commands.neoforge.dump.failure": "Nebylo možné vytvořit soubor s obsahem registru %s na %s", + "commands.neoforge.dump.error.unknown_registry": "Neznámý registr '%s'", + "commands.neoforge.entity.list.invalid": "Neplatný filtr, neshoduje se s žádnou entitou. Použijte /neoforge entity pro celý seznam", + "commands.neoforge.entity.list.invalidworld": "Nebylo možné načíst svět pro dimenzi %1$s. Prosíme, vyberte platnou dimenzi.", + "commands.neoforge.entity.list.none": "Žádná entita nenalazena.", + "commands.neoforge.entity.list.single.header": "Entita: %1$s Celkem: %2$s", + "commands.neoforge.entity.list.multiple.header": "Celkem: %1$s", + "commands.neoforge.setdim.invalid.entity": "Vybraná entita (%1$s) je neplatná.", + "commands.neoforge.setdim.invalid.dim": "Vybrané ID dimenze (%1$s) je neplatné.", + "commands.neoforge.setdim.invalid.nochange": "Vybraná entita (%1$s) již existuje v specifické dimenzi (%2$s).", + "commands.neoforge.setdim.deprecated": "Tento příkaz je zastaralý kvůli smazání ve verzi 1.17, použijte místo něj %s.", + "commands.neoforge.tps.invalid": "Neplatná dimenze %1$s Možné hodnoty: %2$s", + "commands.neoforge.tps.summary.all": "Celkem: Průměrná doba ticku: %1$s ms. Průměrný TPS: %2$s", + "commands.neoforge.mods.list": "Módový seznam: %1$s", + "commands.neoforge.tps.summary.basic": "Dim %1$s: Průměrná doba ticku: %2$s ms. Průměrný TPS: %3$s", + "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Průměrná doba ticku: %3$s ms. Průměrný TPS: %4$s", + "commands.neoforge.tracking.entity.enabled": "Sledování entity povoleno na %d sekund.", + "commands.neoforge.tracking.entity.reset": "Data časování entity byla vymazána!", + "commands.neoforge.tracking.invalid": "Neplatná sledovací data.", + "commands.neoforge.tracking.be.enabled": "Sledování Block Entity povoleno na %d sekund.", + "commands.neoforge.tracking.be.reset": "Data časování Block entity byla vymazána!", + "commands.neoforge.tracking.timing_entry": "%1$s - %2$s [%3$s, %4$s, %5$s]: %6$s", + "commands.neoforge.tracking.no_data": "Zatím nebyla zaznamenána žádná data.", + "commands.neoforge.tags.error.unknown_registry": "Neznámý registr '%s'", + "commands.neoforge.tags.error.unknown_tag": "Neznámý štítek '%s' v registru '%s'", + "commands.neoforge.tags.error.unknown_element": "Neznámý prvek '%s' v registru '%s'", + "commands.neoforge.tags.registry_key": "%s", + "commands.neoforge.tags.tag_count": "Tagy: %s", + "commands.neoforge.tags.copy_tag_names": "Kliknutím zkopírujete všechna jména tagů do schránky", + "commands.neoforge.tags.element_count": "Prvky: %s", + "commands.neoforge.tags.copy_element_names": "Kliknutím zkopírujete všechny názvy prvků do schránky", + "commands.neoforge.tags.tag_key": "%s / %s", + "commands.neoforge.tags.containing_tag_count": "Obsahuje tagy: %s", + "commands.neoforge.tags.element": "%s : %s", + "commands.neoforge.tags.page_info": "%s ", + "commands.neoforge.chunkgen.progress_bar_title": "Generování chunků...", + "commands.neoforge.chunkgen.progress_bar_progress": "Generování %1$s chunků - ", + "commands.neoforge.chunkgen.progress_bar_errors": "(%1$s chyb!)", + "commands.neoforge.chunkgen.already_running": "Generování je již spuštěno. Prosím, nejdříve spusťte '/neoforge generate stop', a poté můžete začít novou generaci.", + "commands.neoforge.chunkgen.started": "Generování %1$s chunků, v oblasti rozměrů %2$sx%3$s chunků (%4$sx%5$s bloků).", + "commands.neoforge.chunkgen.success": "Generování dokončeno!", + "commands.neoforge.chunkgen.error": "Při generování nastalo %1$s chyb! Podívejte se do logu pro více informací.", + "commands.neoforge.chunkgen.stopped": "Generování zastaveno! %1$s chunků z %2$s bylo vygenerováno. (%3$s%%)", + "commands.neoforge.chunkgen.status": "Stav generace! %1$s chunků z %2$s bylo vygenerováno. (%3$s%%)", + "commands.neoforge.chunkgen.not_running": "V současné době neprobíhá žádná před-generace. Spusťte `/neoforge generate help` pro zobrazení seznam příkazů pro zahájení generace.", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Vygeneruje čtverec, kterého střed je na dané pozici, a každá z jeho stran má velikost: chunkRadius * 2.\n§2/neoforge generate stop §r§f- Zastaví aktuální generaci a zobrazí její progres.\n§2/neoforge generate status §r- Zobrazí progres spuštěné generace.\n§2/neoforge generate help §r- Zobrazí tuto zprávu.\nObecný tip: Jestli budete příkazy spouštět přes server konzoli, můžete je spouštět v různých dimenzích použitím \"/execute in neoforge generate ...\"", + "commands.neoforge.timespeed.query": "Čas v %s běží rychlostí %sx (%s minut za den).", + "commands.neoforge.timespeed.query.default": "Čas v %s běží normální rychlostí (20 minut za den).", + "commands.neoforge.timespeed.set": "Nastaven běh času v %s na %sx (%s minut za den).", + "commands.neoforge.timespeed.set.default": "Nastaven běh času v %s na základní nastavení (20 minut za den).", + "commands.config.getwithtype": "Konfigurace pro %s typu %s nalezena na %s", + "commands.config.noconfig": "Konfigurace pro %s typu %s nenalezena", + "neoforge.update.beta.1": "%sPOZOR: %sNeoForge Beta", + "neoforge.update.beta.2": "Mohou nastat závažně problémy, potvrďte si před nahlášením.", + "neoforge.update.newversion": "Je k dispozici nová verze NeoForge: %s", + "neoforge.menu.updatescreen.title": "Aktualizace Módu", + "neoforge.configuration.uitext.title": "Konfigurace %s", + "neoforge.configuration.uitext.type.client": "Nastavení Klienta", + "neoforge.configuration.uitext.type.server": "Nastavení Serveru", + "neoforge.configuration.uitext.type.common": "Běžná nastavení", + "neoforge.configuration.uitext.type.startup": "Nastavení při spuštění", + "neoforge.configuration.uitext.title.client": "Konfigurace Klienta %s", + "neoforge.configuration.uitext.title.server": "Konfigurace Serveru %s", + "neoforge.configuration.uitext.title.common": "Běžná konfigurace %s", + "neoforge.configuration.uitext.title.startup": "Konfigurace při spuštění %s", + "neoforge.configuration.uitext.notonline": [ + { + "text": "Nastavení jsou zde rozhodnuté serverem a nemohou být změněny když jste online.", + "color": "červený" + } + ], + "neoforge.configuration.uitext.notlan": [ + { + "text": "Nastavení zde nemohou být změněny, když je Vaše hra otevřená k LAN. Prosím, vraťte se do hlavního menu a načtěte svět znovu.", + "color": "červený" + } + ], + "neoforge.configuration.uitext.notloaded": [ + { + "text": "Nastavení zde jsou dostupné pouze až po načtení světa.", + "color": "červený" + } + ], + "neoforge.configuration.uitext.unsupportedelement": [ + { + "text": "Tato hodnota nemůže být změněna v UI. Prosím, kontaktujte autora módu, aby pro něj poskytl UI.", + "color": "červený" + } + ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "Tato hodnota je moc veliká pro změnu v UI. Prosím, změňte ji v konfiguračním souboru.", + "color": "červený" + } + ], + "neoforge.configuration.uitext.section": "%s...", + "neoforge.configuration.uitext.sectiontext": "Změnit", + "neoforge.configuration.uitext.breadcrumb": [ + { + "index": 0 + }, + { + "text": " > ", + "color": "zlato", + "bold": true + }, + { + "index": 1 + } + ], + "neoforge.configuration.uitext.listelement": "%s:", + "neoforge.configuration.uitext.undo": "Vrátit zpět", + "neoforge.configuration.uitext.undo.tooltip": "Vrátí zpět změny pouze na této obrazovce.", + "neoforge.configuration.uitext.reset": "Resetovat", + "neoforge.configuration.uitext.reset.tooltip": "Vrátí zpět vše na této obrazovce na výchozí hodnotu.", + "neoforge.configuration.uitext.newlistelement": "+", + "neoforge.configuration.uitext.listelementup": "⏶", + "neoforge.configuration.uitext.listelementdown": "⏷", + "neoforge.configuration.uitext.listelementremove": "❌", + "neoforge.configuration.uitext.rangetooltip": [ + { + "text": "\n\nRozmezí: ", + "color": "šedivá" + }, + { + "index": 0, + "color": "šedivá" + } + ], + "neoforge.configuration.uitext.filenametooltip": [ + { + "text": "Soubor: \"", + "color": "šedivá" + }, + { + "index": 0, + "color": "šedivá" + }, + { + "text": "\"", + "color": "šedivá" + } + ], + "neoforge.configuration.uitext.common": "Obecné volby", + "neoforge.configuration.uitext.client": "Volby klienta", + "neoforge.configuration.uitext.server": "Volby serveru", + "neoforge.configuration.uitext.startup": "Možnosti při spuštění", + "neoforge.configuration.uitext.restart.game.title": "Minecraft je nutné restartovat", + "neoforge.configuration.uitext.restart.game.text": "Jeden či více konfiguračních možností, které byly změněny, se projeví až při spuštění hry.", + "neoforge.configuration.uitext.restart.server.title": "Svět se musí znovu načíst", + "neoforge.configuration.uitext.restart.server.text": "Jeden či více konfiguračních možností, které byly změněny, se projeví až se znovu načte svět.", + "neoforge.configuration.uitext.restart.return": "Ignorovat", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Vaše změny nebudou mít žádný účinek do restartu!", + "color": "červená", + "bold": true + } + ], + "neoforge.configuration.title": "NeoForge konfigurace", + "neoforge.configuration.section.neoforge.client.toml": "Nastavení Klienta", + "neoforge.configuration.section.neoforge.client.toml.title": "Nastavení Klienta", + "neoforge.configuration.section.neoforge.common.toml": "Běžná nastavení", + "neoforge.configuration.section.neoforge.common.toml.title": "Běžná nastavení", + "neoforge.configuration.section.neoforge.server.toml": "Nastavení Serveru", + "neoforge.configuration.section.neoforge.server.toml.title": "Nastavení Serveru", + "neoforge.configgui.advertiseDedicatedServerToLan": "Oznámit dedikovaný server na LAN", + "neoforge.configgui.advertiseDedicatedServerToLan.tooltip": "Zapněte toto nastavení aby dedikovaný server oznamoval lokálním LAN klientům, aby se zobrazoval v Multiplayer obrazovce.", + "neoforge.configgui.forgeLightPipelineEnabled": "NeoForge Light Pipeline", + "neoforge.configgui.forgeLightPipelineEnabled.tooltip": "Povolit NeoForge pipelinu renderování blocků - opraví osvětlení různých modelů.", + "neoforge.configgui.fullBoundingBoxLadders": "Plně Ohraničující Box u Žebříků", + "neoforge.configgui.fullBoundingBoxLadders.tooltip": "Zapněte tuto možnost pro kontrolu celého kolizního pole entity u žebříku, místo pouhého bloku ve kterém se nachází. Způsobí znatelné rozdíly v mechanice, takže výchozí chování je vanilla. Výchozí hodnota: false.", + "neoforge.configgui.logLegacyTagWarnings": "Starší Štítky Logu", + "neoforge.configgui.logLegacyTagWarnings.tooltip": "Konfigurační možnost především pro vývojáře. Na integrovaném serveru zaznamenává v logu módované tagy které používají 'forge' namespace. Výchozí nastavení je DEV_SHORT.", + "neoforge.configgui.logUntranslatedConfigurationWarnings": "Zaznamenat v logu nepřeložené konfigurační klíče", + "neoforge.configgui.logUntranslatedConfigurationWarnings.tooltip": "Konfigurační možnost především pro vývojáře. Při běhu klienta ve vývojovém prostředí zaznamenává do logu konfigurační hodnoty, které nemají svůj překlad.", + "neoforge.configgui.logUntranslatedItemTagWarnings": "Zaznamenat v logu nepřeložené Item Tags", + "neoforge.configgui.logUntranslatedItemTagWarnings.tooltip": "Konfigurační možnost především pro vývojáře. Na integrovaném serveru zaznamenává do logu módované item tagy, které nemají svůj překlad. Požadovaný formát je tag.item.. pro překladový klíč. Výchozí nastavení je SILENCED.", + "neoforge.configgui.permissionHandler": "Manažer oprávnění", + "neoforge.configgui.permissionHandler.tooltip": "Manažer oprávnění použitý na serveru. Výchozí je neoforge:default_handler pokud žádný handler s tímto názvem není registrován.", + "neoforge.configgui.removeErroringBlockEntities": "Odstranit Block Entity volající chyby", + "neoforge.configgui.removeErroringBlockEntities.tooltip": [ + "Zapněte toto nastavení pro smazání všech entit které vyhazují error ve své \"update\" metodě, místo vypnutí serveru a vytvoření crash logu.\n\n", + { + "text": "POZOR, TOTO MŮŽE VŠECHNO POKAZIT.\nBUĎTE OPATRNÍ.\nNEJSME ZODPOVĚDNI ZA JAKÉKOLIV NAPÁCHANÉ ŠKODY.", + "color": "červená", + "bold": true + } + ], + "neoforge.configgui.removeErroringEntities": "Odstranit Entity volající chyby", + "neoforge.configgui.removeErroringEntities.tooltip": [ + "Zapněte toto nastavení pro smazání všech block entit které vyhazují error ve své \"update\" metodě, místo vypnutí serveru a vytvoření crash logu.\n\n", + { + "text": "POZOR, TOTO MŮŽE VŠECHNO POKAZIT.\nBUĎTE OPATRNÍ.\nNEJSME ZODPOVĚDNI ZA JAKÉKOLIV NAPÁCHANÉ ŠKODY.", + "color": "červená", + "bold": true + } + ], + "neoforge.configgui.showLoadWarnings": "Zobrazit Upozornění při Načítání", + "neoforge.configgui.showLoadWarnings.tooltip": "Pokud je zapnuto, NeoForge zobrazí jakákoliv upozornění, která se vyskytla při načítání.", + "neoforge.configgui.useCombinedDepthStencilAttachment": "Používejte kombinovaný doplňek DEPTH_STENCIL", + "neoforge.configgui.useCombinedDepthStencilAttachment.tooltip": "Zapněte toto nastavení pro použití kombinovaného doplňku DEPTH_STENCIL místo dvou samostatných.", + "neoforge.controlsgui.shift": "SHIFT + %s", + "neoforge.controlsgui.control": "CTRL + %s", + "neoforge.controlsgui.control.mac": "CMD + %s", + "neoforge.controlsgui.alt": "ALT + %s", + "neoforge.container.enchant.limitedEnchantability": "Omezená Enchantnost", + "neoforge.swim_speed": "Rychlost Plavání", + "neoforge.name_tag_distance": "Vzdálenost Načítání Jmenovek", + "neoforge.creative_flight": "Létání V Kreativu", + "fluid_type.minecraft.milk": "Mléko", + "fluid_type.minecraft.flowing_milk": "Mléko", + "neoforge.froge.warningScreen.title": "NeoForge snapshot oznámení", + "neoforge.froge.warningScreen.text": "Froge is not officially supported. Bugs and instability are expected.", + "neoforge.froge.supportWarning": "UPOZORNĚNÍ: NeoForge nepodporuje Froge", + "neoforge.gui.exit": "Opustit", + "neoforge.experimentalsettings.tooltip": "Tento svět používá experimentální nastavení, které mohou kdykoliv přestat fungovat.", + "neoforge.selectWorld.backupWarning.experimental.additional": "Tato zpráva se pro tento svět znovu nezobrazí.", + "neoforge.chatType.system": "%1$s", + "pack.neoforge.description": "NeoForge data/resource pack", + "pack.neoforge.source.child": "dítě", + "neoforge.network.negotiation.failure.mod": "Kanál módu \"%1$s\" se nedokázal připojit: %2$s", + "neoforge.network.negotiation.failure.missing.client.server": "Tento kanál chybí na serveru, ale je požadován na klientu!", + "neoforge.network.negotiation.failure.missing.server.client": "Tento kanál chybí na klientu, ale je požadován na serveru!", + "neoforge.network.negotiation.failure.flow.client.missing": "Klient chce tok payloadu: %s, ale server to nepodporuje!", + "neoforge.network.negotiation.failure.flow.server.missing": "Server chce tok payloadu: %s, ale klient to nepodporuje!", + "neoforge.network.negotiation.failure.flow.client.mismatch": "Klient chce tok payloadu: %s, ale server chce tok: %s!", + "neoforge.network.negotiation.failure.flow.server.mismatch": "Server chce tok payloadu: %s, ale klient chce tok: %s!", + "neoforge.network.negotiation.failure.version.client.missing": "Klient chce mít payload vezi: %s, ale server to nepodporuje!", + "neoforge.network.negotiation.failure.version.server.missing": "Server chce mít payload verzi: %s, ale klient to nepodporuje!", + "neoforge.network.negotiation.failure.version.mismatch": "Klient chce mít payload verzi: %s, ale server chce verzi: %s!", + "neoforge.network.invalid_flow": "Chyba při procesu paylodu, který byl zaslán s neplatným tokem: %s", + "neoforge.network.negotiation.failure.vanilla.client.not_supported": "Snažíte se připojit k serveru který běží na NeoForge, ale vy NeoForge nemáte. Prosím, nainstalujte NeoForge verzi: %s pro připojení k tomuto serveru.", + "neoforge.network.negotiation.failure.vanilla.server.not_supported": "Snažíte se připojit k serveru který neběží na NeoForge, ale máte módy, který ho požaduje. Nepodařilo se připojit.", + "neoforge.network.packet_splitter.unknown": "Snaha o rozdělení packetu bez rozdělovače packetů!", + "neoforge.network.advanced_add_entity.failed": "Neúspěch při zpracovávání rozšířených dat spawnu entit: %s", + "neoforge.network.advanced_open_screen.failed": "Neúspěch při snaze otevřít obrazovku s rozšířenými daty: %s", + "neoforge.network.registries.sync.missing": "Nebyly od serveru získané všechny požadované registry! (chybějící: %s)", + "neoforge.network.registries.sync.server-with-unknown-keys": "Server zaslal registry s neznámými klíčy: %s", + "neoforge.network.registries.sync.failed": "Neúspěch při synchronizování registrů ze serveru: %s", + "neoforge.network.aux_light_data.failed": "Neúspěch při zacházení s asistentem dat světel pro chunk %s: %s", + "neoforge.network.data_maps.failed": "Neúspěch při zacházení se synchronizací registrem dat mapy pro registr %s: %s", + "neoforge.network.data_maps.missing_our": "Je nemožné se připoijit k serveru, jelikož chybí povinné registry map dat, které jsou přítomné na klientu: %s", + "neoforge.network.data_maps.missing_their": "Je nemožné se připoijit k serveru, jelikož obsahuje povinné registry map dat, které nejsou přítomné na klientu: %s", + "neoforge.network.extensible_enums.no_vanilla_server": "Tento klient nepodporuje vanilla servery, jelikož má mnoho rozšířených enumů v serverovaném připojení", + "neoforge.network.extensible_enums.enum_set_mismatch": "Sada rozšířených enumů na klientu a na serveru se nerovnají. Ujistěte se, že užíváte stejnou NeoForge verzi jako server", + "neoforge.network.extensible_enums.enum_entry_mismatch": "Sada hodnot přidaných k rozšířeným enumů na klientu a na serveru se nerovnají. Ujistěte se, že užíváte stejný mód a NeoForge verzi jako server. Pro více informací se podívejte do logu" +} diff --git a/src/main/resources/assets/neoforge/lang/da_dk.json b/src/main/resources/assets/neoforge/lang/da_dk.json index c8ca9bc3be..cb6bec74a1 100644 --- a/src/main/resources/assets/neoforge/lang/da_dk.json +++ b/src/main/resources/assets/neoforge/lang/da_dk.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/de_de.json b/src/main/resources/assets/neoforge/lang/de_de.json index 5aaea96874..4e005889f3 100644 --- a/src/main/resources/assets/neoforge/lang/de_de.json +++ b/src/main/resources/assets/neoforge/lang/de_de.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Diese Einstellungen können nicht geändert werden während Du Dein Spiel für andere geöffnet hast. Bitte kehre ins Hauptmenü zurück und lade den Spielstand erneut.", + "text": "Diese Einstellungen können nicht geändert werden, während du dein Spiel für andere im LAN geöffnet hast. Bitte kehre ins Hauptmenü zurück und lade den Spielstand erneut.", "color": "rot" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Diese Einstellungen sind nur verfügbar während ein Spiel läuft.", + "text": "Diese Einstellungen sind nur verfügbar, wenn du dich in einer Welt befindest.", "color": "rot" } ], @@ -154,6 +154,12 @@ "color": "rot" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "Dieser Wert ist zu lang, um hier bearbeitet werden zu können. Bitte bearbeite ihn in der Konfigurationsdatei.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Bearbeiten", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Servereinstellungen", "neoforge.configuration.uitext.startup": "Starteinstellungen", "neoforge.configuration.uitext.restart.game.title": "Minecraft muss neu gestartet werden", - "neoforge.configuration.uitext.restart.game.text": "Eine oder mehrere der geänderten Einstellungen beeinflussen wie das Spiel startet.", + "neoforge.configuration.uitext.restart.game.text": "Eine oder mehrere der geänderten Einstellungen sind nur wirksam, wenn das Spiel gestartet wird.", "neoforge.configuration.uitext.restart.server.title": "Spielstand muss neu geladen werden", - "neoforge.configuration.uitext.restart.server.text": "Eine oder mehrere der geänderten Einstellungen beeinflussen wie ein Spielstand geladen wird.", - "neoforge.configuration.uitext.restart.return": "Noch nicht...", + "neoforge.configuration.uitext.restart.server.text": "Eine oder mehrere der geänderten Einstellungen sind nur wirksam, wenn die Welt neu geladen wird.", + "neoforge.configuration.uitext.restart.return": "Ignorieren", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Deine Änderungen haben keine Wirkung, bis das Spiel neu gestartet wird!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge-Konfiguration", "neoforge.configuration.section.neoforge.client.toml": "Client-Einstellungen", "neoforge.configuration.section.neoforge.client.toml.title": "Client-Einstellungen", @@ -296,7 +309,7 @@ "neoforge.network.data_maps.failed": "Die Synchronisierung der Registrierungsdatenkarte für das Register konnte nicht verarbeitet werden %s: %s", "neoforge.network.data_maps.missing_our": "Kann keine Verbindung zum Server herstellen, da auf dem Server obligatorische Registrierungsdatenkarten fehlen, die auf dem Client vorhanden sind: %s", "neoforge.network.data_maps.missing_their": "Kann keine Verbindung zum Server herstellen, da obligatorische Registrierungsdatenkarten auf dem Server vorhanden sind, die auf dem Client fehlen: %s", - "neoforge.network.extensible_enums.no_vanilla_server": "This client does not support vanilla servers as it has extended enums used in serverbound networking", - "neoforge.network.extensible_enums.enum_set_mismatch": "The set of extensible enums on the client and server do not match. Make sure you are using the same NeoForge version as the server", - "neoforge.network.extensible_enums.enum_entry_mismatch": "The set of values added to extensible enums on the client and server do not match. Make sure you are using the same mod and NeoForge versions as the server. See the log for more details" + "neoforge.network.extensible_enums.no_vanilla_server": "Dieser Client unterstützt Vanilla-Server nicht, da er erweiterte Enums in dem an den Server gerichteten Netzwerk verwendet", + "neoforge.network.extensible_enums.enum_set_mismatch": "Die Menge der erweiterten Enums auf dem Client und dem Server stimmen nicht überein. Stelle sicher, dass du die gleiche NeoForge-Version wie der Server verwendest", + "neoforge.network.extensible_enums.enum_entry_mismatch": "Die Werte, die zu erweiterten Enums auf dem Client und dem Server hinzugefügt wurden, stimmen nicht überein. Stelle sicher, dass du die gleichen Mod- und NeoForge-Versionen wie der Server verwendest. Weitere Details findest du im Log" } diff --git a/src/main/resources/assets/neoforge/lang/en_gb.json b/src/main/resources/assets/neoforge/lang/en_gb.json index 0d0a574384..fef46ba376 100644 --- a/src/main/resources/assets/neoforge/lang/en_gb.json +++ b/src/main/resources/assets/neoforge/lang/en_gb.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/eo_uy.json b/src/main/resources/assets/neoforge/lang/eo_uy.json index 66209bd8d6..63165fcb18 100644 --- a/src/main/resources/assets/neoforge/lang/eo_uy.json +++ b/src/main/resources/assets/neoforge/lang/eo_uy.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/es_es.json b/src/main/resources/assets/neoforge/lang/es_es.json index b960b1bcae..d23a28c119 100644 --- a/src/main/resources/assets/neoforge/lang/es_es.json +++ b/src/main/resources/assets/neoforge/lang/es_es.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/et_ee.json b/src/main/resources/assets/neoforge/lang/et_ee.json index 19db9230f3..ad9498f46c 100644 --- a/src/main/resources/assets/neoforge/lang/et_ee.json +++ b/src/main/resources/assets/neoforge/lang/et_ee.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/fr_fr.json b/src/main/resources/assets/neoforge/lang/fr_fr.json index df28ff9183..c6feef0557 100644 --- a/src/main/resources/assets/neoforge/lang/fr_fr.json +++ b/src/main/resources/assets/neoforge/lang/fr_fr.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/hu_hu.json b/src/main/resources/assets/neoforge/lang/hu_hu.json index 730440a27a..c9195292a6 100644 --- a/src/main/resources/assets/neoforge/lang/hu_hu.json +++ b/src/main/resources/assets/neoforge/lang/hu_hu.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/it_it.json b/src/main/resources/assets/neoforge/lang/it_it.json index 2f5825a060..db7ebdd5da 100644 --- a/src/main/resources/assets/neoforge/lang/it_it.json +++ b/src/main/resources/assets/neoforge/lang/it_it.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/ja_jp.json b/src/main/resources/assets/neoforge/lang/ja_jp.json index f6acf96a94..6c9928ce1c 100644 --- a/src/main/resources/assets/neoforge/lang/ja_jp.json +++ b/src/main/resources/assets/neoforge/lang/ja_jp.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/ko_kr.json b/src/main/resources/assets/neoforge/lang/ko_kr.json index 183e4b279a..e3492e0eab 100644 --- a/src/main/resources/assets/neoforge/lang/ko_kr.json +++ b/src/main/resources/assets/neoforge/lang/ko_kr.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/nl_nl.json b/src/main/resources/assets/neoforge/lang/nl_nl.json index 588385aead..b0f3a822ce 100644 --- a/src/main/resources/assets/neoforge/lang/nl_nl.json +++ b/src/main/resources/assets/neoforge/lang/nl_nl.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/pl_pl.json b/src/main/resources/assets/neoforge/lang/pl_pl.json index b4570ef4f1..05ca184988 100644 --- a/src/main/resources/assets/neoforge/lang/pl_pl.json +++ b/src/main/resources/assets/neoforge/lang/pl_pl.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/pt_br.json b/src/main/resources/assets/neoforge/lang/pt_br.json index 51608e647f..70eaf520c6 100644 --- a/src/main/resources/assets/neoforge/lang/pt_br.json +++ b/src/main/resources/assets/neoforge/lang/pt_br.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/pt_pt.json b/src/main/resources/assets/neoforge/lang/pt_pt.json index 3a4f682f2b..405906c80c 100644 --- a/src/main/resources/assets/neoforge/lang/pt_pt.json +++ b/src/main/resources/assets/neoforge/lang/pt_pt.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/ro_ro.json b/src/main/resources/assets/neoforge/lang/ro_ro.json index 325bf1baf8..c20a393fb6 100644 --- a/src/main/resources/assets/neoforge/lang/ro_ro.json +++ b/src/main/resources/assets/neoforge/lang/ro_ro.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/ru_ru.json b/src/main/resources/assets/neoforge/lang/ru_ru.json index 488729a63e..d37e1f8a80 100644 --- a/src/main/resources/assets/neoforge/lang/ru_ru.json +++ b/src/main/resources/assets/neoforge/lang/ru_ru.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/sk_sk.json b/src/main/resources/assets/neoforge/lang/sk_sk.json index f636c181bd..f0af09f90b 100644 --- a/src/main/resources/assets/neoforge/lang/sk_sk.json +++ b/src/main/resources/assets/neoforge/lang/sk_sk.json @@ -36,7 +36,7 @@ "fml.menu.multiplayer.modsincompatible": "Zoznam módov pre server je nekompatibilný", "fml.menu.multiplayer.networkincompatible": "Serverový sieťový list správ nie je kompatibilný", "fml.menu.multiplayer.missingdatapackregistries": "Chýbajúce potrebné registre pre datapack: %1$s", - "fml.menu.branding": "%s (%s mods)", + "fml.menu.branding": "%s (%s módy)", "fml.menu.notification.title": "Spúšťacie upozornenie", "fml.menu.accessdenied.title": "Prístup k Serveru Zamietnutý", "fml.menu.accessdenied.message": "Fancy Mod Loader sa nemohol pripojiť na tento server\nServer %1$s má zakázaný prístup s módmi", @@ -107,62 +107,68 @@ "commands.neoforge.chunkgen.started": "Generovanie %1$s chunkov, v zóne %2$sx%3$s chunkov (%4$sx%5$s blokov).", "commands.neoforge.chunkgen.success": "Generovanie Dokončené!", "commands.neoforge.chunkgen.error": "Generovanie zaznamenalo %1$s chýb! Pozrite log pre viac informácií.", - "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", - "commands.neoforge.chunkgen.status": "Generation status! %1$s out of %2$s chunks generated. (%3$s%%)", + "commands.neoforge.chunkgen.stopped": "Generovanie zastavilo! %1$s z %2$s chunkov vygenerovaných. (%3$s%%)", + "commands.neoforge.chunkgen.status": "Status generovania! %1$s z %2$s chunkov vygenerovaných. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "Žiadne pregenerovnie chunkov nie je spustené. Spustite `/neoforge generate help` pre zobrazenie príkazov na začatie generovania.", "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Vygeneruje štvorcovo centrovane od danej pozície ktoreá je chunkRadius * 2 na každej strane\n§2/neoforge generate stop §r§f- Zastavý aktuálne generovanie a zobrazí sa docielený progres.\n§2/neoforge generate status §r- Zobrazí docielený progres aktuálne bežiacej generácie.\n§2/neoforge generate help §r- Zobrazí túto správu.\nVšeobecné rady: Pokiaľ je generovanie spúštané z konzoly serveru, môžete spustiť generovanie v iných dimenziách použitím /execute in neoforge generate...", - "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", - "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", - "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", - "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.timespeed.query": "Čas v %s tokoch s rýchlosťou %sx (%s minút za deň).", + "commands.neoforge.timespeed.query.default": "Čas v %s plynie normálne (20 minút na deň).", + "commands.neoforge.timespeed.set": "Nastaviť plynutie času v %s na %sx (%s minúty za deň).", + "commands.neoforge.timespeed.set.default": "Nastaviť plynutie času v %s na predvolené (20 minút za deň).", "commands.config.getwithtype": "Konfigurácia pre %s typu %s nájdená v %s", "commands.config.noconfig": "Konfigurácia pre %s typu %s nenájdená", "neoforge.update.beta.1": "%sVAROVANIE: %sNeoForge Beta", "neoforge.update.beta.2": "Môžu sa vyskytnúť závažné problémy, overte ich pred nahlásením.", "neoforge.update.newversion": "K dispozícii je nová verzia NeoForge: %s", "neoforge.menu.updatescreen.title": "Aktualizácia módu", - "neoforge.configuration.uitext.title": "%s Configuration", - "neoforge.configuration.uitext.type.client": "Client Settings", - "neoforge.configuration.uitext.type.server": "Server Settings", - "neoforge.configuration.uitext.type.common": "Common settings", - "neoforge.configuration.uitext.type.startup": "Startup settings", - "neoforge.configuration.uitext.title.client": "%s Client Configuration", - "neoforge.configuration.uitext.title.server": "%s Server Configuration", - "neoforge.configuration.uitext.title.common": "%s Common Configuration", - "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", + "neoforge.configuration.uitext.title": "%s Konfigurácia", + "neoforge.configuration.uitext.type.client": "Nastavenia Klienta", + "neoforge.configuration.uitext.type.server": "Nastavenia Serveru", + "neoforge.configuration.uitext.type.common": "Bežné nastavenia", + "neoforge.configuration.uitext.type.startup": "Nastavenia spustenia", + "neoforge.configuration.uitext.title.client": "%s Konfigurácia Klienta", + "neoforge.configuration.uitext.title.server": "%s Konfigurácia Serveru", + "neoforge.configuration.uitext.title.common": "%s Bežná Konfigurácia", + "neoforge.configuration.uitext.title.startup": "%s Konfigurácia Spustenia", "neoforge.configuration.uitext.notonline": [ { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" + "text": "Nastavenie tu sú určené serverom a nemôžu byť zmenené pokým je online.", + "color": "červená" } ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" + "text": "Nastavenia tu nemôžu byť upravené pokým je vaša hra otvorená do LAN. Prosím vráťte sa do hlavného menu a načítajte svet znova.", + "color": "červená" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", - "color": "red" + "text": "Nastavenia tu sú k dispozícii len keď je svet načítaný.", + "color": "červená" } ], "neoforge.configuration.uitext.unsupportedelement": [ { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" + "text": "Táto hodnota nemôže byť upravená v UI. Prosím kontaktujte autora módu o poskytnutý vlastného UI preň.", + "color": "červená" + } + ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "Táto hodnota je pridlhá nato aby mohla byť upravená v UI. Prosím upravte ju v konfiguračnom súbore.", + "color": "červená" } ], "neoforge.configuration.uitext.section": "%s...", - "neoforge.configuration.uitext.sectiontext": "Edit", + "neoforge.configuration.uitext.sectiontext": "Upraviť", "neoforge.configuration.uitext.breadcrumb": [ { "index": 0 }, { "text": " > ", - "color": "gold", + "color": "zlato", "bold": true }, { @@ -170,90 +176,97 @@ } ], "neoforge.configuration.uitext.listelement": "%s:", - "neoforge.configuration.uitext.undo": "Undo", - "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", + "neoforge.configuration.uitext.undo": "Krok naspäť", + "neoforge.configuration.uitext.undo.tooltip": "Vráti zmeny len na tejto obrazovke.", "neoforge.configuration.uitext.reset": "Reset", - "neoforge.configuration.uitext.reset.tooltip": "Reverts everything on this screen to its default value.", + "neoforge.configuration.uitext.reset.tooltip": "Vráti všetko na tejto stránke na predvolenú hodnotu.", "neoforge.configuration.uitext.newlistelement": "+", "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", "neoforge.configuration.uitext.rangetooltip": [ { - "text": "\n\nRange: ", - "color": "gray" + "text": "\n\nRádius: ", + "color": "sivá" }, { "index": 0, - "color": "gray" + "color": "sivá" } ], "neoforge.configuration.uitext.filenametooltip": [ { - "text": "File: \"", - "color": "gray" + "text": "Súbor: \"", + "color": "sivá" }, { "index": 0, - "color": "gray" + "color": "sivá" }, { "text": "\"", - "color": "gray" + "color": "sivá" + } + ], + "neoforge.configuration.uitext.common": "Bežné Nastavenia", + "neoforge.configuration.uitext.client": "Nastavenia Klienta", + "neoforge.configuration.uitext.server": "Nastavenia Serveru", + "neoforge.configuration.uitext.startup": "Nastavenia Spustenia", + "neoforge.configuration.uitext.restart.game.title": "Vyžaduje sa reštart Minecraftu", + "neoforge.configuration.uitext.restart.game.text": "Jedno alebo viac z konfiguračných nastavení ktoré boli zmenené budú mať efekt až keď bude hra zapnutá.", + "neoforge.configuration.uitext.restart.server.title": "Svet treba znova načítať", + "neoforge.configuration.uitext.restart.server.text": "Jedno alebo viac z konfiguračných nastavení ktoré boli zmenené budú mať efekt až keď bude hra znova načítaná.", + "neoforge.configuration.uitext.restart.return": "Ignorovať", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Vaše zmeny nebudú mať žiadny efekt pokým nereštartujete!", + "color": "červená", + "bold": true } ], - "neoforge.configuration.uitext.common": "Common Options", - "neoforge.configuration.uitext.client": "Client Options", - "neoforge.configuration.uitext.server": "Server Options", - "neoforge.configuration.uitext.startup": "Startup Options", - "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", - "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", - "neoforge.configuration.title": "NeoForge Configuration", - "neoforge.configuration.section.neoforge.client.toml": "Client settings", - "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", - "neoforge.configuration.section.neoforge.common.toml": "Common settings", - "neoforge.configuration.section.neoforge.common.toml.title": "Common settings", - "neoforge.configuration.section.neoforge.server.toml": "Server settings", - "neoforge.configuration.section.neoforge.server.toml.title": "Server settings", - "neoforge.configgui.advertiseDedicatedServerToLan": "Advertise Dedicated Server To LAN", - "neoforge.configgui.advertiseDedicatedServerToLan.tooltip": "Set this to true to enable advertising the dedicated server to local LAN clients so that it shows up in the Multiplayer screen automatically.", + "neoforge.configuration.title": "NeoForge Konfigurácia", + "neoforge.configuration.section.neoforge.client.toml": "Nastavenia klienta", + "neoforge.configuration.section.neoforge.client.toml.title": "Nastavenia klienta", + "neoforge.configuration.section.neoforge.common.toml": "Bežné nastavenia", + "neoforge.configuration.section.neoforge.common.toml.title": "Bežné nastavenia", + "neoforge.configuration.section.neoforge.server.toml": "Nastavenia serveru", + "neoforge.configuration.section.neoforge.server.toml.title": "Nastavenia serveru", + "neoforge.configgui.advertiseDedicatedServerToLan": "Inzerujte vyhradený server do siete LAN", + "neoforge.configgui.advertiseDedicatedServerToLan.tooltip": "Nastavte toto na true, aby ste povolili reklamu dedikovaného servera lokálnym klientom LAN, aby sa automaticky zobrazoval na obrazovke pre viacerých hráčov.", "neoforge.configgui.forgeLightPipelineEnabled": "NeoForge Light Pipeline", "neoforge.configgui.forgeLightPipelineEnabled.tooltip": "Povoliť kanál vykresľovania blokov NeoForge – opravuje osvetlenie vlastných modelov.", "neoforge.configgui.fullBoundingBoxLadders": "Úplné vymedzovanie boxov rebríkov", "neoforge.configgui.fullBoundingBoxLadders.tooltip": "Nastavte toto na hodnotu true, aby ste skontrolovali ohraničujúci rámček kolízie celej entity pre rebríky namiesto len bloku, v ktorom sa nachádzajú. Spôsobuje viditeľné zmeny v mechanike hry, takže predvolené je základné správanie. Predvolená hodnota: false.", - "neoforge.configgui.logLegacyTagWarnings": "Log Legacy Tags", - "neoforge.configgui.logLegacyTagWarnings.tooltip": "A config option mainly for developers. Logs out modded tags that are using the 'forge' namespace when running on integrated server. Defaults to DEV_SHORT.", - "neoforge.configgui.logUntranslatedConfigurationWarnings": "Log Untranslated Configuration Keys", - "neoforge.configgui.logUntranslatedConfigurationWarnings.tooltip": "A config option mainly for developers. Logs out configuration values that do not have translations when running a client in a development environment.", - "neoforge.configgui.logUntranslatedItemTagWarnings": "Log Untranslated Item Tags", - "neoforge.configgui.logUntranslatedItemTagWarnings.tooltip": "A config option mainly for developers. Logs out modded item tags that do not have translations when running on integrated server. Format desired is tag.item.. for the translation key. Defaults to SILENCED.", - "neoforge.configgui.permissionHandler": "Permission Handler", - "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", + "neoforge.configgui.logLegacyTagWarnings": "Staré Log Značky", + "neoforge.configgui.logLegacyTagWarnings.tooltip": "Možnosť konfigurácie najmä pre developerov. Odhlási módované značky, ktoré používajú menný priestor 'forge' keď bežia na integrovanom servery. Predvolené do DEV_SHORT.", + "neoforge.configgui.logUntranslatedConfigurationWarnings": "Nepreložené Konfiguračné Log Kľúče", + "neoforge.configgui.logUntranslatedConfigurationWarnings.tooltip": "Možnosť konfigurácie najmä pre developerov. Odhlási konfiguračné hodnoty ktoré nemajú preklady keď ide klient v developerskom prostredí.", + "neoforge.configgui.logUntranslatedItemTagWarnings": "Nepreložené Logy Známok Vecí", + "neoforge.configgui.logUntranslatedItemTagWarnings.tooltip": "Možnosť konfigurácie najmä pre developerov. Odhlási módované známky vecí ktoré nemajú preklady keď bežia na integrovanom servery. Požadovaný formát je tag.item.. pre prekladový kľúč. predvolená hodnota je SILENCED.", + "neoforge.configgui.permissionHandler": "Manipulátor Povolení", + "neoforge.configgui.permissionHandler.tooltip": "Manipulátor povolení používaný serverom. Predvolená hodnota do neoforge:default_handler ak nie je žiadny manipulátor s takým menom registrovaný.", "neoforge.configgui.removeErroringBlockEntities": "Odstrániť blokové entity spôsobujúce error", "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", + "Nastavte toto na hodnotu TRUE na odstránenie akejkoľvek Entity, ktorá vyhodí chybu v ich aktualizačnej metóde namiesto uzavretia serveru a nahlásenia logu padnutia.\n\n", { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", + "text": "BUDŤE VAROVANÝ, TOTO BY MOHLO VŠETKO ROZBIŤ.\nPOUŽÍVAJTE OPATRNE.\nNIE SME ZODPOVEDNÝ ZA ŠKODY.", + "color": "červená", "bold": true } ], "neoforge.configgui.removeErroringEntities": "Odstrániť entity spôsobujúce error", "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", + "Nastavte toto na hodnotu TRUE na odstránenie akejkoľvek Blokovej Entity, ktorá vyhodí chybu v ich aktualizačnej metóde namiesto uzavretia serveru a nahlásenia logu padnutia.\n\n", { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", + "text": "BUDŤE VAROVANÝ, TOTO BY MOHLO VŠETKO ROZBIŤ.\nPOUŽÍVAJTE OPATRNE.\nNIE SME ZODPOVEDNÝ ZA ŠKODY.", + "color": "červená", "bold": true } ], "neoforge.configgui.showLoadWarnings": "Zobraziť Varovania Načítavania", "neoforge.configgui.showLoadWarnings.tooltip": "Keď je toto povolené, NeoForge zobrazí všetky varovania, ktoré nastali počas načítavania.", - "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", - "neoforge.configgui.useCombinedDepthStencilAttachment.tooltip": "Set to true to use a combined DEPTH_STENCIL attachment instead of two separate ones.", + "neoforge.configgui.useCombinedDepthStencilAttachment": "Použiť kombinované DEPTH_STENCIL Prílohy", + "neoforge.configgui.useCombinedDepthStencilAttachment.tooltip": "Nastavte toto na hodnotu TRUE pre použitie kombinovaného DEPTH_STENCIL prílohu namiesto dvoch oddelených.", "neoforge.controlsgui.shift": "SHIFT + %s", "neoforge.controlsgui.control": "CTRL + %s", "neoforge.controlsgui.control.mac": "CMD + %s", diff --git a/src/main/resources/assets/neoforge/lang/tr_tr.json b/src/main/resources/assets/neoforge/lang/tr_tr.json index 36c779ebd4..fcecf56a33 100644 --- a/src/main/resources/assets/neoforge/lang/tr_tr.json +++ b/src/main/resources/assets/neoforge/lang/tr_tr.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/tt_ru.json b/src/main/resources/assets/neoforge/lang/tt_ru.json index 1d94b7c579..5385dcc2e4 100644 --- a/src/main/resources/assets/neoforge/lang/tt_ru.json +++ b/src/main/resources/assets/neoforge/lang/tt_ru.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/uk_ua.json b/src/main/resources/assets/neoforge/lang/uk_ua.json index 311685fba9..81b3422072 100644 --- a/src/main/resources/assets/neoforge/lang/uk_ua.json +++ b/src/main/resources/assets/neoforge/lang/uk_ua.json @@ -154,6 +154,12 @@ "color": "червоний" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "Це значення задовге для редагування в інтерфейсі. Будь ласка, відредагуйте його у файлі конфігурації.", + "color": "червоний" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Змінити", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Серверні параметри", "neoforge.configuration.uitext.startup": "Запускові параметри", "neoforge.configuration.uitext.restart.game.title": "Minecraft повинен бути перезавантаженим", - "neoforge.configuration.uitext.restart.game.text": "Один чи кілька варіантів конфігурації, які були змінені, набудуть чинності лише після запуску гри.", + "neoforge.configuration.uitext.restart.game.text": "Один чи кілька параметри конфігурації, які були змінені, набудуть чинності лише після запуску гри.", "neoforge.configuration.uitext.restart.server.title": "Світ має бути перезавантажений", - "neoforge.configuration.uitext.restart.server.text": "Один чи кілька варіантів конфігурації, які були змінені, набудуть чинності лише після запуску чи завантаження світу.", - "neoforge.configuration.uitext.restart.return": "Поки ні...", + "neoforge.configuration.uitext.restart.server.text": "Один чи кілька параметрів конфігурації, які були змінені, набудуть чинності лише після перезавантаження світу.", + "neoforge.configuration.uitext.restart.return": "Ігнорувати", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Зміни не матимуть ніякого ефекту, поки ви не перезавантажитеся!", + "color": "червоний", + "bold": true + } + ], "neoforge.configuration.title": "Конфігурація NeoForge", "neoforge.configuration.section.neoforge.client.toml": "Клієнтські налаштування", "neoforge.configuration.section.neoforge.client.toml.title": "Клієнтські налаштування", diff --git a/src/main/resources/assets/neoforge/lang/vi_vn.json b/src/main/resources/assets/neoforge/lang/vi_vn.json index 3a4f682f2b..405906c80c 100644 --- a/src/main/resources/assets/neoforge/lang/vi_vn.json +++ b/src/main/resources/assets/neoforge/lang/vi_vn.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/zh_cn.json b/src/main/resources/assets/neoforge/lang/zh_cn.json index cc42f35da3..24107e8cd2 100644 --- a/src/main/resources/assets/neoforge/lang/zh_cn.json +++ b/src/main/resources/assets/neoforge/lang/zh_cn.json @@ -107,11 +107,11 @@ "commands.neoforge.chunkgen.started": "正在于 %2$sx%3$s 区块范围(%4$sx%5$s 个方块)中生成 %1$s 个区块。", "commands.neoforge.chunkgen.success": "生成完毕!", "commands.neoforge.chunkgen.error": "生成中发生了 %1$s 个错误!请检查日志以获取更多信息。", - "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", - "commands.neoforge.chunkgen.status": "Generation status! %1$s out of %2$s chunks generated. (%3$s%%)", + "commands.neoforge.chunkgen.stopped": "生成已停止!已生成%2$s中的%1$s个区块(%3$s%%)。", + "commands.neoforge.chunkgen.status": "正在生成! %2$s中的%1$s个区块已生成(%3$s%%)。", "commands.neoforge.chunkgen.not_running": "无进行中的预生成。运行 `/neoforge generate help` 以查看开始生成的命令。", "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- 生成一个以给定坐标为中心的、边长为 chunkRadius * 2 的正方形。\n§2/neoforge generate stop §r§f- 停止当前生成,显示完成进度。\n§2/neoforge generate status §r- 显示当前生成的完成进度。\n§2/neoforge generate help §r- 显示此消息\n通用提示:如果从服务器控制台执行,可以通过 '/execute in neoforge generate...' 在特定维度执行。", - "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", + "commands.neoforge.timespeed.query": "%s 以 %sx (每天%s 分钟) 的速度流动。", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", diff --git a/src/main/resources/assets/neoforge/lang/zh_hk.json b/src/main/resources/assets/neoforge/lang/zh_hk.json index 665a99db37..e3a39d17ba 100644 --- a/src/main/resources/assets/neoforge/lang/zh_hk.json +++ b/src/main/resources/assets/neoforge/lang/zh_hk.json @@ -138,13 +138,13 @@ ], "neoforge.configuration.uitext.notlan": [ { - "text": "Settings in here cannot be editied while your game is open to LAN. Please return to the main menu and load the world again.", + "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", "color": "red" } ], "neoforge.configuration.uitext.notloaded": [ { - "text": "Settings in here are are ony available while a world is loaded.", + "text": "Settings in here are only available while a world is loaded.", "color": "red" } ], @@ -154,6 +154,12 @@ "color": "red" } ], + "neoforge.configuration.uitext.longstring": [ + { + "text": "This value is too long to be edited in the UI. Please edit it in the config file.", + "color": "red" + } + ], "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", "neoforge.configuration.uitext.breadcrumb": [ @@ -207,10 +213,17 @@ "neoforge.configuration.uitext.server": "Server Options", "neoforge.configuration.uitext.startup": "Startup Options", "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed only take effect when the game is started.", + "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed only take effect when a world is started or loaded.", - "neoforge.configuration.uitext.restart.return": "Not yet...", + "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", + "neoforge.configuration.uitext.restart.return": "Ignore", + "neoforge.configuration.uitext.restart.return.tooltip": [ + { + "text": "Your changes will have no effect until you restart!", + "color": "red", + "bold": true + } + ], "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", From c55677949f7e93a914b719755c11106c1adb9b31 Mon Sep 17 00:00:00 2001 From: Henry Loenwind Date: Mon, 5 Aug 2024 22:59:13 +0200 Subject: [PATCH 011/125] Added modifier key states to TooltipFlag and Level to TooltipContext (#1402) --- .../client/gui/screens/Screen.java.patch | 9 ++++ .../CreativeModeInventoryScreen.java.patch | 8 ++- .../multiplayer/SessionSearchTrees.java.patch | 12 ++++- .../net/minecraft/world/item/Item.java.patch | 27 ++++++++++ .../world/item/TooltipFlag.java.patch | 30 ++++++++++++ .../neoforge/client/ClientTooltipFlag.java | 49 +++++++++++++++++++ 6 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 patches/net/minecraft/world/item/TooltipFlag.java.patch create mode 100644 src/main/java/net/neoforged/neoforge/client/ClientTooltipFlag.java diff --git a/patches/net/minecraft/client/gui/screens/Screen.java.patch b/patches/net/minecraft/client/gui/screens/Screen.java.patch index 8ac1f65f2e..cc93b39e1c 100644 --- a/patches/net/minecraft/client/gui/screens/Screen.java.patch +++ b/patches/net/minecraft/client/gui/screens/Screen.java.patch @@ -17,6 +17,15 @@ } protected T addRenderableWidget(T p_169406_) { +@@ -242,7 +_,7 @@ + return p_282833_.getTooltipLines( + Item.TooltipContext.of(p_281881_.level), + p_281881_.player, +- p_281881_.options.advancedItemTooltips ? TooltipFlag.Default.ADVANCED : TooltipFlag.Default.NORMAL ++ net.neoforged.neoforge.client.ClientTooltipFlag.of(p_281881_.options.advancedItemTooltips ? TooltipFlag.Default.ADVANCED : TooltipFlag.Default.NORMAL) + ); + } + @@ -312,8 +_,11 @@ this.width = p_96608_; this.height = p_96609_; diff --git a/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch b/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch index ae61eab098..67ef56cafb 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch @@ -185,7 +185,7 @@ this.renderTooltip(p_283000_, p_281317_, p_282770_); } -@@ -684,7 +_,7 @@ +@@ -684,10 +_,10 @@ public List getTooltipFromContainerItem(ItemStack p_281769_) { boolean flag = this.hoveredSlot != null && this.hoveredSlot instanceof CreativeModeInventoryScreen.CustomCreativeSlot; boolean flag1 = selectedTab.getType() == CreativeModeTab.Type.CATEGORY; @@ -193,7 +193,11 @@ + boolean flag2 = selectedTab.hasSearchBar(); TooltipFlag.Default tooltipflag$default = this.minecraft.options.advancedItemTooltips ? TooltipFlag.Default.ADVANCED : TooltipFlag.Default.NORMAL; TooltipFlag tooltipflag = flag ? tooltipflag$default.asCreative() : tooltipflag$default; - List list = p_281769_.getTooltipLines(Item.TooltipContext.of(this.minecraft.level), this.minecraft.player, tooltipflag); +- List list = p_281769_.getTooltipLines(Item.TooltipContext.of(this.minecraft.level), this.minecraft.player, tooltipflag); ++ List list = p_281769_.getTooltipLines(Item.TooltipContext.of(this.minecraft.level), this.minecraft.player, net.neoforged.neoforge.client.ClientTooltipFlag.of(tooltipflag)); + if (flag1 && flag) { + return list; + } else { @@ -703,7 +_,7 @@ int i = 1; diff --git a/patches/net/minecraft/client/multiplayer/SessionSearchTrees.java.patch b/patches/net/minecraft/client/multiplayer/SessionSearchTrees.java.patch index 3bd75c8394..70a7eabfac 100644 --- a/patches/net/minecraft/client/multiplayer/SessionSearchTrees.java.patch +++ b/patches/net/minecraft/client/multiplayer/SessionSearchTrees.java.patch @@ -1,5 +1,14 @@ --- a/net/minecraft/client/multiplayer/SessionSearchTrees.java +++ b/net/minecraft/client/multiplayer/SessionSearchTrees.java +@@ -60,7 +_,7 @@ + List list = p_346233_.getCollections(); + Registry registry = p_345600_.registryOrThrow(Registries.ITEM); + Item.TooltipContext item$tooltipcontext = Item.TooltipContext.of(p_345600_); +- TooltipFlag tooltipflag = TooltipFlag.Default.NORMAL; ++ TooltipFlag tooltipflag = net.neoforged.neoforge.client.ClientTooltipFlag.of(TooltipFlag.Default.NORMAL); + CompletableFuture completablefuture = this.recipeSearch; + this.recipeSearch = CompletableFuture.supplyAsync( + () -> new FullTextSearchTree<>( @@ -86,44 +_,60 @@ } @@ -43,9 +52,10 @@ + key, () -> { Item.TooltipContext item$tooltipcontext = Item.TooltipContext.of(p_345391_); - TooltipFlag tooltipflag = TooltipFlag.Default.NORMAL.asCreative(); +- TooltipFlag tooltipflag = TooltipFlag.Default.NORMAL.asCreative(); - CompletableFuture completablefuture = this.creativeByNameSearch; - this.creativeByNameSearch = CompletableFuture.supplyAsync( ++ TooltipFlag tooltipflag = net.neoforged.neoforge.client.ClientTooltipFlag.of(TooltipFlag.Default.NORMAL.asCreative()); + CompletableFuture completablefuture = net.neoforged.neoforge.client.CreativeModeTabSearchRegistry.getNameSearchTree(key); + net.neoforged.neoforge.client.CreativeModeTabSearchRegistry.putNameSearchTree(key, CompletableFuture.supplyAsync( () -> new FullTextSearchTree<>( diff --git a/patches/net/minecraft/world/item/Item.java.patch b/patches/net/minecraft/world/item/Item.java.patch index a07fc6dfd8..4054c635cd 100644 --- a/patches/net/minecraft/world/item/Item.java.patch +++ b/patches/net/minecraft/world/item/Item.java.patch @@ -196,3 +196,30 @@ if (datacomponentmap.has(DataComponents.DAMAGE) && datacomponentmap.getOrDefault(DataComponents.MAX_STACK_SIZE, 1) > 1) { throw new IllegalStateException("Item cannot have both durability and be stackable"); } else { +@@ -441,6 +_,14 @@ + @Nullable + MapItemSavedData mapData(MapId p_339670_); + ++ /** ++ * Neo: Returns the level if it's available. ++ */ ++ @Nullable ++ default Level level() { ++ return null; ++ } ++ + static Item.TooltipContext of(@Nullable final Level p_339599_) { + return p_339599_ == null ? EMPTY : new Item.TooltipContext() { + @Override +@@ -456,6 +_,11 @@ + @Override + public MapItemSavedData mapData(MapId p_339628_) { + return p_339599_.getMapData(p_339628_); ++ } ++ ++ @Override ++ public Level level() { ++ return p_339599_; + } + }; + } diff --git a/patches/net/minecraft/world/item/TooltipFlag.java.patch b/patches/net/minecraft/world/item/TooltipFlag.java.patch new file mode 100644 index 0000000000..4a7b43a26c --- /dev/null +++ b/patches/net/minecraft/world/item/TooltipFlag.java.patch @@ -0,0 +1,30 @@ +--- a/net/minecraft/world/item/TooltipFlag.java ++++ b/net/minecraft/world/item/TooltipFlag.java +@@ -8,6 +_,27 @@ + + boolean isCreative(); + ++ /** ++ * Neo: Returns the state of the Control key (as reported by Screen) on the client, or {@code false} on the server. ++ */ ++ default boolean hasControlDown() { ++ return false; ++ } ++ ++ /** ++ * Neo: Returns the state of the Shift key (as reported by Screen) on the client, or {@code false} on the server. ++ */ ++ default boolean hasShiftDown() { ++ return false; ++ } ++ ++ /** ++ * Neo: Returns the state of the Alt key (as reported by Screen) on the client, or {@code false} on the server. ++ */ ++ default boolean hasAltDown() { ++ return false; ++ } ++ + public static record Default(boolean advanced, boolean creative) implements TooltipFlag { + @Override + public boolean isAdvanced() { diff --git a/src/main/java/net/neoforged/neoforge/client/ClientTooltipFlag.java b/src/main/java/net/neoforged/neoforge/client/ClientTooltipFlag.java new file mode 100644 index 0000000000..f4a9a47265 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/ClientTooltipFlag.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client; + +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.world.item.TooltipFlag; +import org.jetbrains.annotations.ApiStatus; + +/** + * A version of {@link TooltipFlag} that knows about Screen and can provide modifier key states. It is patched into all vanilla uses of TooltipFlags in client classes. + *

+ * When calling any tooltip method that needs a TooltipFlag yourself, use either this (by calling {@link #of(TooltipFlag)}) or {@link TooltipFlag.Default} depending on the logical side you're on. + */ +public record ClientTooltipFlag(boolean advanced, boolean creative, boolean shiftDown, boolean controlDown, boolean altDown) implements TooltipFlag { + @ApiStatus.Internal + public ClientTooltipFlag {} + + @Override + public boolean isAdvanced() { + return this.advanced; + } + + @Override + public boolean isCreative() { + return this.creative; + } + + @Override + public boolean hasControlDown() { + return controlDown; + } + + @Override + public boolean hasShiftDown() { + return shiftDown; + } + + @Override + public boolean hasAltDown() { + return altDown; + } + + public static TooltipFlag of(TooltipFlag other) { + return new ClientTooltipFlag(other.isAdvanced(), other.isCreative(), Screen.hasShiftDown(), Screen.hasControlDown(), Screen.hasAltDown()); + } +} From 74a0608688f4579cef45ff178962de9bd0522872 Mon Sep 17 00:00:00 2001 From: Caltinor <62700786+Caltinor@users.noreply.github.com> Date: Mon, 5 Aug 2024 22:57:36 -0400 Subject: [PATCH 012/125] Add PlayerEnchantItemEvent (#1363) This event is fired after a player enchants an item, allowing other mods to react to that action. --- .../inventory/EnchantmentMenu.java.patch | 3 +- .../neoforge/common/CommonHooks.java | 15 +++++++ .../entity/player/PlayerEnchantItemEvent.java | 42 +++++++++++++++++++ .../enchantment/EnchantmentLevelTests.java | 38 ++++++++++++++++- 4 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 src/main/java/net/neoforged/neoforge/event/entity/player/PlayerEnchantItemEvent.java diff --git a/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch b/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch index be2dc61baa..817bb84ff8 100644 --- a/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch +++ b/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch @@ -45,13 +45,14 @@ - itemstack2 = itemstack.transmuteCopy(Items.ENCHANTED_BOOK); - this.enchantSlots.setItem(0, itemstack2); - } - +- - for (EnchantmentInstance enchantmentinstance : list) { - itemstack2.enchant(enchantmentinstance.enchantment, enchantmentinstance.level); - } + // Neo: Allow items to transform themselves when enchanted, instead of relying on hardcoded transformations for Items.BOOK + itemstack2 = itemstack.getItem().applyEnchantments(itemstack, list); + this.enchantSlots.setItem(0, itemstack2); ++ net.neoforged.neoforge.common.CommonHooks.onPlayerEnchantItem(p_39465_, itemstack2, list); itemstack1.consume(i, p_39465_); if (itemstack1.isEmpty()) { diff --git a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java index f4c06f1758..25f4f3c588 100644 --- a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java +++ b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java @@ -102,6 +102,7 @@ import net.minecraft.world.inventory.AnvilMenu; import net.minecraft.world.inventory.ClickAction; import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.inventory.EnchantmentMenu; import net.minecraft.world.inventory.RecipeBookType; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.AdventureModePredicate; @@ -120,6 +121,7 @@ import net.minecraft.world.item.component.ItemAttributeModifiers; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.item.enchantment.Enchantment; +import net.minecraft.world.item.enchantment.EnchantmentInstance; import net.minecraft.world.item.enchantment.ItemEnchantments; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.GameType; @@ -200,6 +202,7 @@ import net.neoforged.neoforge.event.entity.player.AnvilRepairEvent; import net.neoforged.neoforge.event.entity.player.AttackEntityEvent; import net.neoforged.neoforge.event.entity.player.CriticalHitEvent; +import net.neoforged.neoforge.event.entity.player.PlayerEnchantItemEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; import net.neoforged.neoforge.event.level.BlockDropsEvent; @@ -665,6 +668,18 @@ public static InteractionResult onPlaceItemIntoWorld(UseOnContext context) { return ret; } + /** + * Fires {@link PlayerEnchantItemEvent} in {@link EnchantmentMenu#clickMenuButton(Player, int)} after the enchants are + * applied to the item. + * + * @param player the player who clicked the menu button + * @param stack the item enchanted + * @param instances the specific enchantments that were applied to the item. + */ + public static void onPlayerEnchantItem(Player player, ItemStack stack, List instances) { + NeoForge.EVENT_BUS.post(new PlayerEnchantItemEvent(player, stack, instances)); + } + public static boolean onAnvilChange(AnvilMenu container, ItemStack left, ItemStack right, Container outputSlot, String name, long baseCost, Player player) { AnvilUpdateEvent e = new AnvilUpdateEvent(left, right, name, baseCost, player); if (NeoForge.EVENT_BUS.post(e).isCanceled()) diff --git a/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerEnchantItemEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerEnchantItemEvent.java new file mode 100644 index 0000000000..6ab2d9e60f --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/event/entity/player/PlayerEnchantItemEvent.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.event.entity.player; + +import java.util.List; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentInstance; +import net.neoforged.neoforge.common.extensions.IItemExtension; + +/** + * This event fires when a player enchants an item, after {@link IItemExtension#applyEnchantments} has been called. + *

+ * This event is only fired on the logical server. + */ +public class PlayerEnchantItemEvent extends PlayerEvent { + private final ItemStack enchantedItem; + private final List enchantments; + + public PlayerEnchantItemEvent(Player player, ItemStack enchantedItem, List enchantments) { + super(player); + this.enchantedItem = enchantedItem; + this.enchantments = enchantments; + } + + /** + * @return the {@link ItemStack} after it was enchanted + */ + public ItemStack getEnchantedItem() { + return enchantedItem; + } + + /** + * @return the list of {@link EnchantmentInstance}s that were applied to the item for this event firing + */ + public List getEnchantments() { + return enchantments; + } +} diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/enchantment/EnchantmentLevelTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/enchantment/EnchantmentLevelTests.java index 848332d1a8..96d5e43e99 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/enchantment/EnchantmentLevelTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/enchantment/EnchantmentLevelTests.java @@ -5,6 +5,8 @@ package net.neoforged.neoforge.debug.enchantment; +import java.util.Objects; +import net.minecraft.core.BlockPos; import net.minecraft.core.component.DataComponents; import net.minecraft.core.registries.Registries; import net.minecraft.gametest.framework.GameTest; @@ -14,7 +16,10 @@ import net.minecraft.world.item.component.CustomData; import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.item.enchantment.ItemEnchantments; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.EnchantingTableBlockEntity; import net.neoforged.neoforge.event.enchanting.GetEnchantmentLevelEvent; +import net.neoforged.neoforge.event.entity.player.PlayerEnchantItemEvent; import net.neoforged.testframework.DynamicTest; import net.neoforged.testframework.annotation.ForEachTest; import net.neoforged.testframework.annotation.TestHolder; @@ -23,7 +28,7 @@ @ForEachTest(groups = EnchantmentLevelTests.GROUP) public class EnchantmentLevelTests { - public static final String GROUP = "enchantment.level"; + public static final String GROUP = "enchantment"; @GameTest @EmptyTemplate @@ -65,4 +70,35 @@ static void getEnchLevelEvent(final DynamicTest test, final RegistrationHelper r helper.succeed(); }); } + + @GameTest + @EmptyTemplate + @TestHolder(description = "Tests if the PlayerEnchantedItemEvent fired.") + static void playerEnchantItemTest(final DynamicTest test, final RegistrationHelper reg) { + test.eventListeners().forge().addListener((PlayerEnchantItemEvent event) -> { + event.getEnchantedItem().setDamageValue(1); //change a value we can reference in our test sequence + }); + final BlockPos pos = new BlockPos(1, 2, 1); + test.onGameTest(helper -> helper.startSequence(helper::makeMockPlayer) + //ensure the player has enough experience to perform an enchantment + .thenExecute(player -> player.experienceLevel = 30) + //place a table into the world to hold our container + .thenExecute(player -> helper.setBlock(pos, Blocks.ENCHANTING_TABLE)) + //open the menu container on the player + .thenExecute(player -> player.containerMenu = Objects.requireNonNull(Objects.requireNonNull( + Objects.requireNonNull(helper.getBlockEntity(pos, EnchantingTableBlockEntity.class)).getBlockState() + .getMenuProvider(player.level(), helper.absolutePos(pos))) + .createMenu(1, player.getInventory(), player))) + //simulate putting an iron sword in the first slot + .thenExecute(player -> player.containerMenu.setItem(0, player.containerMenu.getStateId(), new ItemStack(Items.IRON_SWORD))) + //simulate putting the lapis into the second slot + .thenExecute(player -> player.containerMenu.setItem(1, player.containerMenu.getStateId(), new ItemStack(Items.LAPIS_LAZULI))) + //ensure the lapis count is enough to pay for any enchanting costs + .thenExecute(player -> player.containerMenu.getSlot(1).getItem().setCount(64)) + //simulate clicking the button on the screen. + .thenExecute(player -> player.containerMenu.clickMenuButton(player, 1)) + //verify the event listener has set the damage value of our item to one + .thenWaitUntil(player -> helper.assertTrue(player.containerMenu.getSlot(0).getItem().getDamageValue() == 1, "Enchanted item damage not set by the event")) + .thenSucceed()); + } } From 7d32e69a37742a6f0227d2c3bca1e2e5979036a7 Mon Sep 17 00:00:00 2001 From: lcy0x1 Date: Tue, 6 Aug 2024 11:01:20 +0800 Subject: [PATCH 013/125] Custom attribute level curve in MobEffect, restoring `getAttributeModifierValue` (#1334) This allows mob effects to provide non-linear attribute modifier values --- .../world/effect/MobEffect.java.patch | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/patches/net/minecraft/world/effect/MobEffect.java.patch b/patches/net/minecraft/world/effect/MobEffect.java.patch index dc2d08f77d..c8eef70796 100644 --- a/patches/net/minecraft/world/effect/MobEffect.java.patch +++ b/patches/net/minecraft/world/effect/MobEffect.java.patch @@ -9,18 +9,48 @@ public static final Codec> CODEC = BuiltInRegistries.MOB_EFFECT.holderByNameCodec(); public static final StreamCodec> STREAM_CODEC = ByteBufCodecs.holderRegistry(Registries.MOB_EFFECT); private static final int AMBIENT_ALPHA = Mth.floor(38.25F); -@@ -179,6 +_,14 @@ - @Override - public FeatureFlagSet requiredFeatures() { - return this.requiredFeatures; +@@ -130,6 +_,18 @@ + return this; + } + ++ /** ++ * Neo: attribute template with custom level curve, for mob effects providing non-linear attribute modifiers. ++ * @param attribute The attribute of the modifier ++ * @param id ID of the modifier ++ * @param operation Operation of the modifier ++ * @param curve A function mapping effect instance amplifier to modifier amount ++ */ ++ public MobEffect addAttributeModifier(Holder attribute, ResourceLocation id, AttributeModifier.Operation operation, it.unimi.dsi.fastutil.ints.Int2DoubleFunction curve) { ++ this.attributeModifiers.put(attribute, new MobEffect.AttributeTemplate(id, curve.apply(0), operation, curve)); ++ return this; + } + + public MobEffect setBlendDuration(int p_316265_) { + this.blendDurationTicks = p_316265_; + return this; +@@ -181,8 +_,24 @@ + return this.requiredFeatures; + } + +- static record AttributeTemplate(ResourceLocation id, double amount, AttributeModifier.Operation operation) { + /** + * Neo: Allowing mods to define client behavior for their MobEffects + * @deprecated Use {@link net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent} instead + */ + @Deprecated(forRemoval = true, since = "1.21") + public void initializeClient(java.util.function.Consumer consumer) { ++ } ++ ++ static record AttributeTemplate(ResourceLocation id, double amount, AttributeModifier.Operation operation, @Nullable it.unimi.dsi.fastutil.ints.Int2DoubleFunction curve) { ++ ++ public AttributeTemplate(ResourceLocation id, double amount, AttributeModifier.Operation operation) { ++ this(id, amount, operation, null); ++ } ++ + public AttributeModifier create(int p_316614_) { ++ if (curve != null) { // Neo: Use the custom attribute value curve if one is present ++ return new AttributeModifier(this.id, this.curve.apply(p_316614_), this.operation); ++ } + return new AttributeModifier(this.id, this.amount * (double)(p_316614_ + 1), this.operation); + } } - - static record AttributeTemplate(ResourceLocation id, double amount, AttributeModifier.Operation operation) { From 82832d0cf4fe77d0ba8b0fbf25c55b3323960f19 Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Wed, 7 Aug 2024 05:41:01 -0400 Subject: [PATCH 014/125] Silence logging for deprecated slimeball tag (#1424) --- .../net/neoforged/neoforge/common/TagConventionLogWarning.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java b/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java index aa9e51f6e6..f874d45787 100644 --- a/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java +++ b/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java @@ -334,7 +334,6 @@ public enum LogWarningMode { createForgeMapEntry(Registries.ITEM, "seeds/wheat", Tags.Items.SEEDS_WHEAT), createForgeMapEntry(Registries.ITEM, "shears", Tags.Items.TOOLS_SHEAR), createForgeMapEntry(Registries.ITEM, "slimeballs", Tags.Items.SLIME_BALLS), - createMapEntry(Registries.ITEM, "c", "slimeballs", Tags.Items.SLIME_BALLS), createForgeMapEntry(Registries.ITEM, "stone", Tags.Items.STONES), createForgeMapEntry(Registries.ITEM, "storage_blocks", Tags.Items.STORAGE_BLOCKS), createForgeMapEntry(Registries.ITEM, "storage_blocks/amethyst", "storage_blocks/amethyst"), From 4aa213f1a58ac8f9862ffbd3dea641c85aafe0b7 Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Wed, 7 Aug 2024 18:07:14 -0400 Subject: [PATCH 015/125] Add contributor docs for tests (#1416) --- docs/CONTRIBUTING.md | 1 + docs/NEOGAMETESTS.md | 146 +++++++++++++++++++++++++++ docs/README.md | 2 +- docs/TESTFRAMEWORK.md | 226 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 374 insertions(+), 1 deletion(-) create mode 100644 docs/NEOGAMETESTS.md create mode 100644 docs/TESTFRAMEWORK.md diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 87981f1fe1..d34d06f231 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -20,6 +20,7 @@ Contributing to NeoForge - Run the game (Runs are available in the IDE) - Run `gradlew :tests:runGameTestServer` or `Tests: GameTestServer` from IDE - Run `gradlew :tests:runGameTestClient` or `Tests: GameTestClient` from IDE + - If possible, write an automated test under the tests project. See [NEOGAMETESTS.md](NEOGAMETESTS.md) for more info. 9. Run `gradlew unpackSourcePatches` to generate patch-files from the patched sources 10. Run `gradlew applyAllFormatting` to automatically format sources 11. Check correct formatting with `gradlew spotlessCheck` diff --git a/docs/NEOGAMETESTS.md b/docs/NEOGAMETESTS.md new file mode 100644 index 0000000000..b9282fc3ac --- /dev/null +++ b/docs/NEOGAMETESTS.md @@ -0,0 +1,146 @@ +# Tests 101 +## Step 1: the test method +First, select the appropriate class the test should live in, and then write the test method. + +```java +import net.neoforged.testframework.annotation.TestHolder; +import net.neoforged.testframework.DynamicTest; + +class SomeTestClass { + @TestHolder(description = "Tests some interesting thing") + static void someNiceTest(final DynamicTest test) { + + } +} +``` +The method name denotes the name of the test. +The method should be annotated with `@TestHolder` in order for it to be found by the framework. +The annotation has several parameters, including a `description` parameter which should contain information regarding what the test does and tests. + +The method shall accept one or two parameter, in the following variants: +- only one parameter of type `DynamicTest` +- the first parameter of type `DynamicTest`, and the second of `RegistrationHelper`. This variant should be used if the test will register blocks + +## Step 2: registering the event listeners +**This is optional**: only if the test is testing an event and as such needs to register event listeners + +Event listeners can be registered to the test's listener groups. The listeners will be registered to the bus +when the test is enabled, and unregistered when it is disabled. + +```java +import net.minecraft.references.Items; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; +import net.neoforged.testframework.annotation.TestHolder; +import net.neoforged.testframework.DynamicTest; + +class SomeTestClass { + @TestHolder(description = "Tests some interesting thing") + static void someNiceTest(final DynamicTest test) { + test.eventListeners().neoforge().addListener((final PlayerEvent.ItemPickupEvent event) -> { + if (event.getStack().is(Items.MELON_SEEDS)) { + // If the event is fired and detects pickup of melon seeds, the test will be considered pass + // and the player will get pumpkin seeds too + event.getEntity().addItem(new ItemStack(Items.PUMPKIN_SEEDS)); + test.pass(); + } + }); + } +} +``` + +A test can be passed by calling the `DynamicTest#pass()` method or failed by calling `DynamicTest#fail(String)`. +In the case of manual tests that require player confirmation to make sure that they passed, `DynamicTest.requestConfirmation(Player, Component message)` can be used to +send the player an in-game message asking for confirmation of the test passing. + +## Step 3: automation +Now for the fun part! Automating the test via `GameTest`s. +We can use the `DynamicTest#onGameTest` method for writing a game test. We also need to annotate the test method with `@GameTest` so that the framework +registers the test as a gametest. +The framework also provides several ways of registering the templates for tests in code: +- for empty templates, the `@EmptyTemplate(value = size)` annotation can be used to give the test an empty structure with the size specified by the `value` parameter, + defaulting to 3x3x3; the `floor` parameter will add an iron floor at y level 1 and increase the test's height by 1 +- the `DynamicTest#registerGameTestTemplate` allows creating a template via the `StructureTemplateBuilder` + +```java +import net.minecraft.core.BlockPos; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.references.Items; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.GameType; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; +import net.neoforged.testframework.annotation.TestHolder; +import net.neoforged.testframework.DynamicTest; +import net.neoforged.testframework.gametest.EmptyTemplate; +import net.neoforged.testframework.gametest.GameTestPlayer; +import net.neoforged.testframework.gametest.StructureTemplateBuilder; + +class SomeTestClass { + @GameTest + @EmptyTemplate(value = "3x3x3", floor = true) + @TestHolder(description = "Tests some interesting thing") + static void someNiceTest(final DynamicTest test) { + test.eventListeners().neoforge().addListener((final PlayerEvent.ItemPickupEvent event) -> { + if (event.getStack().is(Items.MELON_SEEDS)) { + // If the event is fired and detects pickup of melon seeds, the test will be considered pass + // and the player will get pumpkin seeds too + event.getEntity().addItem(new ItemStack(Items.PUMPKIN_SEEDS)); + test.pass(); + } + }); + + // Another way of registering templates in-code: + // test.registerGameTestTemplate(StructureTemplateBuilder.withSize(3, 4, 3) + // .fill(0, 0, 0, 2, 0, 2, Blocks.IRON_BLOCK)); + + test.onGameTest(helper -> { + // Spawn a player at the centre of the test + final GameTestPlayer player = helper.makeTickingMockServerPlayerInLevel(GameType.SURVIVAL) + .moveToCentre(); + // Spawn melon seeds at the player's feet. + // The player is at the centre (x -> 1, z -> 1; x are the south coords and z the north ones, 0 0 being the right-front corner, next to the structure block) + // (y -> 2, y being the vertical position, which is 1-indexed; since 1, the first layer, is the floor, the player is at 2, the second layer) + helper.spawnItem(Items.MELON_SEEDS, 1, 2, 1); + + helper.startSequence() + // Wait until the player picked up the seeds + .thenWaitUntil(() -> helper.assertTrue(player.getInventory().hasAnyMatching(stack -> stack.is(Items.MELON_SEEDS)), "player has no melon seeds")) + // Check for pumpkin seeds in the player's inventory + .thenExecute(() -> helper.assertTrue(player.getInventory().hasAnyMatching(stack -> stack.is(Items.PUMPKIN_SEEDS)), "player had no pumpkin seeds in their inventory")) + // All assertions were true, so the test is a success! + .thenSucceed(); + }); + } +} +``` + +## Extra: using the `RegistrationHelper` +Registering a simple block with a block item, that has the en_us lang entry of `simple block` and a default all-white model: +```java +registrationHelper.blocks().registerSimpleBlock("simple", BlockBehaviour.Properties.of().destroyTime(10f)) + .withLang("simple block").withBlockItem().withDefaultWhiteModel(); +``` + +## Extra: GameTest-only tests +Tests that do not need a `RegistrationHelper` or event listeners and that are, as such, only gametest-able, can skip the `DynamicTest` part and simply write +a gametest method, while allowing the use of the `ExtendedGameTestHelper` provided by the framework, and of the `@EmptyTemplate` annotation: + +```java +import net.minecraft.gametest.framework.GameTest; +import net.neoforged.testframework.annotation.TestHolder; +import net.neoforged.testframework.gametest.EmptyTemplate; + +@GameTest +@EmptyTemplate +@TestHolder(description = "Does something") +static void gameTestOnly(final ExtendedGameTestHelper helper) { + // .... + helper.succeed(); +} +``` + +## Extra: method-based event tests +These tests cannot be automated via gametests, and will only provide manual event testing. They should primarily be used by client tests. +More information can be found [here](TESTFRAMEWORK.md). +If you're unsure how to write a test for a feature, feel free to ask in our [Discord](https://discord.neoforged.net/) server, in the [`#neoforge-github` channel](https://discord.com/channels/313125603924639766/852298000042164244), or consult the existing tests. diff --git a/docs/README.md b/docs/README.md index 95a2a04871..17bd099ebe 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,7 +9,7 @@ NeoForge is a free, open-source, community-oriented modding API for Minecraft. | Version | Support | |---------|---------| -| 1.20.x | Active | +| 1.21.x | Active | * [Download] * [Discord] diff --git a/docs/TESTFRAMEWORK.md b/docs/TESTFRAMEWORK.md new file mode 100644 index 0000000000..06f84c3991 --- /dev/null +++ b/docs/TESTFRAMEWORK.md @@ -0,0 +1,226 @@ +# The Test Framework +This guide will explain the MC Test Framework, how it works, and how to use it. +If you are a contributor looking to add a GameTest for your PR, [please see this guide instead](NEOGAMETESTS.md). +## What is the Framework? +The Framework is used in order to manage and process Minecraft in-game tests, and is designed to be used by NeoForge. +## How does the Framework work? +The Framwork manages tests, which can be enabled or disabled at runtime, using either an in-game command or a UI. Tests have a status which consist of a message and a `Result`, which can be either `PASSED`, `FAILED` or `NOT_PROCESSED`. The status of a test is changed by test itself when it meets certain conditions, or it encounteres exceptions. +The status of tests is synchronized with clients, which means multiple players can simultaneously run tests on the same server. +Tests can also be run without manual player interaction (like on a CI for example), by utilising the [GameTest integration](#gametest-integration). +## Creating a `TestFramework` +A `TestFramework` can be created during mod construction using `FrameworkConfiguration$Builder`: +```java + final TestFrameworkInternal framework = FrameworkConfiguration.builder(new ResourceLocation("examplemod:tests")) // The ID of the framework. Used by logging, primarily + .clientConfiguration(() -> ClientConfiguration.builder() // Client-side compatibility configuration. This is COMPLETLY optional, but it is recommended for ease of use. + .toggleOverlayKey(GLFW.GLFW_KEY_J) // The key used to toggle the tests overlay + .openManagerKey(GLFW.GLFW_KEY_N) // The key used to open the Test Manager screen + .build()) + + .allowClientModifications() // Allow OP'd clients to modify the status of tests, and to enable them + .syncToClients() // Sync the status of tests to clients + + .build().create(); // Build and store the InternalTestFramework. We use the "internal" version because we want to access methods not usually exposed, like the init method + + // Initialise this framework, using the mod event bus of the currently loading mod, and the container of the currently loading mod. + // The container is used for collecting annotations. + // This method will collect and register tests, structure templates, group data, and will fire init listeners. + framework.init(modBus, modContainer); + + // Register the commands of the framework under the `tests` top-level command. + NeoForge.EVENT_BUS.addListener((final RegisterCommandsEvent event) -> { + final LiteralArgumentBuilder node = Commands.literal("tests"); + framework.registerCommands(node); + event.getDispatcher().register(node); + }); +``` + +## Creating tests +Tests are represented by any object implementing `Test` which is registered using `TestFramework$Tests#register(Test)` or using by using a test collector. + +The test framework, by default collects 3 different types of tests: +- [Basic Tests](#Basic-tests) +- [Method-based Tests](#Method-based-tests) +- [Method-based Event Tests](#Method-based-event-tests) + +### Basic tests +Basic tests are represented by any class inherithing from `Test`, annotated with `TestHolder`, which has a no-arg public constructor. The collector will instantiate +the test, using reflection. +**Note**: it is recommended that you extend from `AbstractTest`, as it will configure the test based on the parameters of the `TestHolder` annotation. + +Example basic test using `AbstractTest` which passes when a player enters a section: +```java +@TestHolder( + value = "entity_entering_section", + description = "Tests if the EntityEvent.EnteringSection will be fired when a player moves to another chunk." +) +public class EnteringSectionEventTest extends AbstractTest { + @Override + public void onEnabled(@NotNull EventListenerGroup listeners) { + logger().info("Basic test 'entity_entering_section' has been enabled!"); + listeners.getFor(Bus.NEOFORGE).addListener((final EntityEvent.EnteringSection event) -> { + if (event.getEntity() instanceof Player) { + pass(); + } + }); + } +} +``` + +### Method-based tests +Method-based tests are represented by any *static* method, annotated with `TestHolder`, which has either exactly one parameter of type `DynamicTest`, or a parameter of type `DynamicTest` and `RegistrationHelper`, in this order. +The collector will invoke the method during `TestFramework#init`, allowing you to configure listeners on the test. +**Note**: the method can have any access modifier, as it will be invoked with a trusted lookup! + +Example method-based test which passes when a player enters a section: +```java +@TestHolder( + value = "entity_entering_section", + description = "Tests if the EntityEvent.EnteringSection will be fired when a player moves to another chunk." +) +static void entityEnteringSection(final DynamicTest test /*, final RegistrationHelper reg */) { + test.framework().logger().info("Method-based 'entity_entering_section' test has been initialised!"); + test.whenEnabled(listeners -> { + test.framework().logger().info("Method-based 'entity_entering_section' test has been enabled!"); + + listeners.getFor(Bus.NEOFORGE).addListener((final EntityEvent.EnteringSection event) -> { + if (event.getEntity() instanceof Player) { + test.pass(); + } + }); + }); +} +``` + +### Method-based Event tests +Method-based event tests are represented by any *static* method, annotated with `TestHolder`, which accept exactly 2 parameters: +- the first parameter is of any type which is a subclass of `Event`, and represents the type of the event to listen for; If this parameter implements `IModBusEvent`, the listener will be registered to the `MOD` bus, otherwise it will be registered to the `FORGE` bus; +- the second parameter is of the `DynamicTest` type. + +The collector will register the method as an event listener, and as such the method is invoked every time an event is fired. +**Because of this, the test may *only* be configured in the annotation!** +**Note**: the method can have any access modifier, as it will be invoked with a trusted lookup! + +Example method-based event test which passes when a player enters a section: +```java +@TestHolder( + value = "entity_entering_section", + description = "Tests if the EntityEvent.EnteringSection will be fired when a player moves to another chunk." +) +static void entityEnteringSection(final EntityEvent.EnteringSection event, final DynamicTest test) { + test.framework().logger().info("Method-based 'entity_entering_section' event test listener has been fired!"); + if (event.getEntity() instanceof Player) { + test.pass(); + } +} +``` + +## Annotations + +### The `TestHolder` annotation +The `TestHolder` annotation has different parameters which are used to configure a test: +- `value: String` - the ID of the test; *required*; +- `groups: String[]` - the groups this test is in; +- `title: String` - the human-readable title of the test; +- `description: String[]` - a description of the test; this property is usually used in order to provide instructions on how to use the text; +- `enabledByDefault: boolean` - if the test is enabled by default; +- `side: Dist[]` - the sides that the test should be registered on; **Note**: this property should be used only when *absolutely needed* (like on method-based event tests listening for client-only events). + +### The `ForEachTest` annotation +When applied on a class, the `ForEachTest` annotation will apply common configuration to all method-based tests in the class. +The parameters of `ForEachTest` are: +- `idPrefix: String` - a prefix to be added to the IDs of the child tests; +- `groups: String[]` - the groups to add to the child tests; +- `side: Dist[]` - the sides to load the child tests on. + +Example usage: +```java +@ForEachTest( + idPrefix = "entity_event_", + groups = "events.entity" +) +public class EntityEvents { + @TestHolder(id = "on_join_level") // The ID of the test will be 'entity_event_on_join_level', and it will be in the 'events.entity' group + static void onJoinLevel(final EntityJoinLevelEvent event, final DynamicTest test) {} +} +``` + +### The `OnInit` annotation +Annotate a static method accepting exactly one parameter of `TestFrameworkInternal` (or parent interfaces) to +register that method as an on-init listener, which will be called in `TestFrameworkInternal#init` +The time when the listener will be called depends on the `value` (stage) given as an annotation parameter. + +### The `TestGroup` annotation +Annotate a `String` field with this annotation in order to configure the group with the ID being the underlying value of the field. +The parameters of the annotation: +- `name: String` - the human-readable name of the group; *required*; +- `enabledByDefault: boolean` - if the tests in the group are enabled by default; +- `parents: String[]` - the explicitly-declared parents of the group; + +Example usage for configuring the `events.level_related` group: +```java +@TestGroup(name = "Level-Related Events", enabledByDefault = true, parents = "level_tests") +public static final String LEVEL_RELATED_EVENTS = "events.level_related"; +``` + +### The `RegisterStructureTemplate` annotation +Annotate a static field containing either a `StructureTemplate`, a `Supplier` of `StructureTemplate`, or a `StructureTemplateBuilder` in order to automatically register that code-defined template. +The parameters of the annotation: +- `value: String` - the ID of the template; *required*. + +Example usage for registering a 5x5x5 empty structure template: +```java +@RegisterStructureTemplate("examplemod:empty_5x5") +public static final StructureTemplate EMPTY_5x5 = StructureTemplateBuilder.empty(5, 5, 5); +``` + +## GameTest Integration +The test system has integration with Mojang's GameTest. A test can supply the information required by the GameTest using `@Nullable Test#asGameTest`. The provided `GameTestData` will give the GameTest framework the data it requires. Note that the name of the GameTest is the test's ID, and if the provided `batchName` is null, then the batch of the test will be the ID of its first group. + +Default `GameTestData` providers: +- for basic tests using `AbstractTest`, override `onGameTest` and annotate it with `GameTest` (the annotation will be used to configure the `GameTestData` as vanilla does). That method will be run when the GameTest version of the test is run; +- for method-based tests, annotate the test method with `GameTest` to provide the configuration, and use `DynamicTest#onGameTest` to provide the gametest functionality; +- method-based event tests do not support this functionality! + +Example basic test with GameTest integration: +```java +@TestHolder("lever_test") +public class LeverTest extends AbstractTest { + @Override + @GameTest(template = "examplemod:lever_test_template") + protected void onGameTest(GameTestHelper helper) { + helper.startSequence() + .thenExecute(() -> helper.pullLever(0, 2, 0)) + .thenIdle(1) + .thenWaitUntil(0, () -> helper.assertBlockProperty(new BlockPos(0, 2, 0), LeverBlock.POWERED, true)) + .thenExecute(this::pass) // Pass the test if the lever is powered. If the assertion fails, the framework will make sure to fail the test. + .thenSucceed(); + } +} +``` + +Example method-based test with GameTest integration: +```java +@TestHolder("lever_test") +@GameTest(template = "examplemod:lever_test_template") +static void leverTest(final DynamicTest test) { + test.onGameTest(helper -> helper.startSequence() + .thenExecute(() -> helper.pullLever(0, 2, 0)) + .thenIdle(1) + .thenWaitUntil(0, () -> helper.assertBlockProperty(new BlockPos(0, 2, 0), LeverBlock.POWERED, true)) + .thenExecute(test::pass) // Pass the test if the lever is powered. If the assertion fails, the framework will make sure to fail the test. + .thenSucceed()); +} +``` + +In both examples above, you may register the template in-code, using: +```java +@RegisterStructureTemplate("examplemod:lever_test_template") +static final StructureTemplate LEVER_TEST_TEMPLATE = StructureTemplateBuilder.withSize(1, 2, 1) + .placeFloorLever(0, 1, 0, false) + .build(); +``` +or, if you want to use an empty template, you may use the `@EmptyTemplate` annotation, which accepts: +- a `value: String` - the size of the structure, in `LxHxW` format, defaulting to `3x3x3`; +- a `floor: boolean` - if `true`, the template will have an iron floor, as such increasing the height by one, defaulting to `false`. + +For a guide on GameTests, see [this guide](NEOGAMETESTS.md). \ No newline at end of file From 8d4a78de6917beaf12fe2b7641e39f947e032d3f Mon Sep 17 00:00:00 2001 From: Henry Loenwind Date: Thu, 8 Aug 2024 00:09:39 +0200 Subject: [PATCH 016/125] Enable keyboard navigation in mod list (#1393) --- .../neoforge/client/gui/ModListScreen.java | 2 +- .../client/gui/widget/ModListWidget.java | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java b/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java index 32289b81b6..e59f8f5ca5 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java @@ -359,7 +359,7 @@ public Font getFontRenderer() { } public void setSelected(ModListWidget.ModEntry entry) { - this.selected = entry == this.selected ? null : entry; + this.selected = entry; updateCache(); } diff --git a/src/main/java/net/neoforged/neoforge/client/gui/widget/ModListWidget.java b/src/main/java/net/neoforged/neoforge/client/gui/widget/ModListWidget.java index 1e1d3a656f..2411aec988 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/widget/ModListWidget.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/widget/ModListWidget.java @@ -86,11 +86,26 @@ public void render(GuiGraphics guiGraphics, int entryIdx, int top, int left, int @Override public boolean mouseClicked(double p_mouseClicked_1_, double p_mouseClicked_3_, int p_mouseClicked_5_) { - parent.setSelected(this); - ModListWidget.this.setSelected(this); + // clicking on a selected item a second time unselects it + parent.setSelected(isFocused() ? null : this); + ModListWidget.this.setSelected(isFocused() ? null : this); return false; } + @Override + public void setFocused(boolean focused) { + // ignore focus loss so the item stays selected when tabbing to the config button + if (focused) { + parent.setSelected(this); + ModListWidget.this.setSelected(this); + } + } + + @Override + public boolean isFocused() { + return ModListWidget.this.getSelected() == this; + } + public IModInfo getInfo() { return container.getModInfo(); } From 87875183dcd8239404cbddbe8717db1dbe4f64ee Mon Sep 17 00:00:00 2001 From: IThundxr Date: Thu, 8 Aug 2024 13:01:53 -0400 Subject: [PATCH 017/125] Waxing & Oxidizing DataMaps (#1406) --- .../data/recipes/RecipeProvider.java.patch | 10 ++ .../world/item/HoneycombItem.java.patch | 33 ++++++ .../level/block/WeatheringCopper.java.patch | 45 +++++++ .../neoforge/data_maps/block/oxidizables.json | 85 +++++++++++++ .../neoforge/data_maps/block/waxables.json | 112 ++++++++++++++++++ .../neoforge/common/DataMapHooks.java | 96 +++++++++++++++ .../neoforge/common/NeoForgeMod.java | 2 + .../internal/NeoForgeDataMapsProvider.java | 14 +++ .../common/extensions/IBlockExtension.java | 5 +- .../datamaps/builtin/NeoForgeDataMaps.java | 33 ++++++ .../datamaps/builtin/Oxidizable.java | 26 ++++ .../registries/datamaps/builtin/Waxable.java | 26 ++++ .../neoforge/data_maps/block/oxidizables.json | 7 ++ .../neoforge/data_maps/block/waxables.json | 7 ++ .../neoforge/debug/data/DataMapTests.java | 101 ++++++++++++++++ 15 files changed, 600 insertions(+), 2 deletions(-) create mode 100644 patches/net/minecraft/world/item/HoneycombItem.java.patch create mode 100644 patches/net/minecraft/world/level/block/WeatheringCopper.java.patch create mode 100644 src/generated/resources/data/neoforge/data_maps/block/oxidizables.json create mode 100644 src/generated/resources/data/neoforge/data_maps/block/waxables.json create mode 100644 src/main/java/net/neoforged/neoforge/common/DataMapHooks.java create mode 100644 src/main/java/net/neoforged/neoforge/registries/datamaps/builtin/Oxidizable.java create mode 100644 src/main/java/net/neoforged/neoforge/registries/datamaps/builtin/Waxable.java create mode 100644 tests/src/generated/resources/data/neoforge/data_maps/block/oxidizables.json create mode 100644 tests/src/generated/resources/data/neoforge/data_maps/block/waxables.json diff --git a/patches/net/minecraft/data/recipes/RecipeProvider.java.patch b/patches/net/minecraft/data/recipes/RecipeProvider.java.patch index b9d2ae0ca9..ec1d44e063 100644 --- a/patches/net/minecraft/data/recipes/RecipeProvider.java.patch +++ b/patches/net/minecraft/data/recipes/RecipeProvider.java.patch @@ -57,3 +57,13 @@ BlockFamilies.getAllFamilies().filter(BlockFamily::shouldGenerateRecipe).forEach(p_313461_ -> generateRecipes(p_301146_, p_313461_, p_251836_)); } +@@ -611,8 +_,7 @@ + } + + protected static void waxRecipes(RecipeOutput p_301254_, FeatureFlagSet p_313879_) { +- HoneycombItem.WAXABLES +- .get() ++ net.neoforged.neoforge.common.DataMapHooks.INVERSE_WAXABLES_DATAMAP + .forEach( + (p_337490_, p_337491_) -> { + if (p_337491_.requiredFeatures().isSubsetOf(p_313879_)) { diff --git a/patches/net/minecraft/world/item/HoneycombItem.java.patch b/patches/net/minecraft/world/item/HoneycombItem.java.patch new file mode 100644 index 0000000000..46a6d312b6 --- /dev/null +++ b/patches/net/minecraft/world/item/HoneycombItem.java.patch @@ -0,0 +1,33 @@ +--- a/net/minecraft/world/item/HoneycombItem.java ++++ b/net/minecraft/world/item/HoneycombItem.java +@@ -20,6 +_,10 @@ + import net.minecraft.world.level.gameevent.GameEvent; + + public class HoneycombItem extends Item implements SignApplicator { ++ /** ++ * @deprecated Neo: Use the {@link net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps#WAXABLES data map}, this field will be ignored in a future version ++ */ ++ @Deprecated + public static final Supplier> WAXABLES = Suppliers.memoize( + () -> ImmutableBiMap.builder() + .put(Blocks.COPPER_BLOCK, Blocks.WAXED_COPPER_BLOCK) +@@ -60,6 +_,10 @@ + .put(Blocks.OXIDIZED_COPPER_BULB, Blocks.WAXED_OXIDIZED_COPPER_BULB) + .build() + ); ++ /** ++ * @deprecated Use the {@link net.neoforged.neoforge.common.DataMapHooks#INVERSE_WAXABLES_DATAMAP inverse map} generated from the data map, this field will be ignored in a future version ++ */ ++ @Deprecated + public static final Supplier> WAX_OFF_BY_BLOCK = Suppliers.memoize(() -> WAXABLES.get().inverse()); + + public HoneycombItem(Item.Properties p_150867_) { +@@ -87,7 +_,7 @@ + } + + public static Optional getWaxed(BlockState p_150879_) { +- return Optional.ofNullable(WAXABLES.get().get(p_150879_.getBlock())).map(p_150877_ -> p_150877_.withPropertiesOf(p_150879_)); ++ return Optional.ofNullable(net.neoforged.neoforge.common.DataMapHooks.getBlockWaxed(p_150879_.getBlock())).map(p_150877_ -> p_150877_.withPropertiesOf(p_150879_)); + } + + @Override diff --git a/patches/net/minecraft/world/level/block/WeatheringCopper.java.patch b/patches/net/minecraft/world/level/block/WeatheringCopper.java.patch new file mode 100644 index 0000000000..2efc36e582 --- /dev/null +++ b/patches/net/minecraft/world/level/block/WeatheringCopper.java.patch @@ -0,0 +1,45 @@ +--- a/net/minecraft/world/level/block/WeatheringCopper.java ++++ b/net/minecraft/world/level/block/WeatheringCopper.java +@@ -10,6 +_,10 @@ + import net.minecraft.world.level.block.state.BlockState; + + public interface WeatheringCopper extends ChangeOverTimeBlock { ++ /** ++ * @deprecated Neo: Use {@link net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps#OXIDIZABLES the data map}, this field will be ignored in a future version ++ */ ++ @Deprecated + Supplier> NEXT_BY_BLOCK = Suppliers.memoize( + () -> ImmutableBiMap.builder() + .put(Blocks.COPPER_BLOCK, Blocks.EXPOSED_COPPER) +@@ -41,16 +_,20 @@ + .put(Blocks.WEATHERED_COPPER_BULB, Blocks.OXIDIZED_COPPER_BULB) + .build() + ); ++ /** ++ * @deprecated Neo: Use the {@link net.neoforged.neoforge.common.DataMapHooks#INVERSE_OXIDIZABLES_DATAMAP inverse map} generated from the data map, this field will be ignored in a future version ++ */ ++ @Deprecated + Supplier> PREVIOUS_BY_BLOCK = Suppliers.memoize(() -> NEXT_BY_BLOCK.get().inverse()); + + static Optional getPrevious(Block p_154891_) { +- return Optional.ofNullable(PREVIOUS_BY_BLOCK.get().get(p_154891_)); ++ return Optional.ofNullable(net.neoforged.neoforge.common.DataMapHooks.getPreviousOxidizedStage(p_154891_)); + } + + static Block getFirst(Block p_154898_) { + Block block = p_154898_; + +- for (Block block1 = PREVIOUS_BY_BLOCK.get().get(p_154898_); block1 != null; block1 = PREVIOUS_BY_BLOCK.get().get(block1)) { ++ for (Block block1 = net.neoforged.neoforge.common.DataMapHooks.getPreviousOxidizedStage(p_154898_); block1 != null; block1 = net.neoforged.neoforge.common.DataMapHooks.getPreviousOxidizedStage(block1)) { + block = block1; + } + +@@ -62,7 +_,7 @@ + } + + static Optional getNext(Block p_154905_) { +- return Optional.ofNullable(NEXT_BY_BLOCK.get().get(p_154905_)); ++ return Optional.ofNullable(net.neoforged.neoforge.common.DataMapHooks.getNextOxidizedStage(p_154905_)); + } + + static BlockState getFirst(BlockState p_154907_) { diff --git a/src/generated/resources/data/neoforge/data_maps/block/oxidizables.json b/src/generated/resources/data/neoforge/data_maps/block/oxidizables.json new file mode 100644 index 0000000000..77202e8199 --- /dev/null +++ b/src/generated/resources/data/neoforge/data_maps/block/oxidizables.json @@ -0,0 +1,85 @@ +{ + "values": { + "minecraft:chiseled_copper": { + "next_oxidation_stage": "minecraft:exposed_chiseled_copper" + }, + "minecraft:copper_block": { + "next_oxidation_stage": "minecraft:exposed_copper" + }, + "minecraft:copper_bulb": { + "next_oxidation_stage": "minecraft:exposed_copper_bulb" + }, + "minecraft:copper_door": { + "next_oxidation_stage": "minecraft:exposed_copper_door" + }, + "minecraft:copper_grate": { + "next_oxidation_stage": "minecraft:exposed_copper_grate" + }, + "minecraft:copper_trapdoor": { + "next_oxidation_stage": "minecraft:exposed_copper_trapdoor" + }, + "minecraft:cut_copper": { + "next_oxidation_stage": "minecraft:exposed_cut_copper" + }, + "minecraft:cut_copper_slab": { + "next_oxidation_stage": "minecraft:exposed_cut_copper_slab" + }, + "minecraft:cut_copper_stairs": { + "next_oxidation_stage": "minecraft:exposed_cut_copper_stairs" + }, + "minecraft:exposed_chiseled_copper": { + "next_oxidation_stage": "minecraft:weathered_chiseled_copper" + }, + "minecraft:exposed_copper": { + "next_oxidation_stage": "minecraft:weathered_copper" + }, + "minecraft:exposed_copper_bulb": { + "next_oxidation_stage": "minecraft:weathered_copper_bulb" + }, + "minecraft:exposed_copper_door": { + "next_oxidation_stage": "minecraft:weathered_copper_door" + }, + "minecraft:exposed_copper_grate": { + "next_oxidation_stage": "minecraft:weathered_copper_grate" + }, + "minecraft:exposed_copper_trapdoor": { + "next_oxidation_stage": "minecraft:weathered_copper_trapdoor" + }, + "minecraft:exposed_cut_copper": { + "next_oxidation_stage": "minecraft:weathered_cut_copper" + }, + "minecraft:exposed_cut_copper_slab": { + "next_oxidation_stage": "minecraft:weathered_cut_copper_slab" + }, + "minecraft:exposed_cut_copper_stairs": { + "next_oxidation_stage": "minecraft:weathered_cut_copper_stairs" + }, + "minecraft:weathered_chiseled_copper": { + "next_oxidation_stage": "minecraft:oxidized_chiseled_copper" + }, + "minecraft:weathered_copper": { + "next_oxidation_stage": "minecraft:oxidized_copper" + }, + "minecraft:weathered_copper_bulb": { + "next_oxidation_stage": "minecraft:oxidized_copper_bulb" + }, + "minecraft:weathered_copper_door": { + "next_oxidation_stage": "minecraft:oxidized_copper_door" + }, + "minecraft:weathered_copper_grate": { + "next_oxidation_stage": "minecraft:oxidized_copper_grate" + }, + "minecraft:weathered_copper_trapdoor": { + "next_oxidation_stage": "minecraft:oxidized_copper_trapdoor" + }, + "minecraft:weathered_cut_copper": { + "next_oxidation_stage": "minecraft:oxidized_cut_copper" + }, + "minecraft:weathered_cut_copper_slab": { + "next_oxidation_stage": "minecraft:oxidized_cut_copper_slab" + }, + "minecraft:weathered_cut_copper_stairs": { + "next_oxidation_stage": "minecraft:oxidized_cut_copper_stairs" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/data/neoforge/data_maps/block/waxables.json b/src/generated/resources/data/neoforge/data_maps/block/waxables.json new file mode 100644 index 0000000000..da63fb4c2d --- /dev/null +++ b/src/generated/resources/data/neoforge/data_maps/block/waxables.json @@ -0,0 +1,112 @@ +{ + "values": { + "minecraft:chiseled_copper": { + "waxed": "minecraft:waxed_chiseled_copper" + }, + "minecraft:copper_block": { + "waxed": "minecraft:waxed_copper_block" + }, + "minecraft:copper_bulb": { + "waxed": "minecraft:waxed_copper_bulb" + }, + "minecraft:copper_door": { + "waxed": "minecraft:waxed_copper_door" + }, + "minecraft:copper_grate": { + "waxed": "minecraft:waxed_copper_grate" + }, + "minecraft:copper_trapdoor": { + "waxed": "minecraft:waxed_copper_trapdoor" + }, + "minecraft:cut_copper": { + "waxed": "minecraft:waxed_cut_copper" + }, + "minecraft:cut_copper_slab": { + "waxed": "minecraft:waxed_cut_copper_slab" + }, + "minecraft:cut_copper_stairs": { + "waxed": "minecraft:waxed_cut_copper_stairs" + }, + "minecraft:exposed_chiseled_copper": { + "waxed": "minecraft:waxed_exposed_chiseled_copper" + }, + "minecraft:exposed_copper": { + "waxed": "minecraft:waxed_exposed_copper" + }, + "minecraft:exposed_copper_bulb": { + "waxed": "minecraft:waxed_exposed_copper_bulb" + }, + "minecraft:exposed_copper_door": { + "waxed": "minecraft:waxed_exposed_copper_door" + }, + "minecraft:exposed_copper_grate": { + "waxed": "minecraft:waxed_exposed_copper_grate" + }, + "minecraft:exposed_copper_trapdoor": { + "waxed": "minecraft:waxed_exposed_copper_trapdoor" + }, + "minecraft:exposed_cut_copper": { + "waxed": "minecraft:waxed_exposed_cut_copper" + }, + "minecraft:exposed_cut_copper_slab": { + "waxed": "minecraft:waxed_exposed_cut_copper_slab" + }, + "minecraft:exposed_cut_copper_stairs": { + "waxed": "minecraft:waxed_exposed_cut_copper_stairs" + }, + "minecraft:oxidized_chiseled_copper": { + "waxed": "minecraft:waxed_oxidized_chiseled_copper" + }, + "minecraft:oxidized_copper": { + "waxed": "minecraft:waxed_oxidized_copper" + }, + "minecraft:oxidized_copper_bulb": { + "waxed": "minecraft:waxed_oxidized_copper_bulb" + }, + "minecraft:oxidized_copper_door": { + "waxed": "minecraft:waxed_oxidized_copper_door" + }, + "minecraft:oxidized_copper_grate": { + "waxed": "minecraft:waxed_oxidized_copper_grate" + }, + "minecraft:oxidized_copper_trapdoor": { + "waxed": "minecraft:waxed_oxidized_copper_trapdoor" + }, + "minecraft:oxidized_cut_copper": { + "waxed": "minecraft:waxed_oxidized_cut_copper" + }, + "minecraft:oxidized_cut_copper_slab": { + "waxed": "minecraft:waxed_oxidized_cut_copper_slab" + }, + "minecraft:oxidized_cut_copper_stairs": { + "waxed": "minecraft:waxed_oxidized_cut_copper_stairs" + }, + "minecraft:weathered_chiseled_copper": { + "waxed": "minecraft:waxed_weathered_chiseled_copper" + }, + "minecraft:weathered_copper": { + "waxed": "minecraft:waxed_weathered_copper" + }, + "minecraft:weathered_copper_bulb": { + "waxed": "minecraft:waxed_weathered_copper_bulb" + }, + "minecraft:weathered_copper_door": { + "waxed": "minecraft:waxed_weathered_copper_door" + }, + "minecraft:weathered_copper_grate": { + "waxed": "minecraft:waxed_weathered_copper_grate" + }, + "minecraft:weathered_copper_trapdoor": { + "waxed": "minecraft:waxed_weathered_copper_trapdoor" + }, + "minecraft:weathered_cut_copper": { + "waxed": "minecraft:waxed_weathered_cut_copper" + }, + "minecraft:weathered_cut_copper_slab": { + "waxed": "minecraft:waxed_weathered_cut_copper_slab" + }, + "minecraft:weathered_cut_copper_stairs": { + "waxed": "minecraft:waxed_weathered_cut_copper_stairs" + } + } +} \ No newline at end of file diff --git a/src/main/java/net/neoforged/neoforge/common/DataMapHooks.java b/src/main/java/net/neoforged/neoforge/common/DataMapHooks.java new file mode 100644 index 0000000000..5b61e8a4a2 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/common/DataMapHooks.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.common; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.world.item.HoneycombItem; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.WeatheringCopper; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.neoforge.registries.datamaps.DataMapsUpdatedEvent; +import net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps; +import net.neoforged.neoforge.registries.datamaps.builtin.Oxidizable; +import net.neoforged.neoforge.registries.datamaps.builtin.Waxable; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +// TODO: 1.21.2 remove fallback to vanilla map for waxing and oxidizing +public class DataMapHooks { + // will be removed in 1.21.2 + /** Used in a gametest */ + @ApiStatus.Internal + public static boolean didHaveToFallbackToVanillaMaps = false; + + private static final Map INVERSE_OXIDIZABLES_DATAMAP_INTERNAL = new HashMap<>(); + private static final Map INVERSE_WAXABLES_DATAMAP_INTERNAL = new HashMap<>(); + + /** The inverse map of the oxidizables data map, used in vanilla when scraping oxidization off of a block */ + public static final Map INVERSE_OXIDIZABLES_DATAMAP = Collections.unmodifiableMap(INVERSE_OXIDIZABLES_DATAMAP_INTERNAL); + /** The inverse map of the waxables data map, used in vanilla when scraping wax off of a block */ + public static final Map INVERSE_WAXABLES_DATAMAP = Collections.unmodifiableMap(INVERSE_WAXABLES_DATAMAP_INTERNAL); + + @Nullable + @SuppressWarnings("deprecation") + public static Block getNextOxidizedStage(Block block) { + Oxidizable oxidizable = block.builtInRegistryHolder().getData(NeoForgeDataMaps.OXIDIZABLES); + return oxidizable != null ? oxidizable.nextOxidationStage() : WeatheringCopper.NEXT_BY_BLOCK.get().get(block); + } + + @Nullable + @SuppressWarnings("deprecation") + public static Block getPreviousOxidizedStage(Block block) { + return INVERSE_OXIDIZABLES_DATAMAP.containsKey(block) ? INVERSE_OXIDIZABLES_DATAMAP.get(block) : WeatheringCopper.PREVIOUS_BY_BLOCK.get().get(block); + } + + @Nullable + @SuppressWarnings("deprecation") + public static Block getBlockWaxed(Block block) { + Waxable waxable = block.builtInRegistryHolder().getData(NeoForgeDataMaps.WAXABLES); + return waxable != null ? waxable.waxed() : HoneycombItem.WAXABLES.get().get(block); + } + + @Nullable + @SuppressWarnings("deprecation") + public static Block getBlockUnwaxed(Block block) { + return INVERSE_WAXABLES_DATAMAP.containsKey(block) ? INVERSE_WAXABLES_DATAMAP.get(block) : HoneycombItem.WAX_OFF_BY_BLOCK.get().get(block); + } + + @SubscribeEvent + static void onDataMapsUpdated(DataMapsUpdatedEvent event) { + event.ifRegistry(Registries.BLOCK, registry -> { + INVERSE_OXIDIZABLES_DATAMAP_INTERNAL.clear(); + INVERSE_WAXABLES_DATAMAP_INTERNAL.clear(); + + registry.getDataMap(NeoForgeDataMaps.OXIDIZABLES).forEach((resourceKey, oxidizable) -> { + INVERSE_OXIDIZABLES_DATAMAP_INTERNAL.put(oxidizable.nextOxidationStage(), BuiltInRegistries.BLOCK.get(resourceKey)); + }); + + //noinspection deprecation + WeatheringCopper.PREVIOUS_BY_BLOCK.get().forEach((after, before) -> { + if (!INVERSE_OXIDIZABLES_DATAMAP_INTERNAL.containsKey(after)) { + INVERSE_OXIDIZABLES_DATAMAP_INTERNAL.put(after, before); + didHaveToFallbackToVanillaMaps = true; + } + }); + + registry.getDataMap(NeoForgeDataMaps.WAXABLES).forEach((resourceKey, waxable) -> { + INVERSE_WAXABLES_DATAMAP_INTERNAL.put(waxable.waxed(), BuiltInRegistries.BLOCK.get(resourceKey)); + }); + + //noinspection deprecation + HoneycombItem.WAX_OFF_BY_BLOCK.get().forEach((after, before) -> { + if (!INVERSE_WAXABLES_DATAMAP_INTERNAL.containsKey(after)) { + INVERSE_OXIDIZABLES_DATAMAP_INTERNAL.put(after, before); + didHaveToFallbackToVanillaMaps = true; + } + }); + }); + } +} diff --git a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java index c564c80654..3c0ca35bb5 100644 --- a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java @@ -563,6 +563,8 @@ public NeoForgeMod(IEventBus modEventBus, Dist dist, ModContainer container) { NeoForge.EVENT_BUS.addListener(CapabilityHooks::invalidateCapsOnChunkUnload); NeoForge.EVENT_BUS.addListener(CapabilityHooks::cleanCapabilityListenerReferencesOnTick); + NeoForge.EVENT_BUS.addListener(DataMapHooks::onDataMapsUpdated); + modEventBus.register(NeoForgeDataMaps.class); if (isPRBuild(container.getModInfo().getVersion().toString())) { diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeDataMapsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeDataMapsProvider.java index c94cc2a5ca..9e5604aa69 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeDataMapsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeDataMapsProvider.java @@ -24,8 +24,10 @@ import net.minecraft.world.entity.ai.behavior.WorkAtComposter; import net.minecraft.world.entity.animal.Parrot; import net.minecraft.world.entity.npc.VillagerProfession; +import net.minecraft.world.item.HoneycombItem; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.ComposterBlock; +import net.minecraft.world.level.block.WeatheringCopper; import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity; import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.gameevent.vibrations.VibrationSystem; @@ -37,9 +39,11 @@ import net.neoforged.neoforge.registries.datamaps.builtin.FurnaceFuel; import net.neoforged.neoforge.registries.datamaps.builtin.MonsterRoomMob; import net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps; +import net.neoforged.neoforge.registries.datamaps.builtin.Oxidizable; import net.neoforged.neoforge.registries.datamaps.builtin.ParrotImitation; import net.neoforged.neoforge.registries.datamaps.builtin.RaidHeroGift; import net.neoforged.neoforge.registries.datamaps.builtin.VibrationFrequency; +import net.neoforged.neoforge.registries.datamaps.builtin.Waxable; public class NeoForgeDataMapsProvider extends DataMapProvider { public NeoForgeDataMapsProvider(PackOutput packOutput, CompletableFuture lookupProvider) { @@ -74,5 +78,15 @@ protected void gather() { Arrays.stream(ObfuscationReflectionHelper.[], MonsterRoomFeature>getPrivateValue(MonsterRoomFeature.class, null, "MOBS")) .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) .forEach((type, weight) -> monsterRoomMobs.add(BuiltInRegistries.ENTITY_TYPE.wrapAsHolder(type), new MonsterRoomMob(Weight.of((int) (weight * 100))), false)); + + final var oxidizables = builder(NeoForgeDataMaps.OXIDIZABLES); + WeatheringCopper.NEXT_BY_BLOCK.get().forEach((now, after) -> { + oxidizables.add(now.builtInRegistryHolder(), new Oxidizable(after), false); + }); + + final var waxables = builder(NeoForgeDataMaps.WAXABLES); + HoneycombItem.WAXABLES.get().forEach((now, after) -> { + waxables.add(now.builtInRegistryHolder(), new Waxable(after), false); + }); } } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockExtension.java index de277227ea..f193bfff1e 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockExtension.java @@ -27,7 +27,6 @@ import net.minecraft.world.entity.projectile.FishingHook; import net.minecraft.world.entity.projectile.WitherSkull; import net.minecraft.world.item.AxeItem; -import net.minecraft.world.item.HoneycombItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.ShovelItem; @@ -80,6 +79,7 @@ import net.neoforged.neoforge.capabilities.BlockCapabilityCache; import net.neoforged.neoforge.client.ClientHooks; import net.neoforged.neoforge.client.model.data.ModelData; +import net.neoforged.neoforge.common.DataMapHooks; import net.neoforged.neoforge.common.ItemAbilities; import net.neoforged.neoforge.common.ItemAbility; import net.neoforged.neoforge.common.enums.BubbleColumnDirection; @@ -772,7 +772,8 @@ default BlockState getToolModifiedState(BlockState state, UseOnContext context, } else if (ItemAbilities.AXE_SCRAPE == itemAbility) { return WeatheringCopper.getPrevious(state).orElse(null); } else if (ItemAbilities.AXE_WAX_OFF == itemAbility) { - return Optional.ofNullable(HoneycombItem.WAX_OFF_BY_BLOCK.get().get(state.getBlock())).map(block -> block.withPropertiesOf(state)).orElse(null); + Block waxOffBlock = DataMapHooks.getBlockUnwaxed(state.getBlock()); + return Optional.ofNullable(waxOffBlock).map(block -> block.withPropertiesOf(state)).orElse(null); } else if (ItemAbilities.SHOVEL_FLATTEN == itemAbility) { return ShovelItem.getShovelPathingState(state); } else if (ItemAbilities.HOE_TILL == itemAbility) { diff --git a/src/main/java/net/neoforged/neoforge/registries/datamaps/builtin/NeoForgeDataMaps.java b/src/main/java/net/neoforged/neoforge/registries/datamaps/builtin/NeoForgeDataMaps.java index 42f962de79..330857d541 100644 --- a/src/main/java/net/neoforged/neoforge/registries/datamaps/builtin/NeoForgeDataMaps.java +++ b/src/main/java/net/neoforged/neoforge/registries/datamaps/builtin/NeoForgeDataMaps.java @@ -11,15 +11,20 @@ import net.minecraft.world.entity.ai.behavior.GiveGiftToHero; import net.minecraft.world.entity.animal.Parrot; import net.minecraft.world.entity.npc.VillagerProfession; +import net.minecraft.world.item.HoneycombItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.ComposterBlock; +import net.minecraft.world.level.block.WeatheringCopper; import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity; import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.gameevent.vibrations.VibrationSystem; import net.minecraft.world.level.levelgen.feature.MonsterRoomFeature; import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.neoforge.common.DataMapHooks; +import net.neoforged.neoforge.common.ItemAbilities; import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion; import net.neoforged.neoforge.registries.datamaps.DataMapType; import net.neoforged.neoforge.registries.datamaps.RegisterDataMapTypesEvent; @@ -73,6 +78,19 @@ public class NeoForgeDataMaps { public static final DataMapType, MonsterRoomMob> MONSTER_ROOM_MOBS = DataMapType.builder( id("monster_room_mobs"), Registries.ENTITY_TYPE, MonsterRoomMob.CODEC).synced(MonsterRoomMob.WEIGHT_CODEC, false).build(); + /** + * The {@linkplain Block} data map that replaces {@link WeatheringCopper#NEXT_BY_BLOCK}. + *

+ * The location of this data map is {@code neoforge/data_maps/block/oxidizables.json}, and the values are objects with 1 field: + *

    + *
  • {@code next_oxidized_stage}, a block that the object should convert into once it changes oxidizing states
  • + *
+ * + * The inverted map of this can be found at {@link DataMapHooks#getInverseOxidizablesMap()} + */ + public static final DataMapType OXIDIZABLES = DataMapType.builder( + id("oxidizables"), Registries.BLOCK, Oxidizable.CODEC).synced(Oxidizable.OXIDIZABLE_CODEC, false).build(); + /** * The {@linkplain EntityType} data map that replaces {@link Parrot#MOB_SOUND_MAP}. *

@@ -110,6 +128,19 @@ public class NeoForgeDataMaps { public static final DataMapType VIBRATION_FREQUENCIES = DataMapType.builder( id("vibration_frequencies"), Registries.GAME_EVENT, VibrationFrequency.CODEC).synced(VibrationFrequency.FREQUENCY_CODEC, false).build(); + /** + * The {@linkplain Block} data map that replaces {@link HoneycombItem#WAXABLES}. + *

+ * The location of this data map is {@code neoforge/data_maps/block/waxables.json}, and the values are objects with 1 field: + *

    + *
  • {@code waxed}, a block that the object should convert into once it is right clicked with a {@link ItemAbilities#AXE_WAX_OFF} ability
  • + *
+ * + * The inverted map of this can be found at {@link DataMapHooks#INVERSE_WAXABLES_DATAMAP} + */ + public static final DataMapType WAXABLES = DataMapType.builder( + id("waxables"), Registries.BLOCK, Waxable.CODEC).synced(Waxable.WAXABLE_CODEC, false).build(); + private static ResourceLocation id(final String name) { return ResourceLocation.fromNamespaceAndPath(NeoForgeVersion.MOD_ID, name); } @@ -119,8 +150,10 @@ private static void register(final RegisterDataMapTypesEvent event) { event.register(COMPOSTABLES); event.register(FURNACE_FUELS); event.register(MONSTER_ROOM_MOBS); + event.register(OXIDIZABLES); event.register(PARROT_IMITATIONS); event.register(RAID_HERO_GIFTS); event.register(VIBRATION_FREQUENCIES); + event.register(WAXABLES); } } diff --git a/src/main/java/net/neoforged/neoforge/registries/datamaps/builtin/Oxidizable.java b/src/main/java/net/neoforged/neoforge/registries/datamaps/builtin/Oxidizable.java new file mode 100644 index 0000000000..471c6e401e --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/registries/datamaps/builtin/Oxidizable.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.registries.datamaps.builtin; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.level.block.Block; + +/** + * Data map value for {@linkplain NeoForgeDataMaps#OXIDIZABLES oxidizable blocks} allowing mods to easily register basic + * oxidizing interactions for their blocks. + * + * @param nextOxidationStage the block that the key value will transform into when its oxidation stage changes + */ +public record Oxidizable(Block nextOxidationStage) { + public static final Codec OXIDIZABLE_CODEC = BuiltInRegistries.BLOCK.byNameCodec() + .xmap(Oxidizable::new, Oxidizable::nextOxidationStage); + public static final Codec CODEC = Codec.withAlternative( + RecordCodecBuilder.create(in -> in.group( + BuiltInRegistries.BLOCK.byNameCodec().fieldOf("next_oxidation_stage").forGetter(Oxidizable::nextOxidationStage)).apply(in, Oxidizable::new)), + OXIDIZABLE_CODEC); +} diff --git a/src/main/java/net/neoforged/neoforge/registries/datamaps/builtin/Waxable.java b/src/main/java/net/neoforged/neoforge/registries/datamaps/builtin/Waxable.java new file mode 100644 index 0000000000..0c30cf8c39 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/registries/datamaps/builtin/Waxable.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.registries.datamaps.builtin; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.level.block.Block; + +/** + * Data map value for {@linkplain NeoForgeDataMaps#WAXABLES waxable blocks} allowing mods to easily register basic + * waxing interactions for their blocks. + * + * @param waxed the block that the key value will transform into when waxed with a honeycomb + */ +public record Waxable(Block waxed) { + public static final Codec WAXABLE_CODEC = BuiltInRegistries.BLOCK.byNameCodec() + .xmap(Waxable::new, Waxable::waxed); + public static final Codec CODEC = Codec.withAlternative( + RecordCodecBuilder.create(in -> in.group( + BuiltInRegistries.BLOCK.byNameCodec().fieldOf("waxed").forGetter(Waxable::waxed)).apply(in, Waxable::new)), + WAXABLE_CODEC); +} diff --git a/tests/src/generated/resources/data/neoforge/data_maps/block/oxidizables.json b/tests/src/generated/resources/data/neoforge/data_maps/block/oxidizables.json new file mode 100644 index 0000000000..c34d68020a --- /dev/null +++ b/tests/src/generated/resources/data/neoforge/data_maps/block/oxidizables.json @@ -0,0 +1,7 @@ +{ + "values": { + "neotests_oxidizables_and_waxables_map_test:lightly_oxidized_iron": { + "next_oxidation_stage": "neotests_oxidizables_and_waxables_map_test:more_oxidized_iron" + } + } +} \ No newline at end of file diff --git a/tests/src/generated/resources/data/neoforge/data_maps/block/waxables.json b/tests/src/generated/resources/data/neoforge/data_maps/block/waxables.json new file mode 100644 index 0000000000..5ed8b1c096 --- /dev/null +++ b/tests/src/generated/resources/data/neoforge/data_maps/block/waxables.json @@ -0,0 +1,7 @@ +{ + "values": { + "neotests_oxidizables_and_waxables_map_test:lightly_oxidized_iron": { + "waxed": "neotests_oxidizables_and_waxables_map_test:lightly_oxidized_waxed_iron" + } + } +} \ No newline at end of file diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/data/DataMapTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/data/DataMapTests.java index bc28fee373..5e7c5bbfb3 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/data/DataMapTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/data/DataMapTests.java @@ -17,6 +17,8 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; import net.minecraft.gametest.framework.GameTest; @@ -31,10 +33,16 @@ import net.minecraft.world.damagesource.DamageType; import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.HoneycombItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.ComposterBlock; +import net.minecraft.world.level.block.WeatheringCopper; +import net.minecraft.world.level.block.WeatheringCopperFullBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.neoforged.neoforge.common.DataMapHooks; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.common.data.DataMapProvider; import net.neoforged.neoforge.debug.EventTests; @@ -49,6 +57,8 @@ import net.neoforged.neoforge.registries.datamaps.RegisterDataMapTypesEvent; import net.neoforged.neoforge.registries.datamaps.builtin.Compostable; import net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps; +import net.neoforged.neoforge.registries.datamaps.builtin.Oxidizable; +import net.neoforged.neoforge.registries.datamaps.builtin.Waxable; import net.neoforged.testframework.DynamicTest; import net.neoforged.testframework.annotation.ForEachTest; import net.neoforged.testframework.annotation.TestHolder; @@ -347,6 +357,97 @@ protected void gather() { }); } + /* + * 1. Lightly Oxidized Iron should oxidize into More Oxidized Iron + * 2. Lightly Oxidized Iron should wax into Lightly Oxidized Waxed Iron + * 3. Lightly Oxidized Waxed Iron should scrape off into Lightly Oxidized Iron + */ + @SuppressWarnings("DataFlowIssue") + @GameTest + @EmptyTemplate + @TestHolder(description = "Tests if existing and custom oxidizables and waxables work") + static void oxidizablesAndWaxablesMapTest(final DynamicTest test, final RegistrationHelper reg) { + BlockPos blockPos = new BlockPos(1, 1, 1); + + Holder lightlyOxidizedIron = reg.blocks().register("lightly_oxidized_iron", () -> new WeatheringCopperFullBlock(WeatheringCopper.WeatherState.EXPOSED, BlockBehaviour.Properties.of())); + Holder moreOxidizedIron = reg.blocks().register("more_oxidized_iron", () -> new WeatheringCopperFullBlock(WeatheringCopper.WeatherState.WEATHERED, BlockBehaviour.Properties.of())); + + Holder lightlyOxidizedWaxedIron = reg.blocks().register("lightly_oxidized_waxed_iron", () -> new Block(BlockBehaviour.Properties.of())); + + reg.addProvider(event -> new DataMapProvider(event.getGenerator().getPackOutput(), event.getLookupProvider()) { + @Override + protected void gather() { + builder(NeoForgeDataMaps.OXIDIZABLES) + .add(lightlyOxidizedIron, new Oxidizable(moreOxidizedIron.value()), false); + + builder(NeoForgeDataMaps.WAXABLES) + .add(lightlyOxidizedIron, new Waxable(lightlyOxidizedWaxedIron.value()), false); + } + }); + test.onGameTest(helper -> { + helper.assertFalse( + DataMapHooks.didHaveToFallbackToVanillaMaps, + "The Oxidizable and Waxable Data Map's should not have to fallback to vanilla maps in this gametest, something is very wrong!"); + + // -------------- Test added blocks -------------- \\ + // Test Lightly Oxidized Iron -> More Oxidized Iron + helper.setBlock(blockPos, lightlyOxidizedIron.value()); + if (DataMapHooks.getNextOxidizedStage(lightlyOxidizedIron.value()) == null) + helper.fail("Next oxidization state for lightly oxidized iron was null!"); + helper.setBlock(blockPos, DataMapHooks.getNextOxidizedStage(lightlyOxidizedIron.value())); + helper.assertBlock(blockPos, block -> moreOxidizedIron.value().equals(block), "Wanted: More Oxidized Iron but found something else!"); + + // Test Lightly Oxidized Iron -> Lightly Oxidized Waxed Iron + helper.setBlock(blockPos, lightlyOxidizedIron.value()); + if (DataMapHooks.getBlockWaxed(lightlyOxidizedIron.value()) == null) + helper.fail("Waxed state for lightly oxidized iron was null!"); + helper.setBlock(blockPos, DataMapHooks.getBlockWaxed(lightlyOxidizedIron.value())); + helper.assertBlock(blockPos, block -> lightlyOxidizedWaxedIron.value().equals(block), "Wanted: Lightly Oxidized Waxed Iron but found something else!"); + + // Test Lightly Oxidized Waxed Iron -> Lightly Oxidized Iron + helper.useOn(blockPos, Items.IRON_AXE.getDefaultInstance(), helper.makeMockPlayer(), Direction.NORTH); + helper.assertBlock(blockPos, block -> lightlyOxidizedIron.value().equals(block), "Wanted: Lightly Oxidized Iron but found something else!"); + + // -------------- Test vanilla blocks -------------- \\ + // Test Block of Copper -> Exposed Copper + helper.setBlock(blockPos, Blocks.COPPER_BLOCK); + if (DataMapHooks.getNextOxidizedStage(Blocks.COPPER_BLOCK) == null) + helper.fail("Next oxidization state for copper block was null!"); + helper.setBlock(blockPos, DataMapHooks.getNextOxidizedStage(Blocks.COPPER_BLOCK)); + helper.assertBlock(blockPos, Blocks.EXPOSED_COPPER::equals, "Wanted: Exposed Copper but found something else!"); + + // Test Block of Copper -> Waxed Block of Copper + helper.setBlock(blockPos, Blocks.COPPER_BLOCK); + if (DataMapHooks.getBlockWaxed(Blocks.COPPER_BLOCK) == null) + helper.fail("Waxed state for block of copper was null!"); + helper.setBlock(blockPos, DataMapHooks.getBlockWaxed(Blocks.COPPER_BLOCK)); + helper.assertBlock(blockPos, Blocks.WAXED_COPPER_BLOCK::equals, "Wanted: Waxed Copper of Block but found something else!"); + + // Test Waxed Block of Copper -> Block of Copper + helper.useOn(blockPos, Items.IRON_AXE.getDefaultInstance(), helper.makeMockPlayer(), Direction.NORTH); + helper.assertBlock(blockPos, Blocks.COPPER_BLOCK::equals, "Wanted: Block of Copper but found something else!"); + + // Test vanilla stuff + WeatheringCopper.NEXT_BY_BLOCK.get().forEach((before, after) -> { + helper.assertValueEqual(DataMapHooks.getNextOxidizedStage(before), after, "next oxidized stage of " + before.getName()); + }); + + WeatheringCopper.PREVIOUS_BY_BLOCK.get().forEach((after, before) -> { + helper.assertValueEqual(DataMapHooks.getPreviousOxidizedStage(after), before, "previous oxidized stage of " + before.getName()); + }); + + HoneycombItem.WAXABLES.get().forEach((before, after) -> { + helper.assertValueEqual(DataMapHooks.getBlockWaxed(before), after, "waxed version of " + before.getName()); + }); + + HoneycombItem.WAX_OFF_BY_BLOCK.get().forEach((after, before) -> { + helper.assertValueEqual(DataMapHooks.getBlockUnwaxed(after), before, "unwaxed version of " + before.getName()); + }); + + helper.succeed(); + }); + } + public record SomeObject( int intValue, String stringValue) { From 58b206b69b8a897ccb7169ab5b70a1f2534f7df2 Mon Sep 17 00:00:00 2001 From: Sebastian Hartte Date: Wed, 7 Aug 2024 18:53:31 +0200 Subject: [PATCH 018/125] Port to 1.21.1 and mark it as compatible with 1.21 --- gradle.properties | 6 ++--- .../arguments/EntityArgument.java.patch | 4 ++-- .../arguments/MessageArgument.java.patch | 4 ++-- .../selector/EntitySelectorParser.java.patch | 4 ++-- .../level/block/SculkSensorBlock.java.patch | 2 +- .../level/block/entity/BlockEntity.java.patch | 12 +++++----- .../world/level/chunk/LevelChunk.java.patch | 24 +++++++++---------- .../neoforge/common/CommonHooks.java | 4 ++-- 8 files changed, 30 insertions(+), 30 deletions(-) diff --git a/gradle.properties b/gradle.properties index 667bff0378..8022687928 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,8 +9,8 @@ org.gradle.debug=false java_version=21 -minecraft_version=1.21 -neoform_version=20240613.152323 +minecraft_version=1.21.1 +neoform_version=20240808.144430 # on snapshot versions, used to prefix the version neoforge_snapshot_next_stable=22.0 @@ -30,7 +30,7 @@ jetbrains_annotations_version=24.0.1 slf4j_api_version=2.0.7 apache_maven_artifact_version=3.8.5 jarjar_version=0.4.1 -fancy_mod_loader_version=4.0.23 +fancy_mod_loader_version=4.0.24 mojang_logging_version=1.1.1 log4j_version=2.22.1 guava_version=31.1.2-jre diff --git a/patches/net/minecraft/commands/arguments/EntityArgument.java.patch b/patches/net/minecraft/commands/arguments/EntityArgument.java.patch index f5496e986c..d55d3e357e 100644 --- a/patches/net/minecraft/commands/arguments/EntityArgument.java.patch +++ b/patches/net/minecraft/commands/arguments/EntityArgument.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/commands/arguments/EntityArgument.java +++ b/net/minecraft/commands/arguments/EntityArgument.java -@@ -119,7 +_,7 @@ +@@ -127,7 +_,7 @@ if (p_91482_.getSource() instanceof SharedSuggestionProvider sharedsuggestionprovider) { StringReader stringreader = new StringReader(p_91483_.getInput()); stringreader.setCursor(p_91483_.getStart()); -- EntitySelectorParser entityselectorparser = new EntitySelectorParser(stringreader, sharedsuggestionprovider.hasPermission(2)); +- EntitySelectorParser entityselectorparser = new EntitySelectorParser(stringreader, EntitySelectorParser.allowSelectors(sharedsuggestionprovider)); + EntitySelectorParser entityselectorparser = new EntitySelectorParser(stringreader, net.neoforged.neoforge.common.CommonHooks.canUseEntitySelectors(sharedsuggestionprovider)); try { diff --git a/patches/net/minecraft/commands/arguments/MessageArgument.java.patch b/patches/net/minecraft/commands/arguments/MessageArgument.java.patch index 6f7fe1907c..bd2531e315 100644 --- a/patches/net/minecraft/commands/arguments/MessageArgument.java.patch +++ b/patches/net/minecraft/commands/arguments/MessageArgument.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/commands/arguments/MessageArgument.java +++ b/net/minecraft/commands/arguments/MessageArgument.java -@@ -84,7 +_,7 @@ +@@ -89,7 +_,7 @@ public static record Message(String text, MessageArgument.Part[] parts) { Component resolveComponent(CommandSourceStack p_232197_) throws CommandSyntaxException { -- return this.toComponent(p_232197_, p_232197_.hasPermission(2)); +- return this.toComponent(p_232197_, EntitySelectorParser.allowSelectors(p_232197_)); + return this.toComponent(p_232197_, net.neoforged.neoforge.common.CommonHooks.canUseEntitySelectors(p_232197_)); } diff --git a/patches/net/minecraft/commands/arguments/selector/EntitySelectorParser.java.patch b/patches/net/minecraft/commands/arguments/selector/EntitySelectorParser.java.patch index 9b05f24d2b..1f0e8a3e25 100644 --- a/patches/net/minecraft/commands/arguments/selector/EntitySelectorParser.java.patch +++ b/patches/net/minecraft/commands/arguments/selector/EntitySelectorParser.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/commands/arguments/selector/EntitySelectorParser.java +++ b/net/minecraft/commands/arguments/selector/EntitySelectorParser.java -@@ -476,6 +_,9 @@ +@@ -481,6 +_,9 @@ } this.reader.skip(); @@ -10,7 +10,7 @@ this.parseSelector(); } else { this.parseNameOrUUID(); -@@ -492,6 +_,7 @@ +@@ -497,6 +_,7 @@ p_121248_.suggest("@s", Component.translatable("argument.entity.selector.self")); p_121248_.suggest("@e", Component.translatable("argument.entity.selector.allEntities")); p_121248_.suggest("@n", Component.translatable("argument.entity.selector.nearestEntity")); diff --git a/patches/net/minecraft/world/level/block/SculkSensorBlock.java.patch b/patches/net/minecraft/world/level/block/SculkSensorBlock.java.patch index de183fc8b2..12f47c323f 100644 --- a/patches/net/minecraft/world/level/block/SculkSensorBlock.java.patch +++ b/patches/net/minecraft/world/level/block/SculkSensorBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SculkSensorBlock.java +++ b/net/minecraft/world/level/block/SculkSensorBlock.java -@@ -292,8 +_,13 @@ +@@ -291,8 +_,13 @@ @Override protected void spawnAfterBreak(BlockState p_222142_, ServerLevel p_222143_, BlockPos p_222144_, ItemStack p_222145_, boolean p_222146_) { super.spawnAfterBreak(p_222142_, p_222143_, p_222144_, p_222145_, p_222146_); diff --git a/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch index 26b89617f6..815f48e03b 100644 --- a/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch @@ -18,7 +18,7 @@ public BlockEntity(BlockEntityType p_155228_, BlockPos p_155229_, BlockState p_155230_) { this.type = p_155228_; -@@ -61,6 +_,8 @@ +@@ -72,6 +_,8 @@ } protected void loadAdditional(CompoundTag p_338466_, HolderLookup.Provider p_338445_) { @@ -27,7 +27,7 @@ } public final void loadWithComponents(CompoundTag p_338356_, HolderLookup.Provider p_338558_) { -@@ -76,6 +_,9 @@ +@@ -87,6 +_,9 @@ } protected void saveAdditional(CompoundTag p_187471_, HolderLookup.Provider p_323635_) { @@ -37,7 +37,7 @@ } public final CompoundTag saveWithFullMetadata(HolderLookup.Provider p_323767_) { -@@ -205,10 +_,14 @@ +@@ -216,10 +_,14 @@ public void setRemoved() { this.remove = true; @@ -52,7 +52,7 @@ } public boolean triggerEvent(int p_58889_, int p_58890_) { -@@ -231,6 +_,27 @@ +@@ -246,6 +_,27 @@ return this.type; } @@ -79,8 +79,8 @@ + @Deprecated public void setBlockState(BlockState p_155251_) { - this.blockState = p_155251_; -@@ -309,5 +_,15 @@ + this.validateBlockState(p_155251_); +@@ -325,5 +_,15 @@ T get(DataComponentType p_338658_); T getOrDefault(DataComponentType p_338573_, T p_338734_); diff --git a/patches/net/minecraft/world/level/chunk/LevelChunk.java.patch b/patches/net/minecraft/world/level/chunk/LevelChunk.java.patch index e3f4240e0b..a47b0de44e 100644 --- a/patches/net/minecraft/world/level/chunk/LevelChunk.java.patch +++ b/patches/net/minecraft/world/level/chunk/LevelChunk.java.patch @@ -26,7 +26,7 @@ p_62866_.onPlace(this.level, p_62865_, blockstate, p_62867_); } -@@ -322,6 +_,10 @@ +@@ -327,6 +_,10 @@ @Nullable public BlockEntity getBlockEntity(BlockPos p_62868_, LevelChunk.EntityCreationType p_62869_) { BlockEntity blockentity = this.blockEntities.get(p_62868_); @@ -37,7 +37,7 @@ if (blockentity == null) { CompoundTag compoundtag = this.pendingBlockEntities.remove(p_62868_); if (compoundtag != null) { -@@ -339,9 +_,6 @@ +@@ -344,9 +_,6 @@ this.addAndRegisterBlockEntity(blockentity); } } @@ -47,7 +47,7 @@ } return blockentity; -@@ -355,6 +_,7 @@ +@@ -360,6 +_,7 @@ } this.updateBlockEntityTicker(p_156391_); @@ -55,7 +55,7 @@ } } -@@ -398,6 +_,7 @@ +@@ -403,6 +_,7 @@ BlockEntity blockentity = this.blockEntities.put(blockpos.immutable(), p_156374_); if (blockentity != null && blockentity != p_156374_) { blockentity.setRemoved(); @@ -63,7 +63,7 @@ } } } -@@ -407,9 +_,14 @@ +@@ -412,9 +_,14 @@ public CompoundTag getBlockEntityNbtForSaving(BlockPos p_62932_, HolderLookup.Provider p_323699_) { BlockEntity blockentity = this.getBlockEntity(p_62932_); if (blockentity != null && !blockentity.isRemoved()) { @@ -78,7 +78,7 @@ } else { CompoundTag compoundtag = this.pendingBlockEntities.get(p_62932_); if (compoundtag != null) { -@@ -431,6 +_,7 @@ +@@ -436,6 +_,7 @@ } blockentity.setRemoved(); @@ -86,7 +86,7 @@ } } -@@ -491,7 +_,7 @@ +@@ -496,7 +_,7 @@ p_187974_.accept((p_338077_, p_338078_, p_338079_) -> { BlockEntity blockentity = this.getBlockEntity(p_338077_, LevelChunk.EntityCreationType.IMMEDIATE); if (blockentity != null && p_338079_ != null && blockentity.getType() == p_338078_) { @@ -95,7 +95,7 @@ } }); } -@@ -599,6 +_,7 @@ +@@ -604,6 +_,7 @@ } public void clearAllBlockEntities() { @@ -103,7 +103,7 @@ this.blockEntities.values().forEach(BlockEntity::setRemoved); this.blockEntities.clear(); this.tickersInLevel.values().forEach(p_187966_ -> p_187966_.rebind(NULL_TICKER)); -@@ -606,6 +_,7 @@ +@@ -611,6 +_,7 @@ } public void registerAllBlockEntitiesAfterLevelLoad() { @@ -111,7 +111,7 @@ this.blockEntities.values().forEach(p_187988_ -> { if (this.level instanceof ServerLevel serverlevel) { this.addGameEventListener(p_187988_, serverlevel); -@@ -657,6 +_,14 @@ +@@ -662,6 +_,14 @@ return new LevelChunk.BoundTickingBlockEntity<>(p_156376_, p_156377_); } @@ -126,7 +126,7 @@ class BoundTickingBlockEntity implements TickingBlockEntity { private final T blockEntity; private final BlockEntityTicker ticker; -@@ -674,6 +_,7 @@ +@@ -679,6 +_,7 @@ if (LevelChunk.this.isTicking(blockpos)) { try { ProfilerFiller profilerfiller = LevelChunk.this.level.getProfiler(); @@ -134,7 +134,7 @@ profilerfiller.push(this::getType); BlockState blockstate = LevelChunk.this.getBlockState(blockpos); if (this.blockEntity.getType().isValid(blockstate)) { -@@ -695,7 +_,15 @@ +@@ -700,7 +_,15 @@ CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking block entity"); CrashReportCategory crashreportcategory = crashreport.addCategory("Block entity being ticked"); this.blockEntity.fillCrashReportCategory(crashreportcategory); diff --git a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java index 25f4f3c588..e434bbb54f 100644 --- a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java +++ b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java @@ -38,8 +38,8 @@ import net.minecraft.ResourceLocationException; import net.minecraft.SharedConstants; import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; import net.minecraft.commands.SharedSuggestionProvider; +import net.minecraft.commands.arguments.selector.EntitySelectorParser; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Holder; @@ -1308,7 +1308,7 @@ public static String prefixNamespace(ResourceLocation registryKey) { } public static boolean canUseEntitySelectors(SharedSuggestionProvider provider) { - if (provider.hasPermission(Commands.LEVEL_GAMEMASTERS)) { + if (EntitySelectorParser.allowSelectors(provider)) { return true; } else if (provider instanceof CommandSourceStack source && source.source instanceof ServerPlayer player) { return PermissionAPI.getPermission(player, NeoForgeMod.USE_SELECTORS_PERMISSION); From 37d266ee3099f0e8fea94dd26bc99bec86cbfda9 Mon Sep 17 00:00:00 2001 From: Marc Hermans Date: Thu, 8 Aug 2024 20:05:07 +0200 Subject: [PATCH 019/125] Make 1.21.1 stable From a69634bae42cc2a835437e41481feb545dbaf893 Mon Sep 17 00:00:00 2001 From: Brennan Ward Date: Thu, 8 Aug 2024 22:36:16 -0700 Subject: [PATCH 020/125] [1.21] Fix IShearable (#1433) --- .../minecraft/world/entity/Entity.java.patch | 4 +- .../entity/animal/MushroomCow.java.patch | 21 ++++- .../world/entity/animal/Sheep.java.patch | 11 +++ .../world/entity/animal/SnowGolem.java.patch | 9 ++ .../world/entity/monster/Bogged.java.patch | 11 +++ .../world/item/ShearsItem.java.patch | 34 ++++++-- .../neoforged/neoforge/common/IShearable.java | 82 +++++++++++-------- 7 files changed, 123 insertions(+), 49 deletions(-) create mode 100644 patches/net/minecraft/world/entity/animal/Sheep.java.patch create mode 100644 patches/net/minecraft/world/entity/monster/Bogged.java.patch diff --git a/patches/net/minecraft/world/entity/Entity.java.patch b/patches/net/minecraft/world/entity/Entity.java.patch index cd8784651e..d9fa9191ff 100644 --- a/patches/net/minecraft/world/entity/Entity.java.patch +++ b/patches/net/minecraft/world/entity/Entity.java.patch @@ -452,7 +452,7 @@ } public void checkDespawn() { -@@ -3449,6 +_,126 @@ +@@ -3449,6 +_,128 @@ public boolean mayInteract(Level p_146843_, BlockPos p_146844_) { return true; @@ -466,11 +466,13 @@ + @Nullable + private java.util.Collection captureDrops = null; + ++ @Nullable + @Override + public java.util.Collection captureDrops() { + return captureDrops; + } + ++ @Nullable + @Override + public java.util.Collection captureDrops(@Nullable java.util.Collection value) { + java.util.Collection ret = captureDrops; diff --git a/patches/net/minecraft/world/entity/animal/MushroomCow.java.patch b/patches/net/minecraft/world/entity/animal/MushroomCow.java.patch index d84182042c..fa6f17678a 100644 --- a/patches/net/minecraft/world/entity/animal/MushroomCow.java.patch +++ b/patches/net/minecraft/world/entity/animal/MushroomCow.java.patch @@ -1,5 +1,14 @@ --- a/net/minecraft/world/entity/animal/MushroomCow.java +++ b/net/minecraft/world/entity/animal/MushroomCow.java +@@ -108,7 +_,7 @@ + + this.playSound(soundevent, 1.0F, 1.0F); + return InteractionResult.sidedSuccess(this.level().isClientSide); +- } else if (itemstack.is(Items.SHEARS) && this.readyForShearing()) { ++ } else if (false && itemstack.is(Items.SHEARS) && this.readyForShearing()) { // Neo: Shear logic is handled by IShearable + this.shear(SoundSource.PLAYERS); + this.gameEvent(GameEvent.SHEAR, p_28941_); + if (!this.level().isClientSide) { @@ -165,8 +_,10 @@ public void shear(SoundSource p_28924_) { this.level().playSound(null, this, SoundEvents.MOOSHROOM_SHEAR, p_28924_, 1.0F, 1.0F); @@ -11,7 +20,7 @@ ((ServerLevel)this.level()).sendParticles(ParticleTypes.EXPLOSION, this.getX(), this.getY(0.5), this.getZ(), 1, 0.0, 0.0, 0.0, 0.0); this.discard(); cow.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot()); -@@ -185,10 +_,9 @@ +@@ -185,10 +_,13 @@ this.level().addFreshEntity(cow); for (int i = 0; i < 5; i++) { @@ -19,9 +28,13 @@ - .addFreshEntity( - new ItemEntity(this.level(), this.getX(), this.getY(1.0), this.getZ(), new ItemStack(this.getVariant().blockState.getBlock())) - ); -+ //Neo: Change from addFreshEntity to spawnAtLocation to ensure captureDrops can capture this, we also need to unset the default pickup delay from the item -+ ItemEntity item = spawnAtLocation(new ItemStack(this.getVariant().blockState.getBlock()), getBbHeight()); -+ if (item != null) item.setNoPickUpDelay(); ++ // Neo: Change from addFreshEntity to spawnAtLocation to ensure captureDrops can capture this, we also need to unset the default pickup delay from the item ++ // Vanilla uses this.getY(1.0) for the y-level, which is this.getY() + this.getBbHeight() * 1.0, so we pass the BB height as the Y-offset. ++ ItemEntity item = spawnAtLocation(new ItemStack(this.getVariant().blockState.getBlock()), this.getBbHeight()); ++ if (item != null) { ++ // addFreshEntity does not incur a pickup delay, while spawnAtLocation sets the default pickup delay. ++ item.setNoPickUpDelay(); ++ } } } } diff --git a/patches/net/minecraft/world/entity/animal/Sheep.java.patch b/patches/net/minecraft/world/entity/animal/Sheep.java.patch new file mode 100644 index 0000000000..4871c860c8 --- /dev/null +++ b/patches/net/minecraft/world/entity/animal/Sheep.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/entity/animal/Sheep.java ++++ b/net/minecraft/world/entity/animal/Sheep.java +@@ -212,7 +_,7 @@ + @Override + public InteractionResult mobInteract(Player p_29853_, InteractionHand p_29854_) { + ItemStack itemstack = p_29853_.getItemInHand(p_29854_); +- if (itemstack.is(Items.SHEARS)) { ++ if (false && itemstack.is(Items.SHEARS)) { // Neo: Shear logic is handled by IShearable + if (!this.level().isClientSide && this.readyForShearing()) { + this.shear(SoundSource.PLAYERS); + this.gameEvent(GameEvent.SHEAR, p_29853_); diff --git a/patches/net/minecraft/world/entity/animal/SnowGolem.java.patch b/patches/net/minecraft/world/entity/animal/SnowGolem.java.patch index f77e885fbf..19b14ba776 100644 --- a/patches/net/minecraft/world/entity/animal/SnowGolem.java.patch +++ b/patches/net/minecraft/world/entity/animal/SnowGolem.java.patch @@ -9,3 +9,12 @@ return; } +@@ -127,7 +_,7 @@ + @Override + protected InteractionResult mobInteract(Player p_29920_, InteractionHand p_29921_) { + ItemStack itemstack = p_29920_.getItemInHand(p_29921_); +- if (itemstack.is(Items.SHEARS) && this.readyForShearing()) { ++ if (false && itemstack.is(Items.SHEARS) && this.readyForShearing()) { // Neo: Shear logic is handled by IShearable + this.shear(SoundSource.PLAYERS); + this.gameEvent(GameEvent.SHEAR, p_29920_); + if (!this.level().isClientSide) { diff --git a/patches/net/minecraft/world/entity/monster/Bogged.java.patch b/patches/net/minecraft/world/entity/monster/Bogged.java.patch new file mode 100644 index 0000000000..c77e1925c1 --- /dev/null +++ b/patches/net/minecraft/world/entity/monster/Bogged.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/entity/monster/Bogged.java ++++ b/net/minecraft/world/entity/monster/Bogged.java +@@ -74,7 +_,7 @@ + @Override + protected InteractionResult mobInteract(Player p_330736_, InteractionHand p_331786_) { + ItemStack itemstack = p_330736_.getItemInHand(p_331786_); +- if (itemstack.is(Items.SHEARS) && this.readyForShearing()) { ++ if (false && itemstack.is(Items.SHEARS) && this.readyForShearing()) { // Neo: Shear logic is handled by IShearable + this.shear(SoundSource.PLAYERS); + this.gameEvent(GameEvent.SHEAR, p_330736_); + if (!this.level().isClientSide) { diff --git a/patches/net/minecraft/world/item/ShearsItem.java.patch b/patches/net/minecraft/world/item/ShearsItem.java.patch index 16efe85c84..6f0ad827e7 100644 --- a/patches/net/minecraft/world/item/ShearsItem.java.patch +++ b/patches/net/minecraft/world/item/ShearsItem.java.patch @@ -1,20 +1,38 @@ --- a/net/minecraft/world/item/ShearsItem.java +++ b/net/minecraft/world/item/ShearsItem.java -@@ -55,19 +_,39 @@ +@@ -54,20 +_,57 @@ + || p_43080_.is(BlockTags.WOOL); } - @Override ++ /** ++ * Neo: Migrate shear behavior into {@link ShearsItem#interactLivingEntity} to call into IShearable instead of relying on {@link net.minecraft.world.entity.Mob#mobInteract} ++ *

++ * To preserve vanilla behavior, this method retains the original flow shared by the various mobInteract overrides. ++ */ ++ @Override + public InteractionResult interactLivingEntity(ItemStack stack, Player player, LivingEntity entity, net.minecraft.world.InteractionHand hand) { + if (entity instanceof net.neoforged.neoforge.common.IShearable target) { -+ if (entity.level().isClientSide) return InteractionResult.CONSUME; + BlockPos pos = entity.blockPosition(); ++ boolean isClient = entity.level().isClientSide(); ++ // Check isShearable on both sides (mirrors vanilla readyForShearing()) + if (target.isShearable(player, stack, entity.level(), pos)) { -+ target.onSheared(player, stack, entity.level(), pos) -+ .forEach(drop -> target.spawnShearedDrop(entity.level(), pos, drop)); ++ // Call onSheared on both sides (mirrors vanilla shear()) ++ List drops = target.onSheared(player, stack, entity.level(), pos); ++ // Spawn drops on the server side using spawnShearedDrop to retain vanilla mob-specific behavior ++ if (!isClient) { ++ for(ItemStack drop : drops) { ++ target.spawnShearedDrop(entity.level(), pos, drop); ++ } ++ } ++ // Call GameEvent.SHEAR on both sides + entity.gameEvent(GameEvent.SHEAR, player); -+ stack.hurtAndBreak(1, player, hand == net.minecraft.world.InteractionHand.MAIN_HAND ? net.minecraft.world.entity.EquipmentSlot.MAINHAND : net.minecraft.world.entity.EquipmentSlot.OFFHAND); ++ // Damage the shear item stack by 1 on the server side ++ if (!isClient) { ++ stack.hurtAndBreak(1, player, LivingEntity.getSlotForHand(hand)); ++ } ++ // Return sided success if the entity was shearable ++ return InteractionResult.sidedSuccess(isClient); + } -+ return InteractionResult.SUCCESS; + } + return InteractionResult.PASS; + } @@ -24,7 +42,7 @@ + return net.neoforged.neoforge.common.ItemAbilities.DEFAULT_SHEARS_ACTIONS.contains(itemAbility); + } + -+ @Override + @Override public InteractionResult useOn(UseOnContext p_186371_) { Level level = p_186371_.getLevel(); BlockPos blockpos = p_186371_.getClickedPos(); diff --git a/src/main/java/net/neoforged/neoforge/common/IShearable.java b/src/main/java/net/neoforged/neoforge/common/IShearable.java index 24c9e994f7..ae5d51aabc 100644 --- a/src/main/java/net/neoforged/neoforge/common/IShearable.java +++ b/src/main/java/net/neoforged/neoforge/common/IShearable.java @@ -10,6 +10,8 @@ import java.util.List; import net.minecraft.core.BlockPos; import net.minecraft.sounds.SoundSource; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.Shearable; import net.minecraft.world.entity.animal.MushroomCow; @@ -19,51 +21,51 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; /** + * This interfaces allows shears (modded & vanilla) and {@linkplain Entity entities} (modded & vanilla) to cooperate + * without needing advance knowledge of each other. + *

+ * In the future, this system may function for implementations on {@link Block}s as well. * - * This allows for mods to create there own Shear-like items - * and have them interact with Blocks/Entities without extra work. - * Also, if your block/entity supports the Shears, this allows you - * to support mod-shears as well. - * - * TODO: reconsider this system, currently it is implemented but not checked for, for blocks. + * TODO: Implement support for {@link Block} or remove default implementations from vanilla block classes. */ public interface IShearable { /** - * Checks if the object is currently shearable - * Example: Sheep return false when they have no wool + * Checks if this object can be sheared. + *

+ * For example, Sheep return false when they have no wool. * - * @param item The ItemStack that is being used, may be empty. + * @param item The shear tool that is being used, may be empty. * @param level The current level. - * @param pos Block's position in level. - * @return If this is shearable, and onSheared should be called. + * @param pos The block position of this object (if this is an entity, the value of {@link Entity#blockPosition()}. + * @return If this is shearable, and {@link #onSheared} may be called. */ default boolean isShearable(@Nullable Player player, ItemStack item, Level level, BlockPos pos) { - //Default to checking readyForShearing if we are the vanilla shearable interface, and if we aren't assume a default of true + // Default to checking readyForShearing if we are the vanilla shearable interface, and if we aren't assume a default of true return !(this instanceof Shearable shearable) || shearable.readyForShearing(); } /** - * Performs the shear function on this object. - * This is called for both client, and server. - * The object should perform all actions related to being sheared, - * except for dropping of the items, and removal of the block. - * As those are handled by ItemShears itself. + * Shears this object. This function is called on both sides, and is responsible for performing any and all actions that happen when sheared, except spawning drops. + *

+ * Drops that are spawned as a result of being sheared should be returned from this method, and will be spawned on the server using {@link #spawnShearedDrop}. *

- * For entities, they should trust their internal location information over the values passed into this function. + * {@linkplain Entity Entities} may respect their internal position values instead of relying on the {@code pos} parameter. * - * @param item The ItemStack that is being used, may be empty. + * @param item The shear tool that is being used, may be empty. * @param level The current level. - * @param pos If this is a block, the block's position in level. - * @return A List containing all items that resulted from the shearing process. May be empty. + * @param pos The block position of this object (if this is an entity, the value of {@link Entity#blockPosition()}. + * @return A list holding all dropped items resulting from the shear operation, or an empty list if nothing dropped. */ + @SuppressWarnings("deprecation") // Expected call to deprecated vanilla Shearable#shear default List onSheared(@Nullable Player player, ItemStack item, Level level, BlockPos pos) { if (this instanceof LivingEntity entity && this instanceof Shearable shearable) { if (!level.isClientSide) { - List drops = new ArrayList<>(); - entity.captureDrops(drops); + entity.captureDrops(new ArrayList<>()); shearable.shear(player == null ? SoundSource.BLOCKS : SoundSource.PLAYERS); return entity.captureDrops(null).stream().map(ItemEntity::getItem).toList(); } @@ -74,31 +76,39 @@ default List onSheared(@Nullable Player player, ItemStack item, Level /** * Performs the logic used to drop a shear result into the world at the correct position and with the proper movement. *
- * For entities, they should trust their internal location information over the values passed into this function. + * {@linkplain Entity Entities} may respect their internal position values instead of relying on the {@code pos} parameter. * * @param level The current level. - * @param pos If this is a block, the block's position in level. - * @param drop The ItemStack to drop. + * @param pos The block position of this object (if this is an entity, the value of {@link Entity#blockPosition()}. + * @param drop The stack to drop, from the list of drops returned by {@link #onSheared}. */ default void spawnShearedDrop(Level level, BlockPos pos, ItemStack drop) { if (this instanceof SnowGolem golem) { - golem.spawnAtLocation(drop, 1.7F); + // SnowGolem#shear uses spawnAtLocation(..., this.getEyeHeight()); + golem.spawnAtLocation(drop, golem.getEyeHeight()); } else if (this instanceof Bogged bogged) { - bogged.spawnAtLocation(drop); + // Bogged#spawnShearedMushrooms uses spawnAtLocation(..., this.getBbHeight()); + bogged.spawnAtLocation(drop, bogged.getBbHeight()); } else if (this instanceof MushroomCow cow) { - // Note: Vanilla uses addFreshEntity instead of spawnAtLocation for spawning mooshrooms drops - // In case a mod is capturing drops for the entity we instead do it the same way we patch in MushroomCow#shear + // We patch Mooshrooms from using addFreshEntity to spawnAtLocation to spawnAtLocation to capture the drops. + // In case a mod is also capturing drops, we also replicate that logic here. ItemEntity itemEntity = cow.spawnAtLocation(drop, cow.getBbHeight()); - if (itemEntity != null) itemEntity.setNoPickUpDelay(); - } else if (this instanceof LivingEntity entity) { + if (itemEntity != null) { + itemEntity.setNoPickUpDelay(); + } + } else if (this instanceof Entity entity) { + // Everything else uses the "default" rules invented by Sheep#shear, which uses a y-offset of 1 and these random delta movement values. ItemEntity itemEntity = entity.spawnAtLocation(drop, 1); if (itemEntity != null) { - itemEntity.setDeltaMovement(itemEntity.getDeltaMovement().add( - ((entity.getRandom().nextFloat() - entity.getRandom().nextFloat()) * 0.1F), - (entity.getRandom().nextFloat() * 0.05F), - ((entity.getRandom().nextFloat() - entity.getRandom().nextFloat()) * 0.1F))); + RandomSource rand = entity.getRandom(); + Vec3 newDelta = itemEntity.getDeltaMovement().add( + (rand.nextFloat() - rand.nextFloat()) * 0.1F, + rand.nextFloat() * 0.05F, + (rand.nextFloat() - rand.nextFloat()) * 0.1F); + itemEntity.setDeltaMovement(newDelta); } } else { + // If we aren't an entity, fallback to spawning the item at the given position. level.addFreshEntity(new ItemEntity(level, pos.getX(), pos.getY(), pos.getZ(), drop)); } } From 1f3dfc36ef4add57c56eea996738520689b38bef Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Fri, 9 Aug 2024 10:27:39 -0400 Subject: [PATCH 021/125] Patch MC-274244 to allow tagged items to be picked up by Farmers (#1279) Also fix `villagerCanPlantItem` to only work with farmer villagers. --- patches/net/minecraft/world/entity/npc/Villager.java.patch | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/patches/net/minecraft/world/entity/npc/Villager.java.patch b/patches/net/minecraft/world/entity/npc/Villager.java.patch index df85d8ace4..f206fb91fd 100644 --- a/patches/net/minecraft/world/entity/npc/Villager.java.patch +++ b/patches/net/minecraft/world/entity/npc/Villager.java.patch @@ -37,12 +37,15 @@ p_35409_.addFreshEntityWithPassengers(witch); this.releaseAllPois(); this.discard(); -@@ -831,7 +_,7 @@ +@@ -831,7 +_,10 @@ @Override public boolean wantsToPickUp(ItemStack p_35543_) { Item item = p_35543_.getItem(); - return (WANTED_ITEMS.contains(item) || this.getVillagerData().getProfession().requestedItems().contains(item)) -+ return (WANTED_ITEMS.contains(item) || this.getVillagerData().getProfession().requestedItems().contains(item) || (p_35543_.getItem() instanceof net.neoforged.neoforge.common.SpecialPlantable specialPlantable && specialPlantable.villagerCanPlantItem(this))) ++ // Neo: Patched so that Farmer Villagers will pick up SpecialPlantable items. Also fixes MC-274244 by making "minecraft:villager_plantable_seeds" tagged items also be picked up by Farmer Villagers to be planted later. ++ boolean isFarmerDesiredSeed = (p_35543_.is(ItemTags.VILLAGER_PLANTABLE_SEEDS) || (p_35543_.getItem() instanceof net.neoforged.neoforge.common.SpecialPlantable specialPlantable && specialPlantable.villagerCanPlantItem(this))) ++ && this.getVillagerData().getProfession().secondaryPoi().stream().anyMatch(secondaryPoi -> secondaryPoi.defaultBlockState().is(net.neoforged.neoforge.common.Tags.Blocks.VILLAGER_FARMLANDS)); ++ return (WANTED_ITEMS.contains(item) || this.getVillagerData().getProfession().requestedItems().contains(item) || isFarmerDesiredSeed) && this.getInventory().canAddItem(p_35543_); } From 4c6f3a4418376a89c34a993d83f1fbef73acff08 Mon Sep 17 00:00:00 2001 From: Brennan Ward Date: Fri, 9 Aug 2024 13:53:27 -0700 Subject: [PATCH 022/125] [1.21] Add IItemExtension#supportsEnchantment (#1412) This delegates item<->enchantment compatibility to the item instead of relying on the enchantment's specified item tags. --- .../server/commands/EnchantCommand.java.patch | 11 ++++++ .../world/inventory/AnvilMenu.java.patch | 13 +++++++ .../item/enchantment/Enchantment.java.patch | 34 +++++++++++++++++- .../EnchantRandomlyFunction.java.patch | 11 ++++++ .../common/extensions/IItemExtension.java | 35 +++++++++++++++++-- .../extensions/IItemStackExtension.java | 7 ++++ 6 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 patches/net/minecraft/server/commands/EnchantCommand.java.patch create mode 100644 patches/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java.patch diff --git a/patches/net/minecraft/server/commands/EnchantCommand.java.patch b/patches/net/minecraft/server/commands/EnchantCommand.java.patch new file mode 100644 index 0000000000..c9c0649283 --- /dev/null +++ b/patches/net/minecraft/server/commands/EnchantCommand.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/commands/EnchantCommand.java ++++ b/net/minecraft/server/commands/EnchantCommand.java +@@ -81,7 +_,7 @@ + LivingEntity livingentity = (LivingEntity)entity; + ItemStack itemstack = livingentity.getMainHandItem(); + if (!itemstack.isEmpty()) { +- if (enchantment.canEnchant(itemstack) ++ if (itemstack.supportsEnchantment(p_251252_) // Neo: Respect IItemExtension#supportsEnchantment + && EnchantmentHelper.isEnchantmentCompatible(EnchantmentHelper.getEnchantmentsForCrafting(itemstack).keySet(), p_251252_)) { + itemstack.enchant(p_251252_, p_249941_); + i++; diff --git a/patches/net/minecraft/world/inventory/AnvilMenu.java.patch b/patches/net/minecraft/world/inventory/AnvilMenu.java.patch index 38ae222fff..255c825995 100644 --- a/patches/net/minecraft/world/inventory/AnvilMenu.java.patch +++ b/patches/net/minecraft/world/inventory/AnvilMenu.java.patch @@ -30,6 +30,19 @@ if (itemstack1.isDamageableItem() && itemstack1.getItem().isValidRepairItem(itemstack, itemstack2)) { int l2 = Math.min(itemstack1.getDamageValue(), itemstack1.getMaxDamage() / 4); if (l2 <= 0) { +@@ -176,8 +_,10 @@ + int j2 = entry.getIntValue(); + j2 = i2 == j2 ? j2 + 1 : Math.max(j2, i2); + Enchantment enchantment = holder.value(); +- boolean flag1 = enchantment.canEnchant(itemstack); +- if (this.player.getAbilities().instabuild || itemstack.is(Items.ENCHANTED_BOOK)) { ++ // Neo: Respect IItemExtension#supportsEnchantment - we also delegate the logic for Enchanted Books to this method. ++ // Though we still allow creative players to combine any item with any enchantment in the anvil here. ++ boolean flag1 = itemstack.supportsEnchantment(holder); ++ if (this.player.getAbilities().instabuild) { + flag1 = true; + } + @@ -228,6 +_,7 @@ i += k; itemstack1.remove(DataComponents.CUSTOM_NAME); diff --git a/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch b/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch index 939f9a5229..8237cc26e6 100644 --- a/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch +++ b/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch @@ -1,16 +1,48 @@ --- a/net/minecraft/world/item/enchantment/Enchantment.java +++ b/net/minecraft/world/item/enchantment/Enchantment.java -@@ -132,6 +_,10 @@ +@@ -124,6 +_,10 @@ + return map; + } + ++ /** ++ * @deprecated Neo: Use {@link ItemStack#supportsEnchantment(Holder)} ++ */ ++ @Deprecated + public HolderSet getSupportedItems() { + return this.definition.supportedItems(); + } +@@ -132,10 +_,20 @@ return this.definition.slots().stream().anyMatch(p_345027_ -> p_345027_.test(p_345146_)); } + /** + * @deprecated Neo: Use {@link ItemStack#isPrimaryItemFor(Holder)} ++ * ++ * This method does not respect {@link ItemStack#supportsEnchantment(Holder)} since the {@link Holder} is not available, which makes the result of calling it invalid. + */ + @Deprecated public boolean isPrimaryItem(ItemStack p_336088_) { return this.isSupportedItem(p_336088_) && (this.definition.primaryItems.isEmpty() || p_336088_.is(this.definition.primaryItems.get())); } + ++ /** ++ * @deprecated Neo: Use {@link ItemStack#supportsEnchantment(Holder)} ++ */ ++ @Deprecated + public boolean isSupportedItem(ItemStack p_344865_) { + return p_344865_.is(this.definition.supportedItems); + } +@@ -188,6 +_,10 @@ + return mutablecomponent; + } + ++ /** ++ * @deprecated Neo: Use {@link ItemStack#supportsEnchantment(Holder)} ++ */ ++ @Deprecated + public boolean canEnchant(ItemStack p_44689_) { + return this.definition.supportedItems().contains(p_44689_.getItemHolder()); + } @@ -503,6 +_,15 @@ public static Enchantment.Builder enchantment(Enchantment.EnchantmentDefinition p_345873_) { return new Enchantment.Builder(p_345873_); diff --git a/patches/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java.patch b/patches/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java.patch new file mode 100644 index 0000000000..57bef15771 --- /dev/null +++ b/patches/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java ++++ b/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java +@@ -59,7 +_,7 @@ + Stream> stream = this.options + .map(HolderSet::stream) + .orElseGet(() -> p_80430_.getLevel().registryAccess().registryOrThrow(Registries.ENCHANTMENT).holders().map(Function.identity())) +- .filter(p_344686_ -> !flag1 || p_344686_.value().canEnchant(p_80429_)); ++ .filter(p_344686_ -> !flag1 || p_80429_.supportsEnchantment(p_344686_)); // Neo: Respect IItemExtension#supportsEnchantment + List> list = stream.toList(); + Optional> optional = Util.getRandomSafe(list, randomsource); + if (optional.isEmpty()) { diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java index a8ccb67134..1de3e6358d 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java @@ -8,11 +8,13 @@ import java.util.HashSet; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.function.Consumer; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.core.HolderLookup.RegistryLookup; +import net.minecraft.core.HolderSet; import net.minecraft.core.component.DataComponentMap; import net.minecraft.core.component.DataComponentType; import net.minecraft.core.component.DataComponents; @@ -45,6 +47,7 @@ import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.enchantment.Enchantment; +import net.minecraft.world.item.enchantment.Enchantment.EnchantmentDefinition; import net.minecraft.world.item.enchantment.EnchantmentInstance; import net.minecraft.world.item.enchantment.ItemEnchantments; import net.minecraft.world.level.Level; @@ -422,17 +425,43 @@ default int getEnchantmentValue(ItemStack stack) { * either from the enchantment table or other random enchantment mechanisms. * As a special case, books are primary items for every enchantment. *

- * Other application mechanisms, such as the anvil, check {@link Enchantment#isSupportedItem(ItemStack)} instead. - * If you want those mechanisms to be able to apply an enchantment, you will need to add your item to the relevant tag. + * Other application mechanisms, such as the anvil, check {@link #supportsEnchantment(ItemStack, Holder)} instead. + * If you want those mechanisms to be able to apply an enchantment, you will need to add your item to the relevant tag or override that method. * * @param stack the item stack to be enchanted * @param enchantment the enchantment to be applied * @return true if this item should be treated as a primary item for the enchantment * @apiNote Call via {@link IItemStackExtension#isPrimaryItemFor(Holder)} + * + * @see #supportsEnchantment(ItemStack, Holder) */ @ApiStatus.OverrideOnly default boolean isPrimaryItemFor(ItemStack stack, Holder enchantment) { - return stack.getItem() == Items.BOOK || enchantment.value().isPrimaryItem(stack); + if (stack.getItem() == Items.BOOK) { + return true; + } + Optional> primaryItems = enchantment.value().definition().primaryItems(); + return this.supportsEnchantment(stack, enchantment) && (primaryItems.isEmpty() || stack.is(primaryItems.get())); + } + + /** + * Checks if the provided enchantment is applicable to the passed item stack. + *

+ * By default, this checks if the {@link EnchantmentDefinition#supportedItems()} contains this item, + * special casing enchanted books as they may receive any enchantment. + *

+ * Overriding this method allows for dynamic logic that would not be possible using the tag system. + * + * @param stack the item stack to be enchanted + * @param enchantment the enchantment to be applied + * @return true if this item can accept the enchantment + * @apiNote Call via {@link IItemStackExtension#supportsEnchantment(Holder)} + * + * @see #isPrimaryItemFor(ItemStack, Holder) + */ + @ApiStatus.OverrideOnly + default boolean supportsEnchantment(ItemStack stack, Holder enchantment) { + return stack.is(Items.ENCHANTED_BOOK) || enchantment.value().isSupportedItem(stack); } /** diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IItemStackExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IItemStackExtension.java index 2993635a2b..8c9d46d8e8 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IItemStackExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IItemStackExtension.java @@ -140,6 +140,13 @@ default boolean isPrimaryItemFor(Holder enchantment) { return self().getItem().isPrimaryItemFor(self(), enchantment); } + /** + * @see {@link IItemExtension#supportsEnchantment(ItemStack, Holder)} + */ + default boolean supportsEnchantment(Holder enchantment) { + return self().getItem().supportsEnchantment(self(), enchantment); + } + /** * Gets the gameplay level of the target enchantment on this stack. *

From 797bcd619078bc066ebefb6e0f140517de8ca053 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 11 Aug 2024 13:46:34 -0400 Subject: [PATCH 023/125] Use BlockEntity.getType to check for valid block state (#1442) --- .../world/level/block/entity/BlockEntity.java.patch | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch index 815f48e03b..51453c55cf 100644 --- a/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch @@ -1,14 +1,16 @@ --- a/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -27,7 +_,7 @@ +@@ -27,8 +_,9 @@ import net.minecraft.world.level.block.state.BlockState; import org.slf4j.Logger; -public abstract class BlockEntity { +public abstract class BlockEntity extends net.neoforged.neoforge.attachment.AttachmentHolder implements net.neoforged.neoforge.common.extensions.IBlockEntityExtension { private static final Logger LOGGER = LogUtils.getLogger(); ++ @Deprecated // Neo: always use getType() private final BlockEntityType type; @Nullable + protected Level level; @@ -36,6 +_,8 @@ protected boolean remove; private BlockState blockState; @@ -18,6 +20,15 @@ public BlockEntity(BlockEntityType p_155228_, BlockPos p_155229_, BlockState p_155230_) { this.type = p_155228_; +@@ -51,7 +_,7 @@ + } + + public boolean isValidBlockState(BlockState p_353131_) { +- return this.type.isValid(p_353131_); ++ return this.getType().isValid(p_353131_); // Neo: use getter so correct type is checked for modded subclasses + } + + public static BlockPos getPosFromTag(CompoundTag p_187473_) { @@ -72,6 +_,8 @@ } From 2fee73440aa06fc66b082377c32712ca09fbaed4 Mon Sep 17 00:00:00 2001 From: Brennan Ward Date: Sun, 11 Aug 2024 14:34:39 -0700 Subject: [PATCH 024/125] [1.21] Add support for the `c:register` channel registration payload (#1190) This change will provide better network compat with non-Neo platforms --- .../ClientCommonPacketListenerImpl.java.patch | 12 +- .../ServerCommonPacketListenerImpl.java.patch | 12 +- .../network/filters/NetworkFilters.java | 3 +- .../payload/CommonRegisterPayload.java | 50 ++++++ .../network/payload/CommonVersionPayload.java | 41 +++++ .../registration/ChannelAttributes.java | 95 ++++++++++ .../network/registration/NetworkRegistry.java | 170 +++++++++++------- 7 files changed, 315 insertions(+), 68 deletions(-) create mode 100644 src/main/java/net/neoforged/neoforge/network/payload/CommonRegisterPayload.java create mode 100644 src/main/java/net/neoforged/neoforge/network/payload/CommonVersionPayload.java create mode 100644 src/main/java/net/neoforged/neoforge/network/registration/ChannelAttributes.java diff --git a/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch b/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch index 49028294c0..fa6437a7c7 100644 --- a/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch @@ -20,7 +20,7 @@ } @Override -@@ -149,6 +_,23 @@ +@@ -149,6 +_,33 @@ @Override public void handleCustomPayload(ClientboundCustomPayloadPacket p_295727_) { @@ -35,6 +35,16 @@ + return; + } + ++ if (p_295727_.payload() instanceof net.neoforged.neoforge.network.payload.CommonVersionPayload commonVersionPayload) { ++ net.neoforged.neoforge.network.registration.NetworkRegistry.checkCommonVersion(this.getConnection(), commonVersionPayload); ++ return; ++ } ++ ++ if (p_295727_.payload() instanceof net.neoforged.neoforge.network.payload.CommonRegisterPayload commonRegisterPayload) { ++ net.neoforged.neoforge.network.registration.NetworkRegistry.onCommonRegister(this.getConnection(), commonRegisterPayload); ++ return; ++ } ++ + // Neo: Handle modded payloads. Vanilla payloads do not get sent to the modded handling pass. Additional payloads cannot be registered in the minecraft domain. + if (net.neoforged.neoforge.network.registration.NetworkRegistry.isModdedPayload(p_295727_.payload())) { + net.neoforged.neoforge.network.registration.NetworkRegistry.handleModdedPayload(this, p_295727_); diff --git a/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch b/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch index 32343523b0..d289270c98 100644 --- a/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch +++ b/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch @@ -20,7 +20,7 @@ } private void close() { -@@ -83,6 +_,22 @@ +@@ -83,6 +_,32 @@ @Override public void handleCustomPayload(ServerboundCustomPayloadPacket p_294276_) { @@ -35,6 +35,16 @@ + return; + } + ++ if (p_294276_.payload() instanceof net.neoforged.neoforge.network.payload.CommonVersionPayload commonVersionPayload) { ++ net.neoforged.neoforge.network.registration.NetworkRegistry.checkCommonVersion(this.getConnection(), commonVersionPayload); ++ return; ++ } ++ ++ if (p_294276_.payload() instanceof net.neoforged.neoforge.network.payload.CommonRegisterPayload commonRegisterPayload) { ++ net.neoforged.neoforge.network.registration.NetworkRegistry.onCommonRegister(this.getConnection(), commonRegisterPayload); ++ return; ++ } ++ + // Neo: Handle modded payloads. Vanilla payloads do not get sent to the modded handling pass. Additional payloads cannot be registered in the minecraft domain. + if (net.neoforged.neoforge.network.registration.NetworkRegistry.isModdedPayload(p_294276_.payload())) { + net.neoforged.neoforge.network.registration.NetworkRegistry.handleModdedPayload(this, p_294276_); diff --git a/src/main/java/net/neoforged/neoforge/network/filters/NetworkFilters.java b/src/main/java/net/neoforged/neoforge/network/filters/NetworkFilters.java index d944f1eca3..35bfc50ae3 100644 --- a/src/main/java/net/neoforged/neoforge/network/filters/NetworkFilters.java +++ b/src/main/java/net/neoforged/neoforge/network/filters/NetworkFilters.java @@ -35,8 +35,9 @@ public static void injectIfNecessary(Connection manager) { // this means that they will be processed before the encoder. ChannelPipeline pipeline = manager.channel().pipeline(); - if (pipeline.get(HandlerNames.ENCODER) == null) + if (pipeline.get(HandlerNames.ENCODER) == null) { return; // Realistically this can only ever be null if the connection was prematurely closed due to an error. We return early here to reduce further log spam. + } var connectionType = NetworkRegistry.getConnectionType(manager); instances.forEach((key, filterFactory) -> { diff --git a/src/main/java/net/neoforged/neoforge/network/payload/CommonRegisterPayload.java b/src/main/java/net/neoforged/neoforge/network/payload/CommonRegisterPayload.java new file mode 100644 index 0000000000..4f15a00afc --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/network/payload/CommonRegisterPayload.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.network.payload; + +import java.util.HashSet; +import java.util.Set; +import net.minecraft.network.ConnectionProtocol; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +/** + * Common Register, used to send play-phase channels during the configuration phase. + * + * @param version Declared version of all contained channels. Currently unused by NeoForge. + * @param protocol The {@link ConnectionProtocol} of the contained channels. One of "play" or "configuration". Currently NeoForge only expects and sends "play" channels via this payload. + * @param channels A list of all named channels available for the declared phase. + */ +@ApiStatus.Internal +public record CommonRegisterPayload(int version, ConnectionProtocol protocol, Set channels) implements CustomPacketPayload { + + public static final ResourceLocation ID = ResourceLocation.fromNamespaceAndPath("c", "register"); + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(ID); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.VAR_INT, CommonRegisterPayload::version, + ByteBufCodecs.STRING_UTF8.map(CommonRegisterPayload::protocolById, ConnectionProtocol::id), CommonRegisterPayload::protocol, + ByteBufCodecs.collection(HashSet::new, ResourceLocation.STREAM_CODEC), CommonRegisterPayload::channels, + CommonRegisterPayload::new); + @Override + public Type type() { + return TYPE; + } + + @Nullable + private static ConnectionProtocol protocolById(String id) { + for (ConnectionProtocol p : ConnectionProtocol.values()) { + if (p.id().equals(id)) { + return p; + } + } + return null; + } +} diff --git a/src/main/java/net/neoforged/neoforge/network/payload/CommonVersionPayload.java b/src/main/java/net/neoforged/neoforge/network/payload/CommonVersionPayload.java new file mode 100644 index 0000000000..4012bb6d09 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/network/payload/CommonVersionPayload.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.network.payload; + +import java.util.List; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.network.registration.NetworkRegistry; +import org.jetbrains.annotations.ApiStatus; + +/** + * Common version payload. Negotiates that the other side supports the same underlying implementation of `c:register` as we do. + * + * @param versions A list of all versions supported by the sender. + * + * @see NetworkRegistry#SUPPORTED_COMMON_NETWORKING_VERSIONS + */ +@ApiStatus.Internal +public record CommonVersionPayload(List versions) implements CustomPacketPayload { + public static final ResourceLocation ID = ResourceLocation.fromNamespaceAndPath("c", "version"); + public static final CustomPacketPayload.Type TYPE = new CustomPacketPayload.Type<>(ID); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.VAR_INT.apply(ByteBufCodecs.list()), CommonVersionPayload::versions, + CommonVersionPayload::new); + + public CommonVersionPayload() { + this(NetworkRegistry.SUPPORTED_COMMON_NETWORKING_VERSIONS); + } + + @Override + public Type type() { + return TYPE; + } +} diff --git a/src/main/java/net/neoforged/neoforge/network/registration/ChannelAttributes.java b/src/main/java/net/neoforged/neoforge/network/registration/ChannelAttributes.java new file mode 100644 index 0000000000..a64a3abe39 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/network/registration/ChannelAttributes.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.network.registration; + +import io.netty.channel.Channel; +import io.netty.util.AttributeKey; +import java.util.EnumMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import net.minecraft.network.Connection; +import net.minecraft.network.ConnectionProtocol; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.network.connection.ConnectionType; +import net.neoforged.neoforge.network.payload.CommonRegisterPayload; +import net.neoforged.neoforge.network.payload.MinecraftRegisterPayload; +import net.neoforged.neoforge.network.payload.ModdedNetworkPayload; +import net.neoforged.neoforge.network.payload.ModdedNetworkQueryPayload; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +/** + * Utilities for manipulation of Netty {@link Channel} attributes + */ +@ApiStatus.Internal +public class ChannelAttributes { + /** + * Negotiated modded payload setup from {@link ModdedNetworkQueryPayload} and/or {@link ModdedNetworkPayload}. + */ + public static final AttributeKey PAYLOAD_SETUP = AttributeKey.valueOf("neoforge:payload_setup"); + + /** + * Known ad-hoc channels from {@link MinecraftRegisterPayload}. + */ + public static final AttributeKey> ADHOC_CHANNELS = AttributeKey.valueOf("neoforge:adhoc_channels"); + + /** + * Known common channels from {@link CommonRegisterPayload}. + */ + public static final AttributeKey>> COMMON_CHANNELS = AttributeKey.valueOf("neoforge:common_channels"); + + /** + * The {@link ConnectionType} of the current connection + */ + public static final AttributeKey CONNECTION_TYPE = AttributeKey.valueOf("neoforge:connection_type"); + + @Nullable + public static NetworkPayloadSetup getPayloadSetup(Connection connection) { + return connection.channel().attr(PAYLOAD_SETUP).get(); + } + + public static void setPayloadSetup(Connection connection, NetworkPayloadSetup setup) { + connection.channel().attr(PAYLOAD_SETUP).set(setup); + } + + @Nullable + public static ConnectionType getConnectionType(Connection connection) { + return connection.channel().attr(CONNECTION_TYPE).get(); + } + + public static void setConnectionType(Connection connection, ConnectionType type) { + connection.channel().attr(CONNECTION_TYPE).set(type); + } + + /** + * Returns a mutable set of the currently known ad-hoc channels. + */ + public static Set getOrCreateAdHocChannels(Connection connection) { + Set channels = connection.channel().attr(ADHOC_CHANNELS).get(); + + if (channels == null) { + channels = new HashSet<>(); + connection.channel().attr(ADHOC_CHANNELS).set(channels); + } + + return channels; + } + + /** + * Returns a mutable set of the currently known common channels for the given protocol. + */ + public static Set getOrCreateCommonChannels(Connection connection, ConnectionProtocol protocol) { + Map> channels = connection.channel().attr(COMMON_CHANNELS).get(); + + if (channels == null) { + channels = new EnumMap<>(ConnectionProtocol.class); + connection.channel().attr(COMMON_CHANNELS).set(channels); + } + + return channels.computeIfAbsent(protocol, p -> new HashSet<>()); + } +} diff --git a/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java b/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java index 4c28f6c37d..da26d5bb94 100644 --- a/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java +++ b/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java @@ -10,11 +10,9 @@ import com.google.common.collect.Lists; import com.mojang.logging.LogUtils; import io.netty.channel.ChannelHandlerContext; -import io.netty.util.AttributeKey; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; @@ -60,6 +58,8 @@ import net.neoforged.neoforge.network.negotiation.NegotiableNetworkComponent; import net.neoforged.neoforge.network.negotiation.NegotiationResult; import net.neoforged.neoforge.network.negotiation.NetworkComponentNegotiator; +import net.neoforged.neoforge.network.payload.CommonRegisterPayload; +import net.neoforged.neoforge.network.payload.CommonVersionPayload; import net.neoforged.neoforge.network.payload.MinecraftRegisterPayload; import net.neoforged.neoforge.network.payload.MinecraftUnregisterPayload; import net.neoforged.neoforge.network.payload.ModdedNetworkPayload; @@ -79,16 +79,17 @@ * Additionally, this registry is responsible for handling all packets that are not natively known once they arrive at the receiving end. *

* To prevent payloads from being send to a client that has no idea what to do with them, the registry provides endpoints for the vanilla code base to check if a packet can be send to a client. - *

*/ @ApiStatus.Internal public class NetworkRegistry { - private static final Logger LOGGER = LogUtils.getLogger(); + /** + * Declared common networking versions currently supported by NeoForge. + *

+ * At the time of writing, the only version in existence is 1. + */ + public static final List SUPPORTED_COMMON_NETWORKING_VERSIONS = List.of(1); - private static final AttributeKey ATTRIBUTE_PAYLOAD_SETUP = AttributeKey.valueOf("neoforge:payload_setup"); - private static final AttributeKey> ATTRIBUTE_ADHOC_CHANNELS = AttributeKey.valueOf("neoforge:adhoc_channels"); - private static final AttributeKey ATTRIBUTE_CONNECTION_TYPE = AttributeKey.valueOf("neoforge:connection_type"); - private static final AttributeKey ATTRIBUTE_FLOW = AttributeKey.valueOf("neoforge:flow"); + private static final Logger LOGGER = LogUtils.getLogger(); /** * Map of NeoForge payloads that may be sent before channel negotiation. @@ -99,7 +100,9 @@ public class NetworkRegistry { MinecraftUnregisterPayload.ID, MinecraftUnregisterPayload.STREAM_CODEC, ModdedNetworkQueryPayload.ID, ModdedNetworkQueryPayload.STREAM_CODEC, ModdedNetworkPayload.ID, ModdedNetworkPayload.STREAM_CODEC, - ModdedNetworkSetupFailedPayload.ID, ModdedNetworkSetupFailedPayload.STREAM_CODEC); + ModdedNetworkSetupFailedPayload.ID, ModdedNetworkSetupFailedPayload.STREAM_CODEC, + CommonVersionPayload.ID, CommonVersionPayload.STREAM_CODEC, + CommonRegisterPayload.ID, CommonRegisterPayload.STREAM_CODEC); /** * Registry of all custom payload handlers. The initial state of this map should reflect the protocols which support custom payloads. @@ -117,8 +120,9 @@ private NetworkRegistry() {} * Sets up the network registry by firing {@link RegisterPayloadHandlersEvent}, storing the resulting payload registrations in {@link #PAYLOAD_REGISTRATIONS}. */ public static void setup() { - if (setup) + if (setup) { throw new IllegalStateException("The network registry can only be setup once."); + } ModLoader.postEvent(new RegisterPayloadHandlersEvent()); @@ -244,7 +248,7 @@ public static boolean isModdedPayload(CustomPacketPayload payload) { */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static void handleModdedPayload(ServerCommonPacketListener listener, ServerboundCustomPayloadPacket packet) { - NetworkPayloadSetup payloadSetup = listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).get(); + NetworkPayloadSetup payloadSetup = ChannelAttributes.getPayloadSetup(listener.getConnection()); // Check if channels were negotiated. if (payloadSetup == null) { LOGGER.warn("Received a modded payload before channel negotiation; disconnecting."); @@ -290,7 +294,7 @@ public static void handleModdedPayload(ServerCommonPacketListener listener, Serv */ @SuppressWarnings({ "rawtypes", "unchecked" }) public static void handleModdedPayload(ClientCommonPacketListener listener, ClientboundCustomPayloadPacket packet) { - NetworkPayloadSetup payloadSetup = listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).get(); + NetworkPayloadSetup payloadSetup = ChannelAttributes.getPayloadSetup(listener.getConnection()); // Check if channels were negotiated. if (payloadSetup == null) { LOGGER.warn("Received a modded payload before channel negotiation; disconnecting."); @@ -343,9 +347,8 @@ public static void handleModdedPayload(ClientCommonPacketListener listener, Clie * @param play The play channels that the client has available. */ public static void initializeNeoForgeConnection(ServerConfigurationPacketListener listener, Map> clientChannels) { - listener.getConnection().channel().attr(ATTRIBUTE_CONNECTION_TYPE).set(listener.getConnectionType()); - listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty()); - listener.getConnection().channel().attr(ATTRIBUTE_FLOW).set(PacketFlow.SERVERBOUND); + ChannelAttributes.setPayloadSetup(listener.getConnection(), NetworkPayloadSetup.empty()); + ChannelAttributes.setConnectionType(listener.getConnection(), listener.getConnectionType()); Map results = new IdentityHashMap<>(); @@ -368,8 +371,7 @@ public static void initializeNeoForgeConnection(ServerConfigurationPacketListene NetworkPayloadSetup setup = NetworkPayloadSetup.from(results); - listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(setup); - + ChannelAttributes.setPayloadSetup(listener.getConnection(), setup); NetworkFilters.injectIfNecessary(listener.getConnection()); listener.send(new ModdedNetworkPayload(setup)); @@ -377,6 +379,7 @@ public static void initializeNeoForgeConnection(ServerConfigurationPacketListene nowListeningOn.addAll(getInitialListeningChannels(listener.flow())); nowListeningOn.addAll(setup.getChannels(ConnectionProtocol.CONFIGURATION).keySet()); listener.send(new MinecraftRegisterPayload(nowListeningOn.build())); + sendCommonPayloads(listener); } /** @@ -389,9 +392,8 @@ public static boolean initializeOtherConnection(ServerConfigurationPacketListene NetworkFilters.cleanIfNecessary(listener.getConnection()); // Because we are in vanilla land, no matter what we are not able to support any custom channels. - listener.getConnection().channel().attr(ATTRIBUTE_CONNECTION_TYPE).set(listener.getConnectionType()); - listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty()); - listener.getConnection().channel().attr(ATTRIBUTE_FLOW).set(PacketFlow.SERVERBOUND); + ChannelAttributes.setPayloadSetup(listener.getConnection(), NetworkPayloadSetup.empty()); + ChannelAttributes.setConnectionType(listener.getConnection(), listener.getConnectionType()); for (ConnectionProtocol protocol : PAYLOAD_REGISTRATIONS.keySet()) { NegotiationResult negotiationResult = NetworkComponentNegotiator.negotiate( @@ -417,6 +419,7 @@ public static boolean initializeOtherConnection(ServerConfigurationPacketListene .filter(registration -> registration.getValue().optional()) .forEach(registration -> nowListeningOn.add(registration.getKey())); listener.send(new MinecraftRegisterPayload(nowListeningOn.build())); + sendCommonPayloads(listener); return true; } @@ -439,7 +442,7 @@ public static void checkPacket(Packet packet, ServerCommonPacketListener list return; } - throw new UnsupportedOperationException("Payload {} may not be sent to the client!".formatted(customPayloadPacket.payload().type().id())); + throw new UnsupportedOperationException("Payload %s may not be sent to the client!".formatted(customPayloadPacket.payload().type().id())); } } @@ -461,24 +464,10 @@ public static void checkPacket(Packet packet, ClientCommonPacketListener list return; } - throw new UnsupportedOperationException("Payload {} may not be sent to the server!".formatted(customPayloadPacket.payload().type().id())); + throw new UnsupportedOperationException("Payload %s may not be sent to the server!".formatted(customPayloadPacket.payload().type().id())); } } - /** - * Returns a mutable map of the currently known ad-hoc channels. - */ - private static Set getKnownAdHocChannelsOfOtherEnd(Connection connection) { - var map = connection.channel().attr(ATTRIBUTE_ADHOC_CHANNELS).get(); - - if (map == null) { - map = new HashSet<>(); - connection.channel().attr(ATTRIBUTE_ADHOC_CHANNELS).set(map); - } - - return map; - } - /** * Checks if a given payload is ad-hoc readable, that is, may be read without a negotiated channel being present. *

@@ -517,9 +506,8 @@ public static void onNetworkQuery(ClientConfigurationPacketListener listener) { * @param play The play channels that were negotiated. */ public static void initializeNeoForgeConnection(ClientConfigurationPacketListener listener, NetworkPayloadSetup setup) { - listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(setup); - listener.getConnection().channel().attr(ATTRIBUTE_CONNECTION_TYPE).set(listener.getConnectionType()); - listener.getConnection().channel().attr(ATTRIBUTE_FLOW).set(PacketFlow.CLIENTBOUND); + ChannelAttributes.setPayloadSetup(listener.getConnection(), setup); + ChannelAttributes.setConnectionType(listener.getConnection(), listener.getConnectionType()); // Only inject filters once the payload setup is stored, as the filters might check for available channels. NetworkFilters.injectIfNecessary(listener.getConnection()); @@ -528,6 +516,7 @@ public static void initializeNeoForgeConnection(ClientConfigurationPacketListene nowListeningOn.addAll(getInitialListeningChannels(listener.flow())); nowListeningOn.addAll(setup.getChannels(ConnectionProtocol.CONFIGURATION).keySet()); listener.send(new MinecraftRegisterPayload(nowListeningOn.build())); + sendCommonPayloads(listener); } /** @@ -545,9 +534,8 @@ public static void initializeNeoForgeConnection(ClientConfigurationPacketListene */ public static void initializeOtherConnection(ClientConfigurationPacketListener listener) { // Because we are in vanilla land, no matter what we are not able to support any custom channels. - listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty()); - listener.getConnection().channel().attr(ATTRIBUTE_CONNECTION_TYPE).set(listener.getConnectionType()); - listener.getConnection().channel().attr(ATTRIBUTE_FLOW).set(PacketFlow.CLIENTBOUND); + ChannelAttributes.setPayloadSetup(listener.getConnection(), NetworkPayloadSetup.empty()); + ChannelAttributes.setConnectionType(listener.getConnection(), listener.getConnectionType()); for (ConnectionProtocol protocol : PAYLOAD_REGISTRATIONS.keySet()) { NegotiationResult negotiationResult = NetworkComponentNegotiator.negotiate( @@ -581,6 +569,7 @@ public static void initializeOtherConnection(ClientConfigurationPacketListener l .filter(registration -> registration.getValue().optional()) .forEach(registration -> nowListeningOn.add(registration.getKey())); listener.send(new MinecraftRegisterPayload(nowListeningOn.build())); + sendCommonPayloads(listener); } /** @@ -603,20 +592,24 @@ public static boolean hasChannel(ICommonPacketListener listener, ResourceLocatio * @return True if the connection has a connection setup that can transmit the given payload id, false otherwise. */ public static boolean hasChannel(Connection connection, @Nullable ConnectionProtocol protocol, ResourceLocation payloadId) { - NetworkPayloadSetup payloadSetup = connection.channel().attr(ATTRIBUTE_PAYLOAD_SETUP).get(); - if (payloadSetup == null) { - return getKnownAdHocChannelsOfOtherEnd(connection).contains(payloadId); + NetworkPayloadSetup payloadSetup = ChannelAttributes.getPayloadSetup(connection); + if (payloadSetup != null) { + // If a protocol is specified, only check against channels for that protocol + // Otherwise check against all protocols. + if (protocol != null && payloadSetup.getChannels(protocol).containsKey(payloadId)) { + return true; + } else if (protocol == null && payloadSetup.channels().values().stream().anyMatch(map -> map.containsKey(payloadId))) { + return true; + } } - // If a protocol is specified, only check against channels for that protocol - // Otherwise check against all protocols. - if (protocol != null && payloadSetup.getChannels(protocol).containsKey(payloadId)) { - return true; - } else if (protocol == null && payloadSetup.channels().values().stream().anyMatch(map -> map.containsKey(payloadId))) { + // Support declaration of additional channels through c:register + if (protocol != null && ChannelAttributes.getOrCreateCommonChannels(connection, protocol).contains(payloadId)) { return true; } - return getKnownAdHocChannelsOfOtherEnd(connection).contains(payloadId); + // Always fall back to ad-hoc channels if we failed to find an entry in the payload setup. + return ChannelAttributes.getOrCreateAdHocChannels(connection).contains(payloadId); } /** @@ -628,7 +621,7 @@ public static boolean hasChannel(Connection connection, @Nullable ConnectionProt * @return The filtered packets. */ public static List> filterGameBundlePackets(ChannelHandlerContext context, Iterable> packets) { - final NetworkPayloadSetup payloadSetup = context.channel().attr(ATTRIBUTE_PAYLOAD_SETUP).get(); + NetworkPayloadSetup payloadSetup = context.channel().attr(ChannelAttributes.PAYLOAD_SETUP).get(); if (payloadSetup == null) { LOGGER.trace("Somebody tried to filter bundled packets to a client that has not negotiated with the server. Not filtering."); return Lists.newArrayList(packets.iterator()); @@ -666,10 +659,9 @@ public static List> filterGameBundlePackets * @param connection The connection to configure. */ @VisibleForTesting - public static void configureMockConnection(final Connection connection) { - connection.channel().attr(ATTRIBUTE_CONNECTION_TYPE).set(ConnectionType.NEOFORGE); - connection.channel().attr(ATTRIBUTE_FLOW).set(PacketFlow.SERVERBOUND); - connection.channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty()); + public static void configureMockConnection(Connection connection) { + ChannelAttributes.setPayloadSetup(connection, NetworkPayloadSetup.empty()); + ChannelAttributes.setConnectionType(connection, ConnectionType.NEOFORGE); NetworkPayloadSetup setup = new NetworkPayloadSetup( PAYLOAD_REGISTRATIONS.entrySet().stream() @@ -677,7 +669,7 @@ public static void configureMockConnection(final Connection connection) { entry.getValue().values().stream().map(reg -> new NetworkChannel(reg.id(), reg.version())).collect(Collectors.toMap(NetworkChannel::id, Function.identity())))) .collect(Collectors.toMap(Entry::getKey, Entry::getValue))); - connection.channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(setup); + ChannelAttributes.setPayloadSetup(connection, setup); NetworkFilters.injectIfNecessary(connection); } @@ -691,7 +683,7 @@ public static void configureMockConnection(final Connection connection) { * @param resourceLocations The resource locations to add. */ public static void onMinecraftRegister(Connection connection, Set resourceLocations) { - getKnownAdHocChannelsOfOtherEnd(connection).addAll(resourceLocations); + ChannelAttributes.getOrCreateAdHocChannels(connection).addAll(resourceLocations); } /** @@ -703,7 +695,7 @@ public static void onMinecraftRegister(Connection connection, Set resourceLocations) { - getKnownAdHocChannelsOfOtherEnd(connection).removeAll(resourceLocations); + ChannelAttributes.getOrCreateAdHocChannels(connection).removeAll(resourceLocations); } /** @@ -725,6 +717,57 @@ public static Set getInitialServerUnregisterChannels() { return nowForgottenChannels.build(); } + /** + * Called when a {@link CommonVersionPayload} is received. + * Triggers a disconnect if none of the supplied version match our supported ones. + * Since we only support one version, we don't need to do further handling or record the "active" version just yet. + *

+ * Invoked on the network thread. + * + * @param connection The current connection. + * @param payload The incoming version payload. + */ + public static void checkCommonVersion(Connection connection, CommonVersionPayload payload) { + List otherVersions = payload.versions(); + if (otherVersions.stream().noneMatch(SUPPORTED_COMMON_NETWORKING_VERSIONS::contains)) { + String versions = String.join(", ", SUPPORTED_COMMON_NETWORKING_VERSIONS.stream().map(i -> i.toString()).toList()); + connection.disconnect(Component.literal("Unsupported common network version. This installation of NeoForge only supports: " + versions)); + } + } + + /** + * Replaces any existing common channels with the incoming ones from a {@link CommonRegisterPayload}. + *

+ * Invoked on the network thread. + * + * @param connection The connection to add the channels to. + * @param payload The incoming register payload. + */ + public static void onCommonRegister(Connection connection, CommonRegisterPayload payload) { + Set channels = ChannelAttributes.getOrCreateCommonChannels(connection, payload.protocol()); + channels.clear(); + channels.addAll(payload.channels()); + } + + public static Set getCommonPlayChannels(PacketFlow flow) { + return PAYLOAD_REGISTRATIONS.get(ConnectionProtocol.PLAY) + .entrySet().stream() + .filter(registration -> registration.getValue().matchesFlow(flow)) + .filter(registration -> registration.getValue().optional()) + .map(registration -> registration.getKey()) + .collect(Collectors.toSet()); + } + + public static void sendCommonPayloads(ICommonPacketListener listener) { + if (listener.hasChannel(CommonVersionPayload.ID)) { + listener.send(new CommonVersionPayload()); + } + + if (listener.hasChannel(CommonRegisterPayload.ID)) { + listener.send(new CommonRegisterPayload(1, ConnectionProtocol.PLAY, getCommonPlayChannels(listener.flow()))); + } + } + /** * Invoked when the configuration phase of a connection is completed. *

@@ -733,7 +776,7 @@ public static Set getInitialServerUnregisterChannels() { * @param listener */ public static void onConfigurationFinished(ICommonPacketListener listener) { - final NetworkPayloadSetup setup = listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).get(); + NetworkPayloadSetup setup = ChannelAttributes.getPayloadSetup(listener.getConnection()); if (setup == null) { LOGGER.error("Somebody tried to finish the configuration phase of a connection that has not performed channel negotiation. Not finishing configuration."); return; @@ -751,16 +794,13 @@ public static void onConfigurationFinished(ICommonPacketListener listener) { nowListeningOn.add(ModdedNetworkQueryPayload.ID); } else { // For non-Neo connections, send the registered channels - PAYLOAD_REGISTRATIONS.get(ConnectionProtocol.PLAY).entrySet().stream() - .filter(registration -> registration.getValue().matchesFlow(listener.flow())) - .filter(registration -> registration.getValue().optional()) - .forEach(registration -> nowListeningOn.add(registration.getKey())); + nowListeningOn.addAll(getCommonPlayChannels(listener.flow())); } listener.send(new MinecraftRegisterPayload(nowListeningOn.build())); } public static ConnectionType getConnectionType(Connection connection) { - return Objects.requireNonNull(connection.channel().attr(ATTRIBUTE_CONNECTION_TYPE).get(), "no connection type on connection!"); + return Objects.requireNonNull(ChannelAttributes.getConnectionType(connection), "no connection type on connection!"); } /** From 16e8d5ab23ab2491f3a40c9f5682fd89fae556fe Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Mon, 12 Aug 2024 08:09:10 -0400 Subject: [PATCH 025/125] Add chorus fruit to `c:foods/fruit` tag (#1438) --- src/generated/resources/data/c/tags/item/foods/fruit.json | 1 + .../neoforge/common/data/internal/NeoForgeItemTagsProvider.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/generated/resources/data/c/tags/item/foods/fruit.json b/src/generated/resources/data/c/tags/item/foods/fruit.json index d8703e8edf..419d207c10 100644 --- a/src/generated/resources/data/c/tags/item/foods/fruit.json +++ b/src/generated/resources/data/c/tags/item/foods/fruit.json @@ -3,6 +3,7 @@ "minecraft:apple", "minecraft:golden_apple", "minecraft:enchanted_golden_apple", + "minecraft:chorus_fruit", "minecraft:melon_slice", { "id": "#c:foods/fruits", diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java index a01e03124f..e521ca1429 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java @@ -101,7 +101,7 @@ public void addTags(HolderLookup.Provider lookupProvider) { copy(Tags.Blocks.FENCES_NETHER_BRICK, Tags.Items.FENCES_NETHER_BRICK); copy(Tags.Blocks.FENCES_WOODEN, Tags.Items.FENCES_WOODEN); tag(Tags.Items.FERTILIZERS).add(Items.BONE_MEAL); - tag(Tags.Items.FOODS_FRUIT).add(Items.APPLE, Items.GOLDEN_APPLE, Items.ENCHANTED_GOLDEN_APPLE).add(Items.MELON_SLICE); + tag(Tags.Items.FOODS_FRUIT).add(Items.APPLE, Items.GOLDEN_APPLE, Items.ENCHANTED_GOLDEN_APPLE, Items.CHORUS_FRUIT, Items.MELON_SLICE); tag(Tags.Items.FOODS_VEGETABLE).add(Items.CARROT, Items.GOLDEN_CARROT, Items.POTATO, Items.BEETROOT); tag(Tags.Items.FOODS_BERRY).add(Items.SWEET_BERRIES, Items.GLOW_BERRIES); tag(Tags.Items.FOODS_BREAD).add(Items.BREAD); From 079224a19b9fa09c406e76e83bae842e0254aa8b Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Mon, 12 Aug 2024 08:09:44 -0400 Subject: [PATCH 026/125] Add more crops tag (Cocoa Beans, Cactus, Melon, Pumpkin, and Sugar Cane) (#1432) --- src/generated/resources/assets/c/lang/en_us.json | 5 +++++ src/generated/resources/data/c/tags/item/crops.json | 5 +++++ .../resources/data/c/tags/item/crops/cactus.json | 5 +++++ .../resources/data/c/tags/item/crops/cocoa_bean.json | 5 +++++ .../resources/data/c/tags/item/crops/melon.json | 5 +++++ .../resources/data/c/tags/item/crops/pumpkin.json | 5 +++++ .../resources/data/c/tags/item/crops/sugar_cane.json | 5 +++++ src/main/java/net/neoforged/neoforge/common/Tags.java | 9 +++++++++ .../data/internal/NeoForgeItemTagsProvider.java | 11 ++++++++++- .../data/internal/NeoForgeLanguageProvider.java | 5 +++++ 10 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 src/generated/resources/data/c/tags/item/crops/cactus.json create mode 100644 src/generated/resources/data/c/tags/item/crops/cocoa_bean.json create mode 100644 src/generated/resources/data/c/tags/item/crops/melon.json create mode 100644 src/generated/resources/data/c/tags/item/crops/pumpkin.json create mode 100644 src/generated/resources/data/c/tags/item/crops/sugar_cane.json diff --git a/src/generated/resources/assets/c/lang/en_us.json b/src/generated/resources/assets/c/lang/en_us.json index 0854e0535a..880fe2db09 100644 --- a/src/generated/resources/assets/c/lang/en_us.json +++ b/src/generated/resources/assets/c/lang/en_us.json @@ -165,9 +165,14 @@ "tag.item.c.concretes": "Concretes", "tag.item.c.crops": "Crops", "tag.item.c.crops.beetroot": "Beetroot Crops", + "tag.item.c.crops.cactus": "Cactus Crops", "tag.item.c.crops.carrot": "Carrot Crops", + "tag.item.c.crops.cocoa_bean": "Cocoa Bean Crops", + "tag.item.c.crops.melon": "Melon Crops", "tag.item.c.crops.nether_wart": "Nether Wart Crops", "tag.item.c.crops.potato": "Potato Crops", + "tag.item.c.crops.pumpkin": "Pumpkin Crops", + "tag.item.c.crops.sugar_cane": "Sugar Cane Crops", "tag.item.c.crops.wheat": "Wheat Crops", "tag.item.c.dusts": "Dusts", "tag.item.c.dusts.glowstone": "Glowstone Dusts", diff --git a/src/generated/resources/data/c/tags/item/crops.json b/src/generated/resources/data/c/tags/item/crops.json index eb4402976e..7a0bad9cab 100644 --- a/src/generated/resources/data/c/tags/item/crops.json +++ b/src/generated/resources/data/c/tags/item/crops.json @@ -1,9 +1,14 @@ { "values": [ "#c:crops/beetroot", + "#c:crops/cactus", "#c:crops/carrot", + "#c:crops/cocoa_bean", + "#c:crops/melon", "#c:crops/nether_wart", "#c:crops/potato", + "#c:crops/pumpkin", + "#c:crops/sugar_cane", "#c:crops/wheat", { "id": "#forge:crops", diff --git a/src/generated/resources/data/c/tags/item/crops/cactus.json b/src/generated/resources/data/c/tags/item/crops/cactus.json new file mode 100644 index 0000000000..2624ccf244 --- /dev/null +++ b/src/generated/resources/data/c/tags/item/crops/cactus.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:cactus" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/crops/cocoa_bean.json b/src/generated/resources/data/c/tags/item/crops/cocoa_bean.json new file mode 100644 index 0000000000..a4efea9bb2 --- /dev/null +++ b/src/generated/resources/data/c/tags/item/crops/cocoa_bean.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:cocoa_beans" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/crops/melon.json b/src/generated/resources/data/c/tags/item/crops/melon.json new file mode 100644 index 0000000000..187ed669df --- /dev/null +++ b/src/generated/resources/data/c/tags/item/crops/melon.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:melon" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/crops/pumpkin.json b/src/generated/resources/data/c/tags/item/crops/pumpkin.json new file mode 100644 index 0000000000..fb0859532b --- /dev/null +++ b/src/generated/resources/data/c/tags/item/crops/pumpkin.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:pumpkin" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/crops/sugar_cane.json b/src/generated/resources/data/c/tags/item/crops/sugar_cane.json new file mode 100644 index 0000000000..6e3dc8c982 --- /dev/null +++ b/src/generated/resources/data/c/tags/item/crops/sugar_cane.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:sugar_cane" + ] +} \ No newline at end of file diff --git a/src/main/java/net/neoforged/neoforge/common/Tags.java b/src/main/java/net/neoforged/neoforge/common/Tags.java index a7982f2ae0..fbb4bb6888 100644 --- a/src/main/java/net/neoforged/neoforge/common/Tags.java +++ b/src/main/java/net/neoforged/neoforge/common/Tags.java @@ -315,11 +315,20 @@ public static class Items { * For blocks that are similar to amethyst where they have clusters forming from budding blocks */ public static final TagKey CLUSTERS = tag("clusters"); + /** + * For raw materials harvested from growable plants. Crop items can be edible like carrots or + * non-edible like wheat and cocoa beans. + */ public static final TagKey CROPS = tag("crops"); public static final TagKey CROPS_BEETROOT = tag("crops/beetroot"); + public static final TagKey CROPS_CACTUS = tag("crops/cactus"); public static final TagKey CROPS_CARROT = tag("crops/carrot"); + public static final TagKey CROPS_COCOA_BEAN = tag("crops/cocoa_bean"); + public static final TagKey CROPS_MELON = tag("crops/melon"); public static final TagKey CROPS_NETHER_WART = tag("crops/nether_wart"); public static final TagKey CROPS_POTATO = tag("crops/potato"); + public static final TagKey CROPS_PUMPKIN = tag("crops/pumpkin"); + public static final TagKey CROPS_SUGAR_CANE = tag("crops/sugar_cane"); public static final TagKey CROPS_WHEAT = tag("crops/wheat"); public static final TagKey DUSTS = tag("dusts"); public static final TagKey DUSTS_REDSTONE = tag("dusts/redstone"); diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java index e521ca1429..786b481659 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java @@ -66,11 +66,20 @@ public void addTags(HolderLookup.Provider lookupProvider) { .add(Items.CYAN_CONCRETE_POWDER).add(Items.PURPLE_CONCRETE_POWDER).add(Items.BLUE_CONCRETE_POWDER) .add(Items.BROWN_CONCRETE_POWDER).add(Items.GREEN_CONCRETE_POWDER).add(Items.RED_CONCRETE_POWDER) .add(Items.BLACK_CONCRETE_POWDER); - tag(Tags.Items.CROPS).addTags(Tags.Items.CROPS_BEETROOT, Tags.Items.CROPS_CARROT, Tags.Items.CROPS_NETHER_WART, Tags.Items.CROPS_POTATO, Tags.Items.CROPS_WHEAT); + tag(Tags.Items.CROPS).addTags( + Tags.Items.CROPS_BEETROOT, Tags.Items.CROPS_CACTUS, Tags.Items.CROPS_CARROT, + Tags.Items.CROPS_COCOA_BEAN, Tags.Items.CROPS_MELON, Tags.Items.CROPS_NETHER_WART, + Tags.Items.CROPS_POTATO, Tags.Items.CROPS_PUMPKIN, Tags.Items.CROPS_SUGAR_CANE, + Tags.Items.CROPS_WHEAT); tag(Tags.Items.CROPS_BEETROOT).add(Items.BEETROOT); + tag(Tags.Items.CROPS_CACTUS).add(Items.CACTUS); tag(Tags.Items.CROPS_CARROT).add(Items.CARROT); + tag(Tags.Items.CROPS_COCOA_BEAN).add(Items.COCOA_BEANS); + tag(Tags.Items.CROPS_MELON).add(Items.MELON); tag(Tags.Items.CROPS_NETHER_WART).add(Items.NETHER_WART); tag(Tags.Items.CROPS_POTATO).add(Items.POTATO); + tag(Tags.Items.CROPS_PUMPKIN).add(Items.PUMPKIN); + tag(Tags.Items.CROPS_SUGAR_CANE).add(Items.SUGAR_CANE); tag(Tags.Items.CROPS_WHEAT).add(Items.WHEAT); addColored(Tags.Items.DYED, "{color}_banner"); addColored(Tags.Items.DYED, "{color}_bed"); diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java index e6b399d3e1..420102f12d 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java @@ -152,9 +152,14 @@ protected void addTranslations() { add(Tags.Items.CONCRETE_POWDERS, "Concrete Powders"); add(Tags.Items.CROPS, "Crops"); add(Tags.Items.CROPS_BEETROOT, "Beetroot Crops"); + add(Tags.Items.CROPS_CACTUS, "Cactus Crops"); add(Tags.Items.CROPS_CARROT, "Carrot Crops"); + add(Tags.Items.CROPS_COCOA_BEAN, "Cocoa Bean Crops"); + add(Tags.Items.CROPS_MELON, "Melon Crops"); add(Tags.Items.CROPS_NETHER_WART, "Nether Wart Crops"); add(Tags.Items.CROPS_POTATO, "Potato Crops"); + add(Tags.Items.CROPS_PUMPKIN, "Pumpkin Crops"); + add(Tags.Items.CROPS_SUGAR_CANE, "Sugar Cane Crops"); add(Tags.Items.CROPS_WHEAT, "Wheat Crops"); add(Tags.Items.DUSTS, "Dusts"); add(Tags.Items.DUSTS_GLOWSTONE, "Glowstone Dusts"); From e967c170ec505f9cfa40b53caf8a56310b74c874 Mon Sep 17 00:00:00 2001 From: "Monica S." Date: Tue, 13 Aug 2024 23:20:45 +0100 Subject: [PATCH 027/125] Deprecate DummySavedData for removal and remove associated patches (#1431) --- .../level/storage/DimensionDataStorage.java.patch | 15 +-------------- .../neoforge/common/util/DummySavedData.java | 13 +++++++++++++ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/patches/net/minecraft/world/level/storage/DimensionDataStorage.java.patch b/patches/net/minecraft/world/level/storage/DimensionDataStorage.java.patch index feb8a8fee4..ecf3e43153 100644 --- a/patches/net/minecraft/world/level/storage/DimensionDataStorage.java.patch +++ b/patches/net/minecraft/world/level/storage/DimensionDataStorage.java.patch @@ -1,19 +1,6 @@ --- a/net/minecraft/world/level/storage/DimensionDataStorage.java +++ b/net/minecraft/world/level/storage/DimensionDataStorage.java -@@ -54,16 +_,20 @@ - @Nullable - public T get(SavedData.Factory p_295091_, String p_164860_) { - SavedData saveddata = this.cache.get(p_164860_); -+ if (saveddata == net.neoforged.neoforge.common.util.DummySavedData.DUMMY) return null; - if (saveddata == null && !this.cache.containsKey(p_164860_)) { - saveddata = this.readSavedData(p_295091_.deserializer(), p_295091_.type(), p_164860_); - this.cache.put(p_164860_, saveddata); -+ } else if (saveddata == null) { -+ this.cache.put(p_164860_, net.neoforged.neoforge.common.util.DummySavedData.DUMMY); -+ return null; - } - - return (T)saveddata; +@@ -63,7 +_,7 @@ } @Nullable diff --git a/src/main/java/net/neoforged/neoforge/common/util/DummySavedData.java b/src/main/java/net/neoforged/neoforge/common/util/DummySavedData.java index 26ec0d5e65..b853f3de51 100644 --- a/src/main/java/net/neoforged/neoforge/common/util/DummySavedData.java +++ b/src/main/java/net/neoforged/neoforge/common/util/DummySavedData.java @@ -5,10 +5,17 @@ package net.neoforged.neoforge.common.util; +import java.io.File; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.saveddata.SavedData; +/** + * A no-op {@link SavedData} implementation which does not store data. + * + * @deprecated This type often causes more data corruption than is worth. + */ +@Deprecated(since = "1.21.1", forRemoval = true) public class DummySavedData extends SavedData { public static final DummySavedData DUMMY = new DummySavedData(); @@ -21,4 +28,10 @@ public CompoundTag save(final CompoundTag compound, HolderLookup.Provider provid // NOOP return null; } + + @Override + public void save(final File file, final HolderLookup.Provider provider) { + // Do nothing, because we don't want to overwrite the saved data + // that may already be here. + } } From 3e86c6610c04c3c6bfb28768429da8ea9766b3ac Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Wed, 14 Aug 2024 22:25:51 -0400 Subject: [PATCH 028/125] Cleanup tag translation datagen code (#1436) --- .../java/net/neoforged/neoforge/common/Tags.java | 9 ++------- .../neoforge/common/data/LanguageProvider.java | 16 ++-------------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/common/Tags.java b/src/main/java/net/neoforged/neoforge/common/Tags.java index fbb4bb6888..de73509989 100644 --- a/src/main/java/net/neoforged/neoforge/common/Tags.java +++ b/src/main/java/net/neoforged/neoforge/common/Tags.java @@ -1137,16 +1137,11 @@ public static String getTagTranslationKey(TagKey tagKey) { ResourceLocation registryIdentifier = tagKey.registry().location(); ResourceLocation tagIdentifier = tagKey.location(); - if (!registryIdentifier.getNamespace().equals("minecraft")) { - stringBuilder.append(registryIdentifier.getNamespace()) - .append("."); - } - - stringBuilder.append(registryIdentifier.getPath().replace("/", ".")) + stringBuilder.append(registryIdentifier.toShortLanguageKey().replace("/", ".")) .append(".") .append(tagIdentifier.getNamespace()) .append(".") - .append(tagIdentifier.getPath().replace("/", ".").replace(":", ".")); + .append(tagIdentifier.getPath().replace("/", ".")); return stringBuilder.toString(); } diff --git a/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java b/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java index 5ca9eec7b6..8978f04410 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java @@ -14,13 +14,13 @@ import net.minecraft.data.CachedOutput; import net.minecraft.data.DataProvider; import net.minecraft.data.PackOutput; -import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.entity.EntityType; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Block; +import net.neoforged.neoforge.common.Tags; public abstract class LanguageProvider implements DataProvider { private final Map data = new TreeMap<>(); @@ -114,19 +114,7 @@ public void addTag(Supplier> key, String name) { } public void add(TagKey tagKey, String name) { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("tag."); - - ResourceLocation registryIdentifier = tagKey.registry().location(); - ResourceLocation tagResourceLocation = tagKey.location(); - - stringBuilder.append(registryIdentifier.toShortLanguageKey().replace("/", ".")) - .append(".") - .append(tagResourceLocation.getNamespace()) - .append(".") - .append(tagResourceLocation.getPath().replace("/", ".").replace(":", ".")); - - add(stringBuilder.toString(), name); + add(Tags.getTagTranslationKey(tagKey), name); } public void add(String key, String value) { From 5448483eb49b19026276b5841a6ea9a7c07a10c6 Mon Sep 17 00:00:00 2001 From: Ancient <40538255+ArcAnc@users.noreply.github.com> Date: Thu, 15 Aug 2024 05:26:02 +0300 Subject: [PATCH 029/125] Added method to make creating faces on models less annoying (#1214) --- .../client/model/generators/ModelBuilder.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/net/neoforged/neoforge/client/model/generators/ModelBuilder.java b/src/main/java/net/neoforged/neoforge/client/model/generators/ModelBuilder.java index b9c605903e..c96419f87f 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/generators/ModelBuilder.java +++ b/src/main/java/net/neoforged/neoforge/client/model/generators/ModelBuilder.java @@ -17,6 +17,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.stream.Collectors; @@ -480,6 +481,20 @@ public ElementBuilder allFaces(BiConsumer action) { return this; } + /** + * Creates possible faces for the model as needed, excluding those + * specified in the second argument, and then applies a function to modify added faces. + * + * @param action the function to apply to each direction + * @param exc directions which will be excluded from adding to model file + * @return this builder + * @throws NullPointerException if {@code action} is {@code null} + */ + public ElementBuilder allFacesExcept(BiConsumer action, Set exc) { + Arrays.stream(Direction.values()).filter(d -> !exc.contains(d)).forEach(d -> action.accept(d, face(d))); + return this; + } + /** * Modify all existing faces dynamically using a function. * From fc455e640eedd1a14016fd061f50b83b3b180e40 Mon Sep 17 00:00:00 2001 From: Luke Bemish Date: Thu, 15 Aug 2024 02:04:44 -0500 Subject: [PATCH 030/125] Add `neoforge:overlays` field for cleaner conditional overlays in some use cases (#1425) --- .../server/packs/OverlayMetadataSection.java.patch | 8 +++++++- .../server/packs/repository/Pack.java.patch | 9 ++++++++- .../data/GeneratingOverlayMetadataSection.java | 1 + .../neoforge/resource/ResourcePackLoader.java | 10 +++++++++- tests/src/generated/resources/pack.mcmeta | 11 +++++++++++ .../neoforge/debug/resources/OverlayTests.java | 12 ++++++++++++ .../neoforge/oldtest/DataGeneratorTest.java | 2 ++ .../tags/block}/must_be_overlayed.json | 0 .../tags/block/must_be_overlayed.json | 5 +++++ .../tags/block/must_be_overlayed.json | 5 +++++ 10 files changed, 60 insertions(+), 3 deletions(-) rename tests/src/main/resources/data/{pack_overlays_test/tags/blocks => neoforge_overlays_test/tags/block}/must_be_overlayed.json (100%) create mode 100644 tests/src/main/resources/data/pack_overlays_test/tags/block/must_be_overlayed.json create mode 100644 tests/src/main/resources/neoforge_overlays_test/data/neoforge_overlays_test/tags/block/must_be_overlayed.json diff --git a/patches/net/minecraft/server/packs/OverlayMetadataSection.java.patch b/patches/net/minecraft/server/packs/OverlayMetadataSection.java.patch index 2e54cc8665..4e52d4269f 100644 --- a/patches/net/minecraft/server/packs/OverlayMetadataSection.java.patch +++ b/patches/net/minecraft/server/packs/OverlayMetadataSection.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/packs/OverlayMetadataSection.java +++ b/net/minecraft/server/packs/OverlayMetadataSection.java -@@ -12,7 +_,7 @@ +@@ -12,10 +_,13 @@ public record OverlayMetadataSection(List overlays) { private static final Pattern DIR_VALIDATOR = Pattern.compile("[-_a-zA-Z0-9.]+"); private static final Codec CODEC = RecordCodecBuilder.create( @@ -9,3 +9,9 @@ .apply(p_294898_, OverlayMetadataSection::new) ); public static final MetadataSectionType TYPE = MetadataSectionType.fromCodec("overlays", CODEC); ++ // Neo: alternative metadata section that will only be loaded on neoforged. Useful for making datapacks with special ++ // logic on different modloaders, or when running on neo vs in vanilla, without having to invert the main pack and overlays ++ public static final MetadataSectionType NEOFORGE_TYPE = MetadataSectionType.fromCodec("neoforge:overlays", CODEC); + + private static DataResult validateOverlayDir(String p_296447_) { + return !DIR_VALIDATOR.matcher(p_296447_).matches() diff --git a/patches/net/minecraft/server/packs/repository/Pack.java.patch b/patches/net/minecraft/server/packs/repository/Pack.java.patch index a57d030d23..953df7b321 100644 --- a/patches/net/minecraft/server/packs/repository/Pack.java.patch +++ b/patches/net/minecraft/server/packs/repository/Pack.java.patch @@ -52,11 +52,18 @@ this.location = p_326123_; this.resources = p_249377_; this.metadata = p_326375_; -@@ -55,7 +_,7 @@ +@@ -55,7 +_,14 @@ PackCompatibility packcompatibility = PackCompatibility.forVersion(inclusiverange, p_326341_); OverlayMetadataSection overlaymetadatasection = packresources.getMetadataSection(OverlayMetadataSection.TYPE); List list = overlaymetadatasection != null ? overlaymetadatasection.overlaysForVersion(p_326341_) : List.of(); - pack$metadata = new Pack.Metadata(packmetadatasection.description(), packcompatibility, featureflagset, list); ++ // Neo: add `neoforge:overlays` overlays as well ++ var neoOverlays = packresources.getMetadataSection(OverlayMetadataSection.NEOFORGE_TYPE); ++ if (neoOverlays != null) { ++ list = new java.util.ArrayList<>(list); ++ list.addAll(neoOverlays.overlaysForVersion(p_326341_)); ++ list = List.copyOf(list); ++ } + pack$metadata = new Pack.Metadata(packmetadatasection.description(), packcompatibility, featureflagset, list, packresources.isHidden()); } diff --git a/src/main/java/net/neoforged/neoforge/common/data/GeneratingOverlayMetadataSection.java b/src/main/java/net/neoforged/neoforge/common/data/GeneratingOverlayMetadataSection.java index 90c51b14c8..431fdb4a1f 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/GeneratingOverlayMetadataSection.java +++ b/src/main/java/net/neoforged/neoforge/common/data/GeneratingOverlayMetadataSection.java @@ -23,4 +23,5 @@ public record GeneratingOverlayMetadataSection(List TYPE = MetadataSectionType.fromCodec("overlays", CODEC); + public static final MetadataSectionType NEOFORGE_TYPE = MetadataSectionType.fromCodec("neoforge:overlays", CODEC); } diff --git a/src/main/java/net/neoforged/neoforge/resource/ResourcePackLoader.java b/src/main/java/net/neoforged/neoforge/resource/ResourcePackLoader.java index 60a527100f..049aae13ca 100644 --- a/src/main/java/net/neoforged/neoforge/resource/ResourcePackLoader.java +++ b/src/main/java/net/neoforged/neoforge/resource/ResourcePackLoader.java @@ -166,10 +166,18 @@ private static Pack.Metadata readMeta(PackType type, PackLocationInfo location, .map(FeatureFlagsMetadataSection::flags) .orElse(FeatureFlagSet.of()); - final List overlays = Optional.ofNullable(primaryResources.getMetadataSection(OverlayMetadataSection.TYPE)) + final List vanillaOverlays = Optional.ofNullable(primaryResources.getMetadataSection(OverlayMetadataSection.TYPE)) .map(section -> section.overlaysForVersion(currentVersion)) .orElse(List.of()); + final List neoOverlays = Optional.ofNullable(primaryResources.getMetadataSection(OverlayMetadataSection.NEOFORGE_TYPE)) + .map(section -> section.overlaysForVersion(currentVersion)) + .orElse(List.of()); + + List overlays = new ArrayList<>(vanillaOverlays); + overlays.addAll(neoOverlays); + overlays = List.copyOf(overlays); + if (metadata == null) { return new Pack.Metadata(location.title(), PackCompatibility.COMPATIBLE, flags, overlays, primaryResources.isHidden()); } diff --git a/tests/src/generated/resources/pack.mcmeta b/tests/src/generated/resources/pack.mcmeta index 959f6d8343..fb49f045f8 100644 --- a/tests/src/generated/resources/pack.mcmeta +++ b/tests/src/generated/resources/pack.mcmeta @@ -1,4 +1,15 @@ { + "neoforge:overlays": { + "entries": [ + { + "directory": "neoforge_overlays_test", + "formats": [ + 0, + 2147483647 + ] + } + ] + }, "overlays": { "entries": [ { diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/resources/OverlayTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/resources/OverlayTests.java index 299b8f257d..56d7f6deab 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/resources/OverlayTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/resources/OverlayTests.java @@ -19,6 +19,18 @@ public class OverlayTests { public static final String GROUP = "resources"; + @GameTest + @EmptyTemplate + @TestHolder(description = "Tests if neoforge:overlays overlays from mods work") + static void neoforgeOverlay(final DynamicTest test) { + var tagKey = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("neoforge_overlays_test", "must_be_overlayed")); + test.onGameTest(helper -> { + helper.assertTrue(Blocks.REDSTONE_BLOCK.defaultBlockState().is(tagKey), "Overlay was not applied"); + helper.assertFalse(Blocks.COBBLESTONE.defaultBlockState().is(tagKey), "File under overlay was applied"); + helper.succeed(); + }); + } + @GameTest @EmptyTemplate @TestHolder(description = "Tests if pack overlays from mods work") diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java index 0ba5be5f57..f92fb5b82d 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java @@ -162,6 +162,8 @@ public static void gatherData(GatherDataEvent event) { CompletableFuture lookupProvider = event.getLookupProvider(); gen.addProvider(true, new PackMetadataGenerator(packOutput) + .add(GeneratingOverlayMetadataSection.NEOFORGE_TYPE, new GeneratingOverlayMetadataSection(List.of( + new WithConditions<>(new OverlayMetadataSection.OverlayEntry(new InclusiveRange<>(0, Integer.MAX_VALUE), "neoforge_overlays_test"))))) .add(GeneratingOverlayMetadataSection.TYPE, new GeneratingOverlayMetadataSection(List.of( new WithConditions<>(new OverlayMetadataSection.OverlayEntry(new InclusiveRange<>(0, Integer.MAX_VALUE), "pack_overlays_test")), new WithConditions<>(new OverlayMetadataSection.OverlayEntry(new InclusiveRange<>(0, Integer.MAX_VALUE), "conditional_overlays_enabled"), new ModLoadedCondition("neoforge")), diff --git a/tests/src/main/resources/data/pack_overlays_test/tags/blocks/must_be_overlayed.json b/tests/src/main/resources/data/neoforge_overlays_test/tags/block/must_be_overlayed.json similarity index 100% rename from tests/src/main/resources/data/pack_overlays_test/tags/blocks/must_be_overlayed.json rename to tests/src/main/resources/data/neoforge_overlays_test/tags/block/must_be_overlayed.json diff --git a/tests/src/main/resources/data/pack_overlays_test/tags/block/must_be_overlayed.json b/tests/src/main/resources/data/pack_overlays_test/tags/block/must_be_overlayed.json new file mode 100644 index 0000000000..0865115273 --- /dev/null +++ b/tests/src/main/resources/data/pack_overlays_test/tags/block/must_be_overlayed.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:cobblestone" + ] +} diff --git a/tests/src/main/resources/neoforge_overlays_test/data/neoforge_overlays_test/tags/block/must_be_overlayed.json b/tests/src/main/resources/neoforge_overlays_test/data/neoforge_overlays_test/tags/block/must_be_overlayed.json new file mode 100644 index 0000000000..b62d1a4888 --- /dev/null +++ b/tests/src/main/resources/neoforge_overlays_test/data/neoforge_overlays_test/tags/block/must_be_overlayed.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:redstone_block" + ] +} From fb3d7dfb05cbb994b987e11d77b8efaa50ad5a47 Mon Sep 17 00:00:00 2001 From: JoshieGemFinder <79513611+JoshieGemFinder@users.noreply.github.com> Date: Fri, 16 Aug 2024 15:44:03 +1000 Subject: [PATCH 031/125] Replace modifiers in place with ItemAttributeModifierEvent (#1459) This change ensures that replaced modifiers retain the same iteration order as the original instead of being moved to the end of the list. --- .../event/ItemAttributeModifierEvent.java | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/event/ItemAttributeModifierEvent.java b/src/main/java/net/neoforged/neoforge/event/ItemAttributeModifierEvent.java index bc489baddd..713986d06d 100644 --- a/src/main/java/net/neoforged/neoforge/event/ItemAttributeModifierEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/ItemAttributeModifierEvent.java @@ -22,6 +22,7 @@ import net.minecraft.world.item.component.ItemAttributeModifiers; import net.neoforged.bus.api.Event; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; /** * This event is fired when the attributes for an item stack are queried (for any reason) through {@link ItemStack#getAttributeModifiers()}. @@ -99,8 +100,7 @@ public boolean removeModifier(Holder attribute, ResourceLocation id) * @apiNote Modifiers must have a unique and consistent {@link ResourceLocation} id, or the modifier will not be removed when the item is unequipped. */ public void replaceModifier(Holder attribute, AttributeModifier modifier, EquipmentSlotGroup slot) { - removeModifier(attribute, modifier.id()); - addModifier(attribute, modifier, slot); + getBuilder().replaceModifier(attribute, modifier, slot); } /** @@ -206,6 +206,32 @@ boolean removeModifier(Holder attribute, ResourceLocation id) { return false; } + /** + * Adds a modifier to the list, replacing any existing modifiers with the same id. + * + * @return the previous modifier, or null if there was no previous modifier with the same id + */ + @Nullable + ItemAttributeModifiers.Entry replaceModifier(Holder attribute, AttributeModifier modifier, EquipmentSlotGroup slot) { + Key key = new Key(attribute, modifier.id()); + ItemAttributeModifiers.Entry entry = new ItemAttributeModifiers.Entry(attribute, modifier, slot); + if (entriesByKey.containsKey(key)) { + ItemAttributeModifiers.Entry previousEntry = entriesByKey.get(key); + int index = entries.indexOf(previousEntry); + if (index != -1) { + entries.set(index, entry); + } else { // This should never happen, but it can't hurt to have anyways + entries.add(entry); + } + entriesByKey.put(key, entry); + return previousEntry; + } else { + entries.add(entry); + entriesByKey.put(key, entry); + return null; + } + } + /** * Removes modifiers based on a condition. * From 7918bd0f972310449ae635c6cc844c22bdefe134 Mon Sep 17 00:00:00 2001 From: "neoforged-renovate[bot]" <174042230+neoforged-renovate[bot]@users.noreply.github.com> Date: Sat, 17 Aug 2024 00:31:22 +0300 Subject: [PATCH 032/125] Configure Renovate [skip ci] (#1461) --- .github/renovate.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/renovate.json diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000000..1e76f2df6e --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "github>neoforged/actions//renovate/neoforge" + ] +} From c9b4f6aa2212cc17feb4f7aa384044209d7f0de6 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Fri, 16 Aug 2024 18:05:48 -0400 Subject: [PATCH 033/125] Add QuadLighter#computeLightingForQuad overload that works with vertex data array (#1452) --- .../client/model/lighting/QuadLighter.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/client/model/lighting/QuadLighter.java b/src/main/java/net/neoforged/neoforge/client/model/lighting/QuadLighter.java index 2cf9749e60..3491fea116 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/lighting/QuadLighter.java +++ b/src/main/java/net/neoforged/neoforge/client/model/lighting/QuadLighter.java @@ -5,6 +5,7 @@ package net.neoforged.neoforge.client.model.lighting; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import java.util.Objects; @@ -91,7 +92,19 @@ public final void reset() { * @param quad the quad to compute lightmap values for */ public final void computeLightingForQuad(BakedQuad quad) { - var vertices = quad.getVertices(); + computeLightingForQuad(quad.getVertices(), quad.isShade()); + } + + /** + * Compute the brightness and lightmap values for each vertex of this quad. After a call to this method, the + * values may be accessed using {@link QuadLighter#getComputedBrightness()} and {@link QuadLighter#getComputedLightmap()}. + *

+ * This overload allows cleanly reusing the same vertex data array many times. + * + * @param vertices the vertex data for the quad (must be in {@link DefaultVertexFormat#BLOCK} format) + * @param isShade whether the quad should be shaded (same semantics as {@link BakedQuad#isShade()}) + */ + public final void computeLightingForQuad(int[] vertices, boolean isShade) { for (int i = 0; i < 4; i++) { int offset = i * IQuadTransformer.STRIDE; positions[i][0] = Float.intBitsToFloat(vertices[offset + IQuadTransformer.POSITION]); @@ -127,7 +140,7 @@ public final void computeLightingForQuad(BakedQuad quad) { adjustedPosition[1] = position[1] - 0.5f + ((normal[1] / 127f) * 0.5f); adjustedPosition[2] = position[2] - 0.5f + ((normal[2] / 127f) * 0.5f); - var shade = level.getShade(normals[i][0] / 127f, normals[i][1] / 127f, normals[i][2] / 127f, quad.isShade()); + var shade = level.getShade(normal[0] / 127f, normal[1] / 127f, normal[2] / 127f, isShade); brightness[i] = calculateBrightness(adjustedPosition) * shade; int newLightmap = calculateLightmap(adjustedPosition, normal); lightmap[i] = Math.max(packedLightmap & 0xFFFF, newLightmap & 0xFFFF) | From 6504d1910f57791a4991520984582e155f55c979 Mon Sep 17 00:00:00 2001 From: Henry Loenwind Date: Sat, 17 Aug 2024 18:29:40 +0200 Subject: [PATCH 034/125] Fixed missing Range constructor in ModConfigSpec (#1458) --- .../neoforge/common/ModConfigSpec.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/common/ModConfigSpec.java b/src/main/java/net/neoforged/neoforge/common/ModConfigSpec.java index ac870b4ac9..870ce31e09 100644 --- a/src/main/java/net/neoforged/neoforge/common/ModConfigSpec.java +++ b/src/main/java/net/neoforged/neoforge/common/ModConfigSpec.java @@ -364,8 +364,6 @@ public > ConfigValue defineInRange(List range = new Range<>(clazz, min, max); context.setRange(range); comment("Range: " + range.toString()); - if (min.compareTo(max) > 0) - throw new IllegalArgumentException("Range min most be less then max."); return define(path, defaultSupplier, range); } @@ -486,7 +484,7 @@ public ConfigValue> defineList(List path, Supplier * was updated or the config UI was used. */ public ConfigValue> defineList(List path, Supplier> defaultSupplier, Supplier newElementSupplier, Predicate elementValidator) { - return defineList(path, defaultSupplier, newElementSupplier, elementValidator, new Range(Integer.class, 1, Integer.MAX_VALUE)); + return defineList(path, defaultSupplier, newElementSupplier, elementValidator, ListValueSpec.NON_EMPTY); } /** @@ -606,11 +604,11 @@ public ConfigValue> defineListAllowEmpty(List path * @param elementValidator A {@link Predicate} to verify if a list element is valid. Elements that are read from the config file are removed from the list if the * validator rejects them. * @param sizeRange A {@link Range} defining the valid length of the list. Lists read from the config file that don't validate with this Range will be replaced - * with the default. + * with the default. When null, the list size is unbounded. * @return A {@link ConfigValue} object that can be used to access the config value and that will live-update if the value changed, i.e. because the config file * was updated or the config UI was used. */ - public ConfigValue> defineList(List path, Supplier> defaultSupplier, @Nullable Supplier newElementSupplier, Predicate elementValidator, Range sizeRange) { + public ConfigValue> defineList(List path, Supplier> defaultSupplier, @Nullable Supplier newElementSupplier, Predicate elementValidator, @Nullable Range sizeRange) { context.setClazz(List.class); return define(path, new ListValueSpec(defaultSupplier, newElementSupplier, x -> x instanceof List && ((List) x).stream().allMatch(elementValidator), elementValidator, context, path, sizeRange) { @Override @@ -998,6 +996,13 @@ private Range(Class clazz, V min, V max) { this.clazz = clazz; this.min = min; this.max = max; + if (min.compareTo(max) > 0) { + throw new IllegalArgumentException("Range min must be less then max."); + } + } + + public static Range of(int min, int max) { + return new Range<>(Integer.class, min, max); } public Class getClazz() { @@ -1124,7 +1129,8 @@ public Object getDefault() { } public static class ListValueSpec extends ValueSpec { - private static final Range MAX_ELEMENTS = new Range<>(Integer.class, 0, Integer.MAX_VALUE); + private static final Range MAX_ELEMENTS = Range.of(0, Integer.MAX_VALUE); + private static final Range NON_EMPTY = Range.of(1, Integer.MAX_VALUE); @Nullable private final Supplier newElementSupplier; From d347c48bf432222c9fa4a39ac5cf2045529e108b Mon Sep 17 00:00:00 2001 From: Josiah Glosson Date: Sat, 17 Aug 2024 17:11:49 -0500 Subject: [PATCH 035/125] Make `GlyphProviderType` enum extensible (#1262) --- .../providers/GlyphProviderType.java.patch | 22 ++++++ .../client/CustomGlyphProviderTypeTest.java | 71 +++++++++++++++++++ .../resources/META-INF/enumextensions.json | 9 +++ .../font/vanilla.json | 8 +++ 4 files changed, 110 insertions(+) create mode 100644 patches/net/minecraft/client/gui/font/providers/GlyphProviderType.java.patch create mode 100644 tests/src/main/java/net/neoforged/neoforge/debug/client/CustomGlyphProviderTypeTest.java create mode 100644 tests/src/main/resources/assets/custom_glyph_provider_type_test/font/vanilla.json diff --git a/patches/net/minecraft/client/gui/font/providers/GlyphProviderType.java.patch b/patches/net/minecraft/client/gui/font/providers/GlyphProviderType.java.patch new file mode 100644 index 0000000000..f3abf97df8 --- /dev/null +++ b/patches/net/minecraft/client/gui/font/providers/GlyphProviderType.java.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/client/gui/font/providers/GlyphProviderType.java ++++ b/net/minecraft/client/gui/font/providers/GlyphProviderType.java +@@ -8,7 +_,8 @@ + import net.neoforged.api.distmarker.OnlyIn; + + @OnlyIn(Dist.CLIENT) +-public enum GlyphProviderType implements StringRepresentable { ++@net.neoforged.fml.common.asm.enumextension.NamedEnum ++public enum GlyphProviderType implements StringRepresentable, net.neoforged.fml.common.asm.enumextension.IExtensibleEnum { + BITMAP("bitmap", BitmapProvider.Definition.CODEC), + TTF("ttf", TrueTypeGlyphProviderDefinition.CODEC), + SPACE("space", SpaceProvider.Definition.CODEC), +@@ -31,5 +_,9 @@ + + public MapCodec mapCodec() { + return this.codec; ++ } ++ ++ public static net.neoforged.fml.common.asm.enumextension.ExtensionInfo getExtensionInfo() { ++ return net.neoforged.fml.common.asm.enumextension.ExtensionInfo.nonExtended(GlyphProviderType.class); + } + } diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/client/CustomGlyphProviderTypeTest.java b/tests/src/main/java/net/neoforged/neoforge/debug/client/CustomGlyphProviderTypeTest.java new file mode 100644 index 0000000000..a93921d745 --- /dev/null +++ b/tests/src/main/java/net/neoforged/neoforge/debug/client/CustomGlyphProviderTypeTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.debug.client; + +import com.mojang.datafixers.util.Either; +import com.mojang.serialization.MapCodec; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.font.providers.GlyphProviderDefinition; +import net.minecraft.client.gui.font.providers.GlyphProviderType; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.server.packs.resources.SimplePreparableReloadListener; +import net.minecraft.util.profiling.ProfilerFiller; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.fml.common.asm.enumextension.EnumProxy; +import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent; +import net.neoforged.testframework.DynamicTest; +import net.neoforged.testframework.annotation.ForEachTest; +import net.neoforged.testframework.annotation.TestHolder; + +@ForEachTest(side = Dist.CLIENT, groups = { "client.fonts", "client" }) +public class CustomGlyphProviderTypeTest { + public static final EnumProxy REFERENCE_2_PARAMS = new EnumProxy<>( + GlyphProviderType.class, "neotests:reference_2", Reference2.CODEC); + + @TestHolder(description = "Tests if custom GlyphProviderTypes were used for loading resources", enabledByDefault = true) + static void setupGlyphProviderTypeTest(DynamicTest test) { + test.framework().modEventBus().addListener((RegisterClientReloadListenersEvent event) -> event.registerReloadListener(new SimplePreparableReloadListener() { + @Override + protected Void prepare(ResourceManager p_10796_, ProfilerFiller p_10797_) { + return null; + } + + @Override + protected void apply(Void p_10793_, ResourceManager p_10794_, ProfilerFiller p_10795_) { + final Minecraft minecraft = Minecraft.getInstance(); + final MutableComponent component = Component.literal("iiiii"); + final int vanillaWidth = minecraft.font.width(component.withStyle(s -> s + .withFont(ResourceLocation.withDefaultNamespace("uniform")))); + final int moddedWidth = minecraft.font.width(component.withStyle(s -> s + .withFont(ResourceLocation.fromNamespaceAndPath("custom_glyph_provider_type_test", "vanilla")))); + + if (moddedWidth != vanillaWidth) { + test.fail("Width of modded text is " + moddedWidth + ", but " + vanillaWidth + " was expected."); + return; + } + test.pass(); + } + })); + } + + public record Reference2(ResourceLocation what) implements GlyphProviderDefinition { + public static final MapCodec CODEC = ResourceLocation.CODEC.fieldOf("what") + .xmap(Reference2::new, Reference2::what); + + @Override + public GlyphProviderType type() { + return REFERENCE_2_PARAMS.getValue(); + } + + @Override + public Either unpack() { + return Either.right(new Reference(what)); + } + } +} diff --git a/tests/src/main/resources/META-INF/enumextensions.json b/tests/src/main/resources/META-INF/enumextensions.json index 39243c7652..5e912c58ec 100644 --- a/tests/src/main/resources/META-INF/enumextensions.json +++ b/tests/src/main/resources/META-INF/enumextensions.json @@ -108,6 +108,15 @@ "field": "RAIDER_ENUM_PARAMS" } }, + { + "enum": "net/minecraft/client/gui/font/providers/GlyphProviderType", + "name": "NEOTESTS_REFERENCE_2", + "constructor": "(Ljava/lang/String;Lcom/mojang/serialization/MapCodec;)V", + "parameters": { + "class": "net/neoforged/neoforge/debug/client/CustomGlyphProviderTypeTest", + "field": "REFERENCE_2_PARAMS" + } + }, { "enum": "net/minecraft/world/entity/vehicle/Boat$Type", "name": "NEOTESTS_PAPER", diff --git a/tests/src/main/resources/assets/custom_glyph_provider_type_test/font/vanilla.json b/tests/src/main/resources/assets/custom_glyph_provider_type_test/font/vanilla.json new file mode 100644 index 0000000000..064c7e9e47 --- /dev/null +++ b/tests/src/main/resources/assets/custom_glyph_provider_type_test/font/vanilla.json @@ -0,0 +1,8 @@ +{ + "providers": [ + { + "type": "neotests:reference_2", + "what": "minecraft:uniform" + } + ] +} \ No newline at end of file From 95713a29c7592bf5fd98547545ded5c7f028ad85 Mon Sep 17 00:00:00 2001 From: desht Date: Sat, 17 Aug 2024 23:51:08 +0100 Subject: [PATCH 036/125] Add IClientItemExtensions methods for per-render-layer armor coloring (#1414) --- .../layers/HumanoidArmorLayer.java.patch | 19 ++++++--- .../common/IClientItemExtensions.java | 40 +++++++++++++++++++ 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/patches/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java.patch b/patches/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java.patch index 1b6543d310..545f030b2f 100644 --- a/patches/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java.patch @@ -1,19 +1,26 @@ --- a/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java +++ b/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java -@@ -66,22 +_,24 @@ +@@ -66,22 +_,28 @@ if (armoritem.getEquipmentSlot() == p_117122_) { this.getParentModel().copyPropertiesTo(p_117124_); this.setPartVisibility(p_117124_, p_117122_); + net.minecraft.client.model.Model model = getArmorModelHook(p_117121_, itemstack, p_117122_, p_117124_); boolean flag = this.usesInnerModel(p_117122_); ArmorMaterial armormaterial = armoritem.getMaterial().value(); - int i = itemstack.is(ItemTags.DYEABLE) ? FastColor.ARGB32.opaque(DyedItemColor.getOrDefault(itemstack, -6265536)) : -1; +- int i = itemstack.is(ItemTags.DYEABLE) ? FastColor.ARGB32.opaque(DyedItemColor.getOrDefault(itemstack, -6265536)) : -1; - for (ArmorMaterial.Layer armormaterial$layer : armormaterial.layers()) { - int j = armormaterial$layer.dyeable() ? i : -1; +- for (ArmorMaterial.Layer armormaterial$layer : armormaterial.layers()) { +- int j = armormaterial$layer.dyeable() ? i : -1; - this.renderModel(p_117119_, p_117120_, p_117123_, p_117124_, j, armormaterial$layer.texture(flag)); -+ var texture = net.neoforged.neoforge.client.ClientHooks.getArmorTexture(p_117121_, itemstack, armormaterial$layer, flag, p_117122_); -+ this.renderModel(p_117119_, p_117120_, p_117123_, model, j, texture); ++ net.neoforged.neoforge.client.extensions.common.IClientItemExtensions extensions = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(itemstack); ++ int fallbackColor = extensions.getDefaultDyeColor(itemstack); ++ for (int layerIdx = 0; layerIdx < armormaterial.layers().size(); layerIdx++) { ++ ArmorMaterial.Layer armormaterial$layer = armormaterial.layers().get(layerIdx); ++ int j = extensions.getArmorLayerTintColor(itemstack, p_117121_, armormaterial$layer, layerIdx, fallbackColor); ++ if (j != 0) { ++ var texture = net.neoforged.neoforge.client.ClientHooks.getArmorTexture(p_117121_, itemstack, armormaterial$layer, flag, p_117122_); ++ this.renderModel(p_117119_, p_117120_, p_117123_, model, j, texture); ++ } } ArmorTrim armortrim = itemstack.get(DataComponents.TRIM); diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java b/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java index fb4382db87..385d45a6c7 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java @@ -14,13 +14,17 @@ import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.tags.ItemTags; +import net.minecraft.util.FastColor; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.HumanoidArm; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ArmorMaterial; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.DyedItemColor; import net.minecraft.world.level.block.state.BlockState; import net.neoforged.fml.LogicalSide; import net.neoforged.neoforge.client.ClientHooks; @@ -166,6 +170,42 @@ default boolean shouldSpreadAsEntity(ItemStack stack) { return true; } + /** + * Called when armor layers are rendered by {@link net.minecraft.client.renderer.entity.layers.HumanoidArmorLayer}. + *

+ * Allows custom dye colors to be specified per-layer; default vanilla behavior allows for only a single dye color + * (specified by the {@link net.minecraft.core.component.DataComponents#DYED_COLOR} data component) for all layers. + *

+ * Returning 0 here will cause rendering of this layer to be skipped entirely; this is recommended if the layer + * doesn't need to be rendered for a particular armor slot. + * + * @param stack the armor item stack being rendered + * @param entity the entity wearing the armor + * @param layer the armor layer being rendered + * @param layerIdx an index into the list of layers for the {@code ArmorMaterial} used by this item + * @param fallbackColor the return value of {@link #getDefaultDyeColor(ItemStack)}, passed as a parameter for + * performance + * @return a custom color for the layer, in ARGB format, or 0 to skip rendering + */ + default int getArmorLayerTintColor(ItemStack stack, LivingEntity entity, ArmorMaterial.Layer layer, int layerIdx, int fallbackColor) { + return layer.dyeable() ? fallbackColor : 0xFFFFFFFF; + } + + /** + * Called once per render pass of equipped armor items, regardless of the number of layers; the return value of this + * method is passed to {@link #getArmorLayerTintColor(ItemStack, LivingEntity, ArmorMaterial.Layer, int, int)} as + * the {@code fallbackColor} parameter. + *

+ * You can override this method for your custom armor item to provide an alternative default color for the item when + * no explicit color is specified. + * + * @param stack the armor item stack + * @return a default color for the layer, in ARGB format + */ + default int getDefaultDyeColor(ItemStack stack) { + return stack.is(ItemTags.DYEABLE) ? FastColor.ARGB32.opaque(DyedItemColor.getOrDefault(stack, DyedItemColor.LEATHER_COLOR)) : 0xFFFFFFFF; + } + enum FontContext { /** * Used to display the amount of items in the {@link ItemStack}. From bd445202817d92de7bd65efae342e2515fb09258 Mon Sep 17 00:00:00 2001 From: Dennis C Date: Sun, 18 Aug 2024 19:28:09 +0200 Subject: [PATCH 037/125] Fix wrong position being passed to `IBlockStateExtension#isFireSource()` (#1471) --- patches/net/minecraft/world/level/block/FireBlock.java.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/net/minecraft/world/level/block/FireBlock.java.patch b/patches/net/minecraft/world/level/block/FireBlock.java.patch index 0842498c3a..0e6d1d834e 100644 --- a/patches/net/minecraft/world/level/block/FireBlock.java.patch +++ b/patches/net/minecraft/world/level/block/FireBlock.java.patch @@ -21,7 +21,7 @@ BlockState blockstate = p_221161_.getBlockState(p_221162_.below()); - boolean flag = blockstate.is(p_221161_.dimensionType().infiniburn()); -+ boolean flag = blockstate.isFireSource(p_221161_, p_221162_, Direction.UP); ++ boolean flag = blockstate.isFireSource(p_221161_, p_221162_.below(), Direction.UP); int i = p_221160_.getValue(AGE); if (!flag && p_221161_.isRaining() && this.isNearRain(p_221161_, p_221162_) && p_221163_.nextFloat() < 0.2F + (float)i * 0.03F) { p_221161_.removeBlock(p_221162_, false); From 8d0cdeec2ce8e55db395a8dd498382f5c4d4d9fe Mon Sep 17 00:00:00 2001 From: Apex <29412632+ApexModder@users.noreply.github.com> Date: Sun, 18 Aug 2024 21:39:19 +0100 Subject: [PATCH 038/125] [1.21] Allow looking up a Dimensions translated name (#1428) --- .../commands/ForceLoadCommand.java.patch | 64 +++++++++++++++++++ .../commands/SetSpawnCommand.java.patch | 11 ++++ .../resources/assets/c/lang/en_us.json | 3 + .../common/data/LanguageProvider.java | 7 ++ .../internal/NeoForgeLanguageProvider.java | 6 ++ .../common/extensions/ILevelExtension.java | 34 ++++++++++ .../server/command/DimensionsCommand.java | 19 ++++-- .../neoforge/server/command/TPSCommand.java | 2 +- .../server/command/TimeSpeedCommand.java | 4 +- 9 files changed, 143 insertions(+), 7 deletions(-) create mode 100644 patches/net/minecraft/server/commands/ForceLoadCommand.java.patch create mode 100644 patches/net/minecraft/server/commands/SetSpawnCommand.java.patch diff --git a/patches/net/minecraft/server/commands/ForceLoadCommand.java.patch b/patches/net/minecraft/server/commands/ForceLoadCommand.java.patch new file mode 100644 index 0000000000..3829b2ad6e --- /dev/null +++ b/patches/net/minecraft/server/commands/ForceLoadCommand.java.patch @@ -0,0 +1,64 @@ +--- a/net/minecraft/server/commands/ForceLoadCommand.java ++++ b/net/minecraft/server/commands/ForceLoadCommand.java +@@ -106,13 +_,13 @@ + if (flag) { + p_137683_.sendSuccess( + () -> Component.translatable( +- "commands.forceload.query.success", Component.translationArg(chunkpos), Component.translationArg(resourcekey.location()) ++ "commands.forceload.query.success", Component.translationArg(chunkpos), serverlevel.getDescription() // Neo: Use dimension translation, if one exists + ), + false + ); + return 1; + } else { +- throw ERROR_NOT_TICKING.create(chunkpos, resourcekey.location()); ++ throw ERROR_NOT_TICKING.create(chunkpos, serverlevel.getDescription()); // Neo: Use dimension translation, if one exists + } + } + +@@ -125,15 +_,15 @@ + String s = Joiner.on(", ").join(longset.stream().sorted().map(ChunkPos::new).map(ChunkPos::toString).iterator()); + if (i == 1) { + p_137681_.sendSuccess( +- () -> Component.translatable("commands.forceload.list.single", Component.translationArg(resourcekey.location()), s), false ++ () -> Component.translatable("commands.forceload.list.single", serverlevel.getDescription(), s), false // Neo: Use dimension translation, if one exists + ); + } else { + p_137681_.sendSuccess( +- () -> Component.translatable("commands.forceload.list.multiple", i, Component.translationArg(resourcekey.location()), s), false ++ () -> Component.translatable("commands.forceload.list.multiple", i, serverlevel.getDescription(), s), false // Neo: Use dimension translation, if one exists + ); + } + } else { +- p_137681_.sendFailure(Component.translatable("commands.forceload.added.none", Component.translationArg(resourcekey.location()))); ++ p_137681_.sendFailure(Component.translatable("commands.forceload.added.none", serverlevel.getDescription())); // Neo: Use dimension translation, if one exists + } + + return i; +@@ -144,7 +_,7 @@ + ResourceKey resourcekey = serverlevel.dimension(); + LongSet longset = serverlevel.getForcedChunks(); + longset.forEach(p_137675_ -> serverlevel.setChunkForced(ChunkPos.getX(p_137675_), ChunkPos.getZ(p_137675_), false)); +- p_137696_.sendSuccess(() -> Component.translatable("commands.forceload.removed.all", Component.translationArg(resourcekey.location())), true); ++ p_137696_.sendSuccess(() -> Component.translatable("commands.forceload.removed.all", serverlevel.getDescription()), true); // Neo: Use dimension translation, if one exists + return 0; + } + +@@ -189,7 +_,7 @@ + () -> Component.translatable( + "commands.forceload." + (p_137689_ ? "added" : "removed") + ".single", + Component.translationArg(chunkpos2), +- Component.translationArg(resourcekey.location()) ++ serverlevel.getDescription() // Neo: Use dimension translation, if one exists + ), + true + ); +@@ -200,7 +_,7 @@ + () -> Component.translatable( + "commands.forceload." + (p_137689_ ? "added" : "removed") + ".multiple", + i3, +- Component.translationArg(resourcekey.location()), ++ Component.translationArg(serverlevel.getDescription()), // Neo: Use dimension translation, if one exists + Component.translationArg(chunkpos3), + Component.translationArg(chunkpos1) + ), diff --git a/patches/net/minecraft/server/commands/SetSpawnCommand.java.patch b/patches/net/minecraft/server/commands/SetSpawnCommand.java.patch new file mode 100644 index 0000000000..25f9eeb0ff --- /dev/null +++ b/patches/net/minecraft/server/commands/SetSpawnCommand.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/commands/SetSpawnCommand.java ++++ b/net/minecraft/server/commands/SetSpawnCommand.java +@@ -80,7 +_,7 @@ + p_138652_.getY(), + p_138652_.getZ(), + p_138653_, +- s, ++ p_138650_.getLevel().getDescription(), // Neo: Use dimension translation, if one exists + p_138651_.iterator().next().getDisplayName() + ), + true diff --git a/src/generated/resources/assets/c/lang/en_us.json b/src/generated/resources/assets/c/lang/en_us.json index 880fe2db09..172b6898c8 100644 --- a/src/generated/resources/assets/c/lang/en_us.json +++ b/src/generated/resources/assets/c/lang/en_us.json @@ -1,4 +1,7 @@ { + "dimension.minecraft.overworld": "Overworld", + "dimension.minecraft.the_end": "The End", + "dimension.minecraft.the_nether": "The Nether", "tag.block.c.barrels": "Barrels", "tag.block.c.barrels.wooden": "Wooden Barrels", "tag.block.c.bookshelves": "Bookshelves", diff --git a/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java b/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java index 8978f04410..c7a64d6499 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java @@ -14,13 +14,16 @@ import net.minecraft.data.CachedOutput; import net.minecraft.data.DataProvider; import net.minecraft.data.PackOutput; +import net.minecraft.resources.ResourceKey; import net.minecraft.tags.TagKey; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.entity.EntityType; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.neoforged.neoforge.common.Tags; +import net.neoforged.neoforge.common.extensions.ILevelExtension; public abstract class LanguageProvider implements DataProvider { private final Map data = new TreeMap<>(); @@ -121,4 +124,8 @@ public void add(String key, String value) { if (data.put(key, value) != null) throw new IllegalStateException("Duplicate translation key " + key); } + + public void addDimension(ResourceKey dimension, String value) { + add(dimension.location().toLanguageKey(ILevelExtension.TRANSLATION_PREFIX), value); + } } diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java index 420102f12d..75d947020c 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java @@ -10,6 +10,7 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.world.item.DyeColor; +import net.minecraft.world.level.Level; import net.neoforged.neoforge.common.Tags; import net.neoforged.neoforge.common.data.LanguageProvider; import org.apache.commons.lang3.StringUtils; @@ -21,6 +22,11 @@ public NeoForgeLanguageProvider(PackOutput gen) { @Override protected void addTranslations() { + // Vanilla Dimensions + addDimension(Level.OVERWORLD, "Overworld"); + addDimension(Level.NETHER, "The Nether"); + addDimension(Level.END, "The End"); + // Blocks add(Tags.Blocks.BARRELS, "Barrels"); add(Tags.Blocks.BARRELS_WOODEN, "Wooden Barrels"); diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/ILevelExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/ILevelExtension.java index c0e7537e50..b85347746a 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/ILevelExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/ILevelExtension.java @@ -8,6 +8,7 @@ import java.util.Collection; import java.util.Collections; import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; @@ -19,6 +20,16 @@ import org.jetbrains.annotations.Nullable; public interface ILevelExtension { + /** + * Prefix used for all dimension based translations + *

+ * All dimension translations must start with this prefix, + * followed by the registry namespace and path. + *

+ * {@code dimension..} + */ + String TRANSLATION_PREFIX = "dimension"; + private Level self() { return (Level) this; } @@ -134,4 +145,27 @@ default void invalidateCapabilities(BlockPos pos) {} * but it is safe to call on any {@link Level}, without the need for an {@code instanceof} check. */ default void invalidateCapabilities(ChunkPos pos) {} + + /** + * Returns the translation key for this dimension. + *

+ * Used when looking up the matching translation. + * + * @return Translation key used to lookup translation for this dimension. + * @see #TRANSLATION_PREFIX + */ + default String getDescriptionKey() { + return self().dimension().location().toLanguageKey(TRANSLATION_PREFIX); + } + + /** + * Returns Component which looks up the matching value for {@linkplain #getDescriptionKey()}, + * falling back to the registry name if no translation exists. + * + * @return Translated name or registry name if none exists. + * @see #getDescriptionKey() + */ + default Component getDescription() { + return Component.translatableWithFallback(getDescriptionKey(), self().dimension().location().toString()); + } } diff --git a/src/main/java/net/neoforged/neoforge/server/command/DimensionsCommand.java b/src/main/java/net/neoforged/neoforge/server/command/DimensionsCommand.java index ac50e0991d..72268bf3ea 100644 --- a/src/main/java/net/neoforged/neoforge/server/command/DimensionsCommand.java +++ b/src/main/java/net/neoforged/neoforge/server/command/DimensionsCommand.java @@ -10,7 +10,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.core.Registry; @@ -28,13 +27,25 @@ class DimensionsCommand { ctx.getSource().sendSuccess(() -> Component.translatable("commands.neoforge.dimensions.list"), true); final Registry reg = ctx.getSource().registryAccess().registryOrThrow(Registries.DIMENSION_TYPE); - Map> types = new HashMap<>(); + Map> types = new HashMap<>(); for (ServerLevel dim : ctx.getSource().getServer().getAllLevels()) { - types.computeIfAbsent(reg.getKey(dim.dimensionType()), k -> new ArrayList<>()).add(dim.dimension().location()); + types.computeIfAbsent(reg.getKey(dim.dimensionType()), k -> new ArrayList<>()).add(dim.getDescription()); } types.keySet().stream().sorted().forEach(key -> { - ctx.getSource().sendSuccess(() -> Component.literal(key + ": " + types.get(key).stream().map(ResourceLocation::toString).sorted().collect(Collectors.joining(", "))), false); + ctx.getSource().sendSuccess(() -> { + var component = Component.literal(key + ": "); + var components = types.get(key); + + for (int i = 0; i < components.size(); i++) { + component.append(components.get(i)); + + if (i + 1 < components.size()) + component.append(", "); + } + + return component; + }, false); }); return 0; }); diff --git a/src/main/java/net/neoforged/neoforge/server/command/TPSCommand.java b/src/main/java/net/neoforged/neoforge/server/command/TPSCommand.java index f5190f5d20..eb50fd2963 100644 --- a/src/main/java/net/neoforged/neoforge/server/command/TPSCommand.java +++ b/src/main/java/net/neoforged/neoforge/server/command/TPSCommand.java @@ -49,7 +49,7 @@ private static int sendTime(CommandSourceStack cs, ServerLevel dim) throws Comma final Registry reg = cs.registryAccess().registryOrThrow(Registries.DIMENSION_TYPE); double worldTickTime = mean(times) * 1.0E-6D; double worldTPS = TimeUtil.MILLISECONDS_PER_SECOND / Math.max(worldTickTime, dim.tickRateManager().millisecondsPerTick()); - cs.sendSuccess(() -> Component.translatable("commands.neoforge.tps.summary.named", dim.dimension().location().toString(), reg.getKey(dim.dimensionType()).toString(), TIME_FORMATTER.format(worldTickTime), TIME_FORMATTER.format(worldTPS)), false); + cs.sendSuccess(() -> Component.translatable("commands.neoforge.tps.summary.named", dim.getDescription(), reg.getKey(dim.dimensionType()).toString(), TIME_FORMATTER.format(worldTickTime), TIME_FORMATTER.format(worldTPS)), false); return 1; } diff --git a/src/main/java/net/neoforged/neoforge/server/command/TimeSpeedCommand.java b/src/main/java/net/neoforged/neoforge/server/command/TimeSpeedCommand.java index a0c7eb3fc7..2180e8105f 100644 --- a/src/main/java/net/neoforged/neoforge/server/command/TimeSpeedCommand.java +++ b/src/main/java/net/neoforged/neoforge/server/command/TimeSpeedCommand.java @@ -43,8 +43,8 @@ private static int query(CommandSourceStack source) { return Command.SINGLE_SUCCESS; } - private static String levelName(CommandSourceStack source) { - return source.getLevel().dimension().location().toLanguageKey(); + private static Component levelName(CommandSourceStack source) { + return source.getLevel().getDescription(); } private static float minutes(final float speed) { From 315695eca3dd61ce3b5663cc0f34b41f56cc1014 Mon Sep 17 00:00:00 2001 From: Dennis C Date: Mon, 19 Aug 2024 11:02:06 +0200 Subject: [PATCH 039/125] [1.21.1] Add holder overloads and presence check for client extensions registration (#1455) --- .../common/RegisterClientExtensionsEvent.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/common/RegisterClientExtensionsEvent.java b/src/main/java/net/neoforged/neoforge/client/extensions/common/RegisterClientExtensionsEvent.java index 100986c71d..2270bcdc68 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/common/RegisterClientExtensionsEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/common/RegisterClientExtensionsEvent.java @@ -5,6 +5,8 @@ package net.neoforged.neoforge.client.extensions.common; +import java.util.Arrays; +import net.minecraft.core.Holder; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; @@ -33,6 +35,21 @@ public void registerBlock(IClientBlockExtensions extensions, Block... blocks) { ClientExtensionsManager.register(extensions, ClientExtensionsManager.BLOCK_EXTENSIONS, blocks); } + /** + * Register the given {@link IClientBlockExtensions} for the given {@link Block}s + */ + @SafeVarargs + public final void registerBlock(IClientBlockExtensions extensions, Holder... blocks) { + registerBlock(extensions, Arrays.stream(blocks).map(Holder::value).toArray(Block[]::new)); + } + + /** + * {@return whether a {@link IClientBlockExtensions} has been registered for the given {@link Block}} + */ + public boolean isBlockRegistered(Block block) { + return ClientExtensionsManager.BLOCK_EXTENSIONS.containsKey(block); + } + /** * Register the given {@link IClientItemExtensions} for the given {@link Item}s */ @@ -40,6 +57,21 @@ public void registerItem(IClientItemExtensions extensions, Item... items) { ClientExtensionsManager.register(extensions, ClientExtensionsManager.ITEM_EXTENSIONS, items); } + /** + * Register the given {@link IClientItemExtensions} for the given {@link Item}s + */ + @SafeVarargs + public final void registerItem(IClientItemExtensions extensions, Holder... items) { + registerItem(extensions, Arrays.stream(items).map(Holder::value).toArray(Item[]::new)); + } + + /** + * {@return whether a {@link IClientItemExtensions} has been registered for the given {@link Item}} + */ + public boolean isItemRegistered(Item item) { + return ClientExtensionsManager.ITEM_EXTENSIONS.containsKey(item); + } + /** * Register the given {@link IClientMobEffectExtensions} for the given {@link MobEffect}s */ @@ -47,10 +79,40 @@ public void registerMobEffect(IClientMobEffectExtensions extensions, MobEffect.. ClientExtensionsManager.register(extensions, ClientExtensionsManager.MOB_EFFECT_EXTENSIONS, mobEffects); } + /** + * Register the given {@link IClientMobEffectExtensions} for the given {@link MobEffect}s + */ + @SafeVarargs + public final void registerMobEffect(IClientMobEffectExtensions extensions, Holder... mobEffects) { + registerMobEffect(extensions, Arrays.stream(mobEffects).map(Holder::value).toArray(MobEffect[]::new)); + } + + /** + * {@return whether a {@link IClientMobEffectExtensions} has been registered for the given {@link MobEffect}} + */ + public boolean isMobEffectRegistered(MobEffect mobEffect) { + return ClientExtensionsManager.MOB_EFFECT_EXTENSIONS.containsKey(mobEffect); + } + /** * Register the given {@link IClientFluidTypeExtensions} for the given {@link FluidType}s */ public void registerFluidType(IClientFluidTypeExtensions extensions, FluidType... fluidTypes) { ClientExtensionsManager.register(extensions, ClientExtensionsManager.FLUID_TYPE_EXTENSIONS, fluidTypes); } + + /** + * Register the given {@link IClientFluidTypeExtensions} for the given {@link FluidType}s + */ + @SafeVarargs + public final void registerFluidType(IClientFluidTypeExtensions extensions, Holder... fluidTypes) { + registerFluidType(extensions, Arrays.stream(fluidTypes).map(Holder::value).toArray(FluidType[]::new)); + } + + /** + * {@return whether a {@link IClientFluidTypeExtensions} has been registered for the given {@link FluidType}} + */ + public boolean isFluidTypeRegistered(FluidType fluidType) { + return ClientExtensionsManager.FLUID_TYPE_EXTENSIONS.containsKey(fluidType); + } } From fb8915b8c3bf3220b30d35089b89dcd6a1651f30 Mon Sep 17 00:00:00 2001 From: "neoforged-renovate[bot]" <174042230+neoforged-renovate[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 17:40:35 +0300 Subject: [PATCH 040/125] Update dependency io.github.llamalad7:mixinextras-neoforge to v0.4.1 (#1463) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 8022687928..22de2778cd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -41,7 +41,7 @@ commons_io_version=2.13.0 typetools_version=0.6.3 nashorn_core_version=15.3 lwjgl_glfw_version=3.3.2 -mixin_extras_version=0.3.5 +mixin_extras_version=0.4.1 jupiter_api_version=5.7.0 vintage_engine_version=5.+ From d1ca8e10134056f90a8d10e15c229fc3ca226328 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 22 Aug 2024 09:07:26 -0400 Subject: [PATCH 041/125] Use raw stdout stream for CrashReportExtender (#1477) --- .../net/neoforged/neoforge/logging/CrashReportExtender.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/neoforged/neoforge/logging/CrashReportExtender.java b/src/main/java/net/neoforged/neoforge/logging/CrashReportExtender.java index 8b3a991929..21d2ae09fb 100644 --- a/src/main/java/net/neoforged/neoforge/logging/CrashReportExtender.java +++ b/src/main/java/net/neoforged/neoforge/logging/CrashReportExtender.java @@ -17,6 +17,7 @@ import net.minecraft.CrashReportCategory; import net.minecraft.ReportType; import net.minecraft.SystemReport; +import net.minecraft.server.Bootstrap; import net.neoforged.fml.CrashReportCallables; import net.neoforged.fml.ISystemReportExtender; import net.neoforged.fml.ModLoadingIssue; @@ -83,7 +84,7 @@ public static File dumpModLoadingCrashReport(final Logger logger, final List Date: Sun, 25 Aug 2024 05:19:16 +0200 Subject: [PATCH 042/125] [1.21] Add command for listing data components on held stack (#1418) --- .../server/command/DataComponentCommand.java | 99 +++++++++++++++++++ .../server/command/NeoForgeCommand.java | 3 +- .../resources/assets/neoforge/lang/en_us.json | 8 ++ 3 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 src/main/java/net/neoforged/neoforge/server/command/DataComponentCommand.java diff --git a/src/main/java/net/neoforged/neoforge/server/command/DataComponentCommand.java b/src/main/java/net/neoforged/neoforge/server/command/DataComponentCommand.java new file mode 100644 index 0000000000..dc2e21d521 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/server/command/DataComponentCommand.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.server.command; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.builder.ArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import java.util.Objects; +import java.util.Optional; +import net.minecraft.ChatFormatting; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.core.component.DataComponentMap; +import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.HoverEvent; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.ItemStack; + +class DataComponentCommand { + private static final SimpleCommandExceptionType ERROR_NO_ITEM = new SimpleCommandExceptionType( + Component.translatableEscape("commands.neoforge.data_components.list.error.held_stack_empty")); + + public static ArgumentBuilder register() { + return Commands.literal("data_components") + .requires(cs -> cs.hasPermission(Commands.LEVEL_GAMEMASTERS)) + .then(Commands.literal("list") + .executes(DataComponentCommand::listComponents)); + } + + @SuppressWarnings("OptionalAssignedToNull") + private static int listComponents(CommandContext ctx) throws CommandSyntaxException { + ServerPlayer player = ctx.getSource().getPlayerOrException(); + ItemStack stack = player.getMainHandItem(); + if (stack.isEmpty()) { + throw ERROR_NO_ITEM.create(); + } + + ctx.getSource().sendSuccess(() -> { + // Use Item#getName() instead if ItemStack#getDisplayName() to display the actual item name without influence + // of a written book's title or the ITEM_NAME or CUSTOM_NAME data components + MutableComponent text = Component.translatable("commands.neoforge.data_components.list.title", stack.getItem().getName(stack)); + DataComponentMap prototype = stack.getPrototype(); + DataComponentPatch patch = stack.getComponentsPatch(); + prototype.forEach(component -> { + Optional optData = patch.get(component.type()); + if (optData == null) { // Component is default + Component tooltip = Component.translatable( + "commands.neoforge.data_components.list.tooltip.default", + getTypeId(component.type())); + text.append(print(component.type(), component.value(), ChatFormatting.WHITE, tooltip)); + } else if (optData.isEmpty()) { // Component is deleted + Component tooltip = Component.translatable( + "commands.neoforge.data_components.list.tooltip.deleted", + getTypeId(component.type()), + component.value().toString()); + text.append(print(component.type(), component.value(), ChatFormatting.RED, tooltip)); + } else { // Component is modified + Component tooltip = Component.translatable( + "commands.neoforge.data_components.list.tooltip.modified", + getTypeId(component.type()), + component.value().toString(), + optData.get().toString()); + text.append(print(component.type(), optData.get(), ChatFormatting.YELLOW, tooltip)); + } + }); + patch.entrySet().forEach(entry -> { + if (!prototype.has(entry.getKey()) && entry.getValue().isPresent()) { // New component added + Component tooltip = Component.translatable( + "commands.neoforge.data_components.list.tooltip.added", + getTypeId(entry.getKey()), + entry.getValue().get().toString()); + text.append(print(entry.getKey(), entry.getValue().get(), ChatFormatting.GREEN, tooltip)); + } + }); + return text; + }, false); + + return Command.SINGLE_SUCCESS; + } + + private static String getTypeId(DataComponentType type) { + return Objects.requireNonNull(BuiltInRegistries.DATA_COMPONENT_TYPE.getKey(type)).toString(); + } + + private static Component print(DataComponentType type, Object data, ChatFormatting color, Component tooltip) { + MutableComponent entry = Component.translatable("commands.neoforge.data_components.list.entry.key_value", getTypeId(type), data.toString()); + return Component.translatable("commands.neoforge.data_components.list.entry", entry.withStyle(color)) + .withStyle(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, tooltip))); + } +} diff --git a/src/main/java/net/neoforged/neoforge/server/command/NeoForgeCommand.java b/src/main/java/net/neoforged/neoforge/server/command/NeoForgeCommand.java index c700a681cb..5967982f0c 100644 --- a/src/main/java/net/neoforged/neoforge/server/command/NeoForgeCommand.java +++ b/src/main/java/net/neoforged/neoforge/server/command/NeoForgeCommand.java @@ -23,6 +23,7 @@ public static void register(CommandDispatcher dispatcher) { .then(ModListCommand.register()) .then(TagsCommand.register()) .then(DumpCommand.register()) - .then(TimeSpeedCommand.register())); + .then(TimeSpeedCommand.register()) + .then(DataComponentCommand.register())); } } diff --git a/src/main/resources/assets/neoforge/lang/en_us.json b/src/main/resources/assets/neoforge/lang/en_us.json index d490a61f68..46e4288763 100644 --- a/src/main/resources/assets/neoforge/lang/en_us.json +++ b/src/main/resources/assets/neoforge/lang/en_us.json @@ -119,6 +119,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Config for %s of type %s found at %s", "commands.config.noconfig": "Config for %s of type %s not found", From 3504989a8d894e4281c582da819bfb35b1ad7157 Mon Sep 17 00:00:00 2001 From: sciwhiz12 Date: Sun, 25 Aug 2024 15:08:28 +0800 Subject: [PATCH 043/125] Deprecate `BlockItem#removeFromBlockToItemMap` for removal (#1480) --- patches/net/minecraft/world/item/BlockItem.java.patch | 4 +++- patches/net/minecraft/world/item/Items.java.patch | 4 +++- .../minecraft/world/item/StandingAndWallBlockItem.java.patch | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/patches/net/minecraft/world/item/BlockItem.java.patch b/patches/net/minecraft/world/item/BlockItem.java.patch index a8ef2e4e88..eed7cf8eb1 100644 --- a/patches/net/minecraft/world/item/BlockItem.java.patch +++ b/patches/net/minecraft/world/item/BlockItem.java.patch @@ -31,12 +31,14 @@ @Nullable public BlockPlaceContext updatePlacementContext(BlockPlaceContext p_40609_) { return p_40609_; -@@ -193,6 +_,10 @@ +@@ -193,6 +_,12 @@ public void registerBlocks(Map p_40607_, Item p_40608_) { p_40607_.put(this.getBlock(), p_40608_); + } + ++ /** @deprecated Neo: To be removed without replacement since registry replacement is not a feature anymore. */ ++ @Deprecated(forRemoval = true, since = "1.21.1") + public void removeFromBlockToItemMap(Map blockToItemMap, Item itemIn) { + blockToItemMap.remove(this.getBlock()); } diff --git a/patches/net/minecraft/world/item/Items.java.patch b/patches/net/minecraft/world/item/Items.java.patch index 64125c3d73..5967553b88 100644 --- a/patches/net/minecraft/world/item/Items.java.patch +++ b/patches/net/minecraft/world/item/Items.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/Items.java +++ b/net/minecraft/world/item/Items.java -@@ -2092,11 +_,23 @@ +@@ -2092,11 +_,25 @@ } public static Item registerBlock(Block p_252092_, Block... p_248886_) { @@ -17,6 +17,8 @@ - for (Block block : p_248886_) { - Item.BY_BLOCK.put(block, blockitem); - } ++ /** @deprecated Neo: To be removed without replacement since registry replacement is not a feature anymore. */ ++ @Deprecated(forRemoval = true, since = "1.21.1") + @Override + public void removeFromBlockToItemMap(java.util.Map map, Item self) { + super.removeFromBlockToItemMap(map, self); diff --git a/patches/net/minecraft/world/item/StandingAndWallBlockItem.java.patch b/patches/net/minecraft/world/item/StandingAndWallBlockItem.java.patch index 781b756bc0..c119b7fac0 100644 --- a/patches/net/minecraft/world/item/StandingAndWallBlockItem.java.patch +++ b/patches/net/minecraft/world/item/StandingAndWallBlockItem.java.patch @@ -1,10 +1,12 @@ --- a/net/minecraft/world/item/StandingAndWallBlockItem.java +++ b/net/minecraft/world/item/StandingAndWallBlockItem.java -@@ -50,4 +_,9 @@ +@@ -50,4 +_,11 @@ super.registerBlocks(p_43252_, p_43253_); p_43252_.put(this.wallBlock, p_43253_); } + ++ /** @deprecated Neo: To be removed without replacement since registry replacement is not a feature anymore. */ ++ @Deprecated(forRemoval = true, since = "1.21.1") + public void removeFromBlockToItemMap(Map blockToItemMap, Item itemIn) { + super.removeFromBlockToItemMap(blockToItemMap, itemIn); + blockToItemMap.remove(this.wallBlock); From 93bd7503e27a01ff909d8142602b1493898f34b3 Mon Sep 17 00:00:00 2001 From: "neoforged-renovate[bot]" <174042230+neoforged-renovate[bot]@users.noreply.github.com> Date: Sun, 25 Aug 2024 10:48:48 +0300 Subject: [PATCH 044/125] Update dependency net.fabricmc:sponge-mixin to v0.15.2+mixin.0.8.7 (#1464) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 22de2778cd..0b915fef8c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,7 +23,7 @@ securejarhandler_version=3.0.8 bootstraplauncher_version=2.0.2 asm_version=9.5 installer_version=2.1.+ -mixin_version=0.14.0+mixin.0.8.6 +mixin_version=0.15.2+mixin.0.8.7 terminalconsoleappender_version=1.3.0 nightconfig_version=3.8.0 jetbrains_annotations_version=24.0.1 From 4f23b6f982b2cba63255e7ea46b223ae563ba377 Mon Sep 17 00:00:00 2001 From: Dennis C Date: Mon, 26 Aug 2024 06:43:56 +0200 Subject: [PATCH 045/125] [1.21] Fix PayloadRegistrar constructor not copying the handler thread (#1489) --- .../neoforge/network/registration/PayloadRegistrar.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/neoforged/neoforge/network/registration/PayloadRegistrar.java b/src/main/java/net/neoforged/neoforge/network/registration/PayloadRegistrar.java index 2e1dee20b0..366e9c8b50 100644 --- a/src/main/java/net/neoforged/neoforge/network/registration/PayloadRegistrar.java +++ b/src/main/java/net/neoforged/neoforge/network/registration/PayloadRegistrar.java @@ -35,6 +35,7 @@ public PayloadRegistrar(String version) { private PayloadRegistrar(PayloadRegistrar source) { this.version = source.version; this.optional = source.optional; + this.thread = source.thread; } /** From 991c2f63f9b876bce657ea5fa4b63ae75b106745 Mon Sep 17 00:00:00 2001 From: Technici4n <13494793+Technici4n@users.noreply.github.com> Date: Mon, 26 Aug 2024 18:13:20 +0200 Subject: [PATCH 046/125] Fix rare NPE in CapabilityListenerHolder (#1491) --- .../neoforge/capabilities/CapabilityListenerHolder.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/net/neoforged/neoforge/capabilities/CapabilityListenerHolder.java b/src/main/java/net/neoforged/neoforge/capabilities/CapabilityListenerHolder.java index 7f8a20494b..69cf58b33a 100644 --- a/src/main/java/net/neoforged/neoforge/capabilities/CapabilityListenerHolder.java +++ b/src/main/java/net/neoforged/neoforge/capabilities/CapabilityListenerHolder.java @@ -93,6 +93,8 @@ public void clean() { continue; var set = chunkHolder.get(ref.pos.asLong()); + if (set == null) + continue; // We might remove a different garbage-collected reference, // or we might remove nothing if the reference was already removed. // Because the hash codes will match, that is fine. From a2833eb27558754774441dd988981b452c04f02f Mon Sep 17 00:00:00 2001 From: Dennis C Date: Tue, 27 Aug 2024 12:22:32 +0200 Subject: [PATCH 047/125] [1.21] Add NamespacedDirectoryLister (#1488) --- .../resources/FileToIdConverter.java.patch | 29 +++++++++++ .../neoforge/client/ClientNeoForgeMod.java | 7 +++ .../event/RegisterSpriteSourceTypesEvent.java | 20 +++++++- .../textures/NamespacedDirectoryLister.java | 45 ++++++++++++++++++ .../testframework/impl/TestFrameworkImpl.java | 12 ++++- .../neoforge/debug/client/ClientTests.java | 26 ++++++++++ .../client/CustomSpriteSourceTest.java | 7 ++- .../assets/minecraft/atlases/blocks.json | 6 +++ .../textures/test/dir_list_test_absent.png | Bin 0 -> 4205 bytes .../textures/test/dir_list_test_present.png | Bin 0 -> 4205 bytes 10 files changed, 145 insertions(+), 7 deletions(-) create mode 100644 patches/net/minecraft/resources/FileToIdConverter.java.patch create mode 100644 src/main/java/net/neoforged/neoforge/client/textures/NamespacedDirectoryLister.java create mode 100644 tests/src/main/resources/assets/neotests_dir_list_absent/textures/test/dir_list_test_absent.png create mode 100644 tests/src/main/resources/assets/neotests_dir_list_present/textures/test/dir_list_test_present.png diff --git a/patches/net/minecraft/resources/FileToIdConverter.java.patch b/patches/net/minecraft/resources/FileToIdConverter.java.patch new file mode 100644 index 0000000000..f908144107 --- /dev/null +++ b/patches/net/minecraft/resources/FileToIdConverter.java.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/resources/FileToIdConverter.java ++++ b/net/minecraft/resources/FileToIdConverter.java +@@ -34,4 +_,26 @@ + public Map> listMatchingResourceStacks(ResourceManager p_249881_) { + return p_249881_.listResourceStacks(this.prefix, p_248700_ -> p_248700_.getPath().endsWith(this.extension)); + } ++ ++ /** ++ * List all resources under the given namespace which match this converter ++ * ++ * @param manager The resource manager to collect the resources from ++ * @param namespace The namespace to search under ++ * @return All resources from the given namespace which match this converter ++ */ ++ public Map listMatchingResourcesFromNamespace(ResourceManager manager, String namespace) { ++ return manager.listResources(this.prefix, path -> path.getNamespace().equals(namespace) && path.getPath().endsWith(this.extension)); ++ } ++ ++ /** ++ * List all resource stacks under the given namespace which match this converter ++ * ++ * @param manager The resource manager to collect the resources from ++ * @param namespace The namespace to search under ++ * @return All resource stacks from the given namespace which match this converter ++ */ ++ public Map> listMatchingResourceStacksFromNamespace(ResourceManager manager, String namespace) { ++ return manager.listResourceStacks(this.prefix, path -> path.getNamespace().equals(namespace) && path.getPath().endsWith(this.extension)); ++ } + } diff --git a/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java b/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java index cdf8b961d4..b683378daa 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java @@ -22,6 +22,7 @@ import net.neoforged.neoforge.client.event.ModelEvent; import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent; import net.neoforged.neoforge.client.event.RegisterNamedRenderTypesEvent; +import net.neoforged.neoforge.client.event.RegisterSpriteSourceTypesEvent; import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; import net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent; import net.neoforged.neoforge.client.gui.ConfigurationScreen; @@ -33,6 +34,7 @@ import net.neoforged.neoforge.client.model.ItemLayerModel; import net.neoforged.neoforge.client.model.SeparateTransformsModel; import net.neoforged.neoforge.client.model.obj.ObjLoader; +import net.neoforged.neoforge.client.textures.NamespacedDirectoryLister; import net.neoforged.neoforge.common.ModConfigSpec; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.common.NeoForgeMod; @@ -81,6 +83,11 @@ static void onRegisterNamedRenderTypes(RegisterNamedRenderTypesEvent event) { event.register(ResourceLocation.fromNamespaceAndPath("neoforge", "item_unlit"), RenderType.translucent(), NeoForgeRenderTypes.ITEM_UNSORTED_UNLIT_TRANSLUCENT.get()); } + @SubscribeEvent + static void onRegisterSpriteSourceTypes(RegisterSpriteSourceTypesEvent event) { + event.register(NamespacedDirectoryLister.ID, NamespacedDirectoryLister.TYPE); + } + @SubscribeEvent static void onRegisterClientExtensions(RegisterClientExtensionsEvent event) { event.registerFluidType(new IClientFluidTypeExtensions() { diff --git a/src/main/java/net/neoforged/neoforge/client/event/RegisterSpriteSourceTypesEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RegisterSpriteSourceTypesEvent.java index dbcfbd9fc3..96c0bddf41 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/RegisterSpriteSourceTypesEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/RegisterSpriteSourceTypesEvent.java @@ -22,7 +22,7 @@ * This event is fired once during the construction of the {@link Minecraft} instance or * before datagen when client datagen is enabled. * - *

This event is not {@linkplain ICancellableEvent cancellable}, and does not {@linkplain HasResult have a result}.

+ *

This event is not {@linkplain ICancellableEvent cancellable}.

* *

This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ @@ -39,13 +39,29 @@ public RegisterSpriteSourceTypesEvent(BiMap * * @param id The id to register the {@link SpriteSourceType} under * @param codec The codec for the {@link SpriteSourceType} to register + * + * @deprecated Use {@link #register(ResourceLocation, SpriteSourceType)} instead */ + @Deprecated(forRemoval = true, since = "1.21.1") public SpriteSourceType register(ResourceLocation id, MapCodec codec) { if (this.types.containsKey(id)) { throw new IllegalStateException("Duplicate sprite source type registration " + id); } SpriteSourceType sourceType = new SpriteSourceType(codec); - this.types.put(id, sourceType); + register(id, sourceType); return sourceType; } + + /** + * Registers the given {@link SpriteSourceType} under the given id. + * + * @param id The id to register the {@link SpriteSourceType} under + * @param sourceType The {@link SpriteSourceType} to register + */ + public void register(ResourceLocation id, SpriteSourceType sourceType) { + if (this.types.containsKey(id)) { + throw new IllegalStateException("Duplicate sprite source type registration " + id); + } + this.types.put(id, sourceType); + } } diff --git a/src/main/java/net/neoforged/neoforge/client/textures/NamespacedDirectoryLister.java b/src/main/java/net/neoforged/neoforge/client/textures/NamespacedDirectoryLister.java new file mode 100644 index 0000000000..4e8f334dbc --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/textures/NamespacedDirectoryLister.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.textures; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.client.renderer.texture.atlas.SpriteSource; +import net.minecraft.client.renderer.texture.atlas.SpriteSourceType; +import net.minecraft.client.renderer.texture.atlas.sources.DirectoryLister; +import net.minecraft.resources.FileToIdConverter; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.ResourceManager; +import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion; + +/** + * Namespace-aware version of {@link DirectoryLister}. This version should be preferred when several textures from + * high-traffic directories should be stitched to an atlas without adding assets from other mods that should not be + * stitched to this atlas + */ +public record NamespacedDirectoryLister(String namespace, String sourcePath, String idPrefix) implements SpriteSource { + + private static final MapCodec CODEC = RecordCodecBuilder.mapCodec(inst -> inst.group( + Codec.STRING.fieldOf("namespace").forGetter(lister -> lister.namespace), + Codec.STRING.fieldOf("source").forGetter(lister -> lister.sourcePath), + Codec.STRING.fieldOf("prefix").forGetter(lister -> lister.idPrefix)).apply(inst, NamespacedDirectoryLister::new)); + public static final ResourceLocation ID = ResourceLocation.fromNamespaceAndPath(NeoForgeVersion.MOD_ID, "namespaced_directory"); + public static final SpriteSourceType TYPE = new SpriteSourceType(CODEC); + @Override + public void run(ResourceManager resourceManager, Output output) { + FileToIdConverter converter = new FileToIdConverter("textures/" + this.sourcePath, ".png"); + converter.listMatchingResourcesFromNamespace(resourceManager, this.namespace).forEach((path, resource) -> { + ResourceLocation id = converter.fileToId(path).withPrefix(this.idPrefix); + output.add(id, resource); + }); + } + + @Override + public SpriteSourceType type() { + return TYPE; + } +} diff --git a/testframework/src/main/java/net/neoforged/testframework/impl/TestFrameworkImpl.java b/testframework/src/main/java/net/neoforged/testframework/impl/TestFrameworkImpl.java index bd92bd892a..9eed8f6bdb 100644 --- a/testframework/src/main/java/net/neoforged/testframework/impl/TestFrameworkImpl.java +++ b/testframework/src/main/java/net/neoforged/testframework/impl/TestFrameworkImpl.java @@ -84,6 +84,7 @@ public class TestFrameworkImpl implements MutableTestFramework { private @Nullable MinecraftServer server; private final DynamicStructureTemplates structures; + private boolean inClientWorld = false; private @UnknownNullability String commandName; @@ -237,6 +238,11 @@ public void init(final IEventBus modBus, final ModContainer container) { modBus.addListener(new TestFrameworkPayloadInitialization(this)::onNetworkSetup); modBus.addListener((final RegisterGameTestsEvent event) -> event.register(GameTestRegistration.REGISTER_METHOD)); + synchronized (tests().enabled) { + List.copyOf(tests().enabled).forEach(tests()::disable); + } + tests().initialiseDefaultEnabledTests(); + if (FMLLoader.getDist().isClient()) { setupClient(this, modBus, container); } @@ -248,12 +254,14 @@ public void init(final IEventBus modBus, final ModContainer container) { private static void setupClient(TestFrameworkImpl impl, IEventBus modBus, ModContainer container) { if (impl.client != null) impl.client.init(modBus, container); - NeoForge.EVENT_BUS.addListener((final ClientPlayerNetworkEvent.LoggingIn logOut) -> { + NeoForge.EVENT_BUS.addListener((final ClientPlayerNetworkEvent.LoggingIn logIn) -> { synchronized (impl.tests().enabled) { List.copyOf(impl.tests().enabled).forEach(impl.tests()::disable); } impl.tests().initialiseDefaultEnabledTests(); + impl.inClientWorld = true; }); + NeoForge.EVENT_BUS.addListener((final ClientPlayerNetworkEvent.LoggingOut logOut) -> impl.inClientWorld = false); } @Override @@ -304,6 +312,8 @@ public void changeStatus(Test test, Test.Status newStatus, @Nullable Entity chan logger.info("Status of test '{}' has had status changed to {}{}.", test.id(), newStatus, changer instanceof Player player ? " by " + player.getGameProfile().getName() : ""); + if (server == null && !inClientWorld) return; + final ChangeStatusPayload packet = new ChangeStatusPayload(this, test.id(), newStatus); sendPacketIfOn( () -> PacketDistributor.sendToAllPlayers(packet), diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientTests.java index 6f6b09ec42..658df7f778 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/client/ClientTests.java @@ -11,6 +11,8 @@ import javax.sound.sampled.AudioFormat; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; +import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.resources.sounds.AbstractSoundInstance; import net.minecraft.client.resources.sounds.Sound; import net.minecraft.client.resources.sounds.SoundInstance; @@ -26,6 +28,7 @@ import net.neoforged.neoforge.client.event.ClientChatEvent; import net.neoforged.neoforge.client.event.ClientTickEvent; import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; +import net.neoforged.neoforge.client.event.TextureAtlasStitchedEvent; import net.neoforged.neoforge.common.data.LanguageProvider; import net.neoforged.testframework.DynamicTest; import net.neoforged.testframework.annotation.ForEachTest; @@ -81,6 +84,29 @@ static void keyMappingTest(final DynamicTest test) { }); } + @TestHolder(description = "Tests that the NamespacedDirectoryLister only collects resources from the specified namespace", enabledByDefault = true) + static void namespacedDirectoryListerTest(final DynamicTest test) { + final ResourceLocation MUST_BE_PRESENT = ResourceLocation.fromNamespaceAndPath("neotests_dir_list_present", "test/dir_list_test_present"); + final ResourceLocation MUST_BE_ABSENT = ResourceLocation.fromNamespaceAndPath("neotests_dir_list_absent", "test/dir_list_test_absent"); + + test.framework().modEventBus().addListener((final TextureAtlasStitchedEvent event) -> { + if (!event.getAtlas().location().equals(TextureAtlas.LOCATION_BLOCKS)) { + return; + } + + ResourceLocation missing = MissingTextureAtlasSprite.getLocation(); + if (event.getAtlas().getSprite(MUST_BE_PRESENT).contents().name().equals(missing)) { + test.fail("dir_list_test_present.png must be present but returned the missing texture"); + return; + } + if (!event.getAtlas().getSprite(MUST_BE_ABSENT).contents().name().equals(missing)) { + test.fail("dir_list_test_absent.png must be absent but returned something other than the missing texture"); + return; + } + test.pass(); + }); + } + private static final class SineSound extends AbstractSoundInstance { SineSound(Vec3 position) { super(ResourceLocation.fromNamespaceAndPath("neotests_audio_stream_test", "sine_wave"), SoundSource.BLOCKS, SoundInstance.createUnseededRandom()); diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/CustomSpriteSourceTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/CustomSpriteSourceTest.java index 3c108b31f3..c0608a4f23 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/CustomSpriteSourceTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/CustomSpriteSourceTest.java @@ -47,16 +47,15 @@ public CustomSpriteSourceTest(IEventBus modEventBus) { ITEMS.register(modEventBus); } - private static SpriteSourceType tasLoader; - private void registerTextureAtlasSpriteLoaders(RegisterSpriteSourceTypesEvent event) { - tasLoader = event.register(ResourceLocation.fromNamespaceAndPath(MOD_ID, "custom_sprite_source"), CustomSpriteSource.CODEC); + event.register(ResourceLocation.fromNamespaceAndPath(MOD_ID, "custom_sprite_source"), CustomSpriteSource.TYPE); } private record CustomSpriteSource(ResourceLocation id) implements SpriteSource { private static final Logger LOGGER = LogUtils.getLogger(); private static final MapCodec CODEC = RecordCodecBuilder.mapCodec(inst -> inst.group( ResourceLocation.CODEC.fieldOf("id").forGetter(CustomSpriteSource::id)).apply(inst, CustomSpriteSource::new)); + private static final SpriteSourceType TYPE = new SpriteSourceType(CustomSpriteSource.CODEC); @Override public void run(ResourceManager manager, Output output) { @@ -72,7 +71,7 @@ public void run(ResourceManager manager, Output output) { @Override public SpriteSourceType type() { - return tasLoader; + return TYPE; } static final class CustomSpriteContents extends SpriteContents { diff --git a/tests/src/main/resources/assets/minecraft/atlases/blocks.json b/tests/src/main/resources/assets/minecraft/atlases/blocks.json index 546f163471..e8d0700f11 100644 --- a/tests/src/main/resources/assets/minecraft/atlases/blocks.json +++ b/tests/src/main/resources/assets/minecraft/atlases/blocks.json @@ -3,6 +3,12 @@ { "type": "custom_sprite_source_test:custom_sprite_source", "id": "custom_sprite_source_test:test_item" + }, + { + "type": "neoforge:namespaced_directory", + "namespace": "neotests_dir_list_present", + "source": "test", + "prefix": "test/" } ] } diff --git a/tests/src/main/resources/assets/neotests_dir_list_absent/textures/test/dir_list_test_absent.png b/tests/src/main/resources/assets/neotests_dir_list_absent/textures/test/dir_list_test_absent.png new file mode 100644 index 0000000000000000000000000000000000000000..3f90638ec58749009702f453fdbd207f9990ed51 GIT binary patch literal 4205 zcmeHLYj6`)6yAc;S}CH{QVS#NqVlkt-E21LW=&{I($Xlw*ro`Kj@|6uq)U_RcC&3l zp^B{nMG+{d<5&xWrKkvqh?dtBtbj;Il&3EkA2Bx-J8U5E}lHGgm zcfNbhch9+#O`T`z$6ARzO=HcY5(|X&eJ~OyjvH2! zSx*j4`_wq^!mGIx1`XbP7kzQ#>Miq%+sE#n)ObdE_xO(Oms;i|CUs;KEq;<&HLJPN zbp%G z@^DZ-Id<6QMNPw3rapK^&HZ-rh6BS|%MD*<{?h(dO8M6% zUtFcP3QF!$Yy#?=%zH-y!(XtiIYa5zM2Bpv4^yZTCUGLqf&V1qb>fnr5Qg>Y* z`iN+MVrNQwb^XaR;-_OuVk28xeiqN)A#WY*Y|N-Pd|v-zvu8rWxxfYY^{9H|b;lY` zZoAA>Bg&DZ=Tl@kY08T6b54AJ;_B6tSM7&8&Lu8hrfjkyIbXrbs}x~{O?OXWc`0Pz z1jz>sv5*W)4?%3%F`47bfQtG+Kn&ZlbK6@nR21yk!)7<>mK~r}ET~dIQPos0Usc9i z1uT1FvMt6!f)G$SG!_bmBW%o$>AWnw*USWl>JYWej!k!aP=}-dls3=?63>f?l@vBH z8MP^bpDlFecTvER9V=B;nI(v5G-`;N43ZKcj8?0aASr^PaEQPov%@ME!^4p=8bv3E z6GV7LlvPm*qZ%jYlPXj@hQWEXJHC+YcK6VSBV8&$J%|`56Gj6`ghE8TM?}r5gd|-7 zUDG4tg^fxSf{0Y1@F1@egw-+e6awGlFIOl*Jsp83KoEo=Gy+#O_E~bW%kAm$&?E?m zAzAl=V)sF+qQ6(HKCx*tdOGoeK=&TrKIrb;budJ^-Ka8t;whX4J|j-k6u_;3B5~3v`2A!SZ?^KrI4V~-qHBp^{$%kh#z-+Qmz-Y4g;wTa+;pTEQ&UpvaAe~WwDqUQ!i*5P$IAvHC7{OFwy#qwlOSB2TIFnl?n-T zJIsc4D1cKX#VbicJEjGNYMwpQZrD%)r*ckC1(1}aXqIGH%Iqac)@WsE=3bIw$vC_u zi2m9ChSu5#wRLWKff#}7&(=+yJyitCJ4cIk)h1*&U>j_ca0@qO{pQlRYvlnf^sJWeu<=t`E*PK@qsZNxwHu<3xfBL@0)+ThUz zPeP*SDD2WpJ9PfXSJyuLk1IgxfkpbI?|@tba`j7ret`$7Ye24kDbO$QKz03RawYdZ zOo1@`1r&vkO7}Gr3Vh5O;(K7S6ZuPfuiCkGIkem$7tDwt$gno;ldw;EO@PKk)#c7h z{4ps#EtPDqeO>#LAkF2>^^QBpUpbhQQQ}KKO1{B;HVZ*=3<;w*Eq&h&5r`{qs&m7n HlA6B(eBkM6 literal 0 HcmV?d00001 diff --git a/tests/src/main/resources/assets/neotests_dir_list_present/textures/test/dir_list_test_present.png b/tests/src/main/resources/assets/neotests_dir_list_present/textures/test/dir_list_test_present.png new file mode 100644 index 0000000000000000000000000000000000000000..0cdde54cdbd8b45218670cfcc6c3534897baf5f6 GIT binary patch literal 4205 zcmeHKd2ka|7~i7M8Ym(tRzz8s@c`NECfQtT(o&K_qYcD1Rd77|vip)QO|skFZ4;1+ zf(OS`XaSFziXCn1UB!A-C<9m&oK{c{Ih1;#GK`3z4qj7zo1|?zI^%Rk{%bOu-TjW= z`@Y}zeQ)ws`sU8b)=ko37?$lRbQh!hIPJzj=4DTG)DexpwY}y));jO-O|8Cr=o3dmmKNKoySsw>Z+iX7q60_5 zT=2~3ALozwtmt_|dOaZ z(NI(8EbN>)`MrBenw$NT?`T@#diW%N`DK+eN@py4Xy0w+2X`FbN0slZZ)&&cT1RH) zO?+vre$QsMUAOFu%oT0R*FCd({jb}aJ|f;<{`GwwTh6uLo0)ZLQc3Ltw#J1m8$H+U zTmnje-umvEtl8sc%?!+*y5X+w9aT$?b#@-wlCxLNJNI2q@v2c5IEcyyv$`(6JYKy& zEcIMJwry3@xThz~JE`V>HK(;}?6yk%r!#)+er;n{_k>4Qz9&!Vs_CA-`DTY}a;d-e z>_Z)$y6?z63t#zQ^SR^Hn2B$0m~lvW^qQ5|Hm!X)>k6;`*5xa6UYRs)l<|$Hr88@e z_A>AAa_NrUo9<`*g>Oyy^Wytr73*7`YiKGPk+Wpe%WEpPzdc&LFrQ zcM8s>TeG`s>U&NKA5SfdU)kRNgK+k0>75JQ8z)e0pbY^Xxyvc#h{0#M7wSf9-zPE_w#E2g7 zVgTyn5eYROhB@-$65uMJiU(jwh&qYWTecCnz&nZC&0g9oxnQ|axLAfIi|6{e#TA^L zC-QQ2jyQ_|B2Wc*JQ9v7Y}`pCa9Q-Mi75h4n5Y#_V!qdhyF?k{jGoccWIqv$VwKFnf@&C5r=~;jT))3mC5IE~@EirhFoH}Kw5nmyl5;#>U%!V&K}d*5 z2`@zUAWKyU4v;k{HcgXACp{44-j6%Tx-a*HF|zV{S+~elY2kU?PC{FsaWr zWO$k<1163pX+Q^T90!?z*`5Y5PZm&Df^d3N8WfM9f+j0NL%WGIn9P7=I4dA+fuMyn zLbJ)vFhQfiZb?A#96MW-BLJ0Ch=35Jq-ZFi& z{*h|fKDqEO&0q`gK`R$zNRGA`NycIcl7I<7(#ixZ7CHdzOsazY=!zIrV?c)aA;cr% z3N>hgEBuC3siqB%CRPr$Iv~nO+D4{PMo_6_DQ(B-%ho~tgAYf-AZ?35en}bHy3kHY z^>2kKzEG^^^OLH>`CJ0WhZh+Vzr%D5(={XphGab4UBh$@iGd**4|mu9Mwf2jFa@LN zA5aV(m6}`b?n1|`QGr|LxUs*qZ{ybI)*;D7QsDvx!^U=MSH>>!c^(NfRgbqI^F&t8 z#7lJrd%le!QI5x*@4sO$$N#!_=J>KeS!APu literal 0 HcmV?d00001 From fc3efaac674bb37a916917f0a66082e6138a18dc Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Tue, 27 Aug 2024 07:14:25 -0400 Subject: [PATCH 048/125] Replace CRLF line endings in mod list's details (#1481) --- .../neoforged/neoforge/client/gui/ModListScreen.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java b/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java index e59f8f5ca5..fb67ef7d16 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/ModListScreen.java @@ -47,7 +47,6 @@ import net.neoforged.fml.i18n.MavenVersionTranslator; import net.neoforged.fml.loading.FMLPaths; import net.neoforged.fml.loading.StringUtils; -import net.neoforged.fml.loading.moddiscovery.ModFileInfo; import net.neoforged.neoforge.client.gui.widget.ModListWidget; import net.neoforged.neoforge.client.gui.widget.ScrollPanel; import net.neoforged.neoforge.common.CommonHooks; @@ -404,17 +403,18 @@ public void upload() { lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.version", MavenVersionTranslator.artifactVersionToString(selectedMod.getVersion()))); lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.idstate", selectedMod.getModId(), "LOADED")); // TODO: remove mod loading stages from here too - selectedMod.getConfig().getConfigElement("credits").ifPresent(credits -> lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.credits", credits))); - selectedMod.getConfig().getConfigElement("authors").ifPresent(authors -> lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.authors", authors))); - selectedMod.getConfig().getConfigElement("displayURL").ifPresent(displayURL -> lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.displayurl", displayURL))); + // Normalizing line endings to LF because it is currently not automatically handled for us. Descriptions are already normalized. + selectedMod.getConfig().getConfigElement("credits").ifPresent(credits -> lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.credits", credits).replace("\r\n", "\n"))); + selectedMod.getConfig().getConfigElement("authors").ifPresent(authors -> lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.authors", authors).replace("\r\n", "\n"))); + selectedMod.getConfig().getConfigElement("displayURL").ifPresent(displayURL -> lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.displayurl", displayURL).replace("\r\n", "\n"))); if (selectedMod.getOwningFile() == null || selectedMod.getOwningFile().getMods().size() == 1) lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.nochildmods")); else lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.childmods", selectedMod.getOwningFile().getMods().stream().map(IModInfo::getDisplayName).collect(Collectors.joining(",")))); if (vercheck.status() == VersionChecker.Status.OUTDATED || vercheck.status() == VersionChecker.Status.BETA_OUTDATED) - lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.updateavailable", vercheck.url() == null ? "" : vercheck.url())); - lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.license", ((ModFileInfo) selectedMod.getOwningFile()).getLicense())); + lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.updateavailable", vercheck.url() == null ? "" : vercheck.url()).replace("\r\n", "\n")); + lines.add(FMLTranslations.parseMessage("fml.menu.mods.info.license", selectedMod.getOwningFile().getLicense()).replace("\r\n", "\n")); lines.add(null); lines.add(FMLTranslations.parseMessageWithFallback("fml.menu.mods.info.description." + selectedMod.getModId(), selectedMod::getDescription)); From 1cdd2106f000e4fac3c5367ccc7ba3267a5d526a Mon Sep 17 00:00:00 2001 From: sciwhiz12 Date: Tue, 27 Aug 2024 23:55:21 +0800 Subject: [PATCH 049/125] Enhance readability of mod loading crash reports (#1479) --- .../minecraft/CrashReportCategory.java.patch | 10 +++- .../neoforge/logging/CrashReportExtender.java | 57 +++++++++++++++---- 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/patches/net/minecraft/CrashReportCategory.java.patch b/patches/net/minecraft/CrashReportCategory.java.patch index 50c9e7294b..e8b649ffb5 100644 --- a/patches/net/minecraft/CrashReportCategory.java.patch +++ b/patches/net/minecraft/CrashReportCategory.java.patch @@ -13,7 +13,7 @@ return this.stackTrace.length; } } -@@ -165,16 +_,16 @@ +@@ -165,16 +_,22 @@ if (this.stackTrace != null && this.stackTrace.length > 0) { p_128169_.append("\nStacktrace:"); @@ -30,8 +30,14 @@ return this.stackTrace; + } + ++ /** @deprecated Neo: Use {@link #setStackTrace(StackTraceElement[])} instead. */ ++ @Deprecated(forRemoval = true, since = "1.21.1") + public void applyStackTrace(Throwable t) { -+ this.stackTrace = t.getStackTrace(); ++ setStackTrace(t.getStackTrace()); ++ } ++ ++ public void setStackTrace(StackTraceElement[] stackTrace) { ++ this.stackTrace = stackTrace; } public static void populateBlockDetails(CrashReportCategory p_178951_, LevelHeightAccessor p_178952_, BlockPos p_178953_, @Nullable BlockState p_178954_) { diff --git a/src/main/java/net/neoforged/neoforge/logging/CrashReportExtender.java b/src/main/java/net/neoforged/neoforge/logging/CrashReportExtender.java index 21d2ae09fb..3fddbac195 100644 --- a/src/main/java/net/neoforged/neoforge/logging/CrashReportExtender.java +++ b/src/main/java/net/neoforged/neoforge/logging/CrashReportExtender.java @@ -21,6 +21,7 @@ import net.neoforged.fml.CrashReportCallables; import net.neoforged.fml.ISystemReportExtender; import net.neoforged.fml.ModLoadingIssue; +import net.neoforged.fml.i18n.FMLTranslations; import net.neoforged.neoforge.forge.snapshots.ForgeSnapshotsMod; import net.neoforged.neoforgespi.language.IModFileInfo; import net.neoforged.neoforgespi.language.IModInfo; @@ -54,28 +55,42 @@ public static String generateEnhancedStackTrace(final Throwable throwable, boole return header ? s : s.substring(s.indexOf(Strings.LINE_SEPARATOR)); } + private static final StackTraceElement[] BLANK_STACK_TRACE = new StackTraceElement[0]; + public static File dumpModLoadingCrashReport(final Logger logger, final List issues, final File topLevelDir) { - final CrashReport crashReport = CrashReport.forThrowable(new Exception("Mod Loading has failed"), "Mod loading error has occurred"); + final CrashReport crashReport = CrashReport.forThrowable(new ModLoadingCrashException("Mod loading has failed"), "Mod loading failures have occurred; consult the issue messages for more details"); for (var issue : issues) { final Optional modInfo = Optional.ofNullable(issue.affectedMod()); - final CrashReportCategory category = crashReport.addCategory(modInfo.map(iModInfo -> "MOD " + iModInfo.getModId()).orElse("NO MOD INFO AVAILABLE")); + final CrashReportCategory category = crashReport.addCategory(modInfo.map(iModInfo -> "Mod loading issue for: " + iModInfo.getModId()).orElse("Mod loading issue")); Throwable cause = issue.cause(); int depth = 0; while (cause != null && cause.getCause() != null && cause.getCause() != cause) { category.setDetail("Caused by " + (depth++), cause + generateEnhancedStackTrace(cause.getStackTrace()).replaceAll(Strings.LINE_SEPARATOR + "\t", "\n\t\t")); cause = cause.getCause(); } + // Set the stack trace to the issue cause if possible; if there is no issue cause, then remove the + // stacktrace (since otherwise it is set to the report's 'root' exception, which is a dummy exception) if (cause != null) - category.applyStackTrace(cause); - category.setDetail("Mod File", () -> modInfo.map(IModInfo::getOwningFile).map(t -> t.getFile().getFilePath().toUri().getPath()).orElse("NO FILE INFO")); - category.setDetail("Failure message", () -> issue.translationKey().replace("\n", "\n\t\t")); - for (int i = 0; i < issue.translationArgs().size(); i++) { - var arg = issue.translationArgs().get(i); - category.setDetail("Failure message arg " + (i + 1), () -> arg.toString().replace("\n", "\n\t\t")); + category.setStackTrace(cause.getStackTrace()); + else + category.setStackTrace(BLANK_STACK_TRACE); + category.setDetail("Mod file", () -> modInfo.map(IModInfo::getOwningFile).map(t -> t.getFile().getFilePath().toUri().getPath()).orElse("")); + + try { + //noinspection UnstableApiUsage + category.setDetail("Failure message", () -> FMLTranslations.stripControlCodes(FMLTranslations.translateIssueEnglish(issue)).replace("\n", "\n\t\t")); + } catch (Exception e) { + // If translating the issue failed, fallback to just adding the raw translation key and arguments + category.setDetail("Failure message", () -> issue.translationKey().replace("\n", "\n\t\t")); + for (int i = 0; i < issue.translationArgs().size(); i++) { + var arg = issue.translationArgs().get(i); + category.setDetail("Failure message arg " + (i + 1), () -> arg.toString().replace("\n", "\n\t\t")); + } } - category.setDetail("Mod Version", () -> modInfo.map(IModInfo::getVersion).map(Object::toString).orElse("NO MOD INFO AVAILABLE")); - category.setDetail("Mod Issue URL", () -> modInfo.map(IModInfo::getOwningFile).map(IModFileInfo.class::cast).flatMap(mfi -> mfi.getConfig().getConfigElement("issueTrackerURL")).orElse("NOT PROVIDED")); - category.setDetail("Exception message", Objects.toString(cause, "MISSING EXCEPTION MESSAGE")); + + category.setDetail("Mod version", () -> modInfo.map(IModInfo::getVersion).map(Object::toString).orElse("")); + category.setDetail("Mod issues URL", () -> modInfo.map(IModInfo::getOwningFile).map(IModFileInfo.class::cast).flatMap(mfi -> mfi.getConfig().getConfigElement("issueTrackerURL")).orElse("")); + category.setDetail("Exception message", Objects.toString(cause, "")); } final File file1 = new File(topLevelDir, "crash-reports"); final File file2 = new File(file1, "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-fml.txt"); @@ -87,4 +102,24 @@ public static File dumpModLoadingCrashReport(final Logger logger, final ListThe stacktrace is very likely to be constant (since its only invoked by the sided mod loader classes), so their + * stacktrace is irrelevant for debugging and only serve to distract the reader from the actual exceptions further + * down in the crash report.

+ */ + private static class ModLoadingCrashException extends Exception { + public ModLoadingCrashException(String message) { + super(message); + } + + @Override + public synchronized Throwable fillInStackTrace() { + // Do not fill in the stack trace + return this; + } + } } From 98440b83207e3d91345c7c96b3b619c6f3e29f4f Mon Sep 17 00:00:00 2001 From: Apex <29412632+ApexModder@users.noreply.github.com> Date: Sat, 31 Aug 2024 17:29:17 +0100 Subject: [PATCH 050/125] [1.21] Overhaul tps command to be more colorful and organized (#1422) --- .../neoforge/server/command/TPSCommand.java | 91 +++++++++++++------ .../resources/assets/neoforge/lang/en_us.json | 8 +- 2 files changed, 67 insertions(+), 32 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/server/command/TPSCommand.java b/src/main/java/net/neoforged/neoforge/server/command/TPSCommand.java index eb50fd2963..4703bda119 100644 --- a/src/main/java/net/neoforged/neoforge/server/command/TPSCommand.java +++ b/src/main/java/net/neoforged/neoforge/server/command/TPSCommand.java @@ -5,18 +5,27 @@ package net.neoforged.neoforge.server.command; +import com.google.common.math.Stats; +import com.mojang.brigadier.Command; import com.mojang.brigadier.builder.ArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import java.text.DecimalFormat; +import net.minecraft.ChatFormatting; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.DimensionArgument; -import net.minecraft.core.Registry; -import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.HoverEvent; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.CommonColors; +import net.minecraft.util.Mth; import net.minecraft.util.TimeUtil; -import net.minecraft.world.level.dimension.DimensionType; +import net.minecraft.world.TickRateManager; +import org.jetbrains.annotations.Nullable; +import org.joml.Math; class TPSCommand { private static final DecimalFormat TIME_FORMATTER = new DecimalFormat("########0.000"); @@ -24,40 +33,66 @@ class TPSCommand { static ArgumentBuilder register() { return Commands.literal("tps") - .requires(cs -> cs.hasPermission(0)) //permission - .then(Commands.argument("dim", DimensionArgument.dimension()) - .executes(ctx -> sendTime(ctx.getSource(), DimensionArgument.getDimension(ctx, "dim")))) + .then(Commands.argument("dimension", DimensionArgument.dimension()) + .executes(ctx -> sendTime(ctx, DimensionArgument.getDimension(ctx, "dimension")))) .executes(ctx -> { - for (ServerLevel dim : ctx.getSource().getServer().getAllLevels()) - sendTime(ctx.getSource(), dim); + for (ServerLevel dimension : ctx.getSource().getServer().getAllLevels()) { + sendTime(ctx, dimension); + } - long[] times = ctx.getSource().getServer().getTickTimesNanos(); - double meanTickTime = mean(times) * 1.0E-6D; - double meanTPS = TimeUtil.MILLISECONDS_PER_SECOND / Math.max(meanTickTime, ctx.getSource().getServer().tickRateManager().millisecondsPerTick()); - ctx.getSource().sendSuccess(() -> Component.translatable("commands.neoforge.tps.summary.all", TIME_FORMATTER.format(meanTickTime), TIME_FORMATTER.format(meanTPS)), false); - - return 0; + sendTime(ctx, null); + return Command.SINGLE_SUCCESS; }); } - private static int sendTime(CommandSourceStack cs, ServerLevel dim) throws CommandSyntaxException { - long[] times = cs.getServer().getTickTime(dim.dimension()); + private static int sendTime(CommandContext context, @Nullable ServerLevel dimension) throws CommandSyntaxException { + var src = context.getSource(); + src.sendSuccess(() -> createComponent(src.getServer(), dimension), false); + return Command.SINGLE_SUCCESS; + } + + private static Component createComponent(MinecraftServer server, @Nullable ServerLevel dimension) { + long[] times; + TickRateManager tickRateManager; + + if (dimension == null) { + times = server.getTickTimesNanos(); + tickRateManager = server.tickRateManager(); + } else { + var dimensionTimes = server.getTickTime(dimension.dimension()); + times = dimensionTimes == null ? UNLOADED : dimensionTimes; + tickRateManager = dimension.tickRateManager(); + } + + var tickTime = Stats.meanOf(times) / TimeUtil.NANOSECONDS_PER_MILLISECOND; + var tps = TimeUtil.MILLISECONDS_PER_SECOND / Math.max(tickTime, tickRateManager.millisecondsPerTick()); + var tickTimeComponent = Component.literal(TIME_FORMATTER.format(tickTime)).withColor(CommonColors.LIGHT_GRAY); + var tpsComponent = Component.literal(TIME_FORMATTER.format(tps)).withColor(calculateTPSColor(tickRateManager, tps)); + + MutableComponent component; + + if (dimension == null) { + component = Component.translatable("commands.neoforge.tps.overall", tpsComponent, tickTimeComponent); + } else { + var dimensionType = dimension.dimensionTypeRegistration(); - if (times == null) // Null means the world is unloaded. Not invalid. That's taken care of by DimensionArgument itself. - times = UNLOADED; + var dimensionName = Component.empty().append(dimension.getDescription()).withStyle(style -> style + .withColor(ChatFormatting.GREEN) + .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.translatable( + "commands.neoforge.tps.dimension.tooltip", + dimension.dimension().location().toString(), + dimensionType.getRegisteredName())))); - final Registry reg = cs.registryAccess().registryOrThrow(Registries.DIMENSION_TYPE); - double worldTickTime = mean(times) * 1.0E-6D; - double worldTPS = TimeUtil.MILLISECONDS_PER_SECOND / Math.max(worldTickTime, dim.tickRateManager().millisecondsPerTick()); - cs.sendSuccess(() -> Component.translatable("commands.neoforge.tps.summary.named", dim.getDescription(), reg.getKey(dim.dimensionType()).toString(), TIME_FORMATTER.format(worldTickTime), TIME_FORMATTER.format(worldTPS)), false); + component = Component.translatable("commands.neoforge.tps.dimension", dimensionName, tpsComponent, tickTimeComponent); + } - return 1; + return component.withStyle(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.translatable("commands.neoforge.tps.tooltip", tickRateManager.tickrate())))); } - private static long mean(long[] values) { - long sum = 0L; - for (long v : values) - sum += v; - return sum / values.length; + private static int calculateTPSColor(TickRateManager tickRateManager, double tps) { + // Improved color blending code thanks to sciwhiz12 + float maxTPS = TimeUtil.MILLISECONDS_PER_SECOND / tickRateManager.millisecondsPerTick(); + // 0 degrees (0F) is red, 120 degrees (0.33F) is green + return Mth.hsvToRgb((float) (Mth.inverseLerp(tps, 0, maxTPS) * 0.33F), 1F, 1F); } } diff --git a/src/main/resources/assets/neoforge/lang/en_us.json b/src/main/resources/assets/neoforge/lang/en_us.json index 46e4288763..5e0e4c29db 100644 --- a/src/main/resources/assets/neoforge/lang/en_us.json +++ b/src/main/resources/assets/neoforge/lang/en_us.json @@ -80,11 +80,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "This command is deprecated for removal in 1.17, use %s instead.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Entity tracking enabled for %d seconds.", "commands.neoforge.tracking.entity.reset": "Entity timings data has been cleared!", "commands.neoforge.tracking.invalid": "Invalid tracking data.", From 38ed034a8f5818829f13e629d224bcb859624108 Mon Sep 17 00:00:00 2001 From: GizmoTheMoonPig <67468252+GizmoTheMoonPig@users.noreply.github.com> Date: Sat, 31 Aug 2024 10:41:31 -0600 Subject: [PATCH 051/125] [1.21] Add a system to register custom ReceivingLevelScreens (#1451) --- .../net/minecraft/client/Minecraft.java.patch | 6 +- .../ClientPacketListener.java.patch | 35 ++++++++- .../neoforge/client/ClientHooks.java | 1 + .../DimensionTransitionScreenManager.java | 58 ++++++++++++++ ...egisterDimensionTransitionScreenEvent.java | 70 +++++++++++++++++ .../DimensionTransitionScreenTests.java | 76 +++++++++++++++++++ 6 files changed, 243 insertions(+), 3 deletions(-) create mode 100644 src/main/java/net/neoforged/neoforge/client/DimensionTransitionScreenManager.java create mode 100644 src/main/java/net/neoforged/neoforge/client/event/RegisterDimensionTransitionScreenEvent.java create mode 100644 tests/src/main/java/net/neoforged/neoforge/debug/client/DimensionTransitionScreenTests.java diff --git a/patches/net/minecraft/client/Minecraft.java.patch b/patches/net/minecraft/client/Minecraft.java.patch index f87e63c9f3..13ff259e92 100644 --- a/patches/net/minecraft/client/Minecraft.java.patch +++ b/patches/net/minecraft/client/Minecraft.java.patch @@ -326,14 +326,16 @@ } private boolean isLevelRunningNormally() { -@@ -2056,6 +_,7 @@ +@@ -2056,7 +_,8 @@ } public void setLevel(ClientLevel p_91157_, ReceivingLevelScreen.Reason p_341652_) { +- this.updateScreenAndTick(new ReceivingLevelScreen(() -> false, p_341652_)); + if (this.level != null) net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.LevelEvent.Unload(this.level)); - this.updateScreenAndTick(new ReceivingLevelScreen(() -> false, p_341652_)); ++ this.updateScreenAndTick(net.neoforged.neoforge.client.DimensionTransitionScreenManager.getScreenFromLevel(p_91157_, this.level).create(() -> false, p_341652_)); this.level = p_91157_; this.updateLevelInEngines(p_91157_); + if (!this.isLocalServer) { @@ -2093,6 +_,7 @@ IntegratedServer integratedserver = this.singleplayerServer; this.singleplayerServer = null; diff --git a/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch b/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch index 4ca1a328ab..ba17981ad6 100644 --- a/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch @@ -16,7 +16,7 @@ this.potionBrewing = PotionBrewing.bootstrap(this.enabledFeatures); } -@@ -427,6 +_,7 @@ +@@ -427,12 +_,13 @@ this.minecraft.debugRenderer.clear(); this.minecraft.player.resetPos(); @@ -24,6 +24,13 @@ this.minecraft.player.setId(p_105030_.playerId()); this.level.addEntity(this.minecraft.player); this.minecraft.player.input = new KeyboardInput(this.minecraft.options); + this.minecraft.gameMode.adjustPlayer(this.minecraft.player); + this.minecraft.cameraEntity = this.minecraft.player; +- this.startWaitingForNewLevel(this.minecraft.player, this.level, ReceivingLevelScreen.Reason.OTHER); ++ this.startWaitingForNewLevel(this.minecraft.player, this.level, ReceivingLevelScreen.Reason.OTHER, null, null); + this.minecraft.player.setReducedDebugInfo(p_105030_.reducedDebugInfo()); + this.minecraft.player.setShowDeathScreen(p_105030_.showDeathScreen()); + this.minecraft.player.setDoLimitedCrafting(p_105030_.doLimitedCrafting()); @@ -828,7 +_,8 @@ chatcomponent$state, this.strictErrorHandling, @@ -34,6 +41,15 @@ ) ) ); +@@ -1142,7 +_,7 @@ + localplayer1 = this.minecraft.gameMode.createPlayer(this.level, localplayer.getStats(), localplayer.getRecipeBook()); + } + +- this.startWaitingForNewLevel(localplayer1, this.level, receivinglevelscreen$reason); ++ this.startWaitingForNewLevel(localplayer1, this.level, receivinglevelscreen$reason, localplayer.isDeadOrDying() ? null : resourcekey, localplayer.isDeadOrDying() ? null : resourcekey1); + localplayer1.setId(localplayer.getId()); + this.minecraft.player = localplayer1; + if (flag) { @@ -1164,6 +_,7 @@ } @@ -54,6 +70,23 @@ if (p_337415_ instanceof CommandBlockEntity && this.minecraft.screen instanceof CommandBlockEditScreen) { ((CommandBlockEditScreen)this.minecraft.screen).updateGui(); +@@ -1420,9 +_,15 @@ + } + } + ++ /** @deprecated Neo: use {@link #startWaitingForNewLevel(LocalPlayer, ClientLevel, ReceivingLevelScreen.Reason, ResourceKey, ResourceKey)} instead. */ ++ @Deprecated + private void startWaitingForNewLevel(LocalPlayer p_304688_, ClientLevel p_304528_, ReceivingLevelScreen.Reason p_341690_) { ++ this.startWaitingForNewLevel(p_304688_, p_304528_, p_341690_, null, null); ++ } ++ ++ private void startWaitingForNewLevel(LocalPlayer p_304688_, ClientLevel p_304528_, ReceivingLevelScreen.Reason p_341690_, @Nullable ResourceKey toDimension, @Nullable ResourceKey fromDimension) { + this.levelLoadStatusManager = new LevelLoadStatusManager(p_304688_, p_304528_, this.minecraft.levelRenderer); +- this.minecraft.setScreen(new ReceivingLevelScreen(this.levelLoadStatusManager::levelReady, p_341690_)); ++ this.minecraft.setScreen(net.neoforged.neoforge.client.DimensionTransitionScreenManager.getScreen(toDimension, fromDimension).create(this.levelLoadStatusManager::levelReady, p_341690_)); + } + + @Override @@ -1471,7 +_,9 @@ @Override public void handleCommands(ClientboundCommandsPacket p_104990_) { diff --git a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java index 2349977464..c27d39a3de 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java @@ -1035,6 +1035,7 @@ public static void initClientHooks(Minecraft mc, ReloadableResourceManager resou ItemDecoratorHandler.init(); PresetEditorManager.init(); MapDecorationRendererManager.init(); + DimensionTransitionScreenManager.init(); } /** diff --git a/src/main/java/net/neoforged/neoforge/client/DimensionTransitionScreenManager.java b/src/main/java/net/neoforged/neoforge/client/DimensionTransitionScreenManager.java new file mode 100644 index 0000000000..86a69eaa1e --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/DimensionTransitionScreenManager.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client; + +import com.mojang.datafixers.util.Pair; +import java.util.HashMap; +import java.util.Map; +import java.util.function.BooleanSupplier; +import net.minecraft.client.gui.screens.ReceivingLevelScreen; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.Level; +import net.neoforged.fml.ModLoader; +import net.neoforged.neoforge.client.event.RegisterDimensionTransitionScreenEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +public class DimensionTransitionScreenManager { + private static final Map, ResourceKey>, ReceivingLevelScreenFactory> conditionalDimensionEffects = new HashMap<>(); + private static final Map, ReceivingLevelScreenFactory> toDimensionTransitions = new HashMap<>(); + private static final Map, ReceivingLevelScreenFactory> fromDimensionTransitions = new HashMap<>(); + + @ApiStatus.Internal + static void init() { + ModLoader.postEventWrapContainerInModOrder(new RegisterDimensionTransitionScreenEvent(conditionalDimensionEffects, toDimensionTransitions, fromDimensionTransitions)); + } + + public static ReceivingLevelScreenFactory getScreenFromLevel(@Nullable Level target, @Nullable Level source) { + if (source == null) { //source level is null on login: transition screen should not appear in this case + return getScreen(null, null); + } else if (target == null) { //the target level shouldn't ever be null, but anyone could call Minecraft.setLevel and pass null in + return getScreen(null, source.dimension()); + } + return getScreen(target.dimension(), source.dimension()); + } + + public static ReceivingLevelScreenFactory getScreen(@Nullable ResourceKey toDimension, @Nullable ResourceKey fromDimension) { + var conditionalScreen = conditionalDimensionEffects.get(Pair.of(toDimension, fromDimension)); + if (conditionalScreen != null) { + return conditionalScreen; + } + var toDim = toDimensionTransitions.get(toDimension); + if (toDim != null) { + return toDim; + } + var fromDim = fromDimensionTransitions.get(fromDimension); + if (fromDim != null) { + return fromDim; + } + return ReceivingLevelScreen::new; + } + + public interface ReceivingLevelScreenFactory { + ReceivingLevelScreen create(BooleanSupplier supplier, ReceivingLevelScreen.Reason reason); + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/event/RegisterDimensionTransitionScreenEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RegisterDimensionTransitionScreenEvent.java new file mode 100644 index 0000000000..bf4e500f39 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/event/RegisterDimensionTransitionScreenEvent.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import com.mojang.datafixers.util.Pair; +import java.util.Map; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.Level; +import net.neoforged.bus.api.Event; +import net.neoforged.bus.api.ICancellableEvent; +import net.neoforged.fml.LogicalSide; +import net.neoforged.fml.event.IModBusEvent; +import net.neoforged.neoforge.client.DimensionTransitionScreenManager.ReceivingLevelScreenFactory; +import org.jetbrains.annotations.ApiStatus; + +/** + *

Event for registering screen effects when transitioning across dimensions. + * Note that there is a priority order when it comes to what screens are displayed:
+ * - Using registerConditionalEffect has priority over the usual transition effects, and will only fire when travelling to the specified dimension coming from a certain dimension.
+ * - If a dimension has a screen that displays when entering it, that will have priority over a dimension that has one when you leave it.

+ * + *

This event is not {@linkplain ICancellableEvent cancellable}, and does not {@linkplain HasResult have a result}. + * + *

This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}.

+ */ +public class RegisterDimensionTransitionScreenEvent extends Event implements IModBusEvent { + private final Map, ResourceKey>, ReceivingLevelScreenFactory> conditionalDimensionEffects; + private final Map, ReceivingLevelScreenFactory> toEffects; + private final Map, ReceivingLevelScreenFactory> fromEffects; + + @ApiStatus.Internal + public RegisterDimensionTransitionScreenEvent(Map, ResourceKey>, ReceivingLevelScreenFactory> conditionalDimensionEffects, + Map, ReceivingLevelScreenFactory> toEffects, + Map, ReceivingLevelScreenFactory> fromEffects) { + this.conditionalDimensionEffects = conditionalDimensionEffects; + this.toEffects = toEffects; + this.fromEffects = fromEffects; + } + + /** + * Registers a dimension transition when traveling to a dimension. + * + * @return {@code true} if the screen was registered, {@code false} otherwise. + */ + public boolean registerIncomingEffect(ResourceKey dimension, ReceivingLevelScreenFactory screen) { + return this.toEffects.putIfAbsent(dimension, screen) == null; + } + + /** + * Registers a dimension transition when traveling from a dimension. + * + * @return {@code true} if the screen was registered, {@code false} otherwise. + */ + public boolean registerOutgoingEffect(ResourceKey dimension, ReceivingLevelScreenFactory screen) { + return this.fromEffects.putIfAbsent(dimension, screen) == null; + } + + /** + * Registers a dimension transition when traveling to a dimension from a certain dimension. + * This registration method takes priority over the normal to and from dimension checks. + * + * @return {@code true} if the screen was registered, {@code false} otherwise. + */ + public boolean registerConditionalEffect(ResourceKey toDimension, ResourceKey fromDimension, ReceivingLevelScreenFactory screen) { + return this.conditionalDimensionEffects.putIfAbsent(Pair.of(toDimension, fromDimension), screen) == null; + } +} diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/client/DimensionTransitionScreenTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/client/DimensionTransitionScreenTests.java new file mode 100644 index 0000000000..fdf77428fb --- /dev/null +++ b/tests/src/main/java/net/neoforged/neoforge/debug/client/DimensionTransitionScreenTests.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.debug.client; + +import java.util.function.BooleanSupplier; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.ReceivingLevelScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.neoforge.client.event.RegisterDimensionTransitionScreenEvent; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; +import net.neoforged.testframework.DynamicTest; +import net.neoforged.testframework.annotation.ForEachTest; +import net.neoforged.testframework.annotation.TestHolder; +import net.neoforged.testframework.gametest.EmptyTemplate; + +@ForEachTest(side = Dist.CLIENT, groups = { DimensionTransitionScreenTests.GROUP, "manual" }) +public class DimensionTransitionScreenTests { + public static final String GROUP = "dimension_transition"; + public static final ResourceLocation NETHER_BG = ResourceLocation.withDefaultNamespace("textures/block/netherrack.png"); + public static final ResourceLocation END_BG = ResourceLocation.withDefaultNamespace("textures/block/end_stone.png"); + + @EmptyTemplate + @TestHolder(description = "Tests if a custom dimension transition screen is properly displayed when exiting the Nether") + static void netherOutgoingTransition(DynamicTest test) { + test.framework().modEventBus().addListener((RegisterDimensionTransitionScreenEvent event) -> event.registerOutgoingEffect(Level.NETHER, (supplier, reason) -> new CustomLevelScreen(supplier, reason, NETHER_BG, Component.literal("This displays when returning from the nether!")))); + + test.eventListeners().forge().addListener((PlayerEvent.PlayerChangedDimensionEvent event) -> { + Player player = event.getEntity(); + if (event.getFrom() == Level.NETHER) { + test.requestConfirmation(player, Component.literal("Did the screen display a netherrack background when traveling through the portal?")); + } + }); + } + + @EmptyTemplate + @TestHolder(description = "Tests if a custom dimension transition screen is properly displayed when entering the End") + static void endIncomingTransition(DynamicTest test) { + test.framework().modEventBus().addListener((RegisterDimensionTransitionScreenEvent event) -> event.registerIncomingEffect(Level.END, (supplier, reason) -> new CustomLevelScreen(supplier, reason, END_BG, Component.literal("This displays when going to the end!")))); + + test.eventListeners().forge().addListener((PlayerEvent.PlayerChangedDimensionEvent event) -> { + Player player = event.getEntity(); + if (event.getTo() == Level.END) { + test.requestConfirmation(player, Component.literal("Did the screen display an end stone background when traveling through the portal?")); + } + }); + } + + public static class CustomLevelScreen extends ReceivingLevelScreen { + private final ResourceLocation bgTexture; + private final Component message; + + public CustomLevelScreen(BooleanSupplier supplier, Reason reason, ResourceLocation bgTexture, Component message) { + super(supplier, reason); + this.bgTexture = bgTexture; + this.message = message; + } + + @Override + public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { + this.renderBackground(graphics, mouseX, mouseY, partialTick); + graphics.drawCenteredString(this.font, this.message, this.width / 2, this.height / 2 - 50, 0xFFFFFF); + } + + @Override + public void renderBackground(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { + graphics.blit(this.bgTexture, 0, 0, 0, 0.0F, 0.0F, this.width, this.height, 32, 32); + } + } +} From 659d33f20ecf91cfb36548e3a2331f60c9176da0 Mon Sep 17 00:00:00 2001 From: Brennan Ward Date: Sat, 31 Aug 2024 10:03:15 -0700 Subject: [PATCH 052/125] [1.21] Implement common networking with config tasks (#1483) --- .../ClientCommonPacketListenerImpl.java.patch | 4 +- .../ServerCommonPacketListenerImpl.java.patch | 4 +- .../network/ConfigurationInitialization.java | 18 +++++-- .../configuration/CommonRegisterTask.java | 37 ++++++++++++++ .../configuration/CommonVersionTask.java | 32 +++++++++++++ .../network/registration/NetworkRegistry.java | 48 ++++++++++--------- 6 files changed, 113 insertions(+), 30 deletions(-) create mode 100644 src/main/java/net/neoforged/neoforge/network/configuration/CommonRegisterTask.java create mode 100644 src/main/java/net/neoforged/neoforge/network/configuration/CommonVersionTask.java diff --git a/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch b/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch index fa6437a7c7..8bc8fe4f9c 100644 --- a/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch @@ -36,12 +36,12 @@ + } + + if (p_295727_.payload() instanceof net.neoforged.neoforge.network.payload.CommonVersionPayload commonVersionPayload) { -+ net.neoforged.neoforge.network.registration.NetworkRegistry.checkCommonVersion(this.getConnection(), commonVersionPayload); ++ net.neoforged.neoforge.network.registration.NetworkRegistry.checkCommonVersion(this, commonVersionPayload); + return; + } + + if (p_295727_.payload() instanceof net.neoforged.neoforge.network.payload.CommonRegisterPayload commonRegisterPayload) { -+ net.neoforged.neoforge.network.registration.NetworkRegistry.onCommonRegister(this.getConnection(), commonRegisterPayload); ++ net.neoforged.neoforge.network.registration.NetworkRegistry.onCommonRegister(this, commonRegisterPayload); + return; + } + diff --git a/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch b/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch index d289270c98..bc534702f9 100644 --- a/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch +++ b/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch @@ -36,12 +36,12 @@ + } + + if (p_294276_.payload() instanceof net.neoforged.neoforge.network.payload.CommonVersionPayload commonVersionPayload) { -+ net.neoforged.neoforge.network.registration.NetworkRegistry.checkCommonVersion(this.getConnection(), commonVersionPayload); ++ net.neoforged.neoforge.network.registration.NetworkRegistry.checkCommonVersion(this, commonVersionPayload); + return; + } + + if (p_294276_.payload() instanceof net.neoforged.neoforge.network.payload.CommonRegisterPayload commonRegisterPayload) { -+ net.neoforged.neoforge.network.registration.NetworkRegistry.onCommonRegister(this.getConnection(), commonRegisterPayload); ++ net.neoforged.neoforge.network.registration.NetworkRegistry.onCommonRegister(this, commonRegisterPayload); + return; + } + diff --git a/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java b/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java index c9713d4ed1..2c64664388 100644 --- a/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java +++ b/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java @@ -12,10 +12,14 @@ import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.network.configuration.CheckExtensibleEnums; +import net.neoforged.neoforge.network.configuration.CommonRegisterTask; +import net.neoforged.neoforge.network.configuration.CommonVersionTask; import net.neoforged.neoforge.network.configuration.RegistryDataMapNegotiation; import net.neoforged.neoforge.network.configuration.SyncConfig; import net.neoforged.neoforge.network.configuration.SyncRegistries; import net.neoforged.neoforge.network.event.RegisterConfigurationTasksEvent; +import net.neoforged.neoforge.network.payload.CommonRegisterPayload; +import net.neoforged.neoforge.network.payload.CommonVersionPayload; import net.neoforged.neoforge.network.payload.ConfigFilePayload; import net.neoforged.neoforge.network.payload.FrozenRegistryPayload; import net.neoforged.neoforge.network.payload.FrozenRegistrySyncCompletedPayload; @@ -39,12 +43,18 @@ public static void configureEarlyTasks(ServerConfigurationPacketListener listene @SubscribeEvent private static void configureModdedClient(RegisterConfigurationTasksEvent event) { - if (event.getListener().hasChannel(ConfigFilePayload.TYPE)) { - event.register(new SyncConfig(event.getListener())); + ServerConfigurationPacketListener listener = event.getListener(); + if (listener.hasChannel(CommonVersionPayload.TYPE) && listener.hasChannel(CommonRegisterPayload.TYPE)) { + event.register(new CommonVersionTask()); + event.register(new CommonRegisterTask()); + } + + if (listener.hasChannel(ConfigFilePayload.TYPE)) { + event.register(new SyncConfig(listener)); } //These two can always be registered they detect the listener connection type internally and will skip themselves. - event.register(new RegistryDataMapNegotiation(event.getListener())); - event.register(new CheckExtensibleEnums(event.getListener())); + event.register(new RegistryDataMapNegotiation(listener)); + event.register(new CheckExtensibleEnums(listener)); } } diff --git a/src/main/java/net/neoforged/neoforge/network/configuration/CommonRegisterTask.java b/src/main/java/net/neoforged/neoforge/network/configuration/CommonRegisterTask.java new file mode 100644 index 0000000000..de0b843bee --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/network/configuration/CommonRegisterTask.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.network.configuration; + +import java.util.function.Consumer; +import net.minecraft.network.ConnectionProtocol; +import net.minecraft.network.protocol.PacketFlow; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion; +import net.neoforged.neoforge.network.payload.CommonRegisterPayload; +import net.neoforged.neoforge.network.registration.NetworkRegistry; +import org.jetbrains.annotations.ApiStatus; + +/** + * Common Register configuration task. After completion of {@link CommonVersionTask}, sends a {@link CommonRegisterPayload} to the client + * containing all known serverbound channels, and awaits a response containing the client's known clientbound channels. + */ +@ApiStatus.Internal +public record CommonRegisterTask() implements ICustomConfigurationTask { + public static final Type TYPE = new Type(ResourceLocation.fromNamespaceAndPath(NeoForgeVersion.MOD_ID, "common_register")); + + @Override + public Type type() { + return TYPE; + } + + @Override + public void run(Consumer sender) { + // There is currently no implementation for a version handshake, and the only existing version is 1, so we only send 1. + // Version negotiation will have to be implemented properly if a version 2 is ever added. + sender.accept(new CommonRegisterPayload(1, ConnectionProtocol.PLAY, NetworkRegistry.getCommonPlayChannels(PacketFlow.SERVERBOUND))); + } +} diff --git a/src/main/java/net/neoforged/neoforge/network/configuration/CommonVersionTask.java b/src/main/java/net/neoforged/neoforge/network/configuration/CommonVersionTask.java new file mode 100644 index 0000000000..a8f018a1d3 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/network/configuration/CommonVersionTask.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.network.configuration; + +import java.util.function.Consumer; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion; +import net.neoforged.neoforge.network.payload.CommonVersionPayload; +import org.jetbrains.annotations.ApiStatus; + +/** + * Common Version configuration task. Initiated after registry sync to begin the c:register handshake. + * The server will start the task, send c:version to the client, and await a reply. Upon reply, we transition to {@link CommonRegisterTask}. + */ +@ApiStatus.Internal +public record CommonVersionTask() implements ICustomConfigurationTask { + public static final Type TYPE = new Type(ResourceLocation.fromNamespaceAndPath(NeoForgeVersion.MOD_ID, "common_version")); + + @Override + public Type type() { + return TYPE; + } + + @Override + public void run(Consumer sender) { + sender.accept(new CommonVersionPayload()); + } +} diff --git a/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java b/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java index da26d5bb94..899598ef6d 100644 --- a/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java +++ b/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java @@ -48,6 +48,8 @@ import net.neoforged.neoforge.common.extensions.ICommonPacketListener; import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion; import net.neoforged.neoforge.network.configuration.CheckExtensibleEnums; +import net.neoforged.neoforge.network.configuration.CommonRegisterTask; +import net.neoforged.neoforge.network.configuration.CommonVersionTask; import net.neoforged.neoforge.network.connection.ConnectionType; import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; import net.neoforged.neoforge.network.filters.NetworkFilters; @@ -379,7 +381,6 @@ public static void initializeNeoForgeConnection(ServerConfigurationPacketListene nowListeningOn.addAll(getInitialListeningChannels(listener.flow())); nowListeningOn.addAll(setup.getChannels(ConnectionProtocol.CONFIGURATION).keySet()); listener.send(new MinecraftRegisterPayload(nowListeningOn.build())); - sendCommonPayloads(listener); } /** @@ -419,7 +420,6 @@ public static boolean initializeOtherConnection(ServerConfigurationPacketListene .filter(registration -> registration.getValue().optional()) .forEach(registration -> nowListeningOn.add(registration.getKey())); listener.send(new MinecraftRegisterPayload(nowListeningOn.build())); - sendCommonPayloads(listener); return true; } @@ -516,7 +516,6 @@ public static void initializeNeoForgeConnection(ClientConfigurationPacketListene nowListeningOn.addAll(getInitialListeningChannels(listener.flow())); nowListeningOn.addAll(setup.getChannels(ConnectionProtocol.CONFIGURATION).keySet()); listener.send(new MinecraftRegisterPayload(nowListeningOn.build())); - sendCommonPayloads(listener); } /** @@ -569,7 +568,6 @@ public static void initializeOtherConnection(ClientConfigurationPacketListener l .filter(registration -> registration.getValue().optional()) .forEach(registration -> nowListeningOn.add(registration.getKey())); listener.send(new MinecraftRegisterPayload(nowListeningOn.build())); - sendCommonPayloads(listener); } /** @@ -724,14 +722,22 @@ public static Set getInitialServerUnregisterChannels() { *

* Invoked on the network thread. * - * @param connection The current connection. - * @param payload The incoming version payload. + * @param listener The receiving listener. + * @param payload The incoming version payload. */ - public static void checkCommonVersion(Connection connection, CommonVersionPayload payload) { + public static void checkCommonVersion(ICommonPacketListener listener, CommonVersionPayload payload) { List otherVersions = payload.versions(); if (otherVersions.stream().noneMatch(SUPPORTED_COMMON_NETWORKING_VERSIONS::contains)) { String versions = String.join(", ", SUPPORTED_COMMON_NETWORKING_VERSIONS.stream().map(i -> i.toString()).toList()); - connection.disconnect(Component.literal("Unsupported common network version. This installation of NeoForge only supports: " + versions)); + listener.disconnect(Component.literal("Unsupported common network version. This installation of NeoForge only supports: " + versions)); + } + + if (listener.protocol() == ConnectionProtocol.CONFIGURATION) { + if (listener.flow() == PacketFlow.SERVERBOUND) { + ((ServerConfigurationPacketListener) listener).finishCurrentTask(CommonVersionTask.TYPE); + } else { + listener.send(new CommonVersionPayload()); + } } } @@ -740,13 +746,21 @@ public static void checkCommonVersion(Connection connection, CommonVersionPayloa *

* Invoked on the network thread. * - * @param connection The connection to add the channels to. - * @param payload The incoming register payload. + * @param listener The receiving listener. + * @param payload The incoming register payload. */ - public static void onCommonRegister(Connection connection, CommonRegisterPayload payload) { - Set channels = ChannelAttributes.getOrCreateCommonChannels(connection, payload.protocol()); + public static void onCommonRegister(ICommonPacketListener listener, CommonRegisterPayload payload) { + Set channels = ChannelAttributes.getOrCreateCommonChannels(listener.getConnection(), payload.protocol()); channels.clear(); channels.addAll(payload.channels()); + + if (listener.protocol() == ConnectionProtocol.CONFIGURATION) { + if (listener.flow() == PacketFlow.SERVERBOUND) { + ((ServerConfigurationPacketListener) listener).finishCurrentTask(CommonRegisterTask.TYPE); + } else { + listener.send(new CommonRegisterPayload(1, ConnectionProtocol.PLAY, getCommonPlayChannels(PacketFlow.CLIENTBOUND))); + } + } } public static Set getCommonPlayChannels(PacketFlow flow) { @@ -758,16 +772,6 @@ public static Set getCommonPlayChannels(PacketFlow flow) { .collect(Collectors.toSet()); } - public static void sendCommonPayloads(ICommonPacketListener listener) { - if (listener.hasChannel(CommonVersionPayload.ID)) { - listener.send(new CommonVersionPayload()); - } - - if (listener.hasChannel(CommonRegisterPayload.ID)) { - listener.send(new CommonRegisterPayload(1, ConnectionProtocol.PLAY, getCommonPlayChannels(listener.flow()))); - } - } - /** * Invoked when the configuration phase of a connection is completed. *

From 9b2c819e3d7ede04eabff6fa2ad65c5064371e68 Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Sun, 1 Sep 2024 19:03:00 -0400 Subject: [PATCH 053/125] Add missing `minecraft:enchantable/vanishing` to `c:enchantables` (#1494) --- src/generated/resources/data/c/tags/item/enchantables.json | 6 ++---- .../common/data/internal/NeoForgeItemTagsProvider.java | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/generated/resources/data/c/tags/item/enchantables.json b/src/generated/resources/data/c/tags/item/enchantables.json index 71d26a252b..f33d6e0c2d 100644 --- a/src/generated/resources/data/c/tags/item/enchantables.json +++ b/src/generated/resources/data/c/tags/item/enchantables.json @@ -10,11 +10,9 @@ "#minecraft:enchantable/trident", "#minecraft:enchantable/bow", "#minecraft:enchantable/crossbow", + "#minecraft:enchantable/mace", "#minecraft:enchantable/fire_aspect", "#minecraft:enchantable/durability", - { - "id": "#minecraft:enchantable/mace", - "required": false - } + "#minecraft:enchantable/vanishing" ] } \ No newline at end of file diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java index 786b481659..34fb5799d9 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java @@ -267,7 +267,7 @@ public void addTags(HolderLookup.Provider lookupProvider) { .addTags(Tags.Items.TOOLS_BOW, Tags.Items.TOOLS_BRUSH, Tags.Items.TOOLS_CROSSBOW, Tags.Items.TOOLS_FISHING_ROD, Tags.Items.TOOLS_IGNITER, Tags.Items.TOOLS_SHEAR, Tags.Items.TOOLS_SHIELD, Tags.Items.TOOLS_SPEAR, Tags.Items.TOOLS_MACE, Tags.Items.MINING_TOOL_TOOLS, Tags.Items.MELEE_WEAPON_TOOLS, Tags.Items.RANGED_WEAPON_TOOLS); tag(Tags.Items.ARMORS).addTags(ItemTags.HEAD_ARMOR, ItemTags.CHEST_ARMOR, ItemTags.LEG_ARMOR, ItemTags.FOOT_ARMOR); - tag(Tags.Items.ENCHANTABLES).addTags(ItemTags.ARMOR_ENCHANTABLE, ItemTags.EQUIPPABLE_ENCHANTABLE, ItemTags.WEAPON_ENCHANTABLE, ItemTags.SWORD_ENCHANTABLE, ItemTags.MINING_ENCHANTABLE, ItemTags.MINING_LOOT_ENCHANTABLE, ItemTags.FISHING_ENCHANTABLE, ItemTags.TRIDENT_ENCHANTABLE, ItemTags.BOW_ENCHANTABLE, ItemTags.CROSSBOW_ENCHANTABLE, ItemTags.FIRE_ASPECT_ENCHANTABLE, ItemTags.DURABILITY_ENCHANTABLE).addOptionalTag(ItemTags.MACE_ENCHANTABLE); + tag(Tags.Items.ENCHANTABLES).addTags(ItemTags.ARMOR_ENCHANTABLE, ItemTags.EQUIPPABLE_ENCHANTABLE, ItemTags.WEAPON_ENCHANTABLE, ItemTags.SWORD_ENCHANTABLE, ItemTags.MINING_ENCHANTABLE, ItemTags.MINING_LOOT_ENCHANTABLE, ItemTags.FISHING_ENCHANTABLE, ItemTags.TRIDENT_ENCHANTABLE, ItemTags.BOW_ENCHANTABLE, ItemTags.CROSSBOW_ENCHANTABLE, ItemTags.MACE_ENCHANTABLE, ItemTags.FIRE_ASPECT_ENCHANTABLE, ItemTags.DURABILITY_ENCHANTABLE, ItemTags.VANISHING_ENCHANTABLE); // Backwards compat with pre-1.21 tags. Done after so optional tag is last for better readability. // TODO: Remove backwards compat tag entries in 1.22 From 72d5ebfb0fca0c90870b12a29881ef7c934eb004 Mon Sep 17 00:00:00 2001 From: Henry Loenwind Date: Tue, 3 Sep 2024 12:37:06 +0200 Subject: [PATCH 054/125] Replace json-styled translations with string-value translations (#1490) --- .../client/gui/ConfigurationScreen.java | 51 ++++++--- .../resources/assets/neoforge/lang/en_us.json | 104 +++--------------- 2 files changed, 50 insertions(+), 105 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/client/gui/ConfigurationScreen.java b/src/main/java/net/neoforged/neoforge/client/gui/ConfigurationScreen.java index ccc2f0b64f..becd2d4ca8 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/ConfigurationScreen.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/ConfigurationScreen.java @@ -160,6 +160,17 @@ public boolean existsWithFallback(final String translationKey) { return true; } + /** + * If the given translation key exists, returns it formatted with the given style(s) and as prefixed with the given component. + * Otherwise returns an empty Component. + */ + public Component optional(final Component prefix, final String translationKey, final ChatFormatting... style) { + if (I18n.exists(translationKey)) { + return Component.empty().append(prefix).append(Component.translatable(translationKey).withStyle(style)); + } + return Component.empty(); + } + public void finish() { if (CLIENT.logUntranslatedConfigurationWarnings.get() && !FMLLoader.isProduction() && (!untranslatables.isEmpty() || !untranslatablesWithFallback.isEmpty())) { StringBuilder stringBuilder = new StringBuilder(); @@ -200,7 +211,8 @@ public void finish() { /** * The breadcrumb separator. Default: "%s > %s" */ - private static final String CRUMB = LANG_PREFIX + "breadcrumb"; + public static final Component CRUMB_SEPARATOR = Component.translatable(LANG_PREFIX + "breadcrumb.separator").withStyle(ChatFormatting.GOLD, ChatFormatting.BOLD); + private static final String CRUMB = LANG_PREFIX + "breadcrumb.order"; /** * The label of list elements. Will be supplied the index into the list. Default: "%s:" */ @@ -209,20 +221,26 @@ public void finish() { * How the range will be added to the tooltip when using translated tooltips. Mimics what the comment does in ModConfigSpec. */ private static final String RANGE_TOOLTIP = LANG_PREFIX + "rangetooltip"; + private static final ChatFormatting RANGE_TOOLTIP_STYLE = ChatFormatting.GRAY; /** * How the filename will be added to the tooltip. */ private static final String FILENAME_TOOLTIP = LANG_PREFIX + "filenametooltip"; + private static final ChatFormatting FILENAME_TOOLTIP_STYLE = ChatFormatting.GRAY; + /** + * A literal to create an empty line in a tooltip. + */ + private static final MutableComponent EMPTY_LINE = Component.literal("\n\n"); - public static final Component TOOLTIP_CANNOT_EDIT_THIS_WHILE_ONLINE = Component.translatable(LANG_PREFIX + "notonline"); - public static final Component TOOLTIP_CANNOT_EDIT_THIS_WHILE_OPEN_TO_LAN = Component.translatable(LANG_PREFIX + "notlan"); - public static final Component TOOLTIP_CANNOT_EDIT_NOT_LOADED = Component.translatable(LANG_PREFIX + "notloaded"); + public static final Component TOOLTIP_CANNOT_EDIT_THIS_WHILE_ONLINE = Component.translatable(LANG_PREFIX + "notonline").withStyle(ChatFormatting.RED); + public static final Component TOOLTIP_CANNOT_EDIT_THIS_WHILE_OPEN_TO_LAN = Component.translatable(LANG_PREFIX + "notlan").withStyle(ChatFormatting.RED); + public static final Component TOOLTIP_CANNOT_EDIT_NOT_LOADED = Component.translatable(LANG_PREFIX + "notloaded").withStyle(ChatFormatting.RED); public static final Component NEW_LIST_ELEMENT = Component.translatable(LANG_PREFIX + "newlistelement"); public static final Component MOVE_LIST_ELEMENT_UP = Component.translatable(LANG_PREFIX + "listelementup"); public static final Component MOVE_LIST_ELEMENT_DOWN = Component.translatable(LANG_PREFIX + "listelementdown"); public static final Component REMOVE_LIST_ELEMENT = Component.translatable(LANG_PREFIX + "listelementremove"); - public static final Component UNSUPPORTED_ELEMENT = Component.translatable(LANG_PREFIX + "unsupportedelement"); - public static final Component LONG_STRING = Component.translatable(LANG_PREFIX + "longstring"); + public static final Component UNSUPPORTED_ELEMENT = Component.translatable(LANG_PREFIX + "unsupportedelement").withStyle(ChatFormatting.RED); + public static final Component LONG_STRING = Component.translatable(LANG_PREFIX + "longstring").withStyle(ChatFormatting.RED); public static final Component GAME_RESTART_TITLE = Component.translatable(LANG_PREFIX + "restart.game.title"); public static final Component GAME_RESTART_MESSAGE = Component.translatable(LANG_PREFIX + "restart.game.text"); public static final Component GAME_RESTART_YES = Component.translatable("menu.quit"); // TitleScreen.init() et.al. @@ -231,7 +249,7 @@ public void finish() { public static final Component RETURN_TO_MENU = Component.translatable("menu.returnToMenu"); // PauseScreen.RETURN_TO_MENU public static final Component SAVING_LEVEL = Component.translatable("menu.savingLevel"); // PauseScreen.SAVING_LEVEL public static final Component RESTART_NO = Component.translatable(LANG_PREFIX + "restart.return"); - public static final Component RESTART_NO_TOOLTIP = Component.translatable(LANG_PREFIX + "restart.return.tooltip"); + public static final Component RESTART_NO_TOOLTIP = Component.translatable(LANG_PREFIX + "restart.return.tooltip").withStyle(ChatFormatting.RED, ChatFormatting.BOLD); public static final Component UNDO = Component.translatable(LANG_PREFIX + "undo"); public static final Component UNDO_TOOLTIP = Component.translatable(LANG_PREFIX + "undo.tooltip"); public static final Component RESET = Component.translatable(LANG_PREFIX + "reset"); @@ -281,19 +299,19 @@ protected void addOptions() { button -> minecraft.setScreen(sectionScreen.apply(this, type, modConfig, translatableConfig(modConfig, ".title", LANG_PREFIX + "title." + type.name().toLowerCase(Locale.ROOT))))).width(BIG_BUTTON_WIDTH).build(); MutableComponent tooltip = Component.empty(); if (!((ModConfigSpec) modConfig.getSpec()).isLoaded()) { - tooltip.append(TOOLTIP_CANNOT_EDIT_NOT_LOADED).append(Component.literal("\n\n")); + tooltip.append(TOOLTIP_CANNOT_EDIT_NOT_LOADED).append(EMPTY_LINE); btn.active = false; count = 99; // prevent autoClose } else if (type == Type.SERVER && minecraft.getCurrentServer() != null && !minecraft.isSingleplayer()) { - tooltip.append(TOOLTIP_CANNOT_EDIT_THIS_WHILE_ONLINE).append(Component.literal("\n\n")); + tooltip.append(TOOLTIP_CANNOT_EDIT_THIS_WHILE_ONLINE).append(EMPTY_LINE); btn.active = false; count = 99; // prevent autoClose } else if (type == Type.SERVER && minecraft.hasSingleplayerServer() && minecraft.getSingleplayerServer().isPublished()) { - tooltip.append(TOOLTIP_CANNOT_EDIT_THIS_WHILE_OPEN_TO_LAN).append(Component.literal("\n\n")); + tooltip.append(TOOLTIP_CANNOT_EDIT_THIS_WHILE_OPEN_TO_LAN).append(EMPTY_LINE); btn.active = false; count = 99; // prevent autoClose } - tooltip.append(Component.translatable(FILENAME_TOOLTIP, modConfig.getFileName())); + tooltip.append(Component.translatable(FILENAME_TOOLTIP, modConfig.getFileName()).withStyle(FILENAME_TOOLTIP_STYLE)); btn.setTooltip(Tooltip.create(tooltip)); list.addSmall(btn, null); count++; @@ -514,7 +532,7 @@ public ConfigurationSectionScreen(final Screen parent, final ModConfig.Type type */ public ConfigurationSectionScreen(final Context parentContext, final Screen parent, final Map valueSpecs, final String key, final Set entrySet, Component title) { - this(Context.section(parentContext, parent, entrySet, valueSpecs, key), Component.translatable(CRUMB, parent.getTitle(), title)); + this(Context.section(parentContext, parent, entrySet, valueSpecs, key), Component.translatable(CRUMB, parent.getTitle(), CRUMB_SEPARATOR, title)); } @SuppressWarnings("resource") @@ -558,10 +576,13 @@ protected Component getTooltipComponent(final String key, @Nullable Range ran final boolean hasTranslatedTooltip = translationChecker.existsWithFallback(tooltipKey); MutableComponent component = Component.empty().append(getTranslationComponent(key).withStyle(ChatFormatting.BOLD)); if (hasTranslatedTooltip || !Strings.isBlank(comment)) { - component = component.append(Component.literal("\n\n")).append(Component.translatableWithFallback(tooltipKey, comment)); + component = component.append(EMPTY_LINE).append(Component.translatableWithFallback(tooltipKey, comment)); } + // The "tooltip.warning" key is to be considered an internal API. It will be removed once Neo has a + // generic styling mechanism for translation texts. Use at your own risk. + component = component.append(translationChecker.optional(EMPTY_LINE, tooltipKey + ".warning", ChatFormatting.RED, ChatFormatting.BOLD)); if (hasTranslatedTooltip && range != null) { - component = component.append(Component.translatable(RANGE_TOOLTIP, range.toString())); + component = component.append(EMPTY_LINE).append(Component.translatable(RANGE_TOOLTIP, range.toString()).withStyle(RANGE_TOOLTIP_STYLE)); } return component; } @@ -917,7 +938,7 @@ protected Element createList(final String key, final ListValueSpec spec, fin return new Element(Component.translatable(SECTION, getTranslationComponent(key)), getTooltipComponent(key, null), Button.builder(Component.translatable(SECTION, Component.translatable(translationChecker.check(getTranslationKey(key) + ".button", SECTION_TEXT))), button -> minecraft.setScreen(sectionCache.computeIfAbsent(key, - k -> new ConfigurationListScreen<>(Context.list(context, this), key, Component.translatable(CRUMB, this.getTitle(), getTranslationComponent(key)), spec, list)).rebuild())) + k -> new ConfigurationListScreen<>(Context.list(context, this), key, Component.translatable(CRUMB, this.getTitle(), CRUMB_SEPARATOR, getTranslationComponent(key)), spec, list)).rebuild())) .tooltip(Tooltip.create(getTooltipComponent(key, null))).build(), false); } diff --git a/src/main/resources/assets/neoforge/lang/en_us.json b/src/main/resources/assets/neoforge/lang/en_us.json index 5e0e4c29db..0d78311974 100644 --- a/src/main/resources/assets/neoforge/lang/en_us.json +++ b/src/main/resources/assets/neoforge/lang/en_us.json @@ -147,51 +147,15 @@ "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -201,30 +165,8 @@ "neoforge.configuration.uitext.listelementup": "\u23f6", "neoforge.configuration.uitext.listelementdown": "\u23f7", "neoforge.configuration.uitext.listelementremove": "\u274c", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -234,13 +176,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", @@ -264,23 +200,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Remove Erroring Block Entities", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Remove Erroring Entities", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Show Load Warnings", "neoforge.configgui.showLoadWarnings.tooltip": "When enabled, NeoForge will show any warnings that occurred during loading.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", From dee62213e1fc8773fc68cc7c0088134e2293c30c Mon Sep 17 00:00:00 2001 From: NeoForged Localizations Date: Wed, 4 Sep 2024 00:04:04 +0800 Subject: [PATCH 055/125] New Crowdin updates (#1426) --- .../resources/assets/neoforge/lang/cs_cz.json | 120 ++------ .../resources/assets/neoforge/lang/da_dk.json | 120 ++------ .../resources/assets/neoforge/lang/de_de.json | 146 +++------ .../resources/assets/neoforge/lang/en_gb.json | 120 ++------ .../resources/assets/neoforge/lang/eo_uy.json | 120 ++------ .../resources/assets/neoforge/lang/es_es.json | 120 ++------ .../resources/assets/neoforge/lang/et_ee.json | 120 ++------ .../resources/assets/neoforge/lang/fr_fr.json | 120 ++------ .../resources/assets/neoforge/lang/hu_hu.json | 120 ++------ .../resources/assets/neoforge/lang/it_it.json | 120 ++------ .../resources/assets/neoforge/lang/ja_jp.json | 122 ++------ .../resources/assets/neoforge/lang/ko_kr.json | 152 +++------- .../resources/assets/neoforge/lang/ms_my.json | 247 +++++++++++++++ .../resources/assets/neoforge/lang/nl_nl.json | 120 ++------ .../resources/assets/neoforge/lang/pl_pl.json | 286 +++++++----------- .../resources/assets/neoforge/lang/pt_br.json | 120 ++------ .../resources/assets/neoforge/lang/pt_pt.json | 120 ++------ .../resources/assets/neoforge/lang/ro_ro.json | 120 ++------ .../resources/assets/neoforge/lang/ru_ru.json | 120 ++------ .../resources/assets/neoforge/lang/sk_sk.json | 120 ++------ .../resources/assets/neoforge/lang/tr_tr.json | 120 ++------ .../resources/assets/neoforge/lang/tt_ru.json | 120 ++------ .../resources/assets/neoforge/lang/uk_ua.json | 120 ++------ .../resources/assets/neoforge/lang/vi_vn.json | 120 ++------ .../resources/assets/neoforge/lang/zh_cn.json | 230 +++++--------- .../neoforge/lang/{zh_hk.json => zh_tw.json} | 264 ++++++---------- 26 files changed, 1137 insertions(+), 2590 deletions(-) create mode 100644 src/main/resources/assets/neoforge/lang/ms_my.json rename src/main/resources/assets/neoforge/lang/{zh_hk.json => zh_tw.json} (64%) diff --git a/src/main/resources/assets/neoforge/lang/cs_cz.json b/src/main/resources/assets/neoforge/lang/cs_cz.json index 75160c4ebe..2c95bf1deb 100644 --- a/src/main/resources/assets/neoforge/lang/cs_cz.json +++ b/src/main/resources/assets/neoforge/lang/cs_cz.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "Vybrané ID dimenze (%1$s) je neplatné.", "commands.neoforge.setdim.invalid.nochange": "Vybraná entita (%1$s) již existuje v specifické dimenzi (%2$s).", "commands.neoforge.setdim.deprecated": "Tento příkaz je zastaralý kvůli smazání ve verzi 1.17, použijte místo něj %s.", - "commands.neoforge.tps.invalid": "Neplatná dimenze %1$s Možné hodnoty: %2$s", - "commands.neoforge.tps.summary.all": "Celkem: Průměrná doba ticku: %1$s ms. Průměrný TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Módový seznam: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Průměrná doba ticku: %2$s ms. Průměrný TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Průměrná doba ticku: %3$s ms. Průměrný TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Sledování entity povoleno na %d sekund.", "commands.neoforge.tracking.entity.reset": "Data časování entity byla vymazána!", "commands.neoforge.tracking.invalid": "Neplatná sledovací data.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Čas v %s běží normální rychlostí (20 minut za den).", "commands.neoforge.timespeed.set": "Nastaven běh času v %s na %sx (%s minut za den).", "commands.neoforge.timespeed.set.default": "Nastaven běh času v %s na základní nastavení (20 minut za den).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Konfigurace pro %s typu %s nalezena na %s", "commands.config.noconfig": "Konfigurace pro %s typu %s nenalezena", "neoforge.update.beta.1": "%sPOZOR: %sNeoForge Beta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "Konfigurace Serveru %s", "neoforge.configuration.uitext.title.common": "Běžná konfigurace %s", "neoforge.configuration.uitext.title.startup": "Konfigurace při spuštění %s", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Nastavení jsou zde rozhodnuté serverem a nemohou být změněny když jste online.", - "color": "červený" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Nastavení zde nemohou být změněny, když je Vaše hra otevřená k LAN. Prosím, vraťte se do hlavního menu a načtěte svět znovu.", - "color": "červený" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Nastavení zde jsou dostupné pouze až po načtení světa.", - "color": "červený" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "Tato hodnota nemůže být změněna v UI. Prosím, kontaktujte autora módu, aby pro něj poskytl UI.", - "color": "červený" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "Tato hodnota je moc veliká pro změnu v UI. Prosím, změňte ji v konfiguračním souboru.", - "color": "červený" - } - ], + "neoforge.configuration.uitext.notonline": "Nastavení jsou zde rozhodnuté serverem a nemohou být změněny když jste online.", + "neoforge.configuration.uitext.notlan": "Nastavení zde nemohou být změněny, když je Vaše hra otevřená k LAN. Prosím, vraťte se do hlavního menu a načtěte svět znovu.", + "neoforge.configuration.uitext.notloaded": "Nastavení zde jsou dostupné pouze až po načtení světa.", + "neoforge.configuration.uitext.unsupportedelement": "Tato hodnota nemůže být změněna v UI. Prosím, kontaktujte autora módu, aby pro něj poskytl UI.", + "neoforge.configuration.uitext.longstring": "Tato hodnota je moc veliká pro změnu v UI. Prosím, změňte ji v konfiguračním souboru.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Změnit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "zlato", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Vrátit zpět", "neoforge.configuration.uitext.undo.tooltip": "Vrátí zpět změny pouze na této obrazovce.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRozmezí: ", - "color": "šedivá" - }, - { - "index": 0, - "color": "šedivá" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "Soubor: \"", - "color": "šedivá" - }, - { - "index": 0, - "color": "šedivá" - }, - { - "text": "\"", - "color": "šedivá" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Obecné volby", "neoforge.configuration.uitext.client": "Volby klienta", "neoforge.configuration.uitext.server": "Volby serveru", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "Svět se musí znovu načíst", "neoforge.configuration.uitext.restart.server.text": "Jeden či více konfiguračních možností, které byly změněny, se projeví až se znovu načte svět.", "neoforge.configuration.uitext.restart.return": "Ignorovat", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Vaše změny nebudou mít žádný účinek do restartu!", - "color": "červená", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Vaše změny nebudou mít žádný účinek do restartu!", "neoforge.configuration.title": "NeoForge konfigurace", "neoforge.configuration.section.neoforge.client.toml": "Nastavení Klienta", "neoforge.configuration.section.neoforge.client.toml.title": "Nastavení Klienta", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Manažer oprávnění", "neoforge.configgui.permissionHandler.tooltip": "Manažer oprávnění použitý na serveru. Výchozí je neoforge:default_handler pokud žádný handler s tímto názvem není registrován.", "neoforge.configgui.removeErroringBlockEntities": "Odstranit Block Entity volající chyby", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Zapněte toto nastavení pro smazání všech entit které vyhazují error ve své \"update\" metodě, místo vypnutí serveru a vytvoření crash logu.\n\n", - { - "text": "POZOR, TOTO MŮŽE VŠECHNO POKAZIT.\nBUĎTE OPATRNÍ.\nNEJSME ZODPOVĚDNI ZA JAKÉKOLIV NAPÁCHANÉ ŠKODY.", - "color": "červená", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "POZOR, TOTO MŮŽE VŠECHNO POKAZIT.\nBUĎTE OPATRNÍ.\nNEJSME ZODPOVĚDNI ZA JAKÉKOLIV NAPÁCHANÉ ŠKODY.", "neoforge.configgui.removeErroringEntities": "Odstranit Entity volající chyby", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Zapněte toto nastavení pro smazání všech block entit které vyhazují error ve své \"update\" metodě, místo vypnutí serveru a vytvoření crash logu.\n\n", - { - "text": "POZOR, TOTO MŮŽE VŠECHNO POKAZIT.\nBUĎTE OPATRNÍ.\nNEJSME ZODPOVĚDNI ZA JAKÉKOLIV NAPÁCHANÉ ŠKODY.", - "color": "červená", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "POZOR, TOTO MŮŽE VŠECHNO POKAZIT.\nBUĎTE OPATRNÍ.\nNEJSME ZODPOVĚDNI ZA JAKÉKOLIV NAPÁCHANÉ ŠKODY.", "neoforge.configgui.showLoadWarnings": "Zobrazit Upozornění při Načítání", "neoforge.configgui.showLoadWarnings.tooltip": "Pokud je zapnuto, NeoForge zobrazí jakákoliv upozornění, která se vyskytla při načítání.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Používejte kombinovaný doplňek DEPTH_STENCIL", diff --git a/src/main/resources/assets/neoforge/lang/da_dk.json b/src/main/resources/assets/neoforge/lang/da_dk.json index cb6bec74a1..667edefa31 100644 --- a/src/main/resources/assets/neoforge/lang/da_dk.json +++ b/src/main/resources/assets/neoforge/lang/da_dk.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "This command is deprecated for removal in 1.17, use %s instead.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Entity tracking enabled for %d seconds.", "commands.neoforge.tracking.entity.reset": "Entity timings data has been cleared!", "commands.neoforge.tracking.invalid": "Invalid tracking data.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Config for %s of type %s found at %s", "commands.config.noconfig": "Config for %s of type %s not found", "neoforge.update.beta.1": "%sADVARSEL: %sNeoForge Beta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Remove Erroring Block Entities", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Remove Erroring Entities", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Show Load Warnings", "neoforge.configgui.showLoadWarnings.tooltip": "When enabled, NeoForge will show any warnings that occurred during loading.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/de_de.json b/src/main/resources/assets/neoforge/lang/de_de.json index 4e005889f3..7792a3f15c 100644 --- a/src/main/resources/assets/neoforge/lang/de_de.json +++ b/src/main/resources/assets/neoforge/lang/de_de.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "Die angegebene Dimension-ID (%1$s) ist ungültig.", "commands.neoforge.setdim.invalid.nochange": "Die ausgewählte Entität (%1$s) ist bereits in der angegebenen Dimension (%2$s).", "commands.neoforge.setdim.deprecated": "Dieser Befehl ist veraltet und wird in 1.17 entfernt, verwende stattdessen %s.", - "commands.neoforge.tps.invalid": "Ungültige Dimension %1$s Mögliche Werte: %2$s", - "commands.neoforge.tps.summary.all": "Insgesamt: Mittlere Tickdauer: %1$s ms. Mittlere TPS: %2$s", + "commands.neoforge.tps.overall": "Insgesamt: %s TPS (%s ms/Tick)", + "commands.neoforge.tps.tooltip": "Mittlere TPS; höher ist besser. Ziel-TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/Tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimensionstyp: %s)", "commands.neoforge.mods.list": "Modliste: %1$s", - "commands.neoforge.tps.summary.basic": "Dimension %1$s: Mittlere Tickdauer: %2$s ms. Mittlere TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dimension %1$s (%2$s): Mittlere Tickdauer: %3$s ms. Mittlere TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Entitäts-Tracking für %d Sekunden aktiviert.", "commands.neoforge.tracking.entity.reset": "Entitäts-Timing-Daten wurden gelöscht!", "commands.neoforge.tracking.invalid": "Ungültige Tracking-Daten.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Die Zeit in %s vergeht normal (20 Minuten pro Tag).", "commands.neoforge.timespeed.set": "Die Zeit in %s vergeht jetzt %sx so schnell wie üblich (%s Minuten pro Tag).", "commands.neoforge.timespeed.set.default": "Die Zeit in %s vergeht jetzt normal (20 Minuten pro Tag).", + "commands.neoforge.data_components.list.error.held_stack_empty": "Du hältst kein Item", + "commands.neoforge.data_components.list.title": "Datenkomponenten auf %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Komponente %s enthält den Standardwert", + "commands.neoforge.data_components.list.tooltip.deleted": "Komponente %s mit Wert %s wurde gelöscht", + "commands.neoforge.data_components.list.tooltip.modified": "Komponente %s wurde von %s auf %s geändert", + "commands.neoforge.data_components.list.tooltip.added": "Komponente %s wurde mit dem Wert %s hinzugefügt", "commands.config.getwithtype": "Konfiguration für %s vom Typ %s gefunden bei %s", "commands.config.noconfig": "Konfiguration für %s vom Typ %s nicht gefunden", "neoforge.update.beta.1": "%sWARNUNG: %sNeoForge Beta", @@ -122,59 +130,23 @@ "neoforge.update.newversion": "Neue NeoForge-Version verfügbar: %s", "neoforge.menu.updatescreen.title": "Mod Update", "neoforge.configuration.uitext.title": "%s Einstellungen", - "neoforge.configuration.uitext.type.client": "Clienteinstellungen", - "neoforge.configuration.uitext.type.server": "Servereinstellungen", + "neoforge.configuration.uitext.type.client": "Client Einstellungen", + "neoforge.configuration.uitext.type.server": "Server Einstellungen", "neoforge.configuration.uitext.type.common": "Gemeinsame Einstellungen", - "neoforge.configuration.uitext.type.startup": "Starteinstellungen", - "neoforge.configuration.uitext.title.client": "%s Clienteinstellungen", - "neoforge.configuration.uitext.title.server": "%s Servereinstellungen", - "neoforge.configuration.uitext.title.common": "%s Gemeinsame Einstellungen", + "neoforge.configuration.uitext.type.startup": "Start Einstellungen", + "neoforge.configuration.uitext.title.client": "%s Client Konfiguration", + "neoforge.configuration.uitext.title.server": "%s Server Konfiguration", + "neoforge.configuration.uitext.title.common": "%s allgemeine Konfiguration", "neoforge.configuration.uitext.title.startup": "%s Starteinstellungen", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Diese Einstellungen werden vom Server übernommen und können nicht geändert werden während Du online bist.", - "color": "rot" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Diese Einstellungen können nicht geändert werden, während du dein Spiel für andere im LAN geöffnet hast. Bitte kehre ins Hauptmenü zurück und lade den Spielstand erneut.", - "color": "rot" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Diese Einstellungen sind nur verfügbar, wenn du dich in einer Welt befindest.", - "color": "rot" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "Diese Einstellungen können nicht in der Benutzeroberfläche bearbeitet werden. Kontaktiere die/den Autor:Innen des/der Mod(s) und bitte ihn/sie ein angepasstes Bedienelement zu implementieren.", - "color": "rot" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "Dieser Wert ist zu lang, um hier bearbeitet werden zu können. Bitte bearbeite ihn in der Konfigurationsdatei.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Diese Einstellungen werden vom Server übernommen und können nicht geändert werden während Du online bist.", + "neoforge.configuration.uitext.notlan": "Diese Einstellungen können nicht geändert werden während Du Dein Spiel für andere geöffnet hast. Bitte kehre ins Hauptmenü zurück und lade den Spielstand erneut.", + "neoforge.configuration.uitext.notloaded": "Diese Einstellungen sind nur verfügbar, wenn du dich in einer Welt befindest.", + "neoforge.configuration.uitext.unsupportedelement": "Diese Einstellungen können nicht in der Benutzeroberfläche bearbeitet werden. Kontaktiere die/den Autor:Innen des/der Mod(s) und bitte ihn/sie ein angepasstes Bedienelement zu implementieren.", + "neoforge.configuration.uitext.longstring": "Dieser Wert ist zu lang, um hier bearbeitet werden zu können. Bitte bearbeite ihn in der Konfigurationsdatei.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Bearbeiten", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "Gold", - "bold": true - }, - { - "index": 0 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Rückgängig", "neoforge.configuration.uitext.undo.tooltip": "Änderungen werden nur auf diesem Bildschirm rückgängig gemacht.", @@ -184,47 +156,19 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nWertebereich: ", - "color": "grau" - }, - { - "index": 0, - "color": "grau" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "Datei: \"", - "color": "grau" - }, - { - "index": 0, - "color": "grau" - }, - { - "text": "\"", - "color": "grau" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Wertebereich: %s", + "neoforge.configuration.uitext.filenametooltip": "Datei: \"%s\"", "neoforge.configuration.uitext.common": "Gemeinsame Einstellungen", "neoforge.configuration.uitext.client": "Clienteinstellungen", "neoforge.configuration.uitext.server": "Servereinstellungen", "neoforge.configuration.uitext.startup": "Starteinstellungen", "neoforge.configuration.uitext.restart.game.title": "Minecraft muss neu gestartet werden", - "neoforge.configuration.uitext.restart.game.text": "Eine oder mehrere der geänderten Einstellungen sind nur wirksam, wenn das Spiel gestartet wird.", - "neoforge.configuration.uitext.restart.server.title": "Spielstand muss neu geladen werden", + "neoforge.configuration.uitext.restart.game.text": "Eine oder mehrere der geänderten Einstellungen sind nur wirksam, wenn das Spiel neu-gestartet wird.", + "neoforge.configuration.uitext.restart.server.title": "Welt muss neu geladen werden", "neoforge.configuration.uitext.restart.server.text": "Eine oder mehrere der geänderten Einstellungen sind nur wirksam, wenn die Welt neu geladen wird.", "neoforge.configuration.uitext.restart.return": "Ignorieren", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Deine Änderungen haben keine Wirkung, bis das Spiel neu gestartet wird!", - "color": "red", - "bold": true - } - ], - "neoforge.configuration.title": "NeoForge-Konfiguration", + "neoforge.configuration.uitext.restart.return.tooltip": "Deine Änderungen haben keine Wirkung, bis das Spiel neu gestartet wird!", + "neoforge.configuration.title": "NeoForge Konfiguration", "neoforge.configuration.section.neoforge.client.toml": "Client-Einstellungen", "neoforge.configuration.section.neoforge.client.toml.title": "Client-Einstellungen", "neoforge.configuration.section.neoforge.common.toml": "Gemeinsame Einstellungen", @@ -237,32 +181,20 @@ "neoforge.configgui.forgeLightPipelineEnabled.tooltip": "Aktiviert die NeoForge Block-Darstellungs-Pipeline - korrigiert die Beleuchtung von benutzerdefinierten Modellen.", "neoforge.configgui.fullBoundingBoxLadders": "Leitern im gesamten Kollisionsbereich", "neoforge.configgui.fullBoundingBoxLadders.tooltip": "Ändere dies zu 'true', um den gesamten Kollisionsbereich einer Entität, anstatt nur den Block, in dem sie sich befindet, auf Leitern zu überprüfen. Verursacht merkliche Unterschiede in der Spielmechanik, daher ist die Standardeinstellung die Vanilla-Funktionsweise. Standardwert: 'false'.", - "neoforge.configgui.logLegacyTagWarnings": "Veraltete Tags melden", - "neoforge.configgui.logLegacyTagWarnings.tooltip": "Eine Konfiguration, die hauptsächlich für Entwickler gedacht ist. Meldet Tags von Mods im Log, die den 'forge'-Namensraum verwenden, wenn man der integrierte Server verwendet. Standard ist DEV_SHORT.", - "neoforge.configgui.logUntranslatedConfigurationWarnings": "Unübersetzte Konfigurationstexte melden", + "neoforge.configgui.logLegacyTagWarnings": "Veraltete Tags protokollieren", + "neoforge.configgui.logLegacyTagWarnings.tooltip": "Eine Konfigurationsoption hauptsächlich für Entwickler. Protokolliert Tags von Modifikationen, die den 'forge'-Namensraum verwenden, wenn sie auf einem integrierten Server ausgeführt werden. Standard ist DEV_SHORT.", + "neoforge.configgui.logUntranslatedConfigurationWarnings": "Nicht übersetzte Konfigurationsschlüssel protokollieren", "neoforge.configgui.logUntranslatedConfigurationWarnings.tooltip": "Eine Konfiguration, die hauptsächlich für Entwickler gedacht ist. Meldet Konfigurationswerte im Log, die keine Übersetzung haben, wenn man den Client in einer Entwicklungsumgebung verwendet.", - "neoforge.configgui.logUntranslatedItemTagWarnings": "Unübersetzte Item-Tags melden", + "neoforge.configgui.logUntranslatedItemTagWarnings": "Nicht übersetzte Item-Tags protokollieren", "neoforge.configgui.logUntranslatedItemTagWarnings.tooltip": "Eine Konfiguration, die hauptsächlich für Entwickler gedacht ist. Meldet Item-Tags von Mods im Log, die keine Übersetzungen haben, wenn man den integrierten Server verwendet. Das gewünschte Format ist tag.item.. für den Übersetzungsschlüssel. Standard ist SILENCED.", "neoforge.configgui.permissionHandler": "Berechtigungsverwalter", "neoforge.configgui.permissionHandler.tooltip": "Der vom Server verwendete Berechtigungsverwalter. Standard ist neoforge:default_handler, wenn kein Handler mit diesem Namen registriert wurde.", "neoforge.configgui.removeErroringBlockEntities": "Fehlerhafte Block-Entitäten entfernen", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Aktiviere diese Option, um alle Entitäten mit Fehlern in ihrer Update-Methode zu entfernen, anstatt den Server zu schließen und einen Absturzbericht zu erstellen.\n\n", - { - "text": "SEI GEWARNT: DIES KANN ALLES BESCHÄDIGEN. SPARSAM VERWENDEN. WIR SIND NICHT FÜR SCHÄDEN VERANTWORTLICH.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Aktiviere diese Option, um alle Block-Entitäten mit Fehlern in ihrer Update-Methode zu entfernen, anstatt den Server zu schließen und einen Absturzbericht zu erstellen.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "SEI GEWARNT: DIES KANN ALLES BESCHÄDIGEN. SPARSAM VERWENDEN. WIR SIND NICHT FÜR SCHÄDEN VERANTWORTLICH.", "neoforge.configgui.removeErroringEntities": "Fehlerhafte Entitäten entfernen", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Aktiviere diese Option, um alle Block-Entitäten mit Fehlern in ihrer Update-Methode zu entfernen, anstatt den Server zu schließen und einen Absturzbericht zu erstellen.\n\n", - { - "text": "SEI GEWARNT: DIES KANN ALLES BESCHÄDIGEN. SPARSAM VERWENDEN. WIR SIND NICHT FÜR SCHÄDEN VERANTWORTLICH.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Aktiviere diese Option, um alle Entitäten mit Fehlern in ihrer Update-Methode zu entfernen, anstatt den Server zu schließen und einen Absturzbericht zu erstellen.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "SEI GEWARNT: DIES KANN ALLES BESCHÄDIGEN. SPARSAM VERWENDEN. WIR SIND NICHT FÜR SCHÄDEN VERANTWORTLICH.", "neoforge.configgui.showLoadWarnings": "Ladewarnungen anzeigen", "neoforge.configgui.showLoadWarnings.tooltip": "Wenn aktiviert, zeigt NeoForge alle Warnungen an, die beim Laden aufgetreten sind.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Kombinierten DEPTH_STENCIL-Aufsatz verwenden", diff --git a/src/main/resources/assets/neoforge/lang/en_gb.json b/src/main/resources/assets/neoforge/lang/en_gb.json index fef46ba376..7797dbc97d 100644 --- a/src/main/resources/assets/neoforge/lang/en_gb.json +++ b/src/main/resources/assets/neoforge/lang/en_gb.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "This command is deprecated for removal in 1.17, use %s instead.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Entity tracking enabled for %d seconds.", "commands.neoforge.tracking.entity.reset": "Entity timings data has been cleared!", "commands.neoforge.tracking.invalid": "Invalid tracking data.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Config for %s of type %s found at %s", "commands.config.noconfig": "Config for %s of type %s not found", "neoforge.update.beta.1": "%sWARNING: %sNeoForge Beta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Remove Erroring Block Entities", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Remove Erroring Entities", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Show Load Warnings", "neoforge.configgui.showLoadWarnings.tooltip": "When enabled, NeoForge will show any warnings that occurred during loading.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/eo_uy.json b/src/main/resources/assets/neoforge/lang/eo_uy.json index 63165fcb18..cb1667bac3 100644 --- a/src/main/resources/assets/neoforge/lang/eo_uy.json +++ b/src/main/resources/assets/neoforge/lang/eo_uy.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "This command is deprecated for removal in 1.17, use %s instead.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Entity tracking enabled for %d seconds.", "commands.neoforge.tracking.entity.reset": "Entity timings data has been cleared!", "commands.neoforge.tracking.invalid": "Invalid tracking data.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Config for %s of type %s found at %s", "commands.config.noconfig": "Config for %s of type %s not found", "neoforge.update.beta.1": "%sWARNING: %sNeoForge Beta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Remove Erroring Block Entities", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Remove Erroring Entities", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Show Load Warnings", "neoforge.configgui.showLoadWarnings.tooltip": "When enabled, NeoForge will show any warnings that occurred during loading.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/es_es.json b/src/main/resources/assets/neoforge/lang/es_es.json index d23a28c119..93be1b1bcc 100644 --- a/src/main/resources/assets/neoforge/lang/es_es.json +++ b/src/main/resources/assets/neoforge/lang/es_es.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "Este comando está obsoleto para su eliminación en 1.17, utilice %s en su lugar", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Seguimiento de entidad habilitado durante %d segundos.", "commands.neoforge.tracking.entity.reset": "Se ha borrado la información de tiempos de entidad.", "commands.neoforge.tracking.invalid": "Datos de seguimiento no válidos.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Configuración para %s de tipo %s encontrada en %s", "commands.config.noconfig": "Configuración para %s de tipo %s no encontrada", "neoforge.update.beta.1": "%sADVERTENCIA: %sVersión Beta de NeoForge", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Eliminar entidades de bloque con errores", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Eliminar entidades con errores", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Mostrar advertencias de carga", "neoforge.configgui.showLoadWarnings.tooltip": "Cuando está habilitado, NeoForge mostrará cualquier advertencia que haya ocurrido durante la carga.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/et_ee.json b/src/main/resources/assets/neoforge/lang/et_ee.json index ad9498f46c..22c875870e 100644 --- a/src/main/resources/assets/neoforge/lang/et_ee.json +++ b/src/main/resources/assets/neoforge/lang/et_ee.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "See käsklus on iganenud ning eemaldatakse 1.17-s, kasuta selle asemel %s.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Olemi jälitamine %d sekundiks lubatud.", "commands.neoforge.tracking.entity.reset": "Olemite aegade andmed on tühjendatud!", "commands.neoforge.tracking.invalid": "Sobimatud jälgimisandmed.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Seadistus %s jaoks tüübiga %s leiti asukohast %s", "commands.config.noconfig": "Seadistust %s jaoks tüübiga %s ei leitud", "neoforge.update.beta.1": "%sHOIATUS: %sNeoForge beeta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Eemalda vigu põhjustavad plokiolemid", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Eemalda vigu põhjustavad olemid", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Kuva laadimishoiatused", "neoforge.configgui.showLoadWarnings.tooltip": "Lubamisel kuvab NeoForge mistahes hoiatusi, mis esinesid laadimise käigus.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/fr_fr.json b/src/main/resources/assets/neoforge/lang/fr_fr.json index c6feef0557..984e6149b2 100644 --- a/src/main/resources/assets/neoforge/lang/fr_fr.json +++ b/src/main/resources/assets/neoforge/lang/fr_fr.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "Cette commande est obsolète pour la suppression en 1.17, veuillez utiliser %s à la place.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Suivi des entités activé pour %d secondes.", "commands.neoforge.tracking.entity.reset": "Les données de timings de l'entité ont été effacées !", "commands.neoforge.tracking.invalid": "Données de suivi invalides.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Configuration pour %s de type %s trouvée dans %s", "commands.config.noconfig": "La configuration pour %s du type %s est introuvable", "neoforge.update.beta.1": "%sATTENTION: %sNeoForge Bêta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Supprimer les Block Entities en erreur", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Supprimer les entités erronées", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Afficher les avertissements lors du chargement", "neoforge.configgui.showLoadWarnings.tooltip": "Lorsque cette option est activée, NeoForge affichera tous les avertissements qui se sont produits pendant le chargement.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/hu_hu.json b/src/main/resources/assets/neoforge/lang/hu_hu.json index c9195292a6..ec7866274c 100644 --- a/src/main/resources/assets/neoforge/lang/hu_hu.json +++ b/src/main/resources/assets/neoforge/lang/hu_hu.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "This command is deprecated for removal in 1.17, use %s instead.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Entity tracking enabled for %d seconds.", "commands.neoforge.tracking.entity.reset": "Entity timings data has been cleared!", "commands.neoforge.tracking.invalid": "Invalid tracking data.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Config for %s of type %s found at %s", "commands.config.noconfig": "Config for %s of type %s not found", "neoforge.update.beta.1": "%sWARNING: %sNeoForge Beta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Remove Erroring Block Entities", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Remove Erroring Entities", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Show Load Warnings", "neoforge.configgui.showLoadWarnings.tooltip": "When enabled, NeoForge will show any warnings that occurred during loading.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/it_it.json b/src/main/resources/assets/neoforge/lang/it_it.json index db7ebdd5da..1747ce6a2c 100644 --- a/src/main/resources/assets/neoforge/lang/it_it.json +++ b/src/main/resources/assets/neoforge/lang/it_it.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "Questo comando sarà rimosso in 1.17, utilizzare invece %s.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Monitoraggio entità abilitato per %d secondi.", "commands.neoforge.tracking.entity.reset": "I dati dei tempi delle entità sono stati cancellati!", "commands.neoforge.tracking.invalid": "Dati di tracciamento non validi.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Configurazione per %s di tipo %s trovata in %s", "commands.config.noconfig": "Configurazione per %s di tipo %s non trovata", "neoforge.update.beta.1": "%sATTENZIONE: %sNeoForge Beta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Rimuovi Entità Blocco in Errore", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Rimuovi Entità in Errore", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Mostra Avvisi del Caricamento", "neoforge.configgui.showLoadWarnings.tooltip": "Se abilitata, NeoForge mostrerà tutti gli avvisi che si sono verificati durante il caricamento.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/ja_jp.json b/src/main/resources/assets/neoforge/lang/ja_jp.json index 6c9928ce1c..73ad50928d 100644 --- a/src/main/resources/assets/neoforge/lang/ja_jp.json +++ b/src/main/resources/assets/neoforge/lang/ja_jp.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "指定したディメンションID(%1$s)は有効ではありません", "commands.neoforge.setdim.invalid.nochange": "選択したエンティティ(%1$s)は、指定したディメンション(%2$s)内に既に存在します", "commands.neoforge.setdim.deprecated": "このコマンドは非推奨であり、1.17で削除されます。代わりに%sを使用してください", - "commands.neoforge.tps.invalid": "ディメンション%1$sは有効ではありません。次の値が使用できます:%2$s", - "commands.neoforge.tps.summary.all": "全体:1ティックあたりの時間:%1$s ms、1秒あたりのティック数(TPS):%2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod一覧:%1$s", - "commands.neoforge.tps.summary.basic": "ディメンション%1$s:1ティックあたりの時間:%2$s ms、1秒あたりのティック数(TPS):%3$s", - "commands.neoforge.tps.summary.named": "ディメンション%1$s(%2$s):1ティックあたりの時間:%3$s ms、1秒あたりのティック数(TPS):%4$s", "commands.neoforge.tracking.entity.enabled": "エンティティのトラッキングを%d秒間有効にしました", "commands.neoforge.tracking.entity.reset": "エンティティのタイミングデータを消去しました", "commands.neoforge.tracking.invalid": "トラッキングデータが有効ではありません", @@ -108,13 +108,21 @@ "commands.neoforge.chunkgen.success": "生成が完了しました", "commands.neoforge.chunkgen.error": "%1$s個のエラーが発生しました。詳細な情報はログを確認してください", "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", - "commands.neoforge.chunkgen.status": "Generation status! %1$s out of %2$s chunks generated. (%3$s%%)", + "commands.neoforge.chunkgen.status": "生成ステータス! %1$s / %2$s チャンクが生成されました。 (%3$s%%)", "commands.neoforge.chunkgen.not_running": "事前生成は実行されていません。生成を開始するためのコマンドを確認するには「/neoforge generate help」を実行してください", "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- 指定の位置を中心として、各辺がchunkRadius * 2の正方形で生成します。\n§2/neoforge generate stop §r§f- 現在の生成を停止し、完了した進行状況を表示します。\n§2/neoforge generate status §r- 現在実行中の生成に対する完了した進行状況を表示します。\n§2/neoforge generate help §r- このメッセージを表示します。\nヒント:サーバーコンソールから実行する場合は、/execute in neoforge generate...を使用することで、異なるディメンションで生成を実行できます。", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "%s(種類:%s)の設定が%sで見つかりました", "commands.config.noconfig": "%s(種類:%s)の設定が見つかりません", "neoforge.update.beta.1": "%s警告:%sNeoForge ベータ版", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "エラーを発するブロックエンティティの除去", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "エラーを発するエンティティの除去", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "読み込み時の警告の表示", "neoforge.configgui.showLoadWarnings.tooltip": "有効にすると、読み込み中に発生した警告が表示されるようになります。", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/ko_kr.json b/src/main/resources/assets/neoforge/lang/ko_kr.json index e3492e0eab..c04de76122 100644 --- a/src/main/resources/assets/neoforge/lang/ko_kr.json +++ b/src/main/resources/assets/neoforge/lang/ko_kr.json @@ -36,7 +36,7 @@ "fml.menu.multiplayer.modsincompatible": "호환되지 않는 서버 모드 목록", "fml.menu.multiplayer.networkincompatible": "서버의 네트워크 메시지들이 호환되지 않음", "fml.menu.multiplayer.missingdatapackregistries": "필요한 데이터팩 레지스트리가 누락됨: %1$s", - "fml.menu.branding": "%s (%s mods)", + "fml.menu.branding": "%s (%s 모드)", "fml.menu.notification.title": "시작 알림", "fml.menu.accessdenied.title": "서버 접속이 거부되었습니다", "fml.menu.accessdenied.message": "Fancy Mod Loader가 서버에 접속할 수 없습니다.\n이 서버(%1$s)는 모드가 설치된 클라이언트의 접속을 거부합니다.", @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "'%1$s'은(는) 잘못된 차원입니다.", "commands.neoforge.setdim.invalid.nochange": "해당 엔티티('%1$s')은(는) 이미 지정된 차원('%2$s')에 있습니다.", "commands.neoforge.setdim.deprecated": "이 명령어는 1.17에서 제거될 예정입니다. %s을(를) 대신 사용하세요.", - "commands.neoforge.tps.invalid": "'%1$s'은(는) 잘못된 차원입니다. 올바른 차원들: %2$s", - "commands.neoforge.tps.summary.all": "총합: 평균 틱 처리 시간: %1$s ms. 평균 TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "모드 목록: %1$s", - "commands.neoforge.tps.summary.basic": "차원 %1$s: 평균 틱 처리 시간: %2$s ms. 평균 TPS: %3$s", - "commands.neoforge.tps.summary.named": "차원 %1$s (%2$s): 평균 틱 처리 시간: %3$s ms. 평균 TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "엔티티 처리 시간을 %d초간 수집합니다...", "commands.neoforge.tracking.entity.reset": "엔티티 처리 시간 정보를 삭제합니다!", "commands.neoforge.tracking.invalid": "처리 시간 정보가 손상되었습니다.", @@ -107,14 +107,22 @@ "commands.neoforge.chunkgen.started": "%2$s×%3$s 청크 (%4$s×%5$s 블록) 범위 안에 청크 %1$s개 생성 중.", "commands.neoforge.chunkgen.success": "생성 완료!", "commands.neoforge.chunkgen.error": "청크 생성 중 %1$s개의 오류가 발생했습니다! 출력 로그에서 자세한 내용을 확인하세요.", - "commands.neoforge.chunkgen.stopped": "Generation stopped! %1$s out of %2$s chunks generated. (%3$s%%)", - "commands.neoforge.chunkgen.status": "Generation status! %1$s out of %2$s chunks generated. (%3$s%%)", + "commands.neoforge.chunkgen.stopped": "청크 생성 중단됨! %1$s/%2$s개의 청크를 생성했습니다. (%3$s%%)", + "commands.neoforge.chunkgen.status": "청크 생성 진행률! %1$s/%2$s개의 청크를 생성했습니다. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "현재 청크를 생성하고 있지 않습니다. `/neoforge generate help`를 참고하여 청크 사전 생성 명령어 사용 방법을 확인하세요.", "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start <범위> [진행률 표시] §r§f- 주어진 위치를 중심으로 범위 * 2 길이의 정사각형 구역 내 청크를 생성합니다.\n§2/neoforge generate stop §r§f- 진행 중인 청크 사전 생성을 중단하고 진행률을 표시합니다.\n§2/neoforge generate status §r- 이미 진행 중인 청크 생성 작업의 진행률을 표시합니다.\n§2/neoforge generate help §r- 이 도움말을 표시합니다.\n팁: 다른 차원의 청크를 사전 생성할 땐 '/execute in <차원> neoforge generate...' 식으로 다른 차원에서 명령을 실행하세요.", "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "모드 %s의 설정 %s이(가) %s에서 발견됨", "commands.config.noconfig": "모드 %s의 설정 %s을(를) 찾을 수 없음", "neoforge.update.beta.1": "%s경고: %s 네오 포지 베타 버전입니다", @@ -122,108 +130,44 @@ "neoforge.update.newversion": "새로운 네오 포지 버전으로 업데이트할 수 있습니다: %s", "neoforge.menu.updatescreen.title": "모드 업데이트", "neoforge.configuration.uitext.title": "%s Configuration", - "neoforge.configuration.uitext.type.client": "Client Settings", - "neoforge.configuration.uitext.type.server": "Server Settings", - "neoforge.configuration.uitext.type.common": "Common settings", - "neoforge.configuration.uitext.type.startup": "Startup settings", + "neoforge.configuration.uitext.type.client": "클라이언트 설정", + "neoforge.configuration.uitext.type.server": "서버 설정", + "neoforge.configuration.uitext.type.common": "공통 설정", + "neoforge.configuration.uitext.type.startup": "시작 설정", "neoforge.configuration.uitext.title.client": "%s Client Configuration", "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", - "neoforge.configuration.uitext.undo": "Undo", - "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", - "neoforge.configuration.uitext.reset": "Reset", - "neoforge.configuration.uitext.reset.tooltip": "Reverts everything on this screen to its default value.", + "neoforge.configuration.uitext.undo": "되돌리기", + "neoforge.configuration.uitext.undo.tooltip": "이 화면에서만 변경사항을 되돌립니다.", + "neoforge.configuration.uitext.reset": "초기화", + "neoforge.configuration.uitext.reset.tooltip": "이 화면에 있는 모든 것을 기본 값으로 되돌립니다.", "neoforge.configuration.uitext.newlistelement": "+", "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], - "neoforge.configuration.uitext.common": "Common Options", - "neoforge.configuration.uitext.client": "Client Options", - "neoforge.configuration.uitext.server": "Server Options", - "neoforge.configuration.uitext.startup": "Startup Options", - "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", + "neoforge.configuration.uitext.common": "공통 옵션", + "neoforge.configuration.uitext.client": "클라이언트 옵션", + "neoforge.configuration.uitext.server": "서버 옵션", + "neoforge.configuration.uitext.startup": "시작 옵션", + "neoforge.configuration.uitext.restart.game.title": "마인크래프트를 다시 시작해야 합니다", "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "오류가 발생한 블록 엔티티 제거", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "오류가 나는 엔티티 제거", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "게임을 불러오는 중 발생한 경고 표시", "neoforge.configgui.showLoadWarnings.tooltip": "네오 포지가 게임을 불러오며 발생한 모든 경고 메세지들을 표시합니다.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/ms_my.json b/src/main/resources/assets/neoforge/lang/ms_my.json new file mode 100644 index 0000000000..3f44f98fd2 --- /dev/null +++ b/src/main/resources/assets/neoforge/lang/ms_my.json @@ -0,0 +1,247 @@ +{ + "fml.menu.mods": "Mod", + "fml.menu.mods.title": "Mod", + "fml.menu.mods.normal": "Tutup", + "fml.menu.mods.search": "Cari", + "fml.menu.mods.a_to_z": "A-Z", + "fml.menu.mods.z_to_a": "Z-A", + "fml.menu.mods.config": "Konfigurasi", + "fml.menu.mods.openmodsfolder": "Open mods folder", + "fml.menu.modoptions": "Mod Options...", + "fml.menu.mods.info.version": "Version: %1$s", + "fml.menu.mods.info.idstate": "ModID: %1$s State: {1,lower}", + "fml.menu.mods.info.credits": "Credits: %1$s", + "fml.menu.mods.info.authors": "Authors: %1$s", + "fml.menu.mods.info.displayurl": "Homepage: %1$s", + "fml.menu.mods.info.license": "License: %1$s", + "fml.menu.mods.info.securejardisabled": "Secure mod features disabled, update JDK", + "fml.menu.mods.info.signature": "Signature: %1$s", + "fml.menu.mods.info.signature.unsigned": "TIDAK DITANDA", + "fml.menu.mods.info.trust": "Trust: %1$s", + "fml.menu.mods.info.trust.noauthority": "Tiada", + "fml.menu.mods.info.nochildmods": "No child mods found", + "fml.menu.mods.info.childmods": "Child mods: %1$s", + "fml.menu.mods.info.updateavailable": "Update available: %1$s", + "fml.menu.mods.info.changelogheader": "Log perubahan:", + "fml.menu.multiplayer.compatible": "Compatible FML modded server\n{0,choice,1#1 mod|1<%1$s mods} present", + "fml.menu.multiplayer.incompatible": "Incompatible FML modded server", + "fml.menu.multiplayer.incompatible.extra": "Incompatible FML modded server\n%1$s", + "fml.menu.multiplayer.truncated": "Data may be inaccurate due to protocol size limits.", + "fml.menu.multiplayer.vanilla": "Vanilla server", + "fml.menu.multiplayer.vanilla.incompatible": "Incompatible Vanilla server", + "fml.menu.multiplayer.unknown": "Unknown server %1$s", + "fml.menu.multiplayer.serveroutdated": "NeoForge server network version is outdated", + "fml.menu.multiplayer.clientoutdated": "NeoForge client network version is outdated", + "fml.menu.multiplayer.extraservermods": "Server has additional mods that may be needed on the client", + "fml.menu.multiplayer.modsincompatible": "Server mod list is not compatible", + "fml.menu.multiplayer.networkincompatible": "Server network message list is not compatible", + "fml.menu.multiplayer.missingdatapackregistries": "Missing required datapack registries: %1$s", + "fml.menu.branding": "%s (%s mod)", + "fml.menu.notification.title": "Startup Notification", + "fml.menu.accessdenied.title": "Server Access Denied", + "fml.menu.accessdenied.message": "Fancy Mod Loader could not connect to this server\nThe server %1$s has forbidden modded access", + "fml.menu.backupfailed.title": "Backup Failed", + "fml.menu.backupfailed.message": "There was an error saving the archive %1$s\nPlease fix the problem and try again", + "fml.button.open.file": "Buka %1$s", + "fml.button.open.log": "Open log file", + "fml.button.open.crashreport": "Open crash report", + "fml.button.open.mods.folder": "Open Mods Folder", + "fml.button.continue.launch": "Proceed to main menu", + "fml.modmismatchscreen.missingmods.client": "Your client is missing the following mods, install these mods to join this server:", + "fml.modmismatchscreen.missingmods.server": "The server is missing the following mods, remove these mods from your client to join this server:", + "fml.modmismatchscreen.mismatchedmods": "The following mod versions do not match, install the same version of these mods that the server has to join this server:", + "fml.modmismatchscreen.table.channelname": "Nama saluran", + "fml.modmismatchscreen.table.youneed": "Anda memerlukan", + "fml.modmismatchscreen.table.youhave": "Anda mempunyai", + "fml.modmismatchscreen.table.serverhas": "Pelayan mempunyai", + "fml.modmismatchscreen.additional": "[%1$s additional, see latest.log for the full list]", + "fml.modmismatchscreen.homepage": "Click to get to the homepage of this mod", + "fml.modmismatchscreen.table.reason": "Sebab", + "fml.modmismatchscreen.table.visit.mod_page": "Open the mod page of the mod that registers the channel: %s", + "fml.modmismatchscreen.simplifiedview": "Simplified view", + "fml.resources.modresources": "Resources for %1$s mod files", + "fml.resources.moddata": "Data for %1$s mod files", + "loadwarning.neoforge.prbuild": "This build of NeoForge was created by a community member and is thus §c§lUNSUPPORTED§r", + "commands.neoforge.arguments.enum.invalid": "Enum constant must be one of %1$s, found %2$s", + "commands.neoforge.dimensions.list": "Currently registered dimensions by type:", + "commands.neoforge.dump.success": "New file created with %s registry's contents is at %s", + "commands.neoforge.dump.failure": "Failed to create new file with %s registry's contents at %s", + "commands.neoforge.dump.error.unknown_registry": "Unknown registry '%s'", + "commands.neoforge.entity.list.invalid": "Invalid filter, does not match any entities. Use /neoforge entity list for a proper list", + "commands.neoforge.entity.list.invalidworld": "Could not load world for dimension %1$s. Please select a valid dimension.", + "commands.neoforge.entity.list.none": "No entities found.", + "commands.neoforge.entity.list.single.header": "Entity: %1$s Total: %2$s", + "commands.neoforge.entity.list.multiple.header": "Total: %1$s", + "commands.neoforge.setdim.invalid.entity": "The entity selected (%1$s) is not valid.", + "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", + "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", + "commands.neoforge.setdim.deprecated": "This command is deprecated for removal in 1.17, use %s instead.", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", + "commands.neoforge.mods.list": "Mod List: %1$s", + "commands.neoforge.tracking.entity.enabled": "Entity tracking enabled for %d seconds.", + "commands.neoforge.tracking.entity.reset": "Entity timings data has been cleared!", + "commands.neoforge.tracking.invalid": "Invalid tracking data.", + "commands.neoforge.tracking.be.enabled": "Block Entity tracking enabled for %d seconds.", + "commands.neoforge.tracking.be.reset": "Block entity timings data has been cleared!", + "commands.neoforge.tracking.timing_entry": "%1$s - %2$s [%3$s, %4$s, %5$s]: %6$s", + "commands.neoforge.tracking.no_data": "No data has been recorded yet.", + "commands.neoforge.tags.error.unknown_registry": "Unknown registry '%s'", + "commands.neoforge.tags.error.unknown_tag": "Unknown tag '%s' in registry '%s'", + "commands.neoforge.tags.error.unknown_element": "Unknown element '%s' in registry '%s'", + "commands.neoforge.tags.registry_key": "%s", + "commands.neoforge.tags.tag_count": "Tag: %s", + "commands.neoforge.tags.copy_tag_names": "Click to copy all tag names to clipboard", + "commands.neoforge.tags.element_count": "Elements: %s", + "commands.neoforge.tags.copy_element_names": "Click to copy all element names to clipboard", + "commands.neoforge.tags.tag_key": "%s / %s", + "commands.neoforge.tags.containing_tag_count": "Containing tags: %s", + "commands.neoforge.tags.element": "%s : %s", + "commands.neoforge.tags.page_info": "%s ", + "commands.neoforge.chunkgen.progress_bar_title": "Generating chunks...", + "commands.neoforge.chunkgen.progress_bar_progress": "Generating %1$s chunks - ", + "commands.neoforge.chunkgen.progress_bar_errors": "(%1$s errors!)", + "commands.neoforge.chunkgen.already_running": "Generation already running. Please execute '/neoforge generate stop' first and then you can start a new generation.", + "commands.neoforge.chunkgen.started": "Generating %1$s chunks, in an area of %2$sx%3$s chunks (%4$sx%5$s blocks).", + "commands.neoforge.chunkgen.success": "Generation Done!", + "commands.neoforge.chunkgen.error": "Generation experienced %1$s errors! Check the log for more information.", + "commands.neoforge.chunkgen.stopped": "Penjanaan telah dihentikan! %1$s daripada %2$s cebisan telah dijana. (%3$s%%)", + "commands.neoforge.chunkgen.status": "Status penjanaan! %1$s daripada %2$s cebisan telah dijana. (%3$s%%)", + "commands.neoforge.chunkgen.not_running": "No pregeneration currently running. Run `/neoforge generate help` to see commands for starting generation.", + "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Menghasilkan segi empat sama berpusat pada kedudukan yang diberikan iaitu chunkRadius * 2 pada setiap sisi.\n§2/neoforge generate stop §r§f- Menghentikan generasi semasa dan memaparkan kemajuan yang telah diselesaikannya.\n§2/neoforge generate status §r- Memaparkan kemajuan yang telah selesai untuk penjanaan yang sedang berjalan.\n§2/neoforge generate help §r- Memaparkan mesej ini.\nGeneral tips: Jika dijalankan dari konsol pelayan, anda boleh menjalankan generate dalam dimensi berbeza dengan menggunakan /execute in neoforge generate...", + "commands.neoforge.timespeed.query": "Masa dalam %s sedang mengalir pada kadar %sx (%s minit sehari).", + "commands.neoforge.timespeed.query.default": "Masa dalam %s mengalir seperti biasa (20 minit sehari).", + "commands.neoforge.timespeed.set": "Aliran masa dalam %s ditetapkan kepada %sx (%s minit sehari).", + "commands.neoforge.timespeed.set.default": "Aliran masa dalam %s ditetapkan kepada lalai (20 minit sehari).", + "commands.neoforge.data_components.list.error.held_stack_empty": "Anda tidak memegang sebarang item", + "commands.neoforge.data_components.list.title": "Komponen data pada %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Komponen %s memegang nilai lalainya", + "commands.neoforge.data_components.list.tooltip.deleted": "Komponen %s dengan nilai %s telah dipadamkan", + "commands.neoforge.data_components.list.tooltip.modified": "Komponen %s telah diubah suai daripada %s kepada %s", + "commands.neoforge.data_components.list.tooltip.added": "Komponen %s telah ditambah dengan nilai %s", + "commands.config.getwithtype": "Config for %s of type %s found at %s", + "commands.config.noconfig": "Config for %s of type %s not found", + "neoforge.update.beta.1": "%sWARNING: %sNeoForge Beta", + "neoforge.update.beta.2": "Major issues may arise, verify before reporting.", + "neoforge.update.newversion": "New NeoForge version available: %s", + "neoforge.menu.updatescreen.title": "Kemas Kini Mod", + "neoforge.configuration.uitext.title": "Konfigurasi %s", + "neoforge.configuration.uitext.type.client": "Tetapan Klien", + "neoforge.configuration.uitext.type.server": "Tetapan Pelayan", + "neoforge.configuration.uitext.type.common": "Tetapan biasa", + "neoforge.configuration.uitext.type.startup": "Tetapan permulaan", + "neoforge.configuration.uitext.title.client": "Konfigurasi Klien %s", + "neoforge.configuration.uitext.title.server": "Konfigurasi Pelayan %s", + "neoforge.configuration.uitext.title.common": "Konfigurasi Biasa %s", + "neoforge.configuration.uitext.title.startup": "Konfigurasi Permulaan %s", + "neoforge.configuration.uitext.notonline": "Tetapan di sini ditentukan oleh pelayan dan tidak boleh diubah semasa dalam talian.", + "neoforge.configuration.uitext.notlan": "Tetapan di sini tidak boleh disunting semasa permainan anda dibuka kepada LAN. Sila kembali ke menu utama dan muatkan dunia ini sekali lagi.", + "neoforge.configuration.uitext.notloaded": "Tetapan di sini hanya tersedia semasa dunia dimuatkan.", + "neoforge.configuration.uitext.unsupportedelement": "Nilai ini tidak boleh disunting dalam UI. Sila hubungi pengarang mod tentang menyediakan UI tersuai untuknya.", + "neoforge.configuration.uitext.longstring": "Nilai ini terlalu panjang untuk disunting dalam UI. Sila sunting dalam fail konfigurasi.", + "neoforge.configuration.uitext.section": "%s...", + "neoforge.configuration.uitext.sectiontext": "Sunting", + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", + "neoforge.configuration.uitext.listelement": "%s:", + "neoforge.configuration.uitext.undo": "Buat Asal", + "neoforge.configuration.uitext.undo.tooltip": "Mengembalikan perubahan pada skrin ini sahaja.", + "neoforge.configuration.uitext.reset": "Tetap Semula", + "neoforge.configuration.uitext.reset.tooltip": "Mengembalikan segala-galanya pada skrin ini kepada nilai lalainya.", + "neoforge.configuration.uitext.newlistelement": "+", + "neoforge.configuration.uitext.listelementup": "⏶", + "neoforge.configuration.uitext.listelementdown": "⏷", + "neoforge.configuration.uitext.listelementremove": "❌", + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", + "neoforge.configuration.uitext.common": "Pilihan Biasa", + "neoforge.configuration.uitext.client": "Pilihan Klien", + "neoforge.configuration.uitext.server": "Pilihan Pelayan", + "neoforge.configuration.uitext.startup": "Pilihan Permulaan", + "neoforge.configuration.uitext.restart.game.title": "Minecraft perlu dimulakan semula", + "neoforge.configuration.uitext.restart.game.text": "Satu atau lebih pilihan konfigurasi yang telah diubah hanya akan berkuat kuasa apabila permainan dimulakan.", + "neoforge.configuration.uitext.restart.server.title": "Dunia perlu dimuat semula", + "neoforge.configuration.uitext.restart.server.text": "Satu atau lebih pilihan konfigurasi yang telah diubah hanya akan berkuat kuasa apabila dunia dimuat semula.", + "neoforge.configuration.uitext.restart.return": "Abaikan", + "neoforge.configuration.uitext.restart.return.tooltip": "Perubahan anda tidak akan memberi kesan sehingga anda memulakan semula!", + "neoforge.configuration.title": "Konfigurasi NeoForge", + "neoforge.configuration.section.neoforge.client.toml": "Tetapan klien", + "neoforge.configuration.section.neoforge.client.toml.title": "Tetapan klien", + "neoforge.configuration.section.neoforge.common.toml": "Tetapan biasa", + "neoforge.configuration.section.neoforge.common.toml.title": "Tetapan biasa", + "neoforge.configuration.section.neoforge.server.toml": "Tetapan pelayan", + "neoforge.configuration.section.neoforge.server.toml.title": "Tetapan pelayan", + "neoforge.configgui.advertiseDedicatedServerToLan": "Iklankan Pelayan Khusus Kepada LAN", + "neoforge.configgui.advertiseDedicatedServerToLan.tooltip": "Set this to true to enable advertising the dedicated server to local LAN clients so that it shows up in the Multiplayer screen automatically.", + "neoforge.configgui.forgeLightPipelineEnabled": "Talian Paip Cahaya NeoForge", + "neoforge.configgui.forgeLightPipelineEnabled.tooltip": "Enable the NeoForge block rendering pipeline - fixes the lighting of custom models.", + "neoforge.configgui.fullBoundingBoxLadders": "Full Bounding Box Ladders", + "neoforge.configgui.fullBoundingBoxLadders.tooltip": "Set this to true to check the entire entity's collision bounding box for ladders instead of just the block they are in. Causes noticeable differences in mechanics so default is vanilla behavior. Default: false.", + "neoforge.configgui.logLegacyTagWarnings": "Log Tag Legasi", + "neoforge.configgui.logLegacyTagWarnings.tooltip": "Pilihan konfigurasi terutamanya untuk pembangun. Mengelog keluar tag diubah suai yang menggunakan ruang nama 'forge' apabila dijalankan pada pelayan bersepadu. Dilalaikan kepada DEV_SHORT.", + "neoforge.configgui.logUntranslatedConfigurationWarnings": "Log Kunci Konfigurasi Tidak Diterjemah", + "neoforge.configgui.logUntranslatedConfigurationWarnings.tooltip": "Pilihan konfigurasi terutamanya untuk pembangun. Mengelog keluar nilai konfigurasi yang tidak mempunyai terjemahan semasa menjalankan klien dalam persekitaran pembangunan.", + "neoforge.configgui.logUntranslatedItemTagWarnings": "Log Tag Item Tidak Diterjemah", + "neoforge.configgui.logUntranslatedItemTagWarnings.tooltip": "Pilihan konfigurasi terutamanya untuk pembangun. Mengelog keluar tag item yang diubah suai yang tidak mempunyai terjemahan apabila dijalankan pada pelayan bersepadu. Format yang dikehendaki ialah tag.item.. untuk kunci terjemahan. Dilalaikan kepada SILENCED.", + "neoforge.configgui.permissionHandler": "Pengendali Keizinan", + "neoforge.configgui.permissionHandler.tooltip": "Pengendali keizinan yang digunakan oleh pelayan. Dilalaikan kepada neoforge:default_handler jika tiada pengendali dengan nama itu didaftarkan.", + "neoforge.configgui.removeErroringBlockEntities": "Remove Erroring Block Entities", + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "AMARAN INI BOLEH MEROSAKKAN SEGALANYA.\nGUNAKAN SECARA CERMAT.\nKAMI TIDAK BERTANGGUNGJAWAB ATAS KEROSAKAN.", + "neoforge.configgui.removeErroringEntities": "Remove Erroring Entities", + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "AMARAN INI BOLEH MEROSAKKAN SEGALANYA.\nGUNAKAN SECARA CERMAT.\nKAMI TIDAK BERTANGGUNGJAWAB ATAS KEROSAKAN.", + "neoforge.configgui.showLoadWarnings": "Show Load Warnings", + "neoforge.configgui.showLoadWarnings.tooltip": "When enabled, NeoForge will show any warnings that occurred during loading.", + "neoforge.configgui.useCombinedDepthStencilAttachment": "Gunakan gabungan Lampiran DEPTH_STENCIL", + "neoforge.configgui.useCombinedDepthStencilAttachment.tooltip": "Tetapkan kepada true untuk menggunakan lampiran DEPTH_STENCIL gabungan dan bukannya dua lampiran berasingan.", + "neoforge.controlsgui.shift": "SHIFT + %s", + "neoforge.controlsgui.control": "CTRL + %s", + "neoforge.controlsgui.control.mac": "CMD + %s", + "neoforge.controlsgui.alt": "ALT + %s", + "neoforge.container.enchant.limitedEnchantability": "Limited Enchantability", + "neoforge.swim_speed": "Kelajuan Berenang", + "neoforge.name_tag_distance": "Nametag Render Distance", + "neoforge.creative_flight": "Creative Flight", + "fluid_type.minecraft.milk": "Susu", + "fluid_type.minecraft.flowing_milk": "Susu", + "neoforge.froge.warningScreen.title": "NeoForge snapshots notice", + "neoforge.froge.warningScreen.text": "Froge is not officially supported. Bugs and instability are expected.", + "neoforge.froge.supportWarning": "WARNING: Froge is not supported by NeoForge", + "neoforge.gui.exit": "Keluar", + "neoforge.experimentalsettings.tooltip": "This world uses experimental settings, which could stop working at any time.", + "neoforge.selectWorld.backupWarning.experimental.additional": "This message will not show again for this world.", + "neoforge.chatType.system": "%1$s", + "pack.neoforge.description": "NeoForge data/resource pack", + "pack.neoforge.source.child": "anak", + "neoforge.network.negotiation.failure.mod": "Channel of mod \"%1$s\" failed to connect: %2$s", + "neoforge.network.negotiation.failure.missing.client.server": "This channel is missing on the server side, but required on the client!", + "neoforge.network.negotiation.failure.missing.server.client": "This channel is missing on the client side, but required on the server!", + "neoforge.network.negotiation.failure.flow.client.missing": "The client wants the payload to flow: %s, but the server does not support it!", + "neoforge.network.negotiation.failure.flow.server.missing": "The server wants the payload to flow: %s, but the client does not support it!", + "neoforge.network.negotiation.failure.flow.client.mismatch": "The client wants the payload to flow: %s, but the server wants it to flow: %s!", + "neoforge.network.negotiation.failure.flow.server.mismatch": "The server wants the payload to flow: %s, but the client wants it to flow: %s!", + "neoforge.network.negotiation.failure.version.client.missing": "The client wants the payload to be version: %s, but the server does not support it!", + "neoforge.network.negotiation.failure.version.server.missing": "The server wants the payload to be version: %s, but the client does not support it!", + "neoforge.network.negotiation.failure.version.mismatch": "The client wants the payload to be version: %s, but the server wants it to be version: %s!", + "neoforge.network.invalid_flow": "Failed to process a payload that was send with an invalid flow: %s", + "neoforge.network.negotiation.failure.vanilla.client.not_supported": "You are trying to connect to a server that is running NeoForge, but you are not. Please install NeoForge Version: %s to connect to this server.", + "neoforge.network.negotiation.failure.vanilla.server.not_supported": "You are trying to connect to a server that is not running NeoForge, but you have mods that require it. A connection could not be established.", + "neoforge.network.packet_splitter.unknown": "Tried to split a packet without packet splitter!", + "neoforge.network.advanced_add_entity.failed": "Failed to process advanced entity spawn data: %s", + "neoforge.network.advanced_open_screen.failed": "Failed to open a screen with advanced data: %s", + "neoforge.network.registries.sync.missing": "Not all expected registries were received from the server! (missing: %s)", + "neoforge.network.registries.sync.server-with-unknown-keys": "The server send registries with unknown keys: %s", + "neoforge.network.registries.sync.failed": "Failed to sync registries from the server: %s", + "neoforge.network.aux_light_data.failed": "Failed to handle auxiliary light data for chunk %s: %s", + "neoforge.network.data_maps.failed": "Failed to handle registry data map sync for registry %s: %s", + "neoforge.network.data_maps.missing_our": "Cannot connect to server as it is missing mandatory registry data maps present on the client: %s", + "neoforge.network.data_maps.missing_their": "Cannot connect to server as it has mandatory registry data maps not present on the client: %s", + "neoforge.network.extensible_enums.no_vanilla_server": "Klien ini tidak menyokong pelayan vanila kerana ia mempunyai enum lanjutan yang digunakan dalam rangkaian terikat pelayan", + "neoforge.network.extensible_enums.enum_set_mismatch": "Set enum yang boleh diperluaskan pada klien dan pelayan tidak sepadan. Pastikan anda menggunakan versi NeoForge yang sama seperti pelayan", + "neoforge.network.extensible_enums.enum_entry_mismatch": "Set nilai yang ditambahkan pada enum yang boleh diperluaskan pada klien dan pelayan tidak sepadan. Pastikan anda menggunakan mod dan versi NeoForge yang sama seperti pelayan. Lihat log untuk butiran lanjut" +} diff --git a/src/main/resources/assets/neoforge/lang/nl_nl.json b/src/main/resources/assets/neoforge/lang/nl_nl.json index b0f3a822ce..f637964644 100644 --- a/src/main/resources/assets/neoforge/lang/nl_nl.json +++ b/src/main/resources/assets/neoforge/lang/nl_nl.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "Dit commando is afgeschreven voor verwijderd in 1.17, gebruik in plaats daarvan %s.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Het volgen van Entiteiten is ingeschakeld voor %d seconden.", "commands.neoforge.tracking.entity.reset": "Entiteit timing data is gewist!", "commands.neoforge.tracking.invalid": "Ongeldige volggegevens.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Configuratie voor %s van type %s gevonden bij %s", "commands.config.noconfig": "Configuratie voor %s van type %s niet gevonden", "neoforge.update.beta.1": "%sWAARSCHUWING: %sNeoForge Beta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Verwijder foutveroorzakende blokentiteiten", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Verwijder foutveroorzakende entiteiten", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Toon Laad Waarschuwingen", "neoforge.configgui.showLoadWarnings.tooltip": "Wanneer ingeschakeld, zal NeoForge elke waarschuwing laten zien die optreed tijdens het laden.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/pl_pl.json b/src/main/resources/assets/neoforge/lang/pl_pl.json index 05ca184988..1e3be0e5c6 100644 --- a/src/main/resources/assets/neoforge/lang/pl_pl.json +++ b/src/main/resources/assets/neoforge/lang/pl_pl.json @@ -62,31 +62,31 @@ "fml.resources.modresources": "Zasoby dla plików modyfikacji %1$s", "fml.resources.moddata": "Dane dla %1$s plików modyfikacji", "loadwarning.neoforge.prbuild": "Ta kompilacja NeoForge została stworzona przez członka społeczności i jest §c§lNIEWSPIERANA§r", - "commands.neoforge.arguments.enum.invalid": "Enum constant must be one of %1$s, found %2$s", - "commands.neoforge.dimensions.list": "Currently registered dimensions by type:", - "commands.neoforge.dump.success": "New file created with %s registry's contents is at %s", - "commands.neoforge.dump.failure": "Failed to create new file with %s registry's contents at %s", + "commands.neoforge.arguments.enum.invalid": "Stała Enum musi być jednym z %1$s, znaleziono %2$s", + "commands.neoforge.dimensions.list": "Aktualnie zarejestrowane wymiary według typu:", + "commands.neoforge.dump.success": "Nowy plik utworzony z zawartością rejestru %s jest w %s", + "commands.neoforge.dump.failure": "Nie udało się utworzyć nowego pliku z zawartością rejestru %s w %s", "commands.neoforge.dump.error.unknown_registry": "Unknown registry '%s'", "commands.neoforge.entity.list.invalid": "Nieprawidłowy filtr, nie pasuje do żadnych bytów. Użyj /neoforge entity list dla właściwej listy", - "commands.neoforge.entity.list.invalidworld": "Could not load world for dimension %1$s. Please select a valid dimension.", + "commands.neoforge.entity.list.invalidworld": "Nie można załadować świata dla wymiaru %1$s. Proszę wybrać prawidłowy wymiar.", "commands.neoforge.entity.list.none": "Nie znaleziono obiektów.", - "commands.neoforge.entity.list.single.header": "Entity: %1$s Total: %2$s", - "commands.neoforge.entity.list.multiple.header": "Total: %1$s", - "commands.neoforge.setdim.invalid.entity": "The entity selected (%1$s) is not valid.", - "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", - "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", + "commands.neoforge.entity.list.single.header": "Byt: %1$s Razem: %2$s", + "commands.neoforge.entity.list.multiple.header": "Łącznie: %1$s", + "commands.neoforge.setdim.invalid.entity": "Wybrany byt (%1$s) jest nieprawidłowy.", + "commands.neoforge.setdim.invalid.dim": "Określone ID Wymiaru (%1$s) jest nieprawidłowe.", + "commands.neoforge.setdim.invalid.nochange": "Wybrany byt (%1$s) jest już w określonym wymiarze (%2$s).", "commands.neoforge.setdim.deprecated": "To polecenie jest przestarzałe i zostanie usunięte w 1.17, użyj %s zamiast niej.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", - "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", + "commands.neoforge.tps.overall": "Łącznie: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Średni TPS; wyższy jest lepszy. Docelowy TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Typ wymiaru: %s)", + "commands.neoforge.mods.list": "Lista modyfikacji: %1$s", "commands.neoforge.tracking.entity.enabled": "Śledzenie bytu zostało uruchomione na %d sekund.", "commands.neoforge.tracking.entity.reset": "Entity timings data has been cleared!", "commands.neoforge.tracking.invalid": "Nieprawidłowe dane śledzenia.", "commands.neoforge.tracking.be.enabled": "Blokowanie śledzenia bytów zostało uruchomione na %d sekund.", "commands.neoforge.tracking.be.reset": "Block entity timings data has been cleared!", - "commands.neoforge.tracking.timing_entry": "%1$s - %2$s [%3$s, %4$s, %5$s]: %6$s", + "commands.neoforge.tracking.timing_entry": "%1$s - %2$s [%3$s,%4$s,%5$s]: %6$s", "commands.neoforge.tracking.no_data": "Nie zarejestrowano jeszcze żadnych danych.", "commands.neoforge.tags.error.unknown_registry": "Nieznany rejestr '%s'", "commands.neoforge.tags.error.unknown_tag": "Nieznany tag '%s' w rejestrze '%s'", @@ -111,184 +111,116 @@ "commands.neoforge.chunkgen.status": "Status generacji! %1$s z %2$s chunków wygenerowanych. (%3$s%%)", "commands.neoforge.chunkgen.not_running": "Aktualnie brak uruchomionych pregeneracji. Uruchom `/neoforge generate help` aby zobaczyć polecenia do rozpoczęcia generacji.", "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- Generates a square centered on the given position that is chunkRadius * 2 on each side.\n§2/neoforge generate stop §r§f- Stops the current generation and displays progress that it had completed.\n§2/neoforge generate status §r- Displays the progress completed for the currently running generation.\n§2/neoforge generate help §r- Displays this message.\nGeneral tips: If running from a server console, you can run generate in different dimensions by using /execute in neoforge generate...", - "commands.neoforge.timespeed.query": "Time in %s flows at a rate of %sx (%s minutes per day).", - "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", - "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", - "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", - "commands.config.getwithtype": "Config for %s of type %s found at %s", - "commands.config.noconfig": "Config for %s of type %s not found", - "neoforge.update.beta.1": "%sWARNING: %sNeoForge Beta", - "neoforge.update.beta.2": "Major issues may arise, verify before reporting.", - "neoforge.update.newversion": "New NeoForge version available: %s", + "commands.neoforge.timespeed.query": "Czas w %s przepływa w tempie %sx (%s minut dziennie).", + "commands.neoforge.timespeed.query.default": "Czas w %s przepływa normalnie (20 minut dziennie).", + "commands.neoforge.timespeed.set": "Ustaw przepływ czasu w %s do %sx (%s minut dziennie).", + "commands.neoforge.timespeed.set.default": "Ustaw przepływ czasu w %s na domyślne (20 minut na dzień).", + "commands.neoforge.data_components.list.error.held_stack_empty": "Nie trzymasz żadnego przedmiotu", + "commands.neoforge.data_components.list.title": "Komponenty danych na %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Komponent %s posiada wartość domyślną", + "commands.neoforge.data_components.list.tooltip.deleted": "Komponent %s o wartości %s został usunięty", + "commands.neoforge.data_components.list.tooltip.modified": "Komponent %s został zmodyfikowany z %s na %s", + "commands.neoforge.data_components.list.tooltip.added": "Komponent %s został dodany z wartością %s", + "commands.config.getwithtype": "Opcje dla %s typu %s znaleziona w %s", + "commands.config.noconfig": "Opcje dla %s typu %s nie została znaleziona", + "neoforge.update.beta.1": "%sUWAGA: %sNeoForge Beta", + "neoforge.update.beta.2": "Mogą się pojawić poważne problemy, zweryfikuj przed zgłoszeniem", + "neoforge.update.newversion": "Nowa wersja NeoForge jest dostępna: %s", "neoforge.menu.updatescreen.title": "Aktualizacja modifikacji", - "neoforge.configuration.uitext.title": "%s Configuration", - "neoforge.configuration.uitext.type.client": "Client Settings", - "neoforge.configuration.uitext.type.server": "Server Settings", - "neoforge.configuration.uitext.type.common": "Common settings", - "neoforge.configuration.uitext.type.startup": "Startup settings", - "neoforge.configuration.uitext.title.client": "%s Client Configuration", - "neoforge.configuration.uitext.title.server": "%s Server Configuration", - "neoforge.configuration.uitext.title.common": "%s Common Configuration", - "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.title": "%s Konfiguracja", + "neoforge.configuration.uitext.type.client": "Ustawienia klienta", + "neoforge.configuration.uitext.type.server": "Ustawienia Serwera", + "neoforge.configuration.uitext.type.common": "Ogólne ustawienia", + "neoforge.configuration.uitext.type.startup": "Ustawienia uruchamiania", + "neoforge.configuration.uitext.title.client": "%s Konfiguracja klienta", + "neoforge.configuration.uitext.title.server": "%s Konfiguracja serwera", + "neoforge.configuration.uitext.title.common": "%s Ogólna konfiguracja", + "neoforge.configuration.uitext.title.startup": "%s Konfiguracja uruchamiania", + "neoforge.configuration.uitext.notonline": "Ustawienia w tym świecie są określone przez serwer i nie mogą być zmieniane podczas online.", + "neoforge.configuration.uitext.notlan": "Ustawienia w tym świecie nie mogą być edytowane, gdy gra jest otwarta na LAN. Proszę wrócić do menu głównego i ponownie załadować świat.", + "neoforge.configuration.uitext.notloaded": "Ustawienia tutaj są dostępne tylko wtedy, gdy świat jest ładowany.", + "neoforge.configuration.uitext.unsupportedelement": "Ta wartość nie może być edytowana w interfejsie użytkownika. Skontaktuj się z autorem modyfikacji w celu dostarczenia niestandardowego interfejsu użytkownika.", + "neoforge.configuration.uitext.longstring": "Ta wartość jest zbyt długa, aby być edytowana w interfejsie użytkownika. Proszę edytować ją w pliku konfiguracyjnym.", "neoforge.configuration.uitext.section": "%s...", - "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.sectiontext": "Edytuj", + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", - "neoforge.configuration.uitext.undo": "Undo", - "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", - "neoforge.configuration.uitext.reset": "Reset", - "neoforge.configuration.uitext.reset.tooltip": "Reverts everything on this screen to its default value.", + "neoforge.configuration.uitext.undo": "Cofnij", + "neoforge.configuration.uitext.undo.tooltip": "Odwraca zmiany tylko na tym ekranie.", + "neoforge.configuration.uitext.reset": "Resetuj", + "neoforge.configuration.uitext.reset.tooltip": "Przywraca wszystko na tym ekranie do wartości domyślnej.", "neoforge.configuration.uitext.newlistelement": "+", "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], - "neoforge.configuration.uitext.common": "Common Options", - "neoforge.configuration.uitext.client": "Client Options", - "neoforge.configuration.uitext.server": "Server Options", - "neoforge.configuration.uitext.startup": "Startup Options", - "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", - "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", - "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], - "neoforge.configuration.title": "NeoForge Configuration", - "neoforge.configuration.section.neoforge.client.toml": "Client settings", - "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", - "neoforge.configuration.section.neoforge.common.toml": "Common settings", - "neoforge.configuration.section.neoforge.common.toml.title": "Common settings", - "neoforge.configuration.section.neoforge.server.toml": "Server settings", - "neoforge.configuration.section.neoforge.server.toml.title": "Server settings", - "neoforge.configgui.advertiseDedicatedServerToLan": "Advertise Dedicated Server To LAN", - "neoforge.configgui.advertiseDedicatedServerToLan.tooltip": "Set this to true to enable advertising the dedicated server to local LAN clients so that it shows up in the Multiplayer screen automatically.", - "neoforge.configgui.forgeLightPipelineEnabled": "NeoForge Light Pipeline", + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", + "neoforge.configuration.uitext.common": "Opcje standardowe", + "neoforge.configuration.uitext.client": "Opcje Klienta", + "neoforge.configuration.uitext.server": "Opcje Serwera", + "neoforge.configuration.uitext.startup": "Opcje uruchamiania", + "neoforge.configuration.uitext.restart.game.title": "Minecraft musi zostać uruchomiony ponownie", + "neoforge.configuration.uitext.restart.game.text": "Jedna lub więcej zmienionych opcji konfiguracji zacznie obowiązywać dopiero po uruchomieniu gry.", + "neoforge.configuration.uitext.restart.server.title": "Świat musi zostać ponownie załadowany", + "neoforge.configuration.uitext.restart.server.text": "Jedna lub więcej opcji konfiguracji, które zostały zmienione, zacznie obowiązywać dopiero po przeładowaniu świata.", + "neoforge.configuration.uitext.restart.return": "Ignoruj", + "neoforge.configuration.uitext.restart.return.tooltip": "Twoje zmiany nie będą miały wpływu do czasu ponownego uruchomienia!", + "neoforge.configuration.title": "Konfiguracja NeoForge", + "neoforge.configuration.section.neoforge.client.toml": "Ustawienia klienta", + "neoforge.configuration.section.neoforge.client.toml.title": "Ustawienia klienta", + "neoforge.configuration.section.neoforge.common.toml": "Ogólne ustawienia", + "neoforge.configuration.section.neoforge.common.toml.title": "Ogólne ustawienia", + "neoforge.configuration.section.neoforge.server.toml": "Ustawienia Serwera", + "neoforge.configuration.section.neoforge.server.toml.title": "Ustawienia Serwera", + "neoforge.configgui.advertiseDedicatedServerToLan": "Reklamuj dedykowany serwer do sieci LAN", + "neoforge.configgui.advertiseDedicatedServerToLan.tooltip": "Ustaw to na true, aby włączyć reklamę serwera dedykowanego do lokalnych klientów sieci LAN, tak aby pojawiał się automatycznie na ekranie wieloosobowym.", + "neoforge.configgui.forgeLightPipelineEnabled": "Lekki Rurociąg NeoForge", "neoforge.configgui.forgeLightPipelineEnabled.tooltip": "Włącz proces renderowania bloków NeoForge - poprawia oświetlenie modeli niestandardowych.", "neoforge.configgui.fullBoundingBoxLadders": "Full Bounding Box Ladders", "neoforge.configgui.fullBoundingBoxLadders.tooltip": "Set this to true to check the entire entity's collision bounding box for ladders instead of just the block they are in. Causes noticeable differences in mechanics so default is vanilla behavior. Default: false.", - "neoforge.configgui.logLegacyTagWarnings": "Log Legacy Tags", - "neoforge.configgui.logLegacyTagWarnings.tooltip": "A config option mainly for developers. Logs out modded tags that are using the 'forge' namespace when running on integrated server. Defaults to DEV_SHORT.", - "neoforge.configgui.logUntranslatedConfigurationWarnings": "Log Untranslated Configuration Keys", - "neoforge.configgui.logUntranslatedConfigurationWarnings.tooltip": "A config option mainly for developers. Logs out configuration values that do not have translations when running a client in a development environment.", - "neoforge.configgui.logUntranslatedItemTagWarnings": "Log Untranslated Item Tags", - "neoforge.configgui.logUntranslatedItemTagWarnings.tooltip": "A config option mainly for developers. Logs out modded item tags that do not have translations when running on integrated server. Format desired is tag.item.. for the translation key. Defaults to SILENCED.", - "neoforge.configgui.permissionHandler": "Permission Handler", - "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", + "neoforge.configgui.logLegacyTagWarnings": "Rejestruj starsze tagi", + "neoforge.configgui.logLegacyTagWarnings.tooltip": "Opcja konfiguracyjna głównie dla programistów. Wyloguj modyfikowane tagi, które używają przestrzeni nazw \"forge\" podczas pracy na zintegrowanym serwerze. Domyślnie dla DEV_SHORT.", + "neoforge.configgui.logUntranslatedConfigurationWarnings": "Loguj nieprzetłumaczone klucze konfiguracyjne", + "neoforge.configgui.logUntranslatedConfigurationWarnings.tooltip": "Opcja konfiguracyjna głównie dla programistów. Wyloguje wartości konfiguracyjne, które nie mają tłumaczeń podczas uruchamiania klienta w środowisku programistycznym.", + "neoforge.configgui.logUntranslatedItemTagWarnings": "Loguj nieprzetłumaczone tagi itemów", + "neoforge.configgui.logUntranslatedItemTagWarnings.tooltip": "Opcja konfiguracyjna głównie dla deweloperów. Wyloguj tagi zmodowanego itemu, które nie mają tłumaczeń podczas pracy na zintegrowanym serwerze. Wymagany format to tag.item.. dla klucza tłumaczenia. Domyślnie dla SILENCED.", + "neoforge.configgui.permissionHandler": "Obsługa uprawnień", + "neoforge.configgui.permissionHandler.tooltip": "Obsługa uprawnień używana przez serwer. Domyślnie przekierowuje neoforge:default_handler jeśli nie jest zarejestrowany taki program obsługi o tej nazwie.", "neoforge.configgui.removeErroringBlockEntities": "Remove Erroring Block Entities", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "ZOSTAŁEŚ OSTRZEŻONY TO MOŻE ZEPSUĆ WSZYSTKO\nUŻYJ SPARINGLY\nNIE JESTEŚMY ODPOWIEDZIALNI ZA SZKODY.", "neoforge.configgui.removeErroringEntities": "Remove Erroring Entities", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "ZOSTAŁEŚ OSTRZEŻONY TO MOŻE ZEPSUĆ WSZYSTKO\nUŻYJ SPARINGLY\nNIE JESTEŚMY ODPOWIEDZIALNI ZA SZKODY.", "neoforge.configgui.showLoadWarnings": "Pokaż Ostrzeżenia Ładowania", "neoforge.configgui.showLoadWarnings.tooltip": "Kiedy włączone, NeoForge wyświetli wszelkie ostrzeżenia, które wystąpiły podczas ładowania.", - "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", - "neoforge.configgui.useCombinedDepthStencilAttachment.tooltip": "Set to true to use a combined DEPTH_STENCIL attachment instead of two separate ones.", + "neoforge.configgui.useCombinedDepthStencilAttachment": "Użyj połączonego załącznika DEPTH_STENCIL", + "neoforge.configgui.useCombinedDepthStencilAttachment.tooltip": "Ustaw na true aby użyć połączonego załącznika DEPTH_STENCIL zamiast dwóch oddzielnych.", "neoforge.controlsgui.shift": "SHIFT + %s", "neoforge.controlsgui.control": "CTRL + %s", "neoforge.controlsgui.control.mac": "CMD + %s", "neoforge.controlsgui.alt": "ALT + %s", "neoforge.container.enchant.limitedEnchantability": "Ograniczona zdolność do zaklinania", "neoforge.swim_speed": "Szybkość pływania", - "neoforge.name_tag_distance": "Nametag Render Distance", + "neoforge.name_tag_distance": "Dystans renderowania znaczników", "neoforge.creative_flight": "Creative Flight", "fluid_type.minecraft.milk": "Mleko", "fluid_type.minecraft.flowing_milk": "Mleko", "neoforge.froge.warningScreen.title": "NeoForge snapshots notice", "neoforge.froge.warningScreen.text": "Froge nie jest oficjalnie wspierany. Błędy mogą się pojawić.", - "neoforge.froge.supportWarning": "WARNING: Froge is not supported by NeoForge", + "neoforge.froge.supportWarning": "OSTRZEŻENIE: Froge nie jest wspierane przez NeoForge", "neoforge.gui.exit": "Wyjście", - "neoforge.experimentalsettings.tooltip": "This world uses experimental settings, which could stop working at any time.", - "neoforge.selectWorld.backupWarning.experimental.additional": "This message will not show again for this world.", + "neoforge.experimentalsettings.tooltip": "Ten świat używa ustawień eksperymentalnych, które mogą przestać działać w każdej chwili.", + "neoforge.selectWorld.backupWarning.experimental.additional": "Ta wiadomość nie pojawi się ponownie dla tego świata.", "neoforge.chatType.system": "%1$s", - "pack.neoforge.description": "NeoForge data/resource pack", - "pack.neoforge.source.child": "child", - "neoforge.network.negotiation.failure.mod": "Channel of mod \"%1$s\" failed to connect: %2$s", - "neoforge.network.negotiation.failure.missing.client.server": "This channel is missing on the server side, but required on the client!", - "neoforge.network.negotiation.failure.missing.server.client": "This channel is missing on the client side, but required on the server!", + "pack.neoforge.description": "zasoby NeoForge / pakiet danych", + "pack.neoforge.source.child": "potomstwo", + "neoforge.network.negotiation.failure.mod": "Kanał modyfikacji \"%1$s\" nie mógł się połączyć: %2$s", + "neoforge.network.negotiation.failure.missing.client.server": "Ten kanał brakuje po stronie serwera, ale jest wymagany na kliencie!", + "neoforge.network.negotiation.failure.missing.server.client": "Ten kanał brakuje po stronie klienta, ale jest wymagany na serwerze", "neoforge.network.negotiation.failure.flow.client.missing": "The client wants the payload to flow: %s, but the server does not support it!", "neoforge.network.negotiation.failure.flow.server.missing": "The server wants the payload to flow: %s, but the client does not support it!", "neoforge.network.negotiation.failure.flow.client.mismatch": "The client wants the payload to flow: %s, but the server wants it to flow: %s!", @@ -296,20 +228,20 @@ "neoforge.network.negotiation.failure.version.client.missing": "The client wants the payload to be version: %s, but the server does not support it!", "neoforge.network.negotiation.failure.version.server.missing": "The server wants the payload to be version: %s, but the client does not support it!", "neoforge.network.negotiation.failure.version.mismatch": "The client wants the payload to be version: %s, but the server wants it to be version: %s!", - "neoforge.network.invalid_flow": "Failed to process a payload that was send with an invalid flow: %s", - "neoforge.network.negotiation.failure.vanilla.client.not_supported": "You are trying to connect to a server that is running NeoForge, but you are not. Please install NeoForge Version: %s to connect to this server.", - "neoforge.network.negotiation.failure.vanilla.server.not_supported": "You are trying to connect to a server that is not running NeoForge, but you have mods that require it. A connection could not be established.", - "neoforge.network.packet_splitter.unknown": "Tried to split a packet without packet splitter!", + "neoforge.network.invalid_flow": "Nie powiodło się przetwarzanie ładunku, który został wysłany z nieprawidłowym przepływem: %s", + "neoforge.network.negotiation.failure.vanilla.client.not_supported": "Próbujesz się połączyć się do serwera, który działa na NeoForge, ale nie masz takiej możliwości. Proszę zainstalować Wersję: %s NeoForge, by się połączyć do tego serwera.", + "neoforge.network.negotiation.failure.vanilla.server.not_supported": "Próbujesz się połączyć do serwera, który nie działa na NeoForge, ale masz modyfikacje, które tego wymagają", + "neoforge.network.packet_splitter.unknown": "Spróbowano podzielić pakiet bez rozdzielacza pakietów!", "neoforge.network.advanced_add_entity.failed": "Failed to process advanced entity spawn data: %s", "neoforge.network.advanced_open_screen.failed": "Failed to open a screen with advanced data: %s", - "neoforge.network.registries.sync.missing": "Not all expected registries were received from the server! (missing: %s)", + "neoforge.network.registries.sync.missing": "Nie wszystkie oczekiwane rejestry zostały otrzymane od serwera! (Brakujące: %s)", "neoforge.network.registries.sync.server-with-unknown-keys": "Serwer wysyła rejestry z nieznanymi kluczami: %s", - "neoforge.network.registries.sync.failed": "Failed to sync registries from the server: %s", + "neoforge.network.registries.sync.failed": "Nie powiodła się synchronizacja rejestrów z serwerem: %s ", "neoforge.network.aux_light_data.failed": "Failed to handle auxiliary light data for chunk %s: %s", - "neoforge.network.data_maps.failed": "Failed to handle registry data map sync for registry %s: %s", + "neoforge.network.data_maps.failed": "Nie udało się obsłużyć synchronizacji map danych dla rejestru %s: %s", "neoforge.network.data_maps.missing_our": "Nie można połączyć się z serwerem, ponieważ brakuje obowiązkowych map danych rejestru znajdujących się w kliencie: %s", "neoforge.network.data_maps.missing_their": "Nie można połączyć się z serwerem, ponieważ brakuje obowiązkowych map danych rejestru znajdujących się w kliencie: %s", - "neoforge.network.extensible_enums.no_vanilla_server": "This client does not support vanilla servers as it has extended enums used in serverbound networking", - "neoforge.network.extensible_enums.enum_set_mismatch": "The set of extensible enums on the client and server do not match. Make sure you are using the same NeoForge version as the server", - "neoforge.network.extensible_enums.enum_entry_mismatch": "The set of values added to extensible enums on the client and server do not match. Make sure you are using the same mod and NeoForge versions as the server. See the log for more details" + "neoforge.network.extensible_enums.no_vanilla_server": "Ten klient nie obsługuje serwerów vanilla ponieważ posiada rozszerzone enums używane w sieciach związanych z serwerem", + "neoforge.network.extensible_enums.enum_set_mismatch": "Zestaw rozszerzalnych enumerów na kliencie i serwerze nie pasuje. Upewnij się, że używasz tej samej wersji NeoForge co serwer", + "neoforge.network.extensible_enums.enum_entry_mismatch": "Zestaw wartości dodanych do rozszerzalnych enumów w kliencie i serwerze nie pasuje. Upewnij się, że używasz tych samych wersji modyfikacji i NeoForge co serwer. Więcej informacji znajdziesz w logu" } diff --git a/src/main/resources/assets/neoforge/lang/pt_br.json b/src/main/resources/assets/neoforge/lang/pt_br.json index 70eaf520c6..e931213fac 100644 --- a/src/main/resources/assets/neoforge/lang/pt_br.json +++ b/src/main/resources/assets/neoforge/lang/pt_br.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "This command is deprecated for removal in 1.17, use %s instead.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Entity tracking enabled for %d seconds.", "commands.neoforge.tracking.entity.reset": "Entity timings data has been cleared!", "commands.neoforge.tracking.invalid": "Invalid tracking data.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Config for %s of type %s found at %s", "commands.config.noconfig": "Config for %s of type %s not found", "neoforge.update.beta.1": "%sWARNING: %sNeoForge Beta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Remove Erroring Block Entities", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Remove Erroring Entities", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Show Load Warnings", "neoforge.configgui.showLoadWarnings.tooltip": "When enabled, NeoForge will show any warnings that occurred during loading.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/pt_pt.json b/src/main/resources/assets/neoforge/lang/pt_pt.json index 405906c80c..f43c9088b0 100644 --- a/src/main/resources/assets/neoforge/lang/pt_pt.json +++ b/src/main/resources/assets/neoforge/lang/pt_pt.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "This command is deprecated for removal in 1.17, use %s instead.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Entity tracking enabled for %d seconds.", "commands.neoforge.tracking.entity.reset": "Entity timings data has been cleared!", "commands.neoforge.tracking.invalid": "Invalid tracking data.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Config for %s of type %s found at %s", "commands.config.noconfig": "Config for %s of type %s not found", "neoforge.update.beta.1": "%sWARNING: %sNeoForge Beta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Remove Erroring Block Entities", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Remove Erroring Entities", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Show Load Warnings", "neoforge.configgui.showLoadWarnings.tooltip": "When enabled, NeoForge will show any warnings that occurred during loading.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/ro_ro.json b/src/main/resources/assets/neoforge/lang/ro_ro.json index c20a393fb6..97e50d1982 100644 --- a/src/main/resources/assets/neoforge/lang/ro_ro.json +++ b/src/main/resources/assets/neoforge/lang/ro_ro.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "This command is deprecated for removal in 1.17, use %s instead.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Entity tracking enabled for %d seconds.", "commands.neoforge.tracking.entity.reset": "Entity timings data has been cleared!", "commands.neoforge.tracking.invalid": "Invalid tracking data.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Config for %s of type %s found at %s", "commands.config.noconfig": "Config for %s of type %s not found", "neoforge.update.beta.1": "%sWARNING: %sNeoForge Beta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Remove Erroring Block Entities", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Remove Erroring Entities", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Show Load Warnings", "neoforge.configgui.showLoadWarnings.tooltip": "When enabled, NeoForge will show any warnings that occurred during loading.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/ru_ru.json b/src/main/resources/assets/neoforge/lang/ru_ru.json index d37e1f8a80..0b54ff2c22 100644 --- a/src/main/resources/assets/neoforge/lang/ru_ru.json +++ b/src/main/resources/assets/neoforge/lang/ru_ru.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "Эта команда устарела и помечена для удаления начиная с 1.17, вместо нее используйте %s.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Список модов: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Отслеживание сущностей включено на %d секунд.", "commands.neoforge.tracking.entity.reset": "Данные с таймингами сущностей очищены!", "commands.neoforge.tracking.invalid": "Неверные данные отслеживания.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Конфиг для %s типа %s обнаружен в %s", "commands.config.noconfig": "Конфиг для %s типа %s не найден", "neoforge.update.beta.1": "%sВНИМАНИЕ: %sNeoForge Бета", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Удалять блочные сущности, вызывающие ошибки", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Удалять сущности, вызывающие ошибки", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Показывать предупреждения при загрузке", "neoforge.configgui.showLoadWarnings.tooltip": "Если эта функция включена, NeoForge покажет все предупреждения, возникшие во время загрузки.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/sk_sk.json b/src/main/resources/assets/neoforge/lang/sk_sk.json index f0af09f90b..80b274aa55 100644 --- a/src/main/resources/assets/neoforge/lang/sk_sk.json +++ b/src/main/resources/assets/neoforge/lang/sk_sk.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "Dimenzia s vybraným ID (%1$s) nie je validná.", "commands.neoforge.setdim.invalid.nochange": "Vybraná entita (%1$s) už existuje v špecifikovanej dimenzii (%2$s).", "commands.neoforge.setdim.deprecated": "Tento príkaz je zastaralý a bude vymazaný v 1.17, použite %s namiesto neho.", - "commands.neoforge.tps.invalid": "Invalidná dimenzia %1$s Možné hodnoty: %2$s", - "commands.neoforge.tps.summary.all": "Celkovo: Priemerný čas ticku: %1$s ms. Priemerné TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "List módov: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Priemerný čas ticku: %2$s ms. Priemerné TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Priemerný čas ticku: %3$s ms. Priemerné TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Sledovanie entít povolené na %d sekúnd.", "commands.neoforge.tracking.entity.reset": "Údaje o časovaní entít boli vymazané!", "commands.neoforge.tracking.invalid": "Neplatné dáta sledovania.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Čas v %s plynie normálne (20 minút na deň).", "commands.neoforge.timespeed.set": "Nastaviť plynutie času v %s na %sx (%s minúty za deň).", "commands.neoforge.timespeed.set.default": "Nastaviť plynutie času v %s na predvolené (20 minút za deň).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Konfigurácia pre %s typu %s nájdená v %s", "commands.config.noconfig": "Konfigurácia pre %s typu %s nenájdená", "neoforge.update.beta.1": "%sVAROVANIE: %sNeoForge Beta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Konfigurácia Serveru", "neoforge.configuration.uitext.title.common": "%s Bežná Konfigurácia", "neoforge.configuration.uitext.title.startup": "%s Konfigurácia Spustenia", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Nastavenie tu sú určené serverom a nemôžu byť zmenené pokým je online.", - "color": "červená" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Nastavenia tu nemôžu byť upravené pokým je vaša hra otvorená do LAN. Prosím vráťte sa do hlavného menu a načítajte svet znova.", - "color": "červená" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Nastavenia tu sú k dispozícii len keď je svet načítaný.", - "color": "červená" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "Táto hodnota nemôže byť upravená v UI. Prosím kontaktujte autora módu o poskytnutý vlastného UI preň.", - "color": "červená" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "Táto hodnota je pridlhá nato aby mohla byť upravená v UI. Prosím upravte ju v konfiguračnom súbore.", - "color": "červená" - } - ], + "neoforge.configuration.uitext.notonline": "Nastavenie tu sú určené serverom a nemôžu byť zmenené pokým je online.", + "neoforge.configuration.uitext.notlan": "Nastavenia tu nemôžu byť upravené pokým je vaša hra otvorená do LAN. Prosím vráťte sa do hlavného menu a načítajte svet znova.", + "neoforge.configuration.uitext.notloaded": "Nastavenia tu sú k dispozícii len keď je svet načítaný.", + "neoforge.configuration.uitext.unsupportedelement": "Táto hodnota nemôže byť upravená v UI. Prosím kontaktujte autora módu o poskytnutý vlastného UI preň.", + "neoforge.configuration.uitext.longstring": "Táto hodnota je pridlhá nato aby mohla byť upravená v UI. Prosím upravte ju v konfiguračnom súbore.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Upraviť", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "zlato", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Krok naspäť", "neoforge.configuration.uitext.undo.tooltip": "Vráti zmeny len na tejto obrazovke.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRádius: ", - "color": "sivá" - }, - { - "index": 0, - "color": "sivá" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "Súbor: \"", - "color": "sivá" - }, - { - "index": 0, - "color": "sivá" - }, - { - "text": "\"", - "color": "sivá" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Bežné Nastavenia", "neoforge.configuration.uitext.client": "Nastavenia Klienta", "neoforge.configuration.uitext.server": "Nastavenia Serveru", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "Svet treba znova načítať", "neoforge.configuration.uitext.restart.server.text": "Jedno alebo viac z konfiguračných nastavení ktoré boli zmenené budú mať efekt až keď bude hra znova načítaná.", "neoforge.configuration.uitext.restart.return": "Ignorovať", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Vaše zmeny nebudú mať žiadny efekt pokým nereštartujete!", - "color": "červená", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Vaše zmeny nebudú mať žiadny efekt pokým nereštartujete!", "neoforge.configuration.title": "NeoForge Konfigurácia", "neoforge.configuration.section.neoforge.client.toml": "Nastavenia klienta", "neoforge.configuration.section.neoforge.client.toml.title": "Nastavenia klienta", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Manipulátor Povolení", "neoforge.configgui.permissionHandler.tooltip": "Manipulátor povolení používaný serverom. Predvolená hodnota do neoforge:default_handler ak nie je žiadny manipulátor s takým menom registrovaný.", "neoforge.configgui.removeErroringBlockEntities": "Odstrániť blokové entity spôsobujúce error", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Nastavte toto na hodnotu TRUE na odstránenie akejkoľvek Entity, ktorá vyhodí chybu v ich aktualizačnej metóde namiesto uzavretia serveru a nahlásenia logu padnutia.\n\n", - { - "text": "BUDŤE VAROVANÝ, TOTO BY MOHLO VŠETKO ROZBIŤ.\nPOUŽÍVAJTE OPATRNE.\nNIE SME ZODPOVEDNÝ ZA ŠKODY.", - "color": "červená", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BUDŤE VAROVANÝ, TOTO BY MOHLO VŠETKO ROZBIŤ.\nPOUŽÍVAJTE OPATRNE.\nNIE SME ZODPOVEDNÝ ZA ŠKODY.", "neoforge.configgui.removeErroringEntities": "Odstrániť entity spôsobujúce error", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Nastavte toto na hodnotu TRUE na odstránenie akejkoľvek Blokovej Entity, ktorá vyhodí chybu v ich aktualizačnej metóde namiesto uzavretia serveru a nahlásenia logu padnutia.\n\n", - { - "text": "BUDŤE VAROVANÝ, TOTO BY MOHLO VŠETKO ROZBIŤ.\nPOUŽÍVAJTE OPATRNE.\nNIE SME ZODPOVEDNÝ ZA ŠKODY.", - "color": "červená", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BUDŤE VAROVANÝ, TOTO BY MOHLO VŠETKO ROZBIŤ.\nPOUŽÍVAJTE OPATRNE.\nNIE SME ZODPOVEDNÝ ZA ŠKODY.", "neoforge.configgui.showLoadWarnings": "Zobraziť Varovania Načítavania", "neoforge.configgui.showLoadWarnings.tooltip": "Keď je toto povolené, NeoForge zobrazí všetky varovania, ktoré nastali počas načítavania.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Použiť kombinované DEPTH_STENCIL Prílohy", diff --git a/src/main/resources/assets/neoforge/lang/tr_tr.json b/src/main/resources/assets/neoforge/lang/tr_tr.json index fcecf56a33..50e04e5287 100644 --- a/src/main/resources/assets/neoforge/lang/tr_tr.json +++ b/src/main/resources/assets/neoforge/lang/tr_tr.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "This command is deprecated for removal in 1.17, use %s instead.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Entity tracking enabled for %d seconds.", "commands.neoforge.tracking.entity.reset": "Entity timings data has been cleared!", "commands.neoforge.tracking.invalid": "Invalid tracking data.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Config for %s of type %s found at %s", "commands.config.noconfig": "Config for %s of type %s not found", "neoforge.update.beta.1": "%sWARNING: %sNeoForge Beta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Remove Erroring Block Entities", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Remove Erroring Entities", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Show Load Warnings", "neoforge.configgui.showLoadWarnings.tooltip": "When enabled, NeoForge will show any warnings that occurred during loading.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/tt_ru.json b/src/main/resources/assets/neoforge/lang/tt_ru.json index 5385dcc2e4..b2a216d165 100644 --- a/src/main/resources/assets/neoforge/lang/tt_ru.json +++ b/src/main/resources/assets/neoforge/lang/tt_ru.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "This command is deprecated for removal in 1.17, use %s instead.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Entity tracking enabled for %d seconds.", "commands.neoforge.tracking.entity.reset": "Entity timings data has been cleared!", "commands.neoforge.tracking.invalid": "Invalid tracking data.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Config for %s of type %s found at %s", "commands.config.noconfig": "Config for %s of type %s not found", "neoforge.update.beta.1": "%sWARNING: %sNeoForge Beta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Remove Erroring Block Entities", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Remove Erroring Entities", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Show Load Warnings", "neoforge.configgui.showLoadWarnings.tooltip": "When enabled, NeoForge will show any warnings that occurred during loading.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/uk_ua.json b/src/main/resources/assets/neoforge/lang/uk_ua.json index 81b3422072..da431796eb 100644 --- a/src/main/resources/assets/neoforge/lang/uk_ua.json +++ b/src/main/resources/assets/neoforge/lang/uk_ua.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "Вказаний ID виміру (%1$s) некоректний.", "commands.neoforge.setdim.invalid.nochange": "Обрана сутність (%1$s) вже у вказаному вимірі (%2$s).", "commands.neoforge.setdim.deprecated": "Ця команда застаріла і буде видалена у версії 1.17, використовуйте %s замість цього.", - "commands.neoforge.tps.invalid": "Неприпустимий вимір %1$s Можливі значення: %2$s", - "commands.neoforge.tps.summary.all": "Загалом: Середній час тіку: %1$s мс. Середній TPS: %2$s", + "commands.neoforge.tps.overall": "Загалом: %s TPS (%s мс/тік)", + "commands.neoforge.tps.tooltip": "Середній TPS; чим вище, тим краще. Цільовий TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s мс/тік)", + "commands.neoforge.tps.dimension.tooltip": "%s (Тип виміру: %s)", "commands.neoforge.mods.list": "Список модів: %1$s", - "commands.neoforge.tps.summary.basic": "Вимір %1$s: Середній час тіку: %2$s мс. Середній TPS: %3$s", - "commands.neoforge.tps.summary.named": "Вимір %1$s (%2$s): Середній час тіку: %3$s мс. Середній TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Відстеження сутностей увімкнено на %d секунд.", "commands.neoforge.tracking.entity.reset": "Данні таймінгів сутностей були очищені!", "commands.neoforge.tracking.invalid": "Невірні дані відстеження.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Час в %s тече нормально (20 хвилин на день).", "commands.neoforge.timespeed.set": "Встановіть час в %s до %sx (%s хвилин на день).", "commands.neoforge.timespeed.set.default": "Встановіть потік часу в %s за замовчуванням (20 хвилин на день).", + "commands.neoforge.data_components.list.error.held_stack_empty": "Ви не тримаєте будь-який предмет", + "commands.neoforge.data_components.list.title": "Компоненти даних на %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Компонент %s зберігає його значення за замовчуванням", + "commands.neoforge.data_components.list.tooltip.deleted": "Компонент %s зі значенням %s було видалено", + "commands.neoforge.data_components.list.tooltip.modified": "Компонент %s був змінений з %s в %s", + "commands.neoforge.data_components.list.tooltip.added": "Компонент %s був доданий зі значенням %s", "commands.config.getwithtype": "Конфіг для %s типу %s знайдена в %s", "commands.config.noconfig": "Конфіг для %s типу %s не знайдено", "neoforge.update.beta.1": "%sПОПЕРЕДЖЕННЯ: %sNeoForge Beta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "Серверна конфігурація %s", "neoforge.configuration.uitext.title.common": "Загальна конфігурація %s", "neoforge.configuration.uitext.title.startup": "Запускова конфігурація %s", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Налаштування тут визначаються сервером і не можуть бути змінені доки ви в мережі.", - "color": "червоний" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Налаштування тут не можуть бути відредаговані, поки ваша гра відкрита для локальної мережі. Будь ласка, поверніться до головного меню і завантажте світ ще раз.", - "color": "червоний" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Налаштування тут доступні після завантаження світу.", - "color": "червоний" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "Це значення не можна редагувати в інтерфейсі. Будь ласка, зв'яжіться з автором мода про надання користувацького інтерфейсу для нього.", - "color": "червоний" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "Це значення задовге для редагування в інтерфейсі. Будь ласка, відредагуйте його у файлі конфігурації.", - "color": "червоний" - } - ], + "neoforge.configuration.uitext.notonline": "Налаштування тут визначаються сервером і не можуть бути змінені доки ви в мережі.", + "neoforge.configuration.uitext.notlan": "Налаштування тут не можуть бути відредаговані, поки ваша гра відкрита для локальної мережі. Будь ласка, поверніться до головного меню і завантажте світ ще раз.", + "neoforge.configuration.uitext.notloaded": "Налаштування тут доступні після завантаження світу.", + "neoforge.configuration.uitext.unsupportedelement": "Це значення не можна редагувати в інтерфейсі. Будь ласка, зв'яжіться з автором мода про надання користувацького інтерфейсу для нього.", + "neoforge.configuration.uitext.longstring": "Це значення задовге для редагування в інтерфейсі. Будь ласка, відредагуйте його у файлі конфігурації.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Змінити", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "золотий", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Скасувати", "neoforge.configuration.uitext.undo.tooltip": "Повертає зміни тільки на цьому екрані.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nДіапазон: ", - "color": "сірий" - }, - { - "index": 0, - "color": "сірий" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "Файл: \"", - "color": "сірий" - }, - { - "index": 0, - "color": "сірий" - }, - { - "text": "\"", - "color": "сірий" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Загальні параметри", "neoforge.configuration.uitext.client": "Клієнтські параметри", "neoforge.configuration.uitext.server": "Серверні параметри", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "Світ має бути перезавантажений", "neoforge.configuration.uitext.restart.server.text": "Один чи кілька параметрів конфігурації, які були змінені, набудуть чинності лише після перезавантаження світу.", "neoforge.configuration.uitext.restart.return": "Ігнорувати", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Зміни не матимуть ніякого ефекту, поки ви не перезавантажитеся!", - "color": "червоний", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Зміни не матимуть ніякого ефекту, поки ви не перезавантажитеся!", "neoforge.configuration.title": "Конфігурація NeoForge", "neoforge.configuration.section.neoforge.client.toml": "Клієнтські налаштування", "neoforge.configuration.section.neoforge.client.toml.title": "Клієнтські налаштування", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Менеджер дозволів", "neoforge.configgui.permissionHandler.tooltip": "Менеджер дозволів, що використовує сервер. За замовчуванням neoforge:default_handler, коли такого обробника не зареєстровано з таким іменем.", "neoforge.configgui.removeErroringBlockEntities": "Видалити блок-сутності, які викликають помилки", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Встановіть значення \"true\", для видалення будь-якого об'єкта, що спричиняє помилки в методі оновлення, замість закриття сервера та створення журналу про аварію.\n\n", - { - "text": "УВАГА: ЦЕ МОЖЕ ПОШКОДИТИ ВСЕ.\nВИКОРИСТОВУЙТЕ ОБЕРЕЖНО.\nМИ НЕ ВІДПОВІДАЛЬНІ ЗА ПОШКОДЖЕННЯ.", - "color": "червоний", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "УВАГА: ЦЕ МОЖЕ ПОШКОДИТИ ВСЕ.\nВИКОРИСТОВУЙТЕ ОБЕРЕЖНО.\nМИ НЕ ВІДПОВІДАЛЬНІ ЗА ПОШКОДЖЕННЯ.", "neoforge.configgui.removeErroringEntities": "Видалити сутності, які викликають помилки", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Встановіть значення \"true\", для видалення будь-якого блок-сутності, що спричиняє помилки в методі оновлення, замість закриття сервера та створення журналу про аварію.\n\n", - { - "text": "УВАГА: ЦЕ МОЖЕ ПОШКОДИТИ ВСЕ.\nВИКОРИСТОВУЙТЕ ОБЕРЕЖНО.\nМИ НЕ ВІДПОВІДАЛЬНІ ЗА ПОШКОДЖЕННЯ.", - "color": "червоний", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "УВАГА: ЦЕ МОЖЕ ПОШКОДИТИ ВСЕ.\nВИКОРИСТОВУЙТЕ ОБЕРЕЖНО.\nМИ НЕ ВІДПОВІДАЛЬНІ ЗА ПОШКОДЖЕННЯ.", "neoforge.configgui.showLoadWarnings": "Показувати попередження при завантаженні", "neoforge.configgui.showLoadWarnings.tooltip": "Коли увімкнено, NeoForge покаже всі попередження, що сталися під час завантаження.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Використовувати комбінований атрибут DEPTH_STENCIL", diff --git a/src/main/resources/assets/neoforge/lang/vi_vn.json b/src/main/resources/assets/neoforge/lang/vi_vn.json index 405906c80c..f43c9088b0 100644 --- a/src/main/resources/assets/neoforge/lang/vi_vn.json +++ b/src/main/resources/assets/neoforge/lang/vi_vn.json @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", "commands.neoforge.setdim.deprecated": "This command is deprecated for removal in 1.17, use %s instead.", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", + "commands.neoforge.tps.overall": "Overall: %s TPS (%s ms/tick)", + "commands.neoforge.tps.tooltip": "Mean TPS; higher is better. Target TPS: %s", + "commands.neoforge.tps.dimension": "%s: %s TPS (%s ms/tick)", + "commands.neoforge.tps.dimension.tooltip": "%s (Dimension Type: %s)", "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", "commands.neoforge.tracking.entity.enabled": "Entity tracking enabled for %d seconds.", "commands.neoforge.tracking.entity.reset": "Entity timings data has been cleared!", "commands.neoforge.tracking.invalid": "Invalid tracking data.", @@ -115,6 +115,14 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "Config for %s of type %s found at %s", "commands.config.noconfig": "Config for %s of type %s not found", "neoforge.update.beta.1": "%sWARNING: %sNeoForge Beta", @@ -130,51 +138,15 @@ "neoforge.configuration.uitext.title.server": "%s Server Configuration", "neoforge.configuration.uitext.title.common": "%s Common Configuration", "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", "neoforge.configuration.uitext.undo": "Undo", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", @@ -184,30 +156,8 @@ "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], + "neoforge.configuration.uitext.rangetooltip": "Range: %s", + "neoforge.configuration.uitext.filenametooltip": "File: \"%s\"", "neoforge.configuration.uitext.common": "Common Options", "neoforge.configuration.uitext.client": "Client Options", "neoforge.configuration.uitext.server": "Server Options", @@ -217,13 +167,7 @@ "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], + "neoforge.configuration.uitext.restart.return.tooltip": "Your changes will have no effect until you restart!", "neoforge.configuration.title": "NeoForge Configuration", "neoforge.configuration.section.neoforge.client.toml": "Client settings", "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", @@ -246,23 +190,11 @@ "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "Remove Erroring Block Entities", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "Remove Erroring Entities", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "Show Load Warnings", "neoforge.configgui.showLoadWarnings.tooltip": "When enabled, NeoForge will show any warnings that occurred during loading.", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", diff --git a/src/main/resources/assets/neoforge/lang/zh_cn.json b/src/main/resources/assets/neoforge/lang/zh_cn.json index 24107e8cd2..0deca20fe6 100644 --- a/src/main/resources/assets/neoforge/lang/zh_cn.json +++ b/src/main/resources/assets/neoforge/lang/zh_cn.json @@ -13,7 +13,7 @@ "fml.menu.mods.info.credits": "鸣谢:%1$s", "fml.menu.mods.info.authors": "作者:%1$s", "fml.menu.mods.info.displayurl": "主页:%1$s", - "fml.menu.mods.info.license": "开源许可:%1$s", + "fml.menu.mods.info.license": "许可证:%1$s", "fml.menu.mods.info.securejardisabled": "Secure mod 功能已禁用,请更新 JDK", "fml.menu.mods.info.signature": "签名:%1$s", "fml.menu.mods.info.signature.unsigned": "未签名", @@ -21,7 +21,7 @@ "fml.menu.mods.info.trust.noauthority": "无", "fml.menu.mods.info.nochildmods": "未发现子模组", "fml.menu.mods.info.childmods": "子模组:%1$s", - "fml.menu.mods.info.updateavailable": "可用更新: %1$s", + "fml.menu.mods.info.updateavailable": "可用更新:%1$s", "fml.menu.mods.info.changelogheader": "更新日志:", "fml.menu.multiplayer.compatible": "兼容的 FML 服务器\n有 {0,choice,0<%1$s 个} 模组", "fml.menu.multiplayer.incompatible": "不兼容的 FML 模组服务器", @@ -76,11 +76,11 @@ "commands.neoforge.setdim.invalid.dim": "指定的维度 ID(%1$s)无效。", "commands.neoforge.setdim.invalid.nochange": "选定的实体(%1$s)已经在指定的维度(%2$s)中。", "commands.neoforge.setdim.deprecated": "此命令将在 1.17 中被废弃去除,请使用 %s 代替。", - "commands.neoforge.tps.invalid": "无效的维度 %1$s 可能的值:%2$s", - "commands.neoforge.tps.summary.all": "概述:平均游戏刻耗时:%1$s 毫秒。平均 TPS:%2$s", + "commands.neoforge.tps.overall": "总体:%sTPS(%s毫秒/刻)", + "commands.neoforge.tps.tooltip": "平均TPS;越高越好。目标TPS:%s", + "commands.neoforge.tps.dimension": "%s:%sTPS(%s毫秒/刻)", + "commands.neoforge.tps.dimension.tooltip": "%s(维度类型:%s)", "commands.neoforge.mods.list": "模组列表:%1$s", - "commands.neoforge.tps.summary.basic": "维度 %1$s:平均游戏刻耗时:%2$s 毫秒。平均 TPS:%3$s", - "commands.neoforge.tps.summary.named": "维度 %1$s(%2$s):平均游戏刻耗时:%3$s 毫秒。平均 TPS:%4$s", "commands.neoforge.tracking.entity.enabled": "实体跟踪已启用,时长 %d 秒。", "commands.neoforge.tracking.entity.reset": "实体计时数据已被清理!", "commands.neoforge.tracking.invalid": "无效的跟踪数据。", @@ -107,166 +107,98 @@ "commands.neoforge.chunkgen.started": "正在于 %2$sx%3$s 区块范围(%4$sx%5$s 个方块)中生成 %1$s 个区块。", "commands.neoforge.chunkgen.success": "生成完毕!", "commands.neoforge.chunkgen.error": "生成中发生了 %1$s 个错误!请检查日志以获取更多信息。", - "commands.neoforge.chunkgen.stopped": "生成已停止!已生成%2$s中的%1$s个区块(%3$s%%)。", - "commands.neoforge.chunkgen.status": "正在生成! %2$s中的%1$s个区块已生成(%3$s%%)。", + "commands.neoforge.chunkgen.stopped": "生成已停止!预定生成%2$s个区块,已生成%1$s个。(%3$s%%)", + "commands.neoforge.chunkgen.status": "生成状态!预定生成%2$s个区块,已生成%1$s个。(%3$s%%)", "commands.neoforge.chunkgen.not_running": "无进行中的预生成。运行 `/neoforge generate help` 以查看开始生成的命令。", "commands.neoforge.chunkgen.help_line": "§2/neoforge generate start [progressBar] §r§f- 生成一个以给定坐标为中心的、边长为 chunkRadius * 2 的正方形。\n§2/neoforge generate stop §r§f- 停止当前生成,显示完成进度。\n§2/neoforge generate status §r- 显示当前生成的完成进度。\n§2/neoforge generate help §r- 显示此消息\n通用提示:如果从服务器控制台执行,可以通过 '/execute in neoforge generate...' 在特定维度执行。", - "commands.neoforge.timespeed.query": "%s 以 %sx (每天%s 分钟) 的速度流动。", - "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", - "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", - "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.timespeed.query": "%s的时间以%sx的速度流逝(%s分钟每天)。", + "commands.neoforge.timespeed.query.default": "%s的时间以正常速度流逝(20分钟每天)。", + "commands.neoforge.timespeed.set": "已将%s的时间流速设为%sx(%s分钟每天)。", + "commands.neoforge.timespeed.set.default": "已将%s的时间流速设为默认值(20分钟每天)。", + "commands.neoforge.data_components.list.error.held_stack_empty": "你没有拿任何东西", + "commands.neoforge.data_components.list.title": "%s 上的数据组件:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "组件 %s 具有默认值", + "commands.neoforge.data_components.list.tooltip.deleted": "组件 %s 的值 %s 已被删除", + "commands.neoforge.data_components.list.tooltip.modified": "组件 %s 已从 %s 修改为 %s", + "commands.neoforge.data_components.list.tooltip.added": "组件 %s 添加了值 %s", "commands.config.getwithtype": "%s 类型 %s 的配置在 %s 发现", "commands.config.noconfig": "未发现 %s(类型为 %s)的配置", "neoforge.update.beta.1": "%s警告:%s NeoForge 为测试版", "neoforge.update.beta.2": "可能会出现重大问题,请在报告之前进行核实。", "neoforge.update.newversion": "新版本 NeoForge 可用:%s", "neoforge.menu.updatescreen.title": "模组更新", - "neoforge.configuration.uitext.title": "%s Configuration", - "neoforge.configuration.uitext.type.client": "Client Settings", - "neoforge.configuration.uitext.type.server": "Server Settings", - "neoforge.configuration.uitext.type.common": "Common settings", - "neoforge.configuration.uitext.type.startup": "Startup settings", - "neoforge.configuration.uitext.title.client": "%s Client Configuration", - "neoforge.configuration.uitext.title.server": "%s Server Configuration", - "neoforge.configuration.uitext.title.common": "%s Common Configuration", - "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], - "neoforge.configuration.uitext.section": "%s...", - "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], + "neoforge.configuration.uitext.title": "%s 配置", + "neoforge.configuration.uitext.type.client": "客户端设置", + "neoforge.configuration.uitext.type.server": "服务端设置", + "neoforge.configuration.uitext.type.common": "通用设置", + "neoforge.configuration.uitext.type.startup": "启动时设置", + "neoforge.configuration.uitext.title.client": "%s 客户端配置", + "neoforge.configuration.uitext.title.server": "%s 服务端配置", + "neoforge.configuration.uitext.title.common": "%s 通用配置", + "neoforge.configuration.uitext.title.startup": "%s 启动时配置", + "neoforge.configuration.uitext.notonline": "这里的设置由服务端决定,且无法在线更改。", + "neoforge.configuration.uitext.notlan": "在你的游戏已对局域网开放时,无法编辑这里的设置。请返回主菜单并再次加载世界。", + "neoforge.configuration.uitext.notloaded": "这里的设置只有在进入世界后才可用。", + "neoforge.configuration.uitext.unsupportedelement": "此值不能在UI中编辑。请联系模组作者提供自定义UI。", + "neoforge.configuration.uitext.longstring": "该值太长,无法在UI中编辑。请在配置文件中编辑它。", + "neoforge.configuration.uitext.section": "%s…", + "neoforge.configuration.uitext.sectiontext": "编辑", + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", "neoforge.configuration.uitext.listelement": "%s:", - "neoforge.configuration.uitext.undo": "Undo", - "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", - "neoforge.configuration.uitext.reset": "Reset", - "neoforge.configuration.uitext.reset.tooltip": "Reverts everything on this screen to its default value.", + "neoforge.configuration.uitext.undo": "取消", + "neoforge.configuration.uitext.undo.tooltip": "仅恢复当前的更改。", + "neoforge.configuration.uitext.reset": "重置", + "neoforge.configuration.uitext.reset.tooltip": "将此屏幕上的所有内容恢复为默认值。", "neoforge.configuration.uitext.newlistelement": "+", "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], - "neoforge.configuration.uitext.common": "Common Options", - "neoforge.configuration.uitext.client": "Client Options", - "neoforge.configuration.uitext.server": "Server Options", - "neoforge.configuration.uitext.startup": "Startup Options", - "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", - "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", - "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", - "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", - "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], - "neoforge.configuration.title": "NeoForge Configuration", - "neoforge.configuration.section.neoforge.client.toml": "Client settings", - "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", - "neoforge.configuration.section.neoforge.common.toml": "Common settings", - "neoforge.configuration.section.neoforge.common.toml.title": "Common settings", - "neoforge.configuration.section.neoforge.server.toml": "Server settings", - "neoforge.configuration.section.neoforge.server.toml.title": "Server settings", - "neoforge.configgui.advertiseDedicatedServerToLan": "Advertise Dedicated Server To LAN", - "neoforge.configgui.advertiseDedicatedServerToLan.tooltip": "Set this to true to enable advertising the dedicated server to local LAN clients so that it shows up in the Multiplayer screen automatically.", - "neoforge.configgui.forgeLightPipelineEnabled": "NeoForge Light Pipeline", + "neoforge.configuration.uitext.rangetooltip": "取值范围:%s", + "neoforge.configuration.uitext.filenametooltip": "文件:“%s”", + "neoforge.configuration.uitext.common": "通用选项", + "neoforge.configuration.uitext.client": "客户端选项", + "neoforge.configuration.uitext.server": "服务端选项", + "neoforge.configuration.uitext.startup": "启动时选项", + "neoforge.configuration.uitext.restart.game.title": "Minecraft需要重新启动", + "neoforge.configuration.uitext.restart.game.text": "一个或多个已更改的配置选项只有在下次启动游戏时才会生效。", + "neoforge.configuration.uitext.restart.server.title": "需要重新加载世界", + "neoforge.configuration.uitext.restart.server.text": "一个或多个已更改的配置选项只有在重新加载世界时才会生效。", + "neoforge.configuration.uitext.restart.return": "无视", + "neoforge.configuration.uitext.restart.return.tooltip": "在重启游戏之前,你的更改不会生效!", + "neoforge.configuration.title": "NeoForge 配置", + "neoforge.configuration.section.neoforge.client.toml": "客户端设置", + "neoforge.configuration.section.neoforge.client.toml.title": "客户端设置", + "neoforge.configuration.section.neoforge.common.toml": "通用设置", + "neoforge.configuration.section.neoforge.common.toml.title": "通用设置", + "neoforge.configuration.section.neoforge.server.toml": "服务端设置", + "neoforge.configuration.section.neoforge.server.toml.title": "服务端设置", + "neoforge.configgui.advertiseDedicatedServerToLan": "向局域网开放服务器", + "neoforge.configgui.advertiseDedicatedServerToLan.tooltip": "将此设置为true以启用向本地局域网客户端开放服务器,以便它自动显示在多人游戏屏幕中。", + "neoforge.configgui.forgeLightPipelineEnabled": "NeoForge 光照管线", "neoforge.configgui.forgeLightPipelineEnabled.tooltip": "启用 NeoForge 方块渲染管线 - 修复自定义模型的光照问题。", "neoforge.configgui.fullBoundingBoxLadders": "梯子使用完整实体碰撞箱", "neoforge.configgui.fullBoundingBoxLadders.tooltip": "将此项设置为true,以使梯子检查整个实体的碰撞箱,而不仅仅是它们所处的方块。这将导致明显的机制差异,因此默认使用原版行为。默认:false。", - "neoforge.configgui.logLegacyTagWarnings": "Log Legacy Tags", - "neoforge.configgui.logLegacyTagWarnings.tooltip": "A config option mainly for developers. Logs out modded tags that are using the 'forge' namespace when running on integrated server. Defaults to DEV_SHORT.", - "neoforge.configgui.logUntranslatedConfigurationWarnings": "Log Untranslated Configuration Keys", - "neoforge.configgui.logUntranslatedConfigurationWarnings.tooltip": "A config option mainly for developers. Logs out configuration values that do not have translations when running a client in a development environment.", - "neoforge.configgui.logUntranslatedItemTagWarnings": "Log Untranslated Item Tags", - "neoforge.configgui.logUntranslatedItemTagWarnings.tooltip": "A config option mainly for developers. Logs out modded item tags that do not have translations when running on integrated server. Format desired is tag.item.. for the translation key. Defaults to SILENCED.", - "neoforge.configgui.permissionHandler": "Permission Handler", - "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", + "neoforge.configgui.logLegacyTagWarnings": "记录旧标签", + "neoforge.configgui.logLegacyTagWarnings.tooltip": "一个主要面向开发者的配置选项。在内置服务端上运行时,在日志中记录那些使用“forge”命名空间的模组环境标签。默认值为DEV_SHORT。", + "neoforge.configgui.logUntranslatedConfigurationWarnings": "记录未翻译的配置键", + "neoforge.configgui.logUntranslatedConfigurationWarnings.tooltip": "一个主要面向开发者的配置选项。在开发环境中运行客户端时,在日志中记录没有翻译的配置值。", + "neoforge.configgui.logUntranslatedItemTagWarnings": "记录未翻译的物品标签", + "neoforge.configgui.logUntranslatedItemTagWarnings.tooltip": "一个主要面向开发者的配置选项。在内置服务端上运行时,在日志中记录没有翻译的模组环境物品标签。翻译键要求的格式是tag.item.<命名空间>.<路径>。默认值为SILENCED。", + "neoforge.configgui.permissionHandler": "权限处理", + "neoforge.configgui.permissionHandler.tooltip": "服务器使用的权限处理程序。如果没有注册这样的处理程序,默认为neoforge:default_handler。", "neoforge.configgui.removeErroringBlockEntities": "删除错误方块实体", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "开启此项后,游戏会移除任何在更新方法中出现错误的方块实体,而不是关闭服务端并报告崩溃日志。", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "请注意,这可能会把一切搞砸。\n尽量少使用。\n我们不对损坏负责。", "neoforge.configgui.removeErroringEntities": "删除错误实体", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "开启此项后,游戏会移除任何在更新方法中出现错误的实体,而不是关闭服务端并报告崩溃日志。", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "请注意,这可能会把一切搞砸。\n尽量少使用。\n我们不对损坏负责。", "neoforge.configgui.showLoadWarnings": "显示加载警告", "neoforge.configgui.showLoadWarnings.tooltip": "如果启用,NeoForge 将显示加载过程中出现的任何警告。", - "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", - "neoforge.configgui.useCombinedDepthStencilAttachment.tooltip": "Set to true to use a combined DEPTH_STENCIL attachment instead of two separate ones.", + "neoforge.configgui.useCombinedDepthStencilAttachment": "使用组合DEPTH_STENCIL附件", + "neoforge.configgui.useCombinedDepthStencilAttachment.tooltip": "设置为true将使用组合的DEPTH_STENCIL附件而不是两个单独的附件。", "neoforge.controlsgui.shift": "SHIFT + %s", "neoforge.controlsgui.control": "CTRL + %s", "neoforge.controlsgui.control.mac": "CMD + %s", @@ -309,7 +241,7 @@ "neoforge.network.data_maps.failed": "处理注册表数据映射同步失败 %s: %s", "neoforge.network.data_maps.missing_our": "无法连接至服务器,因为客户端缺少必要的注册表数据映射:%s", "neoforge.network.data_maps.missing_their": "无法连接至服务器,因为客户端上不存在必要的注册表数据映射:%s", - "neoforge.network.extensible_enums.no_vanilla_server": "This client does not support vanilla servers as it has extended enums used in serverbound networking", - "neoforge.network.extensible_enums.enum_set_mismatch": "The set of extensible enums on the client and server do not match. Make sure you are using the same NeoForge version as the server", - "neoforge.network.extensible_enums.enum_entry_mismatch": "The set of values added to extensible enums on the client and server do not match. Make sure you are using the same mod and NeoForge versions as the server. See the log for more details" + "neoforge.network.extensible_enums.no_vanilla_server": "该客户端不支持原版服务器,因为它在服务器端网络中使用了不同连接方式。", + "neoforge.network.extensible_enums.enum_set_mismatch": "客户端和服务器上的模组不匹配。请确保您使用的 NeoForge 版本与服务器上的版本相同。", + "neoforge.network.extensible_enums.enum_entry_mismatch": "客户端和服务器上所需要的模组不匹配。请确保您使用的模组和 NeoForge 版本与服务器上的版本相同。请查看日志以获取更多详细信息。" } diff --git a/src/main/resources/assets/neoforge/lang/zh_hk.json b/src/main/resources/assets/neoforge/lang/zh_tw.json similarity index 64% rename from src/main/resources/assets/neoforge/lang/zh_hk.json rename to src/main/resources/assets/neoforge/lang/zh_tw.json index e3a39d17ba..2f1eab530d 100644 --- a/src/main/resources/assets/neoforge/lang/zh_hk.json +++ b/src/main/resources/assets/neoforge/lang/zh_tw.json @@ -8,43 +8,43 @@ "fml.menu.mods.config": "設定", "fml.menu.mods.openmodsfolder": "開啟模組資料夾", "fml.menu.modoptions": "模組選項...", - "fml.menu.mods.info.version": "Version: %1$s", - "fml.menu.mods.info.idstate": "ModID: %1$s State: {1,lower}", - "fml.menu.mods.info.credits": "Credits: %1$s", - "fml.menu.mods.info.authors": "Authors: %1$s", - "fml.menu.mods.info.displayurl": "Homepage: %1$s", - "fml.menu.mods.info.license": "License: %1$s", + "fml.menu.mods.info.version": "版本:%1$s", + "fml.menu.mods.info.idstate": "模組 ID:%1$s 狀態:{1,lower}", + "fml.menu.mods.info.credits": "鳴謝:%1$s", + "fml.menu.mods.info.authors": "作者:%1$s", + "fml.menu.mods.info.displayurl": "首頁:%1$s", + "fml.menu.mods.info.license": "授權條款:%1$s", "fml.menu.mods.info.securejardisabled": "安全模組功能已被停用,請更新 JDK", - "fml.menu.mods.info.signature": "Signature: %1$s", + "fml.menu.mods.info.signature": "簽章:%1$s", "fml.menu.mods.info.signature.unsigned": "未簽署", - "fml.menu.mods.info.trust": "Trust: %1$s", + "fml.menu.mods.info.trust": "信任:%1$s", "fml.menu.mods.info.trust.noauthority": "無", "fml.menu.mods.info.nochildmods": "未發現子模組", - "fml.menu.mods.info.childmods": "Child mods: %1$s", - "fml.menu.mods.info.updateavailable": "Update available: %1$s", - "fml.menu.mods.info.changelogheader": "更新日誌:", - "fml.menu.multiplayer.compatible": "Compatible FML modded server\n{0,choice,1#1 mod|1<%1$s mods} present", + "fml.menu.mods.info.childmods": "子模組:%1$s", + "fml.menu.mods.info.updateavailable": "有更新可用:%1$s", + "fml.menu.mods.info.changelogheader": "變更紀錄:", + "fml.menu.multiplayer.compatible": "相容的 FML 模組伺服器\n已安裝 {0,choice,1#1 mod|1<%1$s mods} 個模組", "fml.menu.multiplayer.incompatible": "不相容 FML 模組伺服器", - "fml.menu.multiplayer.incompatible.extra": "Incompatible FML modded server\n%1$s", + "fml.menu.multiplayer.incompatible.extra": "不相容 FML 模組伺服器\n%1$s", "fml.menu.multiplayer.truncated": "由於協定大小限制,資料可能不準確。", "fml.menu.multiplayer.vanilla": "原版伺服器", "fml.menu.multiplayer.vanilla.incompatible": "不相容的原版伺服器", - "fml.menu.multiplayer.unknown": "Unknown server %1$s", + "fml.menu.multiplayer.unknown": "未知的伺服器 %1$s", "fml.menu.multiplayer.serveroutdated": "NeoForge 伺服器端網路版本太舊", "fml.menu.multiplayer.clientoutdated": "NeoForge 用戶端網路版本太舊", - "fml.menu.multiplayer.extraservermods": "伺服器有客戶端可能需要的附加模組", + "fml.menu.multiplayer.extraservermods": "伺服器有用戶端可能需要的額外模組", "fml.menu.multiplayer.modsincompatible": "伺服器模組清單不相容", "fml.menu.multiplayer.networkincompatible": "伺服器網路訊息清單不相容", - "fml.menu.multiplayer.missingdatapackregistries": "Missing required datapack registries: %1$s", - "fml.menu.branding": "%s (%s mods)", + "fml.menu.multiplayer.missingdatapackregistries": "缺少所需資料包登錄:%1$s", + "fml.menu.branding": "%s(%s 個模組)", "fml.menu.notification.title": "啟動提醒", - "fml.menu.accessdenied.title": "伺服器存取被拒絕", - "fml.menu.accessdenied.message": "Fancy Mod Loader could not connect to this server\nThe server %1$s has forbidden modded access", + "fml.menu.accessdenied.title": "伺服器存取被拒", + "fml.menu.accessdenied.message": "Fancy Mod Loader 無法連線到此伺服器\n伺服器 %1$s 禁止模組存取", "fml.menu.backupfailed.title": "備份失敗", - "fml.menu.backupfailed.message": "There was an error saving the archive %1$s\nPlease fix the problem and try again", - "fml.button.open.file": "Open %1$s", - "fml.button.open.log": "Open log file", - "fml.button.open.crashreport": "Open crash report", + "fml.menu.backupfailed.message": "儲存存檔 %1$s 時發生錯誤\n請修正這個問題,然後再試一次", + "fml.button.open.file": "開啟 %1$s", + "fml.button.open.log": "開啟記錄檔", + "fml.button.open.crashreport": "開啟崩潰報告", "fml.button.open.mods.folder": "開啟模組資料夾", "fml.button.continue.launch": "繼續前往標題畫面", "fml.modmismatchscreen.missingmods.client": "您的用戶端缺少下列模組,請安裝這些模組以加入此伺服器:", @@ -54,33 +54,33 @@ "fml.modmismatchscreen.table.youneed": "你需要", "fml.modmismatchscreen.table.youhave": "你擁有", "fml.modmismatchscreen.table.serverhas": "伺服器已安裝", - "fml.modmismatchscreen.additional": "[%1$s additional, see latest.log for the full list]", + "fml.modmismatchscreen.additional": "[還有 %1$s 個,查看 latest.log 取得完整清單]", "fml.modmismatchscreen.homepage": "點擊以前往這個模組的主頁", "fml.modmismatchscreen.table.reason": "原因", "fml.modmismatchscreen.table.visit.mod_page": "開啟登錄此頻道的模組(%s)頁面", - "fml.modmismatchscreen.simplifiedview": "Simplified view", - "fml.resources.modresources": "Resources for %1$s mod files", - "fml.resources.moddata": "Data for %1$s mod files", + "fml.modmismatchscreen.simplifiedview": "簡化檢視", + "fml.resources.modresources": "用於 %1$s 模組檔案的資源", + "fml.resources.moddata": "%1$s 模組檔案資料", "loadwarning.neoforge.prbuild": "這個 NeoForge 由社群成員建立,是 §c§l不受支援§r 的", - "commands.neoforge.arguments.enum.invalid": "Enum constant must be one of %1$s, found %2$s", + "commands.neoforge.arguments.enum.invalid": "枚舉常數必須是 %1$s 之一,找到 %2$s", "commands.neoforge.dimensions.list": "目前依照類型註冊的維度:", - "commands.neoforge.dump.success": "New file created with %s registry's contents is at %s", - "commands.neoforge.dump.failure": "Failed to create new file with %s registry's contents at %s", + "commands.neoforge.dump.success": "新建立的 %s 註冊檔案位於 %s", + "commands.neoforge.dump.failure": "無法建立 %s 註冊檔案於 %s", "commands.neoforge.dump.error.unknown_registry": "未知註冊表 '%s'", "commands.neoforge.entity.list.invalid": "無效的篩選器,與任何實體不相符。請使用 /neoforge entity list 以提供正確清單", - "commands.neoforge.entity.list.invalidworld": "Could not load world for dimension %1$s. Please select a valid dimension.", + "commands.neoforge.entity.list.invalidworld": "無法載入維度 %1$s 的世界。請選擇一個有效的維度。", "commands.neoforge.entity.list.none": "找不到實體。", - "commands.neoforge.entity.list.single.header": "Entity: %1$s Total: %2$s", - "commands.neoforge.entity.list.multiple.header": "Total: %1$s", - "commands.neoforge.setdim.invalid.entity": "The entity selected (%1$s) is not valid.", - "commands.neoforge.setdim.invalid.dim": "The dimension ID specified (%1$s) is not valid.", - "commands.neoforge.setdim.invalid.nochange": "The entity selected (%1$s) is already in the dimension specified (%2$s).", - "commands.neoforge.setdim.deprecated": "此指令以在 1.17 中被棄用,請使用 %s 代替。", - "commands.neoforge.tps.invalid": "Invalid dimension %1$s Possible values: %2$s", - "commands.neoforge.tps.summary.all": "Overall: Mean tick time: %1$s ms. Mean TPS: %2$s", - "commands.neoforge.mods.list": "Mod List: %1$s", - "commands.neoforge.tps.summary.basic": "Dim %1$s: Mean tick time: %2$s ms. Mean TPS: %3$s", - "commands.neoforge.tps.summary.named": "Dim %1$s (%2$s): Mean tick time: %3$s ms. Mean TPS: %4$s", + "commands.neoforge.entity.list.single.header": "實體:%1$s 總共:%2$s", + "commands.neoforge.entity.list.multiple.header": "總共:%1$s", + "commands.neoforge.setdim.invalid.entity": "所選實體 (%1$s) 無效。", + "commands.neoforge.setdim.invalid.dim": "指定的維度 ID (%1$s) 無效。", + "commands.neoforge.setdim.invalid.nochange": "所選實體 (%1$s) 已存在於指定的維度 (%2$s) 中。", + "commands.neoforge.setdim.deprecated": "這個指令已在 1.17 中被棄用,請使用 %s 代替。", + "commands.neoforge.tps.overall": "總體:%s TPS(%s 毫秒/刻)", + "commands.neoforge.tps.tooltip": "平均 TPS;數值越高越好。目標 TPS:%s", + "commands.neoforge.tps.dimension": "%s:%s TPS(%s 毫秒/刻)", + "commands.neoforge.tps.dimension.tooltip": "%s(維度類型:%s)", + "commands.neoforge.mods.list": "模組清單:%1$s", "commands.neoforge.tracking.entity.enabled": "實體追踪已啟用,時長 %d 秒。", "commands.neoforge.tracking.entity.reset": "實體計時資料已被清除!", "commands.neoforge.tracking.invalid": "無效的追蹤資料", @@ -101,8 +101,8 @@ "commands.neoforge.tags.element": "%s:%s", "commands.neoforge.tags.page_info": "%s ", "commands.neoforge.chunkgen.progress_bar_title": "正在生成區塊...", - "commands.neoforge.chunkgen.progress_bar_progress": "Generating %1$s chunks - ", - "commands.neoforge.chunkgen.progress_bar_errors": "(%1$s errors!)", + "commands.neoforge.chunkgen.progress_bar_progress": "正在生成 %1$s 個區塊 ", + "commands.neoforge.chunkgen.progress_bar_errors": "(%1$s 個錯誤!)", "commands.neoforge.chunkgen.already_running": "生成已在進行。請先執行 '/neoforge generate stop' 再開始新生成。", "commands.neoforge.chunkgen.started": "Generating %1$s chunks, in an area of %2$sx%3$s chunks (%4$sx%5$s blocks).", "commands.neoforge.chunkgen.success": "生成完畢!", @@ -115,154 +115,86 @@ "commands.neoforge.timespeed.query.default": "Time in %s flows normally (20 minutes per day).", "commands.neoforge.timespeed.set": "Set flow of time in %s to %sx (%s minutes per day).", "commands.neoforge.timespeed.set.default": "Set flow of time in %s to default (20 minutes per day).", + "commands.neoforge.data_components.list.error.held_stack_empty": "You are not holding any item", + "commands.neoforge.data_components.list.title": "Data components on %s:", + "commands.neoforge.data_components.list.entry": "\n - %s", + "commands.neoforge.data_components.list.entry.key_value": "%s: %s", + "commands.neoforge.data_components.list.tooltip.default": "Component %s holds its default value", + "commands.neoforge.data_components.list.tooltip.deleted": "Component %s with value %s was deleted", + "commands.neoforge.data_components.list.tooltip.modified": "Component %s was modified from %s to %s", + "commands.neoforge.data_components.list.tooltip.added": "Component %s was added with value %s", "commands.config.getwithtype": "%s 類型 %s 的配置在 %s 發現", "commands.config.noconfig": "%s 類型 %s 的配置未發現", "neoforge.update.beta.1": "%s警告:%s NeoForge 為測試版", "neoforge.update.beta.2": "可能會出現重大問題,請在回報問題之前進行核實。", "neoforge.update.newversion": "最新 NeoForge 版本可用:%s", "neoforge.menu.updatescreen.title": "模組更新", - "neoforge.configuration.uitext.title": "%s Configuration", - "neoforge.configuration.uitext.type.client": "Client Settings", - "neoforge.configuration.uitext.type.server": "Server Settings", - "neoforge.configuration.uitext.type.common": "Common settings", - "neoforge.configuration.uitext.type.startup": "Startup settings", - "neoforge.configuration.uitext.title.client": "%s Client Configuration", - "neoforge.configuration.uitext.title.server": "%s Server Configuration", - "neoforge.configuration.uitext.title.common": "%s Common Configuration", - "neoforge.configuration.uitext.title.startup": "%s Startup Configuration", - "neoforge.configuration.uitext.notonline": [ - { - "text": "Settings in here are determined by the server and cannot be changed while online.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notlan": [ - { - "text": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", - "color": "red" - } - ], - "neoforge.configuration.uitext.notloaded": [ - { - "text": "Settings in here are only available while a world is loaded.", - "color": "red" - } - ], - "neoforge.configuration.uitext.unsupportedelement": [ - { - "text": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", - "color": "red" - } - ], - "neoforge.configuration.uitext.longstring": [ - { - "text": "This value is too long to be edited in the UI. Please edit it in the config file.", - "color": "red" - } - ], + "neoforge.configuration.uitext.title": "%s 設定", + "neoforge.configuration.uitext.type.client": "用戶端設定", + "neoforge.configuration.uitext.type.server": "伺服器端設定", + "neoforge.configuration.uitext.type.common": "一般設定", + "neoforge.configuration.uitext.type.startup": "啟動設定", + "neoforge.configuration.uitext.title.client": "%s 用戶端設定", + "neoforge.configuration.uitext.title.server": "%s 伺服器端設定", + "neoforge.configuration.uitext.title.common": "%s 一般設定", + "neoforge.configuration.uitext.title.startup": "%s 啟動設定", + "neoforge.configuration.uitext.notonline": "Settings in here are determined by the server and cannot be changed while online.", + "neoforge.configuration.uitext.notlan": "Settings in here cannot be edited while your game is open to LAN. Please return to the main menu and load the world again.", + "neoforge.configuration.uitext.notloaded": "Settings in here are only available while a world is loaded.", + "neoforge.configuration.uitext.unsupportedelement": "This value cannot be edited in the UI. Please contact the mod author about providing a custom UI for it.", + "neoforge.configuration.uitext.longstring": "This value is too long to be edited in the UI. Please edit it in the config file.", "neoforge.configuration.uitext.section": "%s...", - "neoforge.configuration.uitext.sectiontext": "Edit", - "neoforge.configuration.uitext.breadcrumb": [ - { - "index": 0 - }, - { - "text": " > ", - "color": "gold", - "bold": true - }, - { - "index": 1 - } - ], - "neoforge.configuration.uitext.listelement": "%s:", - "neoforge.configuration.uitext.undo": "Undo", + "neoforge.configuration.uitext.sectiontext": "編輯", + "neoforge.configuration.uitext.breadcrumb.order": "%1$s %2$s %3$s", + "neoforge.configuration.uitext.breadcrumb.separator": ">", + "neoforge.configuration.uitext.listelement": "%s:", + "neoforge.configuration.uitext.undo": "取消復原", "neoforge.configuration.uitext.undo.tooltip": "Reverts changes on this screen only.", - "neoforge.configuration.uitext.reset": "Reset", + "neoforge.configuration.uitext.reset": "重設", "neoforge.configuration.uitext.reset.tooltip": "Reverts everything on this screen to its default value.", "neoforge.configuration.uitext.newlistelement": "+", "neoforge.configuration.uitext.listelementup": "⏶", "neoforge.configuration.uitext.listelementdown": "⏷", "neoforge.configuration.uitext.listelementremove": "❌", - "neoforge.configuration.uitext.rangetooltip": [ - { - "text": "\n\nRange: ", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - } - ], - "neoforge.configuration.uitext.filenametooltip": [ - { - "text": "File: \"", - "color": "gray" - }, - { - "index": 0, - "color": "gray" - }, - { - "text": "\"", - "color": "gray" - } - ], - "neoforge.configuration.uitext.common": "Common Options", - "neoforge.configuration.uitext.client": "Client Options", - "neoforge.configuration.uitext.server": "Server Options", - "neoforge.configuration.uitext.startup": "Startup Options", - "neoforge.configuration.uitext.restart.game.title": "Minecraft needs to be restarted", + "neoforge.configuration.uitext.rangetooltip": "範圍:%s", + "neoforge.configuration.uitext.filenametooltip": "檔案:\"%s\"", + "neoforge.configuration.uitext.common": "一般選項", + "neoforge.configuration.uitext.client": "用戶端選項", + "neoforge.configuration.uitext.server": "伺服器端選項", + "neoforge.configuration.uitext.startup": "啟動選項", + "neoforge.configuration.uitext.restart.game.title": "Minecraft 需要重新啟動", "neoforge.configuration.uitext.restart.game.text": "One or more of the configuration option that were changed will only take effect when the game is started.", - "neoforge.configuration.uitext.restart.server.title": "World needs to be reloaded", + "neoforge.configuration.uitext.restart.server.title": "世界需要重新載入", "neoforge.configuration.uitext.restart.server.text": "One or more of the configuration option that were changed will only take effect when the world is reloaded.", - "neoforge.configuration.uitext.restart.return": "Ignore", - "neoforge.configuration.uitext.restart.return.tooltip": [ - { - "text": "Your changes will have no effect until you restart!", - "color": "red", - "bold": true - } - ], - "neoforge.configuration.title": "NeoForge Configuration", - "neoforge.configuration.section.neoforge.client.toml": "Client settings", - "neoforge.configuration.section.neoforge.client.toml.title": "Client settings", - "neoforge.configuration.section.neoforge.common.toml": "Common settings", - "neoforge.configuration.section.neoforge.common.toml.title": "Common settings", - "neoforge.configuration.section.neoforge.server.toml": "Server settings", - "neoforge.configuration.section.neoforge.server.toml.title": "Server settings", + "neoforge.configuration.uitext.restart.return": "忽略", + "neoforge.configuration.uitext.restart.return.tooltip": "你的變更將於重啟遊戲後生效!", + "neoforge.configuration.title": "NeoForge 設定", + "neoforge.configuration.section.neoforge.client.toml": "用戶端設定", + "neoforge.configuration.section.neoforge.client.toml.title": "用戶端設定", + "neoforge.configuration.section.neoforge.common.toml": "一般設定", + "neoforge.configuration.section.neoforge.common.toml.title": "一般設定", + "neoforge.configuration.section.neoforge.server.toml": "伺服器端設定", + "neoforge.configuration.section.neoforge.server.toml.title": "伺服器端設定", "neoforge.configgui.advertiseDedicatedServerToLan": "Advertise Dedicated Server To LAN", "neoforge.configgui.advertiseDedicatedServerToLan.tooltip": "Set this to true to enable advertising the dedicated server to local LAN clients so that it shows up in the Multiplayer screen automatically.", "neoforge.configgui.forgeLightPipelineEnabled": "NeoForge Light Pipeline", "neoforge.configgui.forgeLightPipelineEnabled.tooltip": "啟用 NeoForge 方塊繪製管線 - 修復自訂模型的光照問題。", "neoforge.configgui.fullBoundingBoxLadders": "全邊界框梯子", - "neoforge.configgui.fullBoundingBoxLadders.tooltip": "將此設為 true 可以檢查整個實體的碰撞邊界框以尋找梯子,而不僅僅是它們所在的方塊。這會導致遊戲機制有明顯的不同,因此預設值是遵循原版的遊戲行為。預設值:false。", - "neoforge.configgui.logLegacyTagWarnings": "Log Legacy Tags", + "neoforge.configgui.fullBoundingBoxLadders.tooltip": "將這項選項設為 true 可以檢查整個實體的碰撞邊界框以尋找梯子,而不僅僅是它們所在的方塊。這會導致遊戲機制有明顯的不同,因此預設值是遵循原版的遊戲行為。預設值:false。", + "neoforge.configgui.logLegacyTagWarnings": "記錄舊版標籤", "neoforge.configgui.logLegacyTagWarnings.tooltip": "A config option mainly for developers. Logs out modded tags that are using the 'forge' namespace when running on integrated server. Defaults to DEV_SHORT.", - "neoforge.configgui.logUntranslatedConfigurationWarnings": "Log Untranslated Configuration Keys", + "neoforge.configgui.logUntranslatedConfigurationWarnings": "記錄未翻譯的設定鍵", "neoforge.configgui.logUntranslatedConfigurationWarnings.tooltip": "A config option mainly for developers. Logs out configuration values that do not have translations when running a client in a development environment.", - "neoforge.configgui.logUntranslatedItemTagWarnings": "Log Untranslated Item Tags", + "neoforge.configgui.logUntranslatedItemTagWarnings": "記錄未翻譯的物品標籤", "neoforge.configgui.logUntranslatedItemTagWarnings.tooltip": "A config option mainly for developers. Logs out modded item tags that do not have translations when running on integrated server. Format desired is tag.item.. for the translation key. Defaults to SILENCED.", "neoforge.configgui.permissionHandler": "Permission Handler", "neoforge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to neoforge:default_handler if no such handler with that name is registered.", "neoforge.configgui.removeErroringBlockEntities": "移除錯誤方塊實體", - "neoforge.configgui.removeErroringBlockEntities.tooltip": [ - "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringBlockEntities.tooltip": "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringBlockEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.removeErroringEntities": "移除錯誤實體", - "neoforge.configgui.removeErroringEntities.tooltip": [ - "Set this to true to remove any BlockEntity that throws an error in its update method instead of closing the server and reporting a crash log.\n\n", - { - "text": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", - "color": "red", - "bold": true - } - ], + "neoforge.configgui.removeErroringEntities.tooltip": "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log.", + "neoforge.configgui.removeErroringEntities.tooltip.warning": "BE WARNED THIS COULD SCREW UP EVERYTHING.\nUSE SPARINGLY.\nWE ARE NOT RESPONSIBLE FOR DAMAGES.", "neoforge.configgui.showLoadWarnings": "顯示加載警告", "neoforge.configgui.showLoadWarnings.tooltip": "若啟用,NeoForge 將顯示在載入過程中發生的任何警告。", "neoforge.configgui.useCombinedDepthStencilAttachment": "Use combined DEPTH_STENCIL Attachment", @@ -274,7 +206,7 @@ "neoforge.container.enchant.limitedEnchantability": "有限可附魔性", "neoforge.swim_speed": "游泳速度", "neoforge.name_tag_distance": "命名牌顯示距離", - "neoforge.creative_flight": "Creative Flight", + "neoforge.creative_flight": "創造模式飛行", "fluid_type.minecraft.milk": "奶", "fluid_type.minecraft.flowing_milk": "奶", "neoforge.froge.warningScreen.title": "NeoForge 快照提醒", From 6585d8906ebe9aff76dd85b3778b2f3eddf9dfd7 Mon Sep 17 00:00:00 2001 From: Matyrobbrt <65940752+Matyrobbrt@users.noreply.github.com> Date: Thu, 5 Sep 2024 07:21:23 +0300 Subject: [PATCH 056/125] [no ci] Bump JCC and use the custom Java version action (#1515) --- .github/workflows/build-prs.yml | 12 ++++-------- .github/workflows/check-local-changes.yml | 7 +++---- .github/workflows/test-prs.yml | 7 +++---- projects/neoforge/build.gradle | 6 ++++-- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-prs.yml b/.github/workflows/build-prs.yml index 32717e93ef..9d70bf8a29 100644 --- a/.github/workflows/build-prs.yml +++ b/.github/workflows/build-prs.yml @@ -31,17 +31,13 @@ jobs: run: git switch -C pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.ref }} - - name: Validate wrapper - uses: gradle/actions/wrapper-validation@v3 - - name: Setup JDK 21 - uses: actions/setup-java@v2 + uses: neoforged/actions/setup-java@main with: - java-version: '21' - distribution: 'temurin' + java-version: 21 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 with: cache-read-only: false @@ -58,4 +54,4 @@ jobs: uses: neoforged/action-jar-compatibility/upload@v1 - name: Publish artifacts - uses: neoforged/action-pr-publishing/upload@v1 + uses: neoforged/action-pr-publishing/upload@v1 \ No newline at end of file diff --git a/.github/workflows/check-local-changes.yml b/.github/workflows/check-local-changes.yml index f40a77a4cf..ef101ceacd 100644 --- a/.github/workflows/check-local-changes.yml +++ b/.github/workflows/check-local-changes.yml @@ -25,13 +25,12 @@ jobs: git switch -C pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.ref }} - name: Setup JDK 21 - uses: actions/setup-java@v2 + uses: neoforged/actions/setup-java@main with: - java-version: '21' - distribution: 'temurin' + java-version: 21 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 with: cache-read-only: false diff --git a/.github/workflows/test-prs.yml b/.github/workflows/test-prs.yml index 0fff8674c4..51afdcddad 100644 --- a/.github/workflows/test-prs.yml +++ b/.github/workflows/test-prs.yml @@ -29,13 +29,12 @@ jobs: git switch -C pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.ref }} - name: Setup JDK 21 - uses: actions/setup-java@v2 + uses: neoforged/actions/setup-java@main with: - java-version: '21' - distribution: 'temurin' + java-version: 21 - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@v4 with: cache-read-only: false diff --git a/projects/neoforge/build.gradle b/projects/neoforge/build.gradle index 0393b5455b..cb86838bb3 100644 --- a/projects/neoforge/build.gradle +++ b/projects/neoforge/build.gradle @@ -1,10 +1,11 @@ import net.neoforged.jarcompatibilitychecker.gradle.JCCPlugin +import net.neoforged.jarcompatibilitychecker.gradle.CompatibilityTask import net.neoforged.jarcompatibilitychecker.gradle.ProvideNeoForgeJarTask plugins { id 'java-library' id 'maven-publish' - id 'net.neoforged.jarcompatibilitychecker' version '0.1.9' + id 'net.neoforged.jarcompatibilitychecker' version '0.1.12' id 'net.neoforged.gradleutils' id 'neoforge.versioning' } @@ -23,7 +24,8 @@ dynamicProject { } final checkVersion = JCCPlugin.providePreviousVersion( - project.providers, project.providers.provider({['https://maven.neoforged.net/releases']}), project.providers.provider({'net.neoforged:neoforge'}) + project.providers, project.providers.provider({['https://maven.neoforged.net/releases']}), project.providers.provider({'net.neoforged:neoforge'}), + project.provider { project.version }.map { ver -> CompatibilityTask.VersionComponentTest.MINOR.predicate(ver) } ) final createCompatJar = tasks.register('createCompatibilityCheckJar', ProvideNeoForgeJarTask) { // Use the same jar that the patches were generated against From 1ab0f1972271fb5d0b6188094249f45b4978e9d0 Mon Sep 17 00:00:00 2001 From: Gigabit101 Date: Thu, 5 Sep 2024 05:23:53 +0100 Subject: [PATCH 057/125] Fix null pointer when stopping chunk pregeneration (#1514) --- .../neoforged/neoforge/server/command/GenerateCommand.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/server/command/GenerateCommand.java b/src/main/java/net/neoforged/neoforge/server/command/GenerateCommand.java index a37a5732b1..d3ef9c3f80 100644 --- a/src/main/java/net/neoforged/neoforge/server/command/GenerateCommand.java +++ b/src/main/java/net/neoforged/neoforge/server/command/GenerateCommand.java @@ -96,8 +96,10 @@ private static int stopGeneration(CommandSourceStack source) { double percent = (double) count / total * 100.0; source.sendSuccess(() -> Component.translatable("commands.neoforge.chunkgen.stopped", count, total, percent), true); - generationBar.close(); - generationBar = null; + if (generationBar != null) { + generationBar.close(); + generationBar = null; + } activeTask = null; } else { source.sendSuccess(() -> Component.translatable("commands.neoforge.chunkgen.not_running"), false); From baae1209c3e050829f1832ba7db6a220869ade98 Mon Sep 17 00:00:00 2001 From: Buuz135 Date: Thu, 5 Sep 2024 14:03:01 +0200 Subject: [PATCH 058/125] Add capability support for the Crafter output (#1506) --- .../world/level/block/CrafterBlock.java.patch | 11 +++++++++++ .../items/VanillaInventoryCodeHooks.java | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 patches/net/minecraft/world/level/block/CrafterBlock.java.patch diff --git a/patches/net/minecraft/world/level/block/CrafterBlock.java.patch b/patches/net/minecraft/world/level/block/CrafterBlock.java.patch new file mode 100644 index 0000000000..ac39be323e --- /dev/null +++ b/patches/net/minecraft/world/level/block/CrafterBlock.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/block/CrafterBlock.java ++++ b/net/minecraft/world/level/block/CrafterBlock.java +@@ -221,6 +_,8 @@ + break; + } + } ++ } else { ++ itemstack = net.neoforged.neoforge.items.VanillaInventoryCodeHooks.insertCrafterOutput(p_335887_, p_307620_, p_307387_, itemstack); + } + + if (!itemstack.isEmpty()) { diff --git a/src/main/java/net/neoforged/neoforge/items/VanillaInventoryCodeHooks.java b/src/main/java/net/neoforged/neoforge/items/VanillaInventoryCodeHooks.java index e1765da397..6085397554 100644 --- a/src/main/java/net/neoforged/neoforge/items/VanillaInventoryCodeHooks.java +++ b/src/main/java/net/neoforged/neoforge/items/VanillaInventoryCodeHooks.java @@ -10,6 +10,7 @@ import java.util.Optional; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.core.FrontAndTop; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntitySelector; import net.minecraft.world.item.ItemStack; @@ -17,10 +18,12 @@ import net.minecraft.world.level.block.DropperBlock; import net.minecraft.world.level.block.HopperBlock; import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.CrafterBlockEntity; import net.minecraft.world.level.block.entity.DispenserBlockEntity; import net.minecraft.world.level.block.entity.Hopper; import net.minecraft.world.level.block.entity.HopperBlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.phys.AABB; import net.neoforged.neoforge.capabilities.Capabilities; import org.apache.commons.lang3.tuple.ImmutablePair; @@ -121,6 +124,21 @@ public static boolean insertHook(HopperBlockEntity hopper) { .orElse(false); } + /** + * Added capability support for the Crafter dispensing the result + */ + public static ItemStack insertCrafterOutput(Level level, BlockPos pos, CrafterBlockEntity crafterBlockEntity, ItemStack stack) { + FrontAndTop frontAndTop = level.getBlockState(pos).getValue(BlockStateProperties.ORIENTATION); + return getAttachedItemHandler(level, pos, frontAndTop.front()) + .map(destinationResult -> { + IItemHandler itemHandler = destinationResult.getKey(); + Object destination = destinationResult.getValue(); + ItemStack remainder = putStackInInventoryAllSlots(crafterBlockEntity, destination, itemHandler, stack); + return remainder; + }) + .orElse(stack); + } + private static ItemStack putStackInInventoryAllSlots(BlockEntity source, Object destination, IItemHandler destInventory, ItemStack stack) { for (int slot = 0; slot < destInventory.getSlots() && !stack.isEmpty(); slot++) { stack = insertStack(source, destination, destInventory, stack, slot); From 03035313a4c7dae041101b5b870df4bd894367ff Mon Sep 17 00:00:00 2001 From: Apex <29412632+ApexModder@users.noreply.github.com> Date: Thu, 5 Sep 2024 15:11:28 +0100 Subject: [PATCH 059/125] [21.1] Pass along interaction had to ItemStack.onEntitySwing (#1499) --- .../world/entity/LivingEntity.java.patch | 2 +- .../common/extensions/IItemExtension.java | 16 +++++++++++++++- .../common/extensions/IItemStackExtension.java | 17 ++++++++++++++++- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/patches/net/minecraft/world/entity/LivingEntity.java.patch b/patches/net/minecraft/world/entity/LivingEntity.java.patch index eb260531d3..b22fc4915b 100644 --- a/patches/net/minecraft/world/entity/LivingEntity.java.patch +++ b/patches/net/minecraft/world/entity/LivingEntity.java.patch @@ -440,7 +440,7 @@ public void swing(InteractionHand p_21012_, boolean p_21013_) { + ItemStack stack = this.getItemInHand(p_21012_); -+ if (!stack.isEmpty() && stack.onEntitySwing(this)) return; ++ if (!stack.isEmpty() && stack.onEntitySwing(this, p_21012_)) return; if (!this.swinging || this.swingTime >= this.getCurrentSwingDuration() / 2 || this.swingTime < 0) { this.swingTime = -1; this.swinging = true; diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java index 1de3e6358d..0ae0cb4bc3 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java @@ -21,6 +21,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; +import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; @@ -336,12 +337,25 @@ default ResourceLocation getArmorTexture(ItemStack stack, Entity entity, Equipme * Called when a entity tries to play the 'swing' animation. * * @param entity The entity swinging the item. - * @return True to cancel any further processing by EntityLiving + * @return True to cancel any further processing by {@link LivingEntity} + * @deprecated To be replaced with hand sensitive version in 21.2 + * @see #onEntitySwing(ItemStack, LivingEntity, InteractionHand) */ + @Deprecated(forRemoval = true, since = "21.1") default boolean onEntitySwing(ItemStack stack, LivingEntity entity) { return false; } + /** + * Called when a entity tries to play the 'swing' animation. + * + * @param entity The entity swinging the item. + * @return True to cancel any further processing by {@link LivingEntity} + */ + default boolean onEntitySwing(ItemStack stack, LivingEntity entity, InteractionHand hand) { + return onEntitySwing(stack, entity); + } + /** * Return the itemDamage represented by this ItemStack. Defaults to the Damage * entry in the stack NBT, but can be overridden here for other sources. diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IItemStackExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IItemStackExtension.java index 8c9d46d8e8..f8c61d0bc9 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IItemStackExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IItemStackExtension.java @@ -12,6 +12,7 @@ import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; import net.minecraft.stats.Stats; +import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; @@ -217,12 +218,26 @@ default boolean canDisableShield(ItemStack shield, LivingEntity entity, LivingEn * Called when a entity tries to play the 'swing' animation. * * @param entity The entity swinging the item. - * @return True to cancel any further processing by EntityLiving + * @return True to cancel any further processing by {@link LivingEntity} + * @deprecated To be replaced with hand sensitive version in 21.2 + * @see #onEntitySwing(LivingEntity, InteractionHand) */ + @Deprecated(forRemoval = true, since = "21.1") default boolean onEntitySwing(LivingEntity entity) { return self().getItem().onEntitySwing(self(), entity); } + /** + * Called when a entity tries to play the 'swing' animation. + * + * @param entity The entity swinging the item. + * @param hand The hand the item is held in. + * @return True to cancel any further processing by {@link LivingEntity} + */ + default boolean onEntitySwing(LivingEntity entity, InteractionHand hand) { + return self().getItem().onEntitySwing(self(), entity, hand); + } + /** * Called when an entity stops using an item item for any reason. * From 0f411dd98a2bb8581e454adccb974358e9f6dd30 Mon Sep 17 00:00:00 2001 From: Josiah Glosson Date: Thu, 5 Sep 2024 13:19:22 -0500 Subject: [PATCH 060/125] JSON Entity Animations (#1476) --- .../client/model/HierarchicalModel.java.patch | 48 +++++ .../neoforge/client/ClientHooks.java | 10 +- .../neoforge/client/ClientNeoForgeMod.java | 2 + .../animation/AnimationKeyframeTarget.java | 16 ++ .../entity/animation/AnimationTarget.java | 59 ++++++ .../animation/json/AnimationHolder.java | 78 +++++++ .../animation/json/AnimationLoader.java | 77 +++++++ .../animation/json/AnimationParser.java | 193 ++++++++++++++++++ .../animation/json/AnimationTypeManager.java | 143 +++++++++++++ .../entity/animation/json/package-info.java | 13 ++ .../client/entity/animation/package-info.java | 13 ++ .../RegisterJsonAnimationTypesEvent.java | 60 ++++++ .../data/loading/DatagenModLoader.java | 2 + .../EntityModelSerializationTest.java | 29 +++ 14 files changed, 739 insertions(+), 4 deletions(-) create mode 100644 patches/net/minecraft/client/model/HierarchicalModel.java.patch create mode 100644 src/main/java/net/neoforged/neoforge/client/entity/animation/AnimationKeyframeTarget.java create mode 100644 src/main/java/net/neoforged/neoforge/client/entity/animation/AnimationTarget.java create mode 100644 src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationHolder.java create mode 100644 src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java create mode 100644 src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationParser.java create mode 100644 src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationTypeManager.java create mode 100644 src/main/java/net/neoforged/neoforge/client/entity/animation/json/package-info.java create mode 100644 src/main/java/net/neoforged/neoforge/client/entity/animation/package-info.java create mode 100644 src/main/java/net/neoforged/neoforge/client/event/RegisterJsonAnimationTypesEvent.java create mode 100644 tests/src/junit/java/net/neoforged/neoforge/unittest/EntityModelSerializationTest.java diff --git a/patches/net/minecraft/client/model/HierarchicalModel.java.patch b/patches/net/minecraft/client/model/HierarchicalModel.java.patch new file mode 100644 index 0000000000..b9e5a58ff6 --- /dev/null +++ b/patches/net/minecraft/client/model/HierarchicalModel.java.patch @@ -0,0 +1,48 @@ +--- a/net/minecraft/client/model/HierarchicalModel.java ++++ b/net/minecraft/client/model/HierarchicalModel.java +@@ -27,6 +_,10 @@ + super(p_170623_); + } + ++ protected static net.neoforged.neoforge.client.entity.animation.json.AnimationHolder getAnimation(ResourceLocation key) { ++ return net.neoforged.neoforge.client.entity.animation.json.AnimationLoader.INSTANCE.getAnimationHolder(key); ++ } ++ + @Override + public void renderToBuffer(PoseStack p_170625_, VertexConsumer p_170626_, int p_170627_, int p_170628_, int p_350603_) { + this.root().render(p_170625_, p_170626_, p_170627_, p_170628_, p_350603_); +@@ -44,18 +_,34 @@ + this.animate(p_233382_, p_233383_, p_233384_, 1.0F); + } + ++ protected void animate(AnimationState animationState, net.neoforged.neoforge.client.entity.animation.json.AnimationHolder animation, float ageInTicks) { ++ this.animate(animationState, animation.get(), ageInTicks); ++ } ++ + protected void animateWalk(AnimationDefinition p_268159_, float p_268057_, float p_268347_, float p_268138_, float p_268165_) { + long i = (long)(p_268057_ * 50.0F * p_268138_); + float f = Math.min(p_268347_ * p_268165_, 1.0F); + KeyframeAnimations.animate(this, p_268159_, i, f, ANIMATION_VECTOR_CACHE); + } + ++ protected void animateWalk(net.neoforged.neoforge.client.entity.animation.json.AnimationHolder animation, float limbSwing, float limbSwingAmount, float maxAnimationSpeed, float animationScaleFactor) { ++ this.animateWalk(animation.get(), limbSwing, limbSwingAmount, maxAnimationSpeed, animationScaleFactor); ++ } ++ + protected void animate(AnimationState p_233386_, AnimationDefinition p_233387_, float p_233388_, float p_233389_) { + p_233386_.updateTime(p_233388_, p_233389_); + p_233386_.ifStarted(p_233392_ -> KeyframeAnimations.animate(this, p_233387_, p_233392_.getAccumulatedTime(), 1.0F, ANIMATION_VECTOR_CACHE)); + } + ++ protected void animate(AnimationState animationState, net.neoforged.neoforge.client.entity.animation.json.AnimationHolder animation, float ageInTicks, float speed) { ++ this.animate(animationState, animation.get(), ageInTicks, speed); ++ } ++ + protected void applyStatic(AnimationDefinition p_288996_) { + KeyframeAnimations.animate(this, p_288996_, 0L, 1.0F, ANIMATION_VECTOR_CACHE); ++ } ++ ++ protected void applyStatic(net.neoforged.neoforge.client.entity.animation.json.AnimationHolder animation) { ++ this.applyStatic(animation.get()); + } + } diff --git a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java index c27d39a3de..8bc74f258c 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java @@ -137,6 +137,7 @@ import net.neoforged.fml.ModLoader; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.asm.enumextension.ExtensionInfo; +import net.neoforged.neoforge.client.entity.animation.json.AnimationTypeManager; import net.neoforged.neoforge.client.event.AddSectionGeometryEvent; import net.neoforged.neoforge.client.event.CalculateDetachedCameraDistanceEvent; import net.neoforged.neoforge.client.event.CalculatePlayerTurnEvent; @@ -950,7 +951,7 @@ public static boolean isBlockEntityRendererVisible(Block /** * Modify the position and UVs of the edge quads of generated item models to account for sprite expansion of the * front and back quad. Fixes MC-73186 on generated item models. - * + * * @param elements The generated elements, may include the front and back face * @param sprite The texture from which the elements were generated * @return the original elements list @@ -1036,13 +1037,14 @@ public static void initClientHooks(Minecraft mc, ReloadableResourceManager resou PresetEditorManager.init(); MapDecorationRendererManager.init(); DimensionTransitionScreenManager.init(); + AnimationTypeManager.init(); } /** * Fires {@link RenderFrameEvent.Pre}. Called just before {@link GameRenderer#render(float, long, boolean)} in {@link Minecraft#runTick(boolean)}. *

* Fired before the profiler section for "gameRenderer" is started. - * + * * @param partialTick The current partial tick */ public static void fireRenderFramePre(DeltaTracker partialTick) { @@ -1053,7 +1055,7 @@ public static void fireRenderFramePre(DeltaTracker partialTick) { * Fires {@link RenderFrameEvent.Post}. Called just after {@link GameRenderer#render(float, long, boolean)} in {@link Minecraft#runTick(boolean)}. *

* Fired after the profiler section for "gameRenderer" is ended. - * + * * @param partialTick The current partial tick */ public static void fireRenderFramePost(DeltaTracker partialRick) { @@ -1088,7 +1090,7 @@ public static RegistryLookup resolveLookup(ResourceKey * Called from {@link EffectRenderingInventoryScreen#renderEffects} just before {@link GuiGraphics#renderTooltip(Font, List, Optional, int, int)} is called. - * + * * @param screen The screen rendering the tooltip. * @param effectInst The effect instance whose tooltip is being rendered. * @param tooltip An immutable list containing the existing tooltip lines, which consist of the name and the duration. diff --git a/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java b/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java index b683378daa..071977233d 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java @@ -18,6 +18,7 @@ import net.neoforged.fml.ModContainer; import net.neoforged.fml.common.Mod; import net.neoforged.fml.config.ModConfigs; +import net.neoforged.neoforge.client.entity.animation.json.AnimationLoader; import net.neoforged.neoforge.client.event.ClientPlayerNetworkEvent; import net.neoforged.neoforge.client.event.ModelEvent; import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent; @@ -76,6 +77,7 @@ static void onRegisterGeometryLoaders(ModelEvent.RegisterGeometryLoaders event) @SubscribeEvent static void onRegisterReloadListeners(RegisterClientReloadListenersEvent event) { event.registerReloadListener(ObjLoader.INSTANCE); + event.registerReloadListener(AnimationLoader.INSTANCE); } @SubscribeEvent diff --git a/src/main/java/net/neoforged/neoforge/client/entity/animation/AnimationKeyframeTarget.java b/src/main/java/net/neoforged/neoforge/client/entity/animation/AnimationKeyframeTarget.java new file mode 100644 index 0000000000..cbbac5b2ca --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/entity/animation/AnimationKeyframeTarget.java @@ -0,0 +1,16 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.entity.animation; + +import org.joml.Vector3f; + +/** + * A function for transforming vectors into values that make sense to their keyframe's target. + */ +@FunctionalInterface +public interface AnimationKeyframeTarget { + Vector3f apply(float x, float y, float z); +} diff --git a/src/main/java/net/neoforged/neoforge/client/entity/animation/AnimationTarget.java b/src/main/java/net/neoforged/neoforge/client/entity/animation/AnimationTarget.java new file mode 100644 index 0000000000..a4d093e9af --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/entity/animation/AnimationTarget.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.entity.animation; + +import net.minecraft.client.animation.AnimationChannel; +import net.minecraft.client.animation.KeyframeAnimations; +import org.joml.Vector3f; + +/** + * Wrapper for a {@link AnimationChannel.Target} and a way to transform a simple keyframe vector into a vector that + * makes sense for the given target. + * + * @param channelTarget The associated {@link AnimationChannel.Target}. + * @param keyframeTarget An {@link AnimationKeyframeTarget} that transforms simple vectors into ones that make sense + * for the {@link #channelTarget}. + * @param inverseKeyframeTarget The inverse function of {@link #keyframeTarget}, used for serialization. + */ +public record AnimationTarget( + AnimationChannel.Target channelTarget, + AnimationKeyframeTarget keyframeTarget, + AnimationKeyframeTarget inverseKeyframeTarget) { + + public static final AnimationTarget POSITION = new AnimationTarget( + AnimationChannel.Targets.POSITION, + KeyframeAnimations::posVec, + KeyframeAnimations::posVec // It's its own inverse + ); + public static final AnimationTarget ROTATION = new AnimationTarget( + AnimationChannel.Targets.ROTATION, + KeyframeAnimations::degreeVec, + AnimationTarget::inverseDegreeVec); + public static final AnimationTarget SCALE = new AnimationTarget( + AnimationChannel.Targets.SCALE, + KeyframeAnimations::scaleVec, + AnimationTarget::inverseScaleVec); + private static Vector3f inverseDegreeVec(float x, float y, float z) { + return new Vector3f( + x / (float) (Math.PI / 180.0), + y / (float) (Math.PI / 180.0), + z / (float) (Math.PI / 180.0)); + } + + private static Vector3f inverseScaleVec(double x, double y, double z) { + return new Vector3f((float) (x + 1f), (float) (y + 1f), (float) (z + 1f)); + } + + @Override + public boolean equals(Object obj) { + return this == obj; + } + + @Override + public int hashCode() { + return System.identityHashCode(this); + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationHolder.java b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationHolder.java new file mode 100644 index 0000000000..1222a7efe3 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationHolder.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.entity.animation.json; + +import com.mojang.logging.LogUtils; +import java.util.Map; +import net.minecraft.client.animation.AnimationDefinition; +import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; + +/** + * Holds a single {@link AnimationDefinition} loaded from resource packs. Objects of this class will be automatically updated with new + * {@link AnimationDefinition}s on reload. + */ +public final class AnimationHolder { + public static final AnimationDefinition EMPTY_ANIMATION = new AnimationDefinition(0f, false, Map.of()); + + private static final Logger LOGGER = LogUtils.getLogger(); + + private final ResourceLocation key; + @Nullable + private AnimationDefinition value; + private boolean absentWarned; + + AnimationHolder(ResourceLocation key) { + this.key = key; + } + + void unbind() { + value = null; + absentWarned = false; + } + + void bind(AnimationDefinition value) { + this.value = value; + } + + /** + * Gets the key associated with this animation. + */ + public ResourceLocation key() { + return key; + } + + /** + * Gets the currently loaded animation. If the animation has not been loaded, returns {@link #EMPTY_ANIMATION}. + */ + public AnimationDefinition get() { + final var result = value; + if (result == null) { + if (!absentWarned) { + absentWarned = true; + LOGGER.warn("Missing entity animation {}", key); + } + return EMPTY_ANIMATION; + } + return result; + } + + /** + * Gets the currently loaded animation or null if it has not been loaded. + */ + @Nullable + public AnimationDefinition getOrNull() { + return value; + } + + /** + * Returns whether the animation has been loaded. + */ + public boolean isBound() { + return value != null; + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java new file mode 100644 index 0000000000..44debb35bf --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.entity.animation.json; + +import com.google.common.collect.MapMaker; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.mojang.logging.LogUtils; +import com.mojang.serialization.JsonOps; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import net.minecraft.client.animation.AnimationDefinition; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; +import net.minecraft.util.profiling.ProfilerFiller; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; + +/** + * A loader for entity animations written in JSON. You can also get parsed animations from this class. + */ +public final class AnimationLoader extends SimpleJsonResourceReloadListener { + private static final Logger LOGGER = LogUtils.getLogger(); + + public static final AnimationLoader INSTANCE = new AnimationLoader(); + + private final Map animations = new MapMaker().weakValues().concurrencyLevel(1).makeMap(); + @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") + private final List strongHolderReferences = new ArrayList<>(); + + private AnimationLoader() { + super(new Gson(), "animations/entity"); + } + + /** + * Gets a loaded {@link AnimationDefinition} with the specified {@code key}. + */ + @Nullable + public AnimationDefinition getAnimation(ResourceLocation key) { + final var holder = animations.get(key); + return holder != null ? holder.getOrNull() : null; + } + + /** + * Returns an {@link AnimationHolder} for an animation. If the specified animation has not been loaded, the holder + * will be unbound, but may be bound in the future. + */ + public AnimationHolder getAnimationHolder(ResourceLocation key) { + return animations.computeIfAbsent(key, AnimationHolder::new); + } + + @Override + protected void apply(Map animationJsons, ResourceManager resourceManager, ProfilerFiller profiler) { + animations.values().forEach(AnimationHolder::unbind); + strongHolderReferences.clear(); + int loaded = 0; + for (final var entry : animationJsons.entrySet()) { + try { + final var animation = AnimationParser.CODEC.parse(JsonOps.INSTANCE, entry.getValue()) + .getOrThrow(JsonParseException::new); + final var holder = getAnimationHolder(entry.getKey()); + holder.bind(animation); + strongHolderReferences.add(holder); + loaded++; + } catch (Exception e) { + LOGGER.error("Failed to load animation {}", entry.getKey(), e); + } + } + LOGGER.info("Loaded {} entity animations", loaded); + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationParser.java b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationParser.java new file mode 100644 index 0000000000..463f4da7b8 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationParser.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.entity.animation.json; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.KeyDispatchCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import it.unimi.dsi.fastutil.Pair; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; +import java.util.function.UnaryOperator; +import net.minecraft.client.animation.AnimationChannel; +import net.minecraft.client.animation.AnimationDefinition; +import net.minecraft.client.animation.Keyframe; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.ExtraCodecs; +import net.neoforged.neoforge.client.entity.animation.AnimationKeyframeTarget; +import net.neoforged.neoforge.client.entity.animation.AnimationTarget; +import org.joml.Vector3f; + +/** + * A parser for parsing JSON-based entity animation files. + */ +public final class AnimationParser { + /** + * {@snippet lang = JSON : "minecraft:rotation" + * } + */ + private static final Codec TARGET_CODEC = ResourceLocation.CODEC + .flatXmap( + name -> Optional.ofNullable(AnimationTypeManager.getTarget(name)) + .map(DataResult::success) + .orElseGet(() -> DataResult.error(() -> String.format( + Locale.ENGLISH, "Animation target '%s' not found. Registered targets: %s", + name, AnimationTypeManager.getTargetList()))), + target -> Optional.ofNullable(AnimationTypeManager.getTargetName(target)) + .map(DataResult::success) + .orElseGet(() -> DataResult.error(() -> String.format( + Locale.ENGLISH, "Unregistered animation target '%s'. Registered targets: %s", + target, AnimationTypeManager.getTargetList())))); + + /** + * {@snippet lang = JSON : "minecraft:linear" + * } + */ + private static final Codec INTERPOLATION_CODEC = ResourceLocation.CODEC + .flatXmap( + name -> Optional.ofNullable(AnimationTypeManager.getInterpolation(name)) + .map(DataResult::success) + .orElseGet(() -> DataResult.error(() -> String.format( + Locale.ENGLISH, "Animation interpolation '%s' not found. Registered interpolations: %s", + name, AnimationTypeManager.getInterpolationList()))), + target -> Optional.ofNullable(AnimationTypeManager.getInterpolationName(target)) + .map(DataResult::success) + .orElseGet(() -> DataResult.error(() -> String.format( + Locale.ENGLISH, "Unregistered animation interpolation '%s'. Registered interpolations: %s", + target, AnimationTypeManager.getInterpolationList())))); + + /** + * {@snippet lang = JSON : + * { + * "keyframes": [ + * { + * "timestamp": 0.5, + * "target": [22.5, 0.0, 0.0], + * "interpolation": "minecraft:linear" + * } + * ], + * "target": "minecraft:rotation" + * } + * } + */ + public static final MapCodec CHANNEL_CODEC = new KeyDispatchCodec<>( + "target", + TARGET_CODEC, + channel -> Optional.ofNullable(AnimationTypeManager.getTargetFromChannelTarget(channel.target())) + .map(DataResult::success) + .orElseGet(() -> DataResult.error(() -> String.format( + Locale.ENGLISH, "Unregistered animation channel target '%s'. Registered targets: %s", + channel.target(), AnimationTypeManager.getTargetList()))), + target -> DataResult.success( + Optional.ofNullable(AnimationTypeManager.getKeyframeCodec(target)) + .orElseGet(() -> keyframeCodec(target)) + .listOf() + .xmap( + keyframes -> new AnimationChannel(target.channelTarget(), keyframes.toArray(Keyframe[]::new)), + channel -> Arrays.asList(channel.keyframes())) + .fieldOf("keyframes"))); + + /** + * {@snippet lang = JSON : + * { + * "bone": "head", + * "keyframes": [ + * { + * "timestamp": 0.5, + * "target": [22.5, 0.0, 0.0], + * "interpolation": "minecraft:linear" + * } + * ], + * "target": "minecraft:rotation" + * } + * } + */ + private static final Codec> NAMED_CHANNEL_CODEC = RecordCodecBuilder.create( + instance -> instance.group( + Codec.STRING.fieldOf("bone").forGetter(Pair::key), + CHANNEL_CODEC.forGetter(Pair::value)).apply(instance, Pair::of)); + + /** + * {@snippet lang = JSON : + * { + * "length": 1.125, + * "loop": true, + * "animations": [ + * { + * "bone": "head", + * "keyframes": [ + * { + * "timestamp": 0.5, + * "target": [22.5, 0.0, 0.0], + * "interpolation": "minecraft:linear" + * } + * ] + * } + * ] + * } + * } + */ + public static final Codec CODEC = RecordCodecBuilder.create( + instance -> instance.group( + Codec.FLOAT.fieldOf("length").forGetter(AnimationDefinition::lengthInSeconds), + Codec.BOOL.optionalFieldOf("loop", false).forGetter(AnimationDefinition::looping), + NAMED_CHANNEL_CODEC.listOf() + .>>xmap( + list -> { + final var result = new HashMap>(); + for (final var animation : list) { + result.computeIfAbsent(animation.key(), k -> new ArrayList<>()).add(animation.value()); + } + return result; + }, + map -> { + final var result = new ArrayList>(); + for (final var entry : map.entrySet()) { + for (final var channel : entry.getValue()) { + result.add(Pair.of(entry.getKey(), channel)); + } + } + return result; + }) + .fieldOf("animations") + .forGetter(AnimationDefinition::boneAnimations)) + .apply(instance, AnimationDefinition::new)); + + private AnimationParser() {} + + /** + * {@snippet lang = JSON : + * { + * "timestamp": 0.5, + * "target": [22.5, 0.0, 0.0], + * "interpolation": "minecraft:linear" + * } + * } + */ + static Codec keyframeCodec(AnimationTarget target) { + return RecordCodecBuilder.create( + instance -> instance.group( + Codec.FLOAT.fieldOf("timestamp").forGetter(Keyframe::timestamp), + ExtraCodecs.VECTOR3F + .xmap( + keyframeTargetToUnaryOp(target.keyframeTarget()), + keyframeTargetToUnaryOp(target.inverseKeyframeTarget())) + .fieldOf("target") + .forGetter(Keyframe::target), + INTERPOLATION_CODEC.fieldOf("interpolation").forGetter(Keyframe::interpolation)).apply(instance, Keyframe::new)); + } + + private static UnaryOperator keyframeTargetToUnaryOp(AnimationKeyframeTarget target) { + return vec -> target.apply(vec.x, vec.y, vec.z); + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationTypeManager.java b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationTypeManager.java new file mode 100644 index 0000000000..7e309bcdab --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationTypeManager.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.entity.animation.json; + +import com.google.common.collect.ImmutableBiMap; +import com.google.common.collect.ImmutableMap; +import com.mojang.serialization.Codec; +import java.util.function.Function; +import java.util.stream.Collectors; +import net.minecraft.client.animation.AnimationChannel; +import net.minecraft.client.animation.Keyframe; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.fml.ModLoader; +import net.neoforged.neoforge.client.entity.animation.AnimationTarget; +import net.neoforged.neoforge.client.event.RegisterJsonAnimationTypesEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +/** + * Manager for custom {@link AnimationTarget}s and {@link AnimationChannel.Interpolation interpolation function}s. + *

+ * The built-in {@link AnimationTarget}s are: {@code minecraft:position}, {@code minecraft:rotation}, and + * {@code minecraft:scale}. + *

+ * The built-in {@link AnimationChannel.Interpolation interpolation function}s are {@code minecraft:linear} and + * {@code minecraft:catmullrom}. + */ +public final class AnimationTypeManager { + private static final ImmutableBiMap DEFAULT_TARGETS = ImmutableBiMap.of( + ResourceLocation.withDefaultNamespace("position"), AnimationTarget.POSITION, + ResourceLocation.withDefaultNamespace("rotation"), AnimationTarget.ROTATION, + ResourceLocation.withDefaultNamespace("scale"), AnimationTarget.SCALE); + private static final ImmutableBiMap DEFAULT_INTERPOLATIONS = ImmutableBiMap.of( + ResourceLocation.withDefaultNamespace("linear"), AnimationChannel.Interpolations.LINEAR, + ResourceLocation.withDefaultNamespace("catmullrom"), AnimationChannel.Interpolations.CATMULLROM); + + private static ImmutableBiMap TARGETS = DEFAULT_TARGETS; + private static ImmutableMap TARGETS_BY_CHANNEL_TARGET = ImmutableMap.of(); + private static ImmutableMap> KEYFRAME_CODECS = ImmutableMap.of(); + private static ImmutableBiMap INTERPOLATIONS = DEFAULT_INTERPOLATIONS; + private static String TARGET_LIST = ""; + private static String INTERPOLATION_LIST = ""; + + static { + recomputeDerivedFields(); + } + + private AnimationTypeManager() {} + + /** + * Gets the {@link AnimationTarget} associated with the given {@code name}. + */ + @Nullable + public static AnimationTarget getTarget(ResourceLocation name) { + return TARGETS.get(name); + } + + /** + * Gets the {@link ResourceLocation} associated with the given {@code target}. + */ + @Nullable + public static ResourceLocation getTargetName(AnimationTarget target) { + return TARGETS.inverse().get(target); + } + + /** + * Gets the full {@link AnimationTarget} from its {@link AnimationTarget#channelTarget() channelTarget}. + */ + @Nullable + public static AnimationTarget getTargetFromChannelTarget(AnimationChannel.Target target) { + return TARGETS_BY_CHANNEL_TARGET.get(target); + } + + /** + * Gets the {@link Codec} used to decode a {@link Keyframe} with the specified {@link AnimationTarget}. + */ + @Nullable + public static Codec getKeyframeCodec(AnimationTarget target) { + return KEYFRAME_CODECS.get(target); + } + + /** + * Gets the {@link AnimationChannel.Interpolation interpolation function} associated with the given {@code name}. + */ + @Nullable + public static AnimationChannel.Interpolation getInterpolation(ResourceLocation name) { + return INTERPOLATIONS.get(name); + } + + /** + * Gets the {@link ResourceLocation} associated with the given {@code interpolation}. + */ + @Nullable + public static ResourceLocation getInterpolationName(AnimationChannel.Interpolation interpolation) { + return INTERPOLATIONS.inverse().get(interpolation); + } + + /** + * Retrieves a comma-separated list of all available {@link AnimationTarget}s, for use in error messages. + */ + public static String getTargetList() { + return TARGET_LIST; + } + + /** + * Retrieves a comma-separated list of all available + * {@link AnimationChannel.Interpolation interpolation function}s, for use in error messages. + */ + public static String getInterpolationList() { + return INTERPOLATION_LIST; + } + + @ApiStatus.Internal + public static void init() { + final var targets = ImmutableBiMap.builder().putAll(DEFAULT_TARGETS); + final var interpolations = ImmutableBiMap.builder().putAll(DEFAULT_INTERPOLATIONS); + final var event = new RegisterJsonAnimationTypesEvent(targets, interpolations); + ModLoader.postEventWrapContainerInModOrder(event); + TARGETS = targets.buildOrThrow(); + INTERPOLATIONS = interpolations.buildOrThrow(); + recomputeDerivedFields(); + } + + private static void recomputeDerivedFields() { + TARGETS_BY_CHANNEL_TARGET = TARGETS.values() + .stream() + .collect(ImmutableMap.toImmutableMap(AnimationTarget::channelTarget, Function.identity())); + KEYFRAME_CODECS = TARGETS.values() + .stream() + .collect(ImmutableMap.toImmutableMap(Function.identity(), AnimationParser::keyframeCodec)); + TARGET_LIST = TARGETS.keySet() + .stream() + .map(ResourceLocation::toString) + .collect(Collectors.joining(", ")); + INTERPOLATION_LIST = INTERPOLATIONS.keySet() + .stream() + .map(ResourceLocation::toString) + .collect(Collectors.joining(", ")); + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/entity/animation/json/package-info.java b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/package-info.java new file mode 100644 index 0000000000..1f3500287e --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/package-info.java @@ -0,0 +1,13 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +@FieldsAreNonnullByDefault +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package net.neoforged.neoforge.client.entity.animation.json; + +import javax.annotation.ParametersAreNonnullByDefault; +import net.minecraft.FieldsAreNonnullByDefault; +import net.minecraft.MethodsReturnNonnullByDefault; diff --git a/src/main/java/net/neoforged/neoforge/client/entity/animation/package-info.java b/src/main/java/net/neoforged/neoforge/client/entity/animation/package-info.java new file mode 100644 index 0000000000..c8fda9c36c --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/entity/animation/package-info.java @@ -0,0 +1,13 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +@FieldsAreNonnullByDefault +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package net.neoforged.neoforge.client.entity.animation; + +import javax.annotation.ParametersAreNonnullByDefault; +import net.minecraft.FieldsAreNonnullByDefault; +import net.minecraft.MethodsReturnNonnullByDefault; diff --git a/src/main/java/net/neoforged/neoforge/client/event/RegisterJsonAnimationTypesEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RegisterJsonAnimationTypesEvent.java new file mode 100644 index 0000000000..7bbcf12031 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/event/RegisterJsonAnimationTypesEvent.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import com.google.common.collect.ImmutableMap; +import java.util.HashMap; +import java.util.Map; +import net.minecraft.client.animation.AnimationChannel; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.bus.api.Event; +import net.neoforged.fml.event.IModBusEvent; +import net.neoforged.neoforge.client.entity.animation.AnimationTarget; +import org.jetbrains.annotations.ApiStatus; + +/** + * Allows registering custom {@link AnimationTarget}s and + * {@link AnimationChannel.Interpolation interpolation function}s for loading JSON entity animation files. + */ +public class RegisterJsonAnimationTypesEvent extends Event implements IModBusEvent { + private final ImmutableMap.Builder targets; + private final ImmutableMap.Builder interpolations; + private final Map registeredTargets = new HashMap<>(); + private final Map registeredInterpolations = new HashMap<>(); + + @ApiStatus.Internal + public RegisterJsonAnimationTypesEvent( + ImmutableMap.Builder targets, + ImmutableMap.Builder interpolations) { + this.targets = targets; + this.interpolations = interpolations; + } + + /** + * Register a custom {@link AnimationTarget} with the specified {@code key}. + */ + public void registerTarget(ResourceLocation key, AnimationTarget target) { + checkDuplicate("target", key, registeredTargets, target); + targets.put(key, target); + } + + /** + * Register a custom {@link AnimationChannel.Interpolation interpolation function} with the specified {@code key}. + */ + public void registerInterpolation(ResourceLocation key, AnimationChannel.Interpolation interpolation) { + checkDuplicate("interpolation", key, registeredInterpolations, interpolation); + interpolations.put(key, interpolation); + } + + private static void checkDuplicate(String what, ResourceLocation key, Map by, T obj) { + final var prevObj = by.putIfAbsent(key, obj); + if (prevObj != null) { + throw new IllegalStateException( + "Duplicate " + what + " registration for " + key + ". " + + obj + " tried to overwrite " + prevObj + "."); + } + } +} diff --git a/src/main/java/net/neoforged/neoforge/data/loading/DatagenModLoader.java b/src/main/java/net/neoforged/neoforge/data/loading/DatagenModLoader.java index 583269b9cf..687dc8dd71 100644 --- a/src/main/java/net/neoforged/neoforge/data/loading/DatagenModLoader.java +++ b/src/main/java/net/neoforged/neoforge/data/loading/DatagenModLoader.java @@ -16,6 +16,7 @@ import net.minecraft.server.Bootstrap; import net.neoforged.fml.ModLoader; import net.neoforged.neoforge.client.ClientHooks; +import net.neoforged.neoforge.client.entity.animation.json.AnimationTypeManager; import net.neoforged.neoforge.common.data.ExistingFileHelper; import net.neoforged.neoforge.data.event.GatherDataEvent; import net.neoforged.neoforge.internal.CommonModLoader; @@ -55,6 +56,7 @@ public static void begin(final Set mods, final Path path, final Collecti } if (clientGenerators) { ClientHooks.registerSpriteSourceTypes(); + AnimationTypeManager.init(); } existingFileHelper = new ExistingFileHelper(existingPacks, existingMods, structureValidator, assetIndex, assetsDir); ModLoader.runEventGenerator(mc -> new GatherDataEvent(mc, dataGeneratorConfig.makeGenerator(p -> dataGeneratorConfig.isFlat() ? p : p.resolve(mc.getModId()), diff --git a/tests/src/junit/java/net/neoforged/neoforge/unittest/EntityModelSerializationTest.java b/tests/src/junit/java/net/neoforged/neoforge/unittest/EntityModelSerializationTest.java new file mode 100644 index 0000000000..ee201e6909 --- /dev/null +++ b/tests/src/junit/java/net/neoforged/neoforge/unittest/EntityModelSerializationTest.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.unittest; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.mojang.serialization.JsonOps; +import net.minecraft.client.animation.definitions.BreezeAnimation; +import net.neoforged.neoforge.client.entity.animation.json.AnimationParser; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; + +/** + * Tests that animations can be serialized into json and deserialized to be identical to the original. + */ +@TestMethodOrder(MethodOrderer.MethodName.class) +public class EntityModelSerializationTest { + @Test + void breezeRoundTripTest() { + final var beforeSerialize = BreezeAnimation.JUMP; + final var serialized = AnimationParser.CODEC.encodeStart(JsonOps.INSTANCE, beforeSerialize).getOrThrow(); + final var afterDeserialize = AnimationParser.CODEC.parse(JsonOps.INSTANCE, serialized).getOrThrow(); + assertThat(afterDeserialize).usingRecursiveComparison().isEqualTo(beforeSerialize); + } +} From 84794f34ea45651bee91b604ee3fe2d6345e3837 Mon Sep 17 00:00:00 2001 From: Marc Hermans Date: Sun, 8 Sep 2024 10:23:38 +0200 Subject: [PATCH 061/125] Update to the latest NeoGradle (#1518) --- gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 7 +++++-- gradlew.bat | 2 ++ projects/neoforge/build.gradle | 4 ++-- settings.gradle | 2 +- tests/build.gradle | 11 ++++++----- 7 files changed, 17 insertions(+), 11 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba8a0da8d277868979cfbc8ad796..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch delta 12612 zcmY+pRa6|n(lttO3GVLh?(Xh3xVuAe26uONcL=V5;I6?T_zdn2`Oi5I_gl9gx~lft zRjVKRp?B~8Wyrx5$mS3|py!Njy{0Wt4i%@s8v88pK z6fPNA45)|*9+*w5kcg$o)}2g}%JfXe6l9ig4T8ia3Hlw#3f^fAKW63%<~GZJd-0YA z9YjleCs~#Y?V+`#nr+49hhsr$K$k!lg}AZDw@>2j=f7t~5IW6#K|lAX7|^N}lJ)I!km`nrwx> z))1Es16__aXGVzQM0EC8xH+O!nqTFBg9Ci{NwRK*CP<6s`Gq(~#lqb(zOlh6ZDBK* zr$|NDj^s6VanrKa+QC;5>twePaexqRI%RO~OY075y?NN90I|f^(P# zF=b>fZ73b5JzD`#GC3lTQ_B3lMeBWgQUGYnFw*HQC}^z{$6G4j(n4y-pRxPT(d2Wgb%vCH(?+t&Pj z)QM`zc`U`+<~D+9E{4Uj2kc#*6eZMU$4Oj6QMfA^K!rbl`iBix=2sPrs7j@aqIrE zTaZJ2M09>rp$mgyUZ!r2$UK{+DGqgl`n;*qFF~M(r#eh`T{MO?2&j?xgr8FU$u3-` zhRDc_I23LL4)K&xg$^&l-W=!Jp-P(_Ie07q>Je;QLxi8LaEc%;WIacJD_T69egF?7 z;I_Sg_!+qrur8$Hq4grigaiVF>U7uWJ@Hkd&%kmFnQN-P^fq0gB1|uRt!U#X;DnlV zo?yHWTw7g5B;#xxY`adhi4yZn@f(7-Xa(J6S=#d@&rlFw!qfvholE>MEb|VWn^g}G zMSrK&zQ^vDId&ojL!{%{o7?s{7;{+u%L{|tar(gp?Uxq3p?xAysB>0E$eG#$tvkk9 z2Q2gEP17{U6@UD*v({5MP-CTZfvWMItVjb4c;i~WLq&{?Q1(koX&vt7+$z}10{^Id z{KDjGi0JpD7@;~odF__0m|p;5rIrHidOP9^mwKe#-&JX-X@acc)06G{LO1Wu)#gvZ za~y9(fhA%UwkDOVU1LBJ`0ROE z4&)dJKK%mG@+CIm?+wt9f~@xIMr8}UH*K1j| z0pppo{7gv3v{URwxVMeg>Ps!L5IKxm zjac2egjgb0vH5i75$s|sY_RYec#>faqJk|AGgV;v=^%BM(^p{p;(^SVt-88G9f!q; z>p}9E4^f0=01S2pQBE4}9YqE%TV)*hlU^8k9{&=K76+*Ax^r=AkBb%OCP^P2nm0Ri z;D-|Zk?gGeU<12ti2CnPVNA(Pb)02+r|&yTWW-OJO7 zNLb0pps6aN?A~NJp5kj{{IOlf!5KWMleV@-hYLift)D>-7K+tgs=7Ake}oBnIy-y1 z(Hn@Hjw=_(x>dO5ysQsrnE%A*bk0K<-j{1Yqz@#n#jOL^AzCr#wR|WYzqk6i7v)Lf zkXdKxzuu20aP{Tbg$(+9&oh7cd(Uoqqf<#ujb$q4sZ~gxFbQfS zS)kNklyL*{2AELgjZ(LBu*>S(oH5AaJ;YiB@;l@=O%F6B?oanzoYRM^fQ9-<~^=3$H0g^JPMLQo@SZ@QuNvy)tyJ)LSj`+()#fy?{aV4Yg^7dlQ7AQM^3GLCR2dAFR zJjtfKiVqF`l-H_fz0HD|9g>)pOxn}k!vdZ=DO!7Sikm{Z%P6BrRkBS6W?ZB5W&7rT z@uYpf@M@a!z7H&o@-yrcCL^Ff3e7p3T`R9p?@o-acXmbTSa0>ZANzCSgovsd%;i$| zVus`not!oL#(W`L-!9w0jdaECaG4hk{V7IOs676ZquZH~0TX5hDq|)x z6T497l|E?f4)LA>j=S8}b$0LS=I4h|hUFJYJODT8Li@#6kF$k0)@*l{RnM1HQ%?VT ze-Pqlc!~t(oumVC*?5fwR;P6u{tHaZ~*LlD;B)4f? z?lpWfa2P@)g57flVl83Ej%P`2)gGyaPjhvD(%i~{`2b>#3!+y&` z!2nuwHMFA-zUY}f1^0B8<`N)Gr=A4TS@b1qykmd0Pq{?r)+1^^+D(=xasb^Tf!oK9 zBLL+*p6M_#ufgLzgq1zcSwZsZnQWFLC3`Yxdg-2=*tT`J9nrfYt)RF)YryBf8_gW{ zvKbB+oZLehfT)S#<|y1)E0hW^?+AnqPXq9Hu;v3dsMGdr{SVyF63;K<8VcgI#~}1i zLYSBL0K;RTT(;>2x=*!1Di9w0mwr;`CN}kM65|Ay{~z}_^JKOsRaN<~#9O^iiW<5P zYN7r~HV!#Nz~IZU`P>1Xe%4f~K}KcF#X&5kO*G}-)74S*tQ8CietdPcA1Yl;S=Mr# z`#MYY!{s^uo=jn7;k6O%(}fN+*0cWMpt~#n9DR<3NyU?+3D^AgI}S)Cu-Tljg`VY} zX1=fq$?8$DtOeGxE6f8lbS_6Q3C4+LDTO$}_IpM$Xv<|QSC%+Oll^q$y`7o@jD{dp zNDl|&X)r7wETa-#h*d`KXntxI(Y{vLha{$0i7@G8xx^m=c<{lJ9?p-i!^W{%j7-oo z0W^SzZ^(Wkyz*We{lEn%Yhu-ycUOHtrRiVJL4~&S91*D0MrLu}Q>v-Mc?GcWfpyz% zX|UvcN@krFO#@v|CtYM}g|=L3%aMo$E5<@CM%c*;?u>LOTz00@+dt1{yg1y=$h+{|D17U}$*^fE^H&8b431EUE z<9tv0V_#%#&1N#j7AKCj!tTK@J%oFW*ESW<(#Gl#Xs%v<@AitI?s92nLzm<)w3Wkkom1f$gcdUi%g_*jofy&}N#luL<$GVIe{iQkQ)sIHVy zBgItnPBFamrv6Kb{eE($Q(f`ZPeW!Hm%Y@F*OF1sKB{Yy|C>WEv_mfvv-N-jh)B-5 z4a!1WcT@9a+hGaBrc~sz=>G?Q!*Zp^JFRUvBMyNR1;`)j$RhH$6gEyVKhd$&K-CFT zXaWC-Y=fyOnqT84iMn9o5oLEOI(_3fk!W^8-74|q1QhQ|CmT0i=b;6Z3u?E{p7V{? z;f#Q-33!L+4&QQcZ~GAqu$NS{M;u%`+#9=7^Oa5PKvCCCWNG_~l(CidS!+xr-*gg{ z$UQ`_1tLT_9jB=Hckkwu>G{s0b0F4bnR7GibmHo?>TR&<3?D;5Fb#gd8*wYa$$~ar z7epl1qM)L{kwiNjQk}?)CFpNTd?0wAOUZ|gC{Ub|c-7h~+Rm(JbdoRe!RNVBQi!M8 z+~U6E2X&KSA*T6KJvsqwqZl#1&==Dm(#b^&VAKQ>7ygv*Fyr;)q9*^F@dCTg2g!w~ z%hg)UXAUyIpIbLXJv1nZX+a_C)BOH2hUim|>=JHCRf(!dtTidb&*~I!JrfRe+PO>w z@ox$G2a3i9d_N9J=|2$y2m-P&#PTNwe!oLBZFs;z|F5kXvBDn<)WwE0E3$ow=zg3R zK(9;sf0t;VEV3@gAg7jRtnj%-6O@!Hvg*;XcUAw}!=2*aErvB(eQIm(-UGmq^J=XN zTqJo$Y|WKo^HlBF3BXJrA#}7ZLg=r*w`I*~Ix`o&2k8^(0mt8Rp=A>F`&gehhp@Jy z^e^#B2!~$LvNCKugg)8)-G%&THdk~kfextilegP9?#C#()F59U$&eo(h|5>ceo*Em z{PEE79T$YP|Kr7K`WBHbtQwyxFkCl6xX&+oUf90B5xoi3_5KHHCyEE*oPbOQkfMz& z6^hT8_NXd2iWk{q9IKae1{_7hMPH8I7_BMtVOM4 z6jm?E0QJOn$qrgsJ`9w##GB9?G})-GXSQo6(tYS(Q0-Ct$co?Zzl0?NHsDRron?;_ zZZgQg)%XW>P?8_&zoGuF(>Och2kEJXsu1_X&~w87x!b z>~h!a>e7{`p@+#hXF88wI*JeWRZ;J4ev4<}HWf|Z;(7$E!S5l9wzBHFe>^I{2`a;a)QnAwa2xv1e(bq$<}!8o^ofGvYpk7dBR+`*%iE;hUY5 zaHF}OjGO9r*{%lmcK^uFiTHgoUD`^9Nx@~;Bg!V* zuuJ&ti{DQiq7RyJAR94wem{}cPK1J(Yxnn_{=>?USqz-~&QXRStS^s-7TksZ$AEI! z#og36s3JGtGU{CnDHRFtipFqvrE*gw7_K@NN0h+ItTq@4fqN!HeQU1y7*X?9+IfZT4Vxebpt z%#VzgdDK~-&+=Z*#>=n#XUhNvBZp3=Cr41jMqwJkHLf3L7Vm~V#GgJ(Jpii~PmJ#s zA7Ft!{xD@z>9DUb4JbiUBdNEcU4BO$651iN*mp*f)HbRRM`Cx5cR?5IfEcU{IZWwf zz(M6CDv)>xa3x}K6%tP^i15P1&&DOLK=k~+jNR$UK3frSl+|PjSC-dBItvD~LL! z>_g(YYdO4k(5EbPOw+v+;G7~jYm>F@Ai|o`gs%F)F8tDz$dl7Q%aCe|v|$UkAul_R zNlA-beBX^IJU?kgS`E$it7nF4DaI!SJAGq)2P&Few(-|tp z?K+%D3e4{pfkayrcbm0ftu6Ol2ZzdKM+4i!hNP3NRL`EvvZJ3yvNr2MV%igZ4kj``Qrdb_OI$7jWP z;l0DYf&0(-*QcP5zrP`HVznW+SbH63Qx$7_9~NjRNg7eKqI!UJ=XH`g^=t8GiFTu( z?2L{JKEu%jJx&XjNzU(*!ZNmL1@RlJA0G$2_LrAb_7lmjil(GSlSM zwTes`m+3R;3#N~Xg#9owh3ycXV8@ZlaY_16kpPFA={721b~URO4HD3sp%fmkZM}k) zZB0#)kP=RkNB~R-MCk8aljG_bagt4vIb~8)BV%(b8_;)&Kf9GX+%O_cNG|(D$!3&D zL(I8}*LqN5NntipFlN13=`D>6!{D@CFMBH0kW3=HccJV+xW~|$qeFR5i-2{X+iWMu zI2$gepQ)H_B%ip_BlWOQ*|pErXs|4ir{IHccgaIJ84irE{?+$KDABXr&f`jB^V-c% z$$u`uU1YB^{<+UN2cNg#7&0bz@yF?5>j|;)5&IV3wIQp58X#OE-M^$HdyvL|Um5t? zhZlAG!Mz%XkUe3t471JM*Yur}o30vzu6RN7gJyNcf!IItsDO730mcJ*O!~V``y5=3 zNJGp34DZ}wd1H6V`Uuy%es>BiO_aE-S8jzir#$& zyk)@2a5tP$@g%jW^b^JGdo)X@Q%sE`^lDQmY9m%uDFpPX`w9%=yQ+nneMm#OaXcD` z9}{tn5A2b2z9783vL2_jSao?uxJhWJoq%47*RafM4o0@gY(p)F>qT4^XM5GLzV#6j zC+HoGhAne7o_w{WUo(B++z7lU3Y0k1rYv9|TSv0vR-Du(5=VakbbelgZTeDn+a_Wv zq_j-^+Qz1WAl;Zg>ahX|CERbX1V%B!hTKN?M}fGoA07M(WU&NfT&TmN`P@56U2 z^)vLDs|Ln~0iTtn-?KTeQl@T&bskJFuTUS!m+$CS9vnd}8(UMO|Kv6TCfGN9NUu&4 zL{)GTxPq>fwsJ~aU=4Qhuq8*RzDsP(LZh$BHezq&9gK$IS<|DYbm})$QTGCS6T;Dr zEkLct!b+#<1r9OKG@P!f1wm8>=Nz!7OzJm!g<+`?N3;YaA3(P@EL=(sTaRMDD!c8=-XN^4BXp(eVkj$NmEMYPP>YJ4bJ3yUud z<3BeJAJ$6z^TuywnfH5lv#$lgwraNw{IV=tIznPH1DT`v-5yS=!)J<}xxl}uZf9azA2A97Haf!;<3y01hlw?dWNEv@TLi1s-mO4vmIT%O_42nS z$VRWrs9NngqRRkWAnWkn%`Rw@?wH|)7XL`EL5EZu$qyJW31&CB^T_)qwIv!{;E_6 zo-9XAryQRlk-O0>o#-SZO>|6OYq;}<*>Wu1AsVRiXY4f8qb;+sItv3AyS!4Ry+q}) zA!pAB|BmC;=RIOk^^vlsEH(!Q!7_1FK~ZB2err*o!+b(r=m1b?$6d!%zmN+69LXnT z&gRmM+n_R-F@sT*IYv0_mGPvur!u`iWbQO7SqiGFLeY&yga zf`lM&B74FA2C?N@8_z652fjhBEoDUKbP8hL{0{HAF%qDo7)o3=3rg#6)T7%%5^wl% z9R0*S*<~>nzYOdQk2l`9h#t+gJy_xujw6xjV(8S<_DbVg61&pT%Hi42l%D73G?adn znB%UdNM0p}lEF-P2%TAMam2zpQev71e>a$$%i+r~b+D9G9pF|oY_*(-u*89oKsXLY+UIbqq)MQ%(GYS{(*n_S_*RN$*~`zUtab%0aKwhx znc)Yo?{xq1sJCgQD)TeTci1ucvbez9q=A72H(-SB18Kl&6^vHV8^i!p@>iF!DIw17 z+8Q)TNisB7>pwyww4y)yJx*wX6SJO78eLBC-ar1+k$Z9fy;wBD|3kzI{<+l*>PSY^ z_?nLOZaeWbU@C3hfK?X;Di*8CHCPkx2qco6(ZyJdqSzp^TJ_5Lpa0UP{Gy+!b0Lr% z@xYxSjUKoY6L#>$qx~KD$-0=|OF7zhVP~ntMgEALYPIfhj@+ z!;JJ7te>CcovruwHsJH6Lta$nm|%^C@=V-rmhU{+I~0(|XHQ9jt@L7pb{gx#{4r!) zg($FyFTslcgu(~6lYr$nW?)%*l#VJ=R-jxK(x=t1bWlu(nL66T#qj%3aZ@uVhy}Co zDU_q61DD5FqqJ*#c|(M5tV)XBN?Ac^12*q)VN4yKPJ|#==S_`_QD9|0ls!`2)SwuHDRA_OfXQDq3%qW&MZB}Z!=k-9xqev8jHz(H z{^D@cIB~QiK>~wa)A&^Ll^Wi6QgCzU;iv-BHsLBs zH7=jN%|>0S`SjP%M&AF1PNVDp_FZ?2Bm@7`DC&v(pYrw!!yD#4 z6+<=HS0Ln6MhoKxF<%~H`y20{vf#pxh=;j{zY381gvAFekgG|>G1zo8$&az{V=;JR zy_puF4$L$?EMhT?;TpQoR*j16ll`#AS4e96C}yp_aGKkBe?1H|k_;gG-~Xorc<;lI zkB}fB{$c-D2mGA&{rm<*@F5)c3X+6??g~XoEwuzSuch0D@W~P5(2I8v8F$c2$Vw51 zP#YLSBDqtWW^EYBl^QYHF+MA7am6f4DOhwnJM=W9$uvMOsZ%_~?)2C#wb?CkI$7{K zEi)=#|5pFvg^){zK5kpBLjB2kZ+$ZB|L=W|aNwyyb(gC2l7bcpx{E-H@)q6@D6N^xh`{1E%ItF2$eeB_SjI@b2WgTpS1thwg&n`jiIzw^TtXUyB{00($GIq>vbj|}bav}}Q_~wp3>k8!E@hVC;OMUTu|= zAy#vXH*GrUHu7^cNZWe1>y;2(51js9wbu+R3Aa*(wzH9+X0dIsf&gc_x|_LP z>~CF^?(~U}+l~ehe|i>?4eo!xkq&Lk+RR-1duNP#o~>@1x)s&i&u zRaYL@+D&_M|JLI6fHbEr_`U;HgPTh#E3?sB)A$*gqyBgg*ql|a-m*TX5rACbWKCE6 zdeQ`v8m6>g^ugv`p|HY^#1QZrGGUj0^HVDc@{?Q0yhalbBEV{+|HzC^-{&e{5K%z9 z6Bxtnfu1!@Mp+Q&*&~;FOg&*Vm<@4b;{FG0-!UUXX!|)1w}op!B_|7_s~d(+=9Gba zKp8`LaB4D(H=cGcspJ_TjYaOwMb=sGn^gtUVhK!UI~2KKYEE-NC}F>+BEY7IVvy%KRvm00tg!Q`y=er}wpEetX}K@;}(}{s9AzV#q2@ zBy7}->|N?13POrs`;U?(qAG(I$~Gt+Rgw%aNZ_0fs_utVvRJT-7z4!@x36v@=NBX=IqkK{#Kg0w48de@?#Yb4M(Svj5=T+<ONr8-oh7l?Cji@+erqur zFhZ=9|Lk=$`c}v4u`)-!!UI=!9Jo@h&7p4RlS#u! zZ7-prn75JkV?VjptX;@$#`U`{vB!=Z?V`T*FBF>J?vsML7e6@2GbUteMFfX-TUu{2 zLNIG*;dV)8GV8gAgEf#)X3A>p3^CRka1v?~8x^anBhQ=L=LsOl=&pcOYHo98m##ye z34MtGCDK!`ptl?taGMr5q{!zVc? zG00e){TV?`YA9eB;(lA3lXI?RrB4BYQGk?vOmTIUJED=(`_*gtn2DB-t4WW54as*W zb2kD-lWX>lb$+W!VFakki>B^Vc+u$?NLF>)!U%b@Y}gYJ>m2H=^x0=nsE0TF^Yu0h ztgH8-o1%+jCk(+&`|)tTfEVHq0cMeFa{Uz)X$;fCq%Y=SOWML6bYfeP8j5hktL`KK z(18`XrUn&WN9PtFxh&dX`y~YBsmdhi7Kw%tKzM%^VEhdD<_XkulW-x=JN6OPbFI4@ zzDDRN+f=@{0h*MswwOqG6gJ?{NuHx(y-|FUGsxyZ*x0~$MW(eY>vqq4Fh#t7uzw=- zKB?|!0N~!h^AMdLa)oR!Ca#HZ9&Zf)ghuO<^RN)4twRlygHnQG(BE{cDc5E}OF4;xss6gYyV~EcJvJkX)xNWb=@yw!uq0v-sf^rvkp-;?DPWK@*SEw|V;IH=7 zfQqEV_>DjOPT~8X*J|H8=&RnzK4~S7ML~nLX^%s-Vqc^aWy7N$y57qciZGcqy#=zU zs8hcHiI=D$+RB{|62{ohCTiaML6FI4Uhzo5D{Jik@poCs0w7F)*w}F4r0sJ~#u-72 z5bK=ANt=M$Dh5NKnxGsg9NRR?WD-x|FhTwBjd zD<-K>44DB~i%frJOfnzh1R>PRY34kw!6~p3M$JLaD1r@`=h)~Ngks-(gdXh^Q?BTP zZ^Zj5w1AwtuR2$~E7s9iZdF}z%pv1em^V2rM{1tLUY@-+Sc0(9jA|iZWml1;v13=U zHf?y@#mb--7z6$ue>`qjhE~brk$AY-RG90~5wcBbDReXR2)pKg{L>;H(DI`U!MLNQ zY9rFJP@ZQ}jlcMh%WSCo%vf+nd0Gmd*F%KMIe>slCUh)8Ma|;M_I+v#;|ueg9oLg; zq2HtZX%&#F7vdpNlkX?}(C7dGC^y#NB#m4%69RzTNrk%4ol~hSI%>2r6B|*ZkW(*P z;u#s;+faHo{tfy+1L^RzWDi*^JR0iY(zJDB36y_QJ+|E-2x+cY z!V8uLNktH~q>WQZuY!Ap66WP|E!0PA1jK~)^8oJVGbspJs6QL!!-5Qm7 zHYI|_`Actg?vDzdg5{86w@GS$G6ANzff7->6i5pB$T4O}`fZ_;{217Om0gN5zTr12 z5mW{hCzCE-QubjxN$TAE-XgI-8dTY@OZmq`y+y_>dk*(qXF0{nam|q@~i}Utp*k{yurq(DW54hkDT4bbg z=_etM?Nf5W^o-HEu9_?&xEqPg^P^mTxLH8n%u$!mWvFG|{&)jtnU&6|5-`~eaNz0%D1BDo`{ zS1N5(KW5v^2eLdd_%`uaRndF@h0Uo6=M|8?b~KbOLZk{HXEnGmtgZXf2inI*1r%n! zQ3&%RI4r{f&dwW~HwH0Ked9b!k6{>_19H z_Ai>5IChDMY(FfMyG%;30?SQ{iV9KyGru62+Y)~qSQ91}b~}w<&*}R&1c#$O`H@~c z5)2S_eXx}M#N{MuGeQS9@#UJB@;W_j50b}jIhxMPloEFQZdvwxiU^RYycTzgK)-vl3LT&$L8~@68$C8~5_U{cR$E#w*x65(qw&eoL@>%ZHvj zWnEMlSh*(o&oy|J7eJ5OD`ssy%F?*Vp?`Cq;FShyl{ZoKCG5g{y}>usznni#8ki(i zO{w@n{iAj1_ooX@+s*!uW60WcH~*bNOT6z%0jVML5};wVrQp~`Uss_{cO2oud_nNA8^B$?07fJ6?iI)Q zuo9G)O-z)DqstrBqf>B%S05hf-wep0@$BFHKSrkZ{za3D)yVzRz)2{wf8(Wp+xyAM z$rtyx$gi3A=V~V!`Q3;BM0$>*VVtxEM|xDL^gew7ydy3Q6YzD&THRz*q33Ms_D;M- zbCx1Ft#UNB)V3bf`~{ImI72OTp^|bF8?G8#FRj+Biy8ET5#rA3sd|0FR@U(LAJ%w8 zS1%n8Z=Amhw)92rIsof=YVWF4jw&F*j1LG@-`+cR0-~2LqXRH8(Ccne{y#MCPncF64U`0uO zWmi$dlii~1D0rLR{qc|_2M!C$t8^=G7xQY)9!#Y331A|>N)EhmyVdLWL9I3YLJ`7? zZmpqUJB>Ni9oiL)^1IK1UoMyhWE{$9M2M6Xi zPKk7GpMsA6vjZbU7~i+u|J6Nk|Ci!Y3UMUT2|`M;JsNQACdJ%ooo9Yt{?A+0hMpxi znEa~~sxC>rKrU6bd=WRb;%wsH>A#j4{({&1GYSNR57Gama(3)2A;SM>qop}l>Jk2* zn1+C$fIxuwzg3mCU#SOqb-wOCb6mBcYlA5+mt<&_J~sBxc(GQtBFINUO~Mr7<-uu($>P HJ4oML2Lo<@i8BwbL^1~GkG`E7C$SEa_ zF^}Ea+#Je`Xy6;#D0FPnSrR%Y!QGA~NA^{oWmW8C<3dr{x6wWQ{4+bzemqV5W$i5~ z=J0jXZ>uZb>DT@0Ks?4QJ{`z?8JWl3$y;2pj#$XP*pv$>$g(z43{YH9KmmR6<#sIn zA`#=0#sgycaBQ^&}Xba!|KaZ8~b30v~nLt z9%#gz_*=~KD{3t^X~l>480*}PhKN=??g`RV|4Ud{Gyyl187MJ}r(#e+H$GEdI+p1s zq_25h;fV)$EPK%Dw-(G=f`yHB-_tttsC!?k7*#!|4a>`Ahj8nm?&n>NRs%jkZW^3-0P_yMP5&*6a26{MRj1&TPF zyE#|c)5uUHzMWx=rMKpuPih*V=S;W3MzIZTw2uTbr}8`p2bm+Z6Sa%vvWAWSf4H)p(+ zSQ8;EvUa#wqWV+9vmIio(%7wukK2SwjUS8Yl%Rq%=~PU)2$Tvm6`1!r3H@U#_|bB0 zmlT1PS3wPB(b&^+@YY7Y$n4l3mV3-X0$>z|gZp6O*Lhzn&?Gad2ZCF;+#95-Y?#y+ z?*l@Yf=a4w{Px=o!N|3~_XKfk&G;fN>Ps&dp2FpA~qD=0~=!NOS@B#XAKKkND>Y{4>rqxrViKD7;?>j8`R` z&G)3FN|dfsxnaI^!d1G%=>AbTTxZWo;n-DLrQ!sj=f~VAOe5zhGS(dgx|!ls62fbX zV@<7Ck^!}R=`Swr?(7w1rY6Nmq~sfXJ?TiKJLn=&SQdEt9$@0 zA+h1Wbwbri0s-stc8yVq;mRa6@kEf8^KXUz&jcic!+avDvvJFa>k0ioWug=T3oPw; zyj4it&0@>_*uI@2=^+T7sL1_!^aJW@Xfo8aC#3^WtQC7fET8b9C} z*u^ue6Ojn z7@(eskJ2+cNnH9~VyfIh<-|7!je~vGy*odz(sk-u$~SrYF3glruZ*W`{sqnS+9=;Z zh{D@MSG91%lr&ua8%$sJF%y1I<|e;EdfJykY8#D$Hc_81n5`$7;1N|b0tvvPLzSg& zn7!5x?T*@rQUKcUhTIjV(rw*5oQYlm5DbEO?60#mohHfbR$3_x#+PZoYi@Vd4`#YgKyTd^!4n{fN~WZDY61sAOm6 zl!d^i*a01QxpWM9Pcl?&{RgO}uq%ErOk5WpECvnfEh!*YP&1Sl)uTN4hg??Vqs~i5 zYsfufz3?{TtwuBN=`0~Qg1PlWH#OGG$ zLLWU17$v``)CE1cds_7kj8mJ{-+l8{DS|zAQ&3|qpOY=!J|kXUhXue9|H>4gqk|n) z-i34GmxLFj8asb3D#D&=ya*a5`C<=o?G;Ev^LV%;l#nH#O=7Nh@z1Do>j6Q;I5S2P zhg|AZbC&|c7}uSJt57s2IK#rSWuararn-02dkptTjo*R{c5o(bWV}_k3BBnKcE|6l zrHl&ezUyw^DmaMdDFVn<8ZY=7_{u{uW&*F<7Al6};lD(u;SB=RpIwI)PTyL=e25h* zGi{lRT}snjbMK~IUx|EGonH+w;iC2Ws)x>=5_{5$m?K z5(*1jMn%u0V1Y%m@`YS3kskt~`1p(rA4uk;Cs!w^KL$w>MH)+cP6|XKr4FfHIATJH z!EGAK4N>1yFR`-zW|w%ByRe#=&kA&#WyUldDGpt!wf-8SFWiSi!5QZL+l7*CE?u!NW1T$<1rdLJ9y3u{_zvHaM?#Rm4 zFk}^1!ffcrB|XK3gsO-s=wr*sUe&^$yN|KxrA)uW00Gu60%pw_+DcUjW`oW<35OC8 zq2{j8SgC}W$?10pvFU83(SL$%C?Kctu3*cs0aa%q!fjn1%xD*Jrm!F3HGR9-C{b?- zHp(cL;ezXMpL@0-1v0DMWddSDNZ5h?q50cOZyVi#bU3&PWE=(hpVn|M4_KYG5h9LffKNRsfhr^=SYiKg?#r&HNMi2@cd4aYL9lw(5_IvQJ zcB*DD()hUSAD^PdA0y|QrVnqwgI@pUXZXjHq3lG2OU&7sPOxxU$Y3&ytj6Qb=2#cC z;{d-{k|xI*bu+Vy&N+}{i(+1me!M;nshY_*&ZQLTGG*xNw#{RpI`3^eGfHck+*38NRgiGahkFethtVY=czJs#)VVc{T65rhU#3Vf?X)8f0)X{w!J3J{z|Sq|%?)nA+zo?$>L9@o`Kc|*7sJo4UjIqu0Ir~S5k^vEH};6K?-dZ0h*m%-1L zf!VC%YbM1~sZOG5zu&Sh>R;(md*_)kGHP)<;OA44W?y53PI%{&@MEN}9TOiqu+1a3AGetBr$c)Ao3OX>iGxmA;^^_alwS818r4Pn&uYe^;z6dh z)68T|AN=hjNdGpF7n>y+RTAZc9&opTXf zqWfK_dUv=mW{p_vN>|(cIkd(+Jy}qnK{IW%X*3!l`^H~FbAHwof+vLZ0C2ZXN1$v7 zgN&R9c8IO`fkR{6U%ERq8FN<1DQYbAN0-pH7EfcA{A&nhT!Be>jj>J!bNRw4NF|}! z1c70_#fkk!VQ!q1h2ff@`yDyrI1`np>*e#D4-Z~*!T^8#o*$V~!8bWQaie?P@KGBb z8rXc!YDL!$3ZgZZ%;-%~0Kn<+d+{xJ$stQbtN8GWV?MCJvzPU|(E(1z;rFw{&6vy) z3*@y%7Tx8rH-p$boS>bLyod?OKRE8v`QSBvGfY6f}_{Zo1q85xoyOF16n~yHx2W ziydUoYLkJmzq|n&2S(O!ZmLdP1(o1Jsq88cX)x3V-BK5eF&0e_0G!5?U7&3KN0`mc zH&Lt)q8!d_VgzxyL^(@xrbp2y)Hmr^V48));RSfE=*Ly0uh9!$3dv-vMZr2URf@l5zdwLjGZB zugY>7_fd_vbV*Qv1?H~>Z%RD%nEeFSI$n$$Lrpc6g>i4+XdBB!%zM$Bhrz5Swzyg? z$~I~n@~-wTBY3-T&pr+|gC+OHDoR?I(eLWa{Z#Rsh>lc~%u0!&R|s0pA*w<7QZ}{i z*AFr~0F3y~f$MGh_HDL7J_1?SxKL}fWIk!$G}`^{)xh*dZ5kK>xGL9>V`WZZg_ z)^Vm)EQK`yfh5KiR(vb&aHvhich z_5o+{d~0+4BEBqYJXyXBIEb1UgVDs;a!N2$9WA>CbfrWryqT25)S4E4)QXBd*3jN} z?phkAt`1rKW?xoLzEm!*IfkH|P>BtECVr0l8-IGk_`UjE#IWkUGqvyS+dMrCnFl<7RCgSMX^qn|Ld_4iYRldO zY&cHhv)GDo8nKvKwAbfyLR%t?9gG?R7~PSD#4D-;?F&!kV59O}neYut5AGbKwy-(U zqyBi=&Mgj|VIo>$u!DHM`R7O?W8-idbePuxiJMH``6c_5L-chKd}=rGC5Gfrc{f!* zWFEBm?l@_b7kzY7%1RQQbG5V<4=ZlkZ%sF74Q|mKOc7Ak7dP2#quiGcZ0_J%7Q?j{ zv9{WFw;n5G-Mn%r#0R;{jLt{yy}9J6rQ(>X9pJ`7Xy?Zv z=lNit#qXaq?CnElK^zF~sG}U5oCpR0T>FH=ZX}Prju$);?;VOhFH8L3I><9P_A|C+ z{;>~dk%9rrq(snjsEm}oUz2FQ21MCG*e?g)?{!&|eg7PX@I+Q0!hL6C7ZVY|g2E>i zr!Ri2@OfEu$)d52+>+cpgh6Z;cLYCZ&EMR0i<^~4&wEu_bdo;y^6}+U2GIQgW$|Od z_jg{O=pU>0-H$P-EOlWyQy#W0r@@_uT}Lg+!d5NxMii7aT1=|qm6BRaWOf{Pws54v zTu=}LR!V(JzI07>QR;;px0+zq=(s+XH-0~rVbmGp8<)7G+Jf)UYs<$Dd>-K+4}CsD zS}KYLmkbRvjwBO3PB%2@j(vOpm)!JABH_E7X^f#V-bzifSaKtE)|QrczC1$sC<<*Y z$hY*3E10fYk`2W09gM_U<2>+r^+ro$Bqh-O7uSa)cfPE_<#^O) zF+5V;-8LaCLKdIh3UB@idQZL`0Vx8`OE#6*1<;8(zi&E7MWB1S%~HAm%axyIHN2vd zA(pJGm_PraB0Aat3~?obWBs?iSc*NhM!{-l_WNCx4@F7I?)5&oI|z{o@JKd1HZ}zf*#}JjK3$ z-;3V*WJZvUcKvSOBH4c7C{fl8oRw8-vfgKQjNiR|KhQ%k6hWNEke(k8w-Ro| z7Y3)FsY-?7%;VT64vRM)l0%&HI~BXkSAOV#F3Bf#|3QLZM%6C{paqLTb3MU-_)`{R zRdfVQ)uX90VCa3ja$8m;cdtxQ*(tNjIfVb%#TCJWeH?o4RY#LWpyZBJHR| z6G-!4W5O^Z8U}e5GfZ!_M{B``ve{r0Z#CXV0x@~X#Pc;}{{ClY_uw^=wWurj0RKnoFzeY` z;gS!PCLCo*c}-hLc?C&wv&>P1hH75=p#;D3{Q8UZ0ctX!b)_@Ur=WCMEuz>pTs$@s z#7bIutL9Pm2FDb~d+H}uBI#pu6R}T{nzpz9U0XLb9lu@=9bTY&PEyFwhHHtXFX~6C zrcg|qqTk(|MIM%KQ<@j=DOjt|V)+8K26wE_CBNnZTg+Z+s}AU|jp6CFoIptG1{J*# z7Ne~l;ba*=bSwAMQ|Vq#fW~+je4PXA91YFzBubNF?ovIOw-$C-8=Ehed{lGD0}(Id zRe4sh8L>&T%{>8o))he}eE;5_ zxoXk3wX?MyNl-xF!q1d$G?=wp^`@09(jU&X zOqZIBI#dN`2PJNdATR3ivtub|nO$dulSaP|e4)WXF1YAGN1pDQIbIjXFG!oC85Mt; zW$eteoL{y^5t4TMRwP$jNPjZFpGsWnGe=jMMqKtcZm9Y9PFZLi*1p@qoKKub^T@2+ zk$@*KYdQ?Z`}<%4ALwk*Yc{(WTf@#u;as(fvE^9{Gk)lWbJP*SjttWofV0s?AB({~l zZI1hZVWFT~W-T?nfMMcnCS4-#6H-MU7H$KxD;yaM46K4Kc@~Q>xzB+QnD_I`b_l3m zo9pRx46b!p?a^&zCDwygqqV3epjs(s0NQI6ARA1n!Yy-qduipxQ& zUAlqRpNjBS+y-ZheD(!R;F}&^V_}b_gqH%tVZ5%%ziO7k^w=es+wZtK^i*vmrWNLMs{oWu_CIov|s1raZiS)>38>pYu;i+-t zI_DiNe6aA4KTZ2P09qPj(0~K4nUq^0+f(2$g`229zkG4jLzRvJUWE0oF1XHL4t3UN zDH466G56sy9hTZoAJB!C3;@F;ONxEk5u6Mv%zdo}Rq`=* zw1n7MOhfNSV48TS989ArIcj`C%Gk8~93~u>)!Yt2b4ZriKj9x2d`H2HQNJ=I>hkDlcZn zqRj>!;oRMTIOu zx|Zfsu~v76T{z7AC(jxj^c@tnJHZtGPsq$DE!8kqvkDx5W?KUJPL+!Ffpwfa+|5z5 zKPCiOPqZZrAG;2%OH0T$W|`C@C*!Z`@Wkop{CTjB&Tk`+{XPnt`ND`Haz;xV`H^RS zyXYtw@WlqTvToi;=mq1<-|IQ(gcOpU%)b#_46|IuWL#4$oYLbqwuk6=Q@xZaJSKVF zZcHs~ZBl;&lF3=+nK; zF`4gSCeZXlwmC_t4I`#PUNQ*)Uv&oGxMALip|sxv^lyVV73tKI7)+QY5=tEMas{vTD-BaTJ^*Y6gq~PU;F5X!sxqiq$iFCo+Uv7m%1w((=e}Vf*=dtds|6 zbX}91!G?C*KG03eHoN}RZS9DJxa&8YwNCT8?JxMXyZqZr13NA|GB{+vG`08C{V(yy zf*Lw$+tYSU_+dI`3n{bMrPdDb`A=Mkg!O=k>1|*3MC8j~- zXL79J4E=U^H=iBLTeHE_OKzE&dws8RNynsSJ!d;`zK?P92U{f)xvD7VQVosrXZrL+ z6lMVdD1YgL;%(1cq{#bS6yXmp|DS@nax#AqqlZhtUQdh<^2vr5`EpAO

LGYq)sa(w9^3-f}NHy=GR4v%t2YZly3m1G@5y`xBh_HGrD%f z>;|Ty?9FiJAc&UVD(StT4I` zfVQwxhE9bXE6r2mKO8Ag7{L^jCyqQb0QqKDPE=RAgqn8q1O^>(z7h5kE(6va%QqRZ zkIOmp(})rLSS(2{=C12e&@!W2=Jel-^_R``0xHO^+t!(oXbcv5yhD4g*$t_F)_5Dl zSVCgesW%;DtYPCFs{G;GX_o?1J3;QQPPv)rWw;>} zJ&KwnUqwNXloNXlK_+pNDfI~hON#SokVJb&ilg8d7^NWo2ZQymCqQMnjfi>ePibjr z-Z@q!?RGN$Mj}Nk){X_vaj6?Mj$>ACR*z|6MsXy3VZ^PFn@yHkPo(>m(iWepn8SC@ z>D2;R4m+gDRZ=SIX!b+CP(qE=JDIUkn=D$aUu+Ihn9-+k1LS3PreQg0N5eWIG@x${nC3v^7caS>1!PKNAY9J z#}E}Q9w#SP>(GY7Hbj&z4$Li6o5taBO|4+F`yS9zq*LJ<38wy4I>HA9(&GYrk4dLajKGww))BWli6Ln1A^Lda@N~p+snkb9C z@OthI+<##vp8!HVQT4Wk(=@zQ{OvZ$EKWS73+JHb)eYLGD-cqi6^|vd$<+IHuc?Nq zW7JertT~3))4?J|28n$I@nAD0c1%9C&IVhEZX~mUsf{efyS(XNG%ch;!N~d7S(Ri7 zb&=BuON95aVA&kLn6&MVU|x}xPMp7xwWxNU1wS+F6#y}1@^wQZB*(&ecT?RnQcI}Y z2*z!^!D?gDUhc@;M^OpLs4mq>C&p{}OWVv<)S9KMars@0JQ{c_ScGsFo3BJ)Irg++ zAWwypJdTO-_{Uh8m(Z!3KL7K{ZZzKHj;{M8I$mV>k znTM?sa0);^=X^cglL`uC+^J)M7nEa$w=VwFULg~%DJllw+7dJAj3{qnP5i3@wr7%y zjXp?Wl2%Th=my&3u?Q$RV6N5tzKMSPTsc#J+-cDDp~qFB6bL2C8AS7Y3PKtVhdhl) zIaLqH5+OnWPWSt(lQCgkN8lczc-V%_iZ{>#1%Z$N*>lu#S;0MZ$T2Y8Kg!U;hAZj> z6S#%$DQ_`Ic%Zr@?}GgjRXg@qTj^17n`65oJ@Wj0u1X8&+UVd|Xs?J+i_^GZ94m6= zUc96~Q`OJvlKB_Lr15*Yw_PUPEr?f?H&00b^-W%26mD)(n(rGGNfK9~2h=C>p-7BZ zFd&*&Msdu{w~(eyFOglwCPH^Rb}O(N7LtS+nnEwDx*pGD?|&9Si~M43a+*L(b0$5A zv`T`(G3xO;I_sx;FwTP21ZlfDpz zOo?}Vlgf~fo{YWm@n_JyD*frOg{XsvBA~|Tn4V6hu>Gd>89-rblfVJUaGvj6X%NZ} z$tFF9sx=4_$*c~G`9iPLGh@=sV+O{D2-t*K@J7H=`V+oVt}8?04WwU3h1BgS!f%1P zFak-T#7`TtLcR=Yz>g0R!ZQrH!YiZOQN=_V-UyncN1Rc18?KY?#O`v#JK+pq0K$~H z3D@v9DZF42R)b9#BBX{^$DOMlJ!g)Gc za{o-1e%F6NvgKq9tC8pV+9S$;9*zNv{J*)n&dmf~anP1)4~N%~h#c(=B#3*KgzhCKhFdgDoWi2IDog{RVyzK|Y`rCUs3T~pJMmdZJy4?b z&s5G=zhf**(t7Y^oC_mcTsE-{^}wiaoUu&?kojLKs>SJPxjcP>{a5CbXCx92AcBE) zHtqP}LjZ{W>PH?Tu(E0X=%{PBMW@F_?#7b&#!^q`<-5$ur+-q6 z{dn=(^UZw6*3-XM_(=@<1_*i&XM4=0t5u!gm6 z{UlmNGPKgO_;e;q9|#esq~Sq`<}%d{+sRmhvsA{5i*91=tub>OZZ%)xUA#4q$dDyy z1`w4%?OPLg3JeZb#cqSMO?*Xn%|-FCcuH2i2fn_{IFusub6;NQdN|7TD1N?%E8*g? z$apAt@cEe!I%jB=*q$p_3=t_5R0ph%{qaq+QDg!c99Y!Xa!&oDZOeis_ot)gNXr{l zdY$|So2Qed2Y7KMNBrS^E169kG%h<+z{Z_p_;shB!uY)>yAVcK=&!bg`lVg)4T1|7 z0}7FpfydVH4F87K@c!nEG+WGKm{Ouo)Slpl;#qcEIQ0zdMfLA#;dBxYw;p;KoVv6| z3_D5&7rJdG12CnDSvZUW?$UC6^UVSW^|vw|o-_4bz)(w5(3AiVhpeT(|=f#x_}E?s#qHZF#xA6AF_ujl$G z-jHD%q(d2}v2PhXx&6YWps~m(^+RXl91Q#xRRJBhjKl$FG4bk);|ag;ieUZ&!Ii3$ z(iGz1+0m7#g5>ASldBbNZL=ZHh=tmmJt$!71; zIML2GhEz1pg@1rQN(M^_691wAGkJ@Pga_05WuQ6! zG5RkGY2^`@(H~pp7&Ga+Pwh3L!Njj!-rc;^bTIfo5hP@H##1X8xUZJckrx>id`bAd3QUx9GuomqBYZ!uN1-&o zvTxC?;p8vL67&fW8fw(YOqt>L@bdLrEF*3OgYe$4n4{ zEB40LiU#6-0@5jdN`0w}N0qi@c0~oT2FP z)LNk&a82my?jv(tQpiMi$TK_L@lub#lsM$R{Dk?Ya@%%%huZkct~tSWM714c!45k}-ZLVA-bVM`>|_ZBbW_m-7| z3U%xrAhi}n?T(2F{_n4EZ10inkIFl#y09?7$uwBoJgqY8vylwev)fDOn;>0R!aEnV zBz%j0Mqpx~EZU3q@%+oV7;}|vt7$~ou@faEIq{p?FY$XXg&6*K)b_LP=}gi9`Bij3 zN`zEo|B6*|-;>S`rNa^BKRDbDAk>X#MsR`EvL>6bqU@SaDDs z8>bu@3YdRaWs*Te@G-UHjU%F~kTHw5(0PVJ+pwh#ha2u;DB+UMo@A5UYIl#5rtBV- zGX_hIpw}3C@H*Us(Cc-d#-gNrG#w$(9+S=GxO>3SR`SE2fHZ2KrDc#_C^$jI>Y}#; zMwY=R6@+dWi~0RXw(c@3GZ&%~9K(q&ee0Zw;pwL`E_tZak-#8^_b)Dpyi73^he?xV zXJ08&wh5-M&}qy4f7!D&=E)puDD(Nmg1d_(j`4LvxM5x_huNg-pGG%9rYqO6mImyJ@}*3Y>^3OvcnTG%EV1) zq_Ap?Z!Iw__7#D=pOWnQN$gB!Mr0!9yx|g<4icJh{cFOu3B8}&RiYm+Mb;VEK``LK zL(NcpcTiGieOIssSjr?ob}^``nNf&UcJhXyncO9m{6gD$kqSD`S69(aF8dkWz5>!9 zBLe4Sib7Hs2x_L2Ls6Ish$MGVKrGt5+_2zCyP1byaCg3upo+-I}R4&$m)8 zQ7|jc1Z^VWggpuQj*cP;>Zo9LS!VSzrqmZczaf;u`d0J(f%Z9r%An@s!e>n9%y=n!IZ_tVGu{Jmsbp}Fk%HJIU?a+-~bjfLTuH|JExA8EROowzr zqW9{YyZhR0a4clRK>1I4Ncx&WER~{iE;F^$T7K%X@3PGOA%6#Z%p3TS^&M;Dnjw@i z^o!$9nhcsmcHcY4?4j9+ofL_CWsZ4Hcch(rjsGfGD(nsH>w}^ERqGnz%iGj0j{g}h z7wMkJ-2Z2~eS>2!i}0~B63i;>SyFJU2+>VCS^AxaDOx%g6-t0eM^P<3+*z`ztvOqrG3)&#$K?& z_Y0wbWID47@cU`E1A6A&!`aZk0ZE@z-h#l1NqX2#`$Uev2gepW`rf8*!=rD5&;Jb{ zl08rU>dPo=K%-1Ao1~G-@4ve~y5#9E8x;TE0k5d^TC(=Zc>mwjW^c=+U-<9}b0ku~}gj z3sbW>R2M6DR!g#NUP;nxo>)@7*=RP{U18SDop6b2&PHce^&h97@xx3t+VK+!keE#} z;(Uf&89as9k8{$nkLbuB!-d7TP`_VJpL^Xs8OKB~ri$YUbW8fch64}7|0EWoT(TRj{ z*GT<7Y<7DsrCi79ZsM)z#c(!nNOGySOCkY1fAuQOq12&iUVC!a`#O;dBLf=d?&4*B zI~LgAO7E0qxK(uRTM;IgJ}+z^gD+bi-6I!3x{r9`l~%8TRP%UE0V8E*Sz>Nl1NVG<<7(wDHZ+HcOkQm$O&k+vyx)y)x{Pz!U8hS$*m zByc0h6BUI*BOpuL==P+H|Hx%`>7!W+1H!l9vi&)`V zyn2o9{z=lc+VX*!Vh~SF=)L}Z40XeG>LF6cP^b+R$NxSeUqbK^Q*UTalKzP8X%{9@RSCXm_NhF>{=S2 zi}ezam_^P`S!!-cyEW9y7DBbK93roz@Raccy*v}?mKXScU9E_4g;hBU7}zSofAFda zKYEe?{{I54 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b82aa23a4f..9355b41557 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a4269..f5feea6d6b 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 25da30dbde..9d21a21834 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/projects/neoforge/build.gradle b/projects/neoforge/build.gradle index cb86838bb3..24a2c688ca 100644 --- a/projects/neoforge/build.gradle +++ b/projects/neoforge/build.gradle @@ -194,7 +194,7 @@ runs { gameTestServer { } gameTestClient { } data { - programArguments.addAll '--mod', 'neoforge' + arguments.addAll '--mod', 'neoforge' modSources.add project.sourceSets.main @@ -209,7 +209,7 @@ runs.configureEach { it -> gameDir.mkdirs(); it.workingDirectory.set gameDir - it.programArguments.addAll '--gameDir', gameDir.absolutePath + it.arguments.addAll '--gameDir', gameDir.absolutePath } launcherProfile { diff --git a/settings.gradle b/settings.gradle index 33563e5350..f6be0883b4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,7 +7,7 @@ pluginManagement { } plugins { - id 'net.neoforged.gradle.platform' version '7.0.150' + id 'net.neoforged.gradle.platform' version '7.0.163' } rootProject.name = rootDir.name diff --git a/tests/build.gradle b/tests/build.gradle index 83f5f7dcc0..d724be0976 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -68,7 +68,7 @@ runs { data { configure neoforgeProject.runTypes.data - programArguments.addAll '--flat', '--all', '--validate', + arguments.addAll '--flat', '--all', '--validate', '--mod', 'data_gen_test', '--mod', 'global_loot_test', '--mod', 'scaffolding_test', @@ -90,13 +90,14 @@ runs { gameDir.mkdirs(); workingDirectory.set gameDir - programArguments.addAll '--gameDir', gameDir.absolutePath + arguments.addAll '--gameDir', gameDir.absolutePath } } //We need the assets and natives tasks from the forge project. runs.configureEach { - dependsOn(neoforgeProject.runtime.assets, neoforgeProject.runtime.natives) + dependsOn.add(neoforgeProject.runtime.assets) + dependsOn.add(neoforgeProject.runtime.natives) modSource neoforgeProject.sourceSets.main modSource testframeworkProject.sourceSets.main } @@ -104,10 +105,10 @@ runs.configureEach { afterEvaluate { runs.data { // Override --output that forge already has - def args = new ArrayList(programArguments.get()); + def args = new ArrayList(arguments.get()); def outputIndex = args.indexOf('--output'); args.set(outputIndex+1, file('src/generated/resources/').absolutePath); - programArguments.set(args); + arguments.set(args); } runs.junit.modSources.all().get().values().remove(sourceSets.main) } From ff9d23f218aa506348e184cc491fc19773111808 Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Sun, 8 Sep 2024 15:56:52 -0400 Subject: [PATCH 062/125] Namespace the Neoforge Entity Animation JSONs with `neoforge/` (#1525) --- .../neoforge/client/entity/animation/json/AnimationLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java index 44debb35bf..8fd278c8fc 100644 --- a/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java +++ b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java @@ -35,7 +35,7 @@ public final class AnimationLoader extends SimpleJsonResourceReloadListener { private final List strongHolderReferences = new ArrayList<>(); private AnimationLoader() { - super(new Gson(), "animations/entity"); + super(new Gson(), "neoforge/animations/entity"); } /** From 08c334bcebbdc4d8fe6a59836305bbf94ef069d5 Mon Sep 17 00:00:00 2001 From: sciwhiz12 Date: Mon, 9 Sep 2024 05:01:11 +0800 Subject: [PATCH 063/125] Add back original constructor for `TagsProvider.TagAppender` (#1520) --- .../data/tags/TagsProvider.java.patch | 21 ++++++++++----- .../extensions/ITagAppenderExtension.java | 4 +-- .../extensions/ITagBuilderExtension.java | 27 +++++++++++++++++++ 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/patches/net/minecraft/data/tags/TagsProvider.java.patch b/patches/net/minecraft/data/tags/TagsProvider.java.patch index f52c3bdce5..7cf15ff1f6 100644 --- a/patches/net/minecraft/data/tags/TagsProvider.java.patch +++ b/patches/net/minecraft/data/tags/TagsProvider.java.patch @@ -108,24 +108,28 @@ return this.builders.computeIfAbsent(p_236452_.location(), p_236442_ -> TagBuilder.create()); } -@@ -127,11 +_,13 @@ +@@ -127,11 +_,19 @@ }); } - public static class TagAppender { + public static class TagAppender implements net.neoforged.neoforge.common.extensions.ITagAppenderExtension { private final TagBuilder builder; -+ private final String modId; -- protected TagAppender(TagBuilder p_256426_) { -- this.builder = p_256426_; -+ protected TagAppender(TagBuilder p_236454_, String modId) { -+ this.builder = p_236454_; + protected TagAppender(TagBuilder p_256426_) { ++ this(p_256426_, ""); ++ } ++ ++ private final String modId; ++ /** @deprecated Neo: The additional mod ID parameter is unused; use the one-parameter constructor instead. */ ++ @Deprecated(forRemoval = true, since = "1.21.1") ++ protected TagAppender(TagBuilder p_256426_, String modId) { + this.builder = p_256426_; + this.modId = modId; } public final TagsProvider.TagAppender add(ResourceKey p_256138_) { -@@ -169,6 +_,19 @@ +@@ -169,6 +_,22 @@ public TagsProvider.TagAppender addOptionalTag(ResourceLocation p_176842_) { this.builder.addOptionalTag(p_176842_); return this; @@ -136,10 +140,13 @@ + return this; + } + ++ // TODO: In 1.21.2, mark this as @ApiStatus.Internal + public TagBuilder getInternalBuilder() { + return builder; + } + ++ /** @deprecated Neo: Avoid using this method to get the mod ID, as this method will be removed in 1.21.2. */ ++ @Deprecated(forRemoval = true, since = "1.21.1") + public String getModID() { + return modId; } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/ITagAppenderExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/ITagAppenderExtension.java index fdd4a00438..57d19aaa04 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/ITagAppenderExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/ITagAppenderExtension.java @@ -54,7 +54,7 @@ default TagsProvider.TagAppender replace(boolean value) { */ default TagsProvider.TagAppender remove(final ResourceLocation location) { TagsProvider.TagAppender builder = self(); - builder.getInternalBuilder().removeElement(location, builder.getModID()); + builder.getInternalBuilder().removeElement(location); return builder; } @@ -106,7 +106,7 @@ default TagsProvider.TagAppender remove(final ResourceKey firstResourceKey */ default TagsProvider.TagAppender remove(TagKey tag) { TagsProvider.TagAppender builder = self(); - builder.getInternalBuilder().removeTag(tag.location(), builder.getModID()); + builder.getInternalBuilder().removeTag(tag.location()); return builder; } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/ITagBuilderExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/ITagBuilderExtension.java index 18d488597e..c63342f984 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/ITagBuilderExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/ITagBuilderExtension.java @@ -10,6 +10,7 @@ import net.minecraft.tags.TagEntry; public interface ITagBuilderExtension { + // TODO: In 1.21.2, rename this to self() and mark as private default TagBuilder getRawBuilder() { return (TagBuilder) this; } @@ -20,7 +21,9 @@ default TagBuilder getRawBuilder() { * @param tagEntry The tag entry to add to the remove list * @param source The source of the caller for logging purposes (generally a modid) * @return The builder for chaining purposes + * @deprecated Use {@link TagBuilder#remove(TagEntry)} instead. */ + @Deprecated(forRemoval = true, since = "1.21.1") default TagBuilder remove(final TagEntry tagEntry, final String source) { return this.getRawBuilder().remove(tagEntry); } @@ -31,19 +34,43 @@ default TagBuilder remove(final TagEntry tagEntry, final String source) { * @param elementID The ID of the element to add to the remove list * @param source The source of the caller for logging purposes (generally a modid) * @return The builder for chaining purposes + * @deprecated Use {@link #removeElement(ResourceLocation)} instead. */ + @Deprecated(forRemoval = true, since = "1.21.1") default TagBuilder removeElement(final ResourceLocation elementID, final String source) { return this.remove(TagEntry.element(elementID), source); } + /** + * Adds a single-element entry to the remove list. + * + * @param elementID The ID of the element to add to the remove list + * @return The builder for chaining purposes + */ + default TagBuilder removeElement(final ResourceLocation elementID) { + return this.getRawBuilder().remove(TagEntry.element(elementID)); + } + /** * Adds a tag to the remove list. * * @param tagID The ID of the tag to add to the remove list * @param source The source of the caller for logging purposes (generally a modid) * @return The builder for chaining purposes + * @deprecated Use {@link #removeElement(ResourceLocation)} instead. */ + @Deprecated(forRemoval = true, since = "1.21.1") default TagBuilder removeTag(final ResourceLocation tagID, final String source) { return this.remove(TagEntry.tag(tagID), source); } + + /** + * Adds a tag to the remove list. + * + * @param tagID The ID of the tag to add to the remove list + * @return The builder for chaining purposes + */ + default TagBuilder removeTag(final ResourceLocation tagID) { + return this.getRawBuilder().remove(TagEntry.tag(tagID)); + } } From 54ef98db5ec225804cb9d3aa007e5a0b80b40205 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 9 Sep 2024 04:24:37 -0400 Subject: [PATCH 064/125] Add a helper for constructing singleton ModelData instances (#1524) --- .../neoforge/client/model/data/ModelData.java | 12 ++++++++++++ .../neoforge/oldtest/block/FullPotsAccessorDemo.java | 2 +- .../neoforge/oldtest/client/model/MegaModelTest.java | 4 ++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/client/model/data/ModelData.java b/src/main/java/net/neoforged/neoforge/client/model/data/ModelData.java index e980e296f0..ba793cc7ea 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/data/ModelData.java +++ b/src/main/java/net/neoforged/neoforge/client/model/data/ModelData.java @@ -70,6 +70,18 @@ public static Builder builder() { return new Builder(null); } + /** + * Helper to create a {@link ModelData} instance for a single property-value pair, without the verbosity + * and runtime overhead of creating a builder object. + */ + public static ModelData of(ModelProperty property, T value) { + Preconditions.checkState(property.test(value), "The provided value is invalid for this property."); + // Must use one of the two map types from the builder to avoid megamorphic calls to Map.get() later + Reference2ReferenceArrayMap, Object> map = new Reference2ReferenceArrayMap<>(1); + map.put(property, value); + return new ModelData(map); + } + public static final class Builder { /** * Hash maps are slower than array maps for *extremely* small maps (empty maps or singletons are the most diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/block/FullPotsAccessorDemo.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/block/FullPotsAccessorDemo.java index f04c814e50..207a9aeb14 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/block/FullPotsAccessorDemo.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/block/FullPotsAccessorDemo.java @@ -165,7 +165,7 @@ private static class DioriteFlowerPotBlockEntity extends BlockEntity { public DioriteFlowerPotBlockEntity(BlockPos pos, BlockState state) { super(DIORITE_POT_BLOCK_ENTITY.get(), pos, state); - modelData = ModelData.builder().with(PLANT_PROPERTY, plant).build(); + modelData = ModelData.of(PLANT_PROPERTY, plant); } public void setPlant(Block plant) { diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/MegaModelTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/MegaModelTest.java index 2fdbf63445..fd787f71ec 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/MegaModelTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/MegaModelTest.java @@ -133,11 +133,11 @@ public Entity(BlockPos pos, BlockState state) { @Override public ModelData getModelData() { - return ModelData.builder().with(TestData.PROPERTY, new TestData(new Transformation( + return ModelData.of(TestData.PROPERTY, new TestData(new Transformation( new Vector3f(0, y * 0.2f, 0), new Quaternionf(1f, 1f, 1f, 1f), Transformation.identity().getScale(), - new Quaternionf(1f, 1f, 1f, 1f)))).build(); + new Quaternionf(1f, 1f, 1f, 1f)))); } } } From eb624e856ddb8120d1611e1c1e71f126500b9634 Mon Sep 17 00:00:00 2001 From: ZestyBlaze <68081568+ZestyBlaze@users.noreply.github.com> Date: Mon, 9 Sep 2024 21:44:46 +0100 Subject: [PATCH 065/125] Add `hangingSignBlock` method to `BlockStateProvider` (#1528) --- .../client/model/generators/BlockStateProvider.java | 12 ++++++++++++ .../models/block/acacia_hanging_sign.json | 5 +++++ .../minecraft/blockstates/acacia_hanging_sign.json | 7 +++++++ .../blockstates/acacia_wall_hanging_sign.json | 7 +++++++ .../neoforge/oldtest/DataGeneratorTest.java | 3 +++ 5 files changed, 34 insertions(+) create mode 100644 tests/src/generated/resources/assets/data_gen_test/models/block/acacia_hanging_sign.json create mode 100644 tests/src/generated/resources/assets/minecraft/blockstates/acacia_hanging_sign.json create mode 100644 tests/src/generated/resources/assets/minecraft/blockstates/acacia_wall_hanging_sign.json diff --git a/src/main/java/net/neoforged/neoforge/client/model/generators/BlockStateProvider.java b/src/main/java/net/neoforged/neoforge/client/model/generators/BlockStateProvider.java index dc0c4782f3..72745b01ba 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/generators/BlockStateProvider.java +++ b/src/main/java/net/neoforged/neoforge/client/model/generators/BlockStateProvider.java @@ -29,6 +29,7 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.ButtonBlock; +import net.minecraft.world.level.block.CeilingHangingSignBlock; import net.minecraft.world.level.block.CrossCollisionBlock; import net.minecraft.world.level.block.DoorBlock; import net.minecraft.world.level.block.FenceBlock; @@ -42,6 +43,7 @@ import net.minecraft.world.level.block.StandingSignBlock; import net.minecraft.world.level.block.TrapDoorBlock; import net.minecraft.world.level.block.WallBlock; +import net.minecraft.world.level.block.WallHangingSignBlock; import net.minecraft.world.level.block.WallSignBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.AttachFace; @@ -481,6 +483,16 @@ public void signBlock(StandingSignBlock signBlock, WallSignBlock wallSignBlock, simpleBlock(wallSignBlock, sign); } + public void hangingSignBlock(CeilingHangingSignBlock hangingSignBlock, WallHangingSignBlock wallHangingSignBlock, ResourceLocation texture) { + ModelFile hangingSign = models().sign(name(hangingSignBlock), texture); + hangingSignBlock(hangingSignBlock, wallHangingSignBlock, hangingSign); + } + + public void hangingSignBlock(CeilingHangingSignBlock hangingSignBlock, WallHangingSignBlock wallHangingSignBlock, ModelFile hangingSign) { + simpleBlock(hangingSignBlock, hangingSign); + simpleBlock(wallHangingSignBlock, hangingSign); + } + public void fourWayBlock(CrossCollisionBlock block, ModelFile post, ModelFile side) { MultiPartBlockStateBuilder builder = getMultipartBuilder(block) .part().modelFile(post).addModel().end(); diff --git a/tests/src/generated/resources/assets/data_gen_test/models/block/acacia_hanging_sign.json b/tests/src/generated/resources/assets/data_gen_test/models/block/acacia_hanging_sign.json new file mode 100644 index 0000000000..9d088d1113 --- /dev/null +++ b/tests/src/generated/resources/assets/data_gen_test/models/block/acacia_hanging_sign.json @@ -0,0 +1,5 @@ +{ + "textures": { + "particle": "minecraft:block/stripped_acacia_log" + } +} \ No newline at end of file diff --git a/tests/src/generated/resources/assets/minecraft/blockstates/acacia_hanging_sign.json b/tests/src/generated/resources/assets/minecraft/blockstates/acacia_hanging_sign.json new file mode 100644 index 0000000000..21adab31a7 --- /dev/null +++ b/tests/src/generated/resources/assets/minecraft/blockstates/acacia_hanging_sign.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "data_gen_test:block/acacia_hanging_sign" + } + } +} \ No newline at end of file diff --git a/tests/src/generated/resources/assets/minecraft/blockstates/acacia_wall_hanging_sign.json b/tests/src/generated/resources/assets/minecraft/blockstates/acacia_wall_hanging_sign.json new file mode 100644 index 0000000000..21adab31a7 --- /dev/null +++ b/tests/src/generated/resources/assets/minecraft/blockstates/acacia_wall_hanging_sign.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "data_gen_test:block/acacia_hanging_sign" + } + } +} \ No newline at end of file diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java index f92fb5b82d..104839af33 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/DataGeneratorTest.java @@ -86,6 +86,7 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.ButtonBlock; +import net.minecraft.world.level.block.CeilingHangingSignBlock; import net.minecraft.world.level.block.DoorBlock; import net.minecraft.world.level.block.FenceGateBlock; import net.minecraft.world.level.block.FurnaceBlock; @@ -96,6 +97,7 @@ import net.minecraft.world.level.block.StairBlock; import net.minecraft.world.level.block.StandingSignBlock; import net.minecraft.world.level.block.TrapDoorBlock; +import net.minecraft.world.level.block.WallHangingSignBlock; import net.minecraft.world.level.block.WallSignBlock; import net.minecraft.world.level.dimension.BuiltinDimensionTypes; import net.minecraft.world.level.dimension.DimensionType; @@ -742,6 +744,7 @@ protected void registerStatesAndModels() { pressurePlateBlock((PressurePlateBlock) Blocks.ACACIA_PRESSURE_PLATE, blockTexture(Blocks.ACACIA_PLANKS)); signBlock((StandingSignBlock) Blocks.ACACIA_SIGN, (WallSignBlock) Blocks.ACACIA_WALL_SIGN, blockTexture(Blocks.ACACIA_PLANKS)); + hangingSignBlock((CeilingHangingSignBlock) Blocks.ACACIA_HANGING_SIGN, (WallHangingSignBlock) Blocks.ACACIA_WALL_HANGING_SIGN, blockTexture(Blocks.STRIPPED_ACACIA_LOG)); simpleBlock(Blocks.TORCH, models().torch("torch", mcLoc("block/torch"))); horizontalBlock(Blocks.WALL_TORCH, models().torchWall("wall_torch", mcLoc("block/torch")), 90); From 42ad3e8620857a3f86c82a92c52b6bb73c3f7837 Mon Sep 17 00:00:00 2001 From: "neoforged-renovate[bot]" <174042230+neoforged-renovate[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 12:10:56 +0300 Subject: [PATCH 066/125] Update asm to v9.7 (#1508) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 0b915fef8c..ce5c12aeb9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -21,7 +21,7 @@ eventbus_version=8.0.1 modlauncher_version=11.0.4 securejarhandler_version=3.0.8 bootstraplauncher_version=2.0.2 -asm_version=9.5 +asm_version=9.7 installer_version=2.1.+ mixin_version=0.15.2+mixin.0.8.7 terminalconsoleappender_version=1.3.0 From a1640e14caa378b5c21b6481f4cf88ea0ddc7587 Mon Sep 17 00:00:00 2001 From: dhyces <10985914+dhyces@users.noreply.github.com> Date: Tue, 10 Sep 2024 05:45:40 -0400 Subject: [PATCH 067/125] [1.21.1] Adjust `DeferredRegister$DataComponents` constructor to accept registry key (#1522) --- .../neoforge/registries/DeferredRegister.java | 22 +++++++++++++++++++ .../oldtest/DeferredRegistryTest.java | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/neoforged/neoforge/registries/DeferredRegister.java b/src/main/java/net/neoforged/neoforge/registries/DeferredRegister.java index 8222fffabe..f404f8f8e4 100644 --- a/src/main/java/net/neoforged/neoforge/registries/DeferredRegister.java +++ b/src/main/java/net/neoforged/neoforge/registries/DeferredRegister.java @@ -156,6 +156,20 @@ public static DeferredRegister.Blocks createBlocks(String modid) { return new Blocks(modid); } + /** + * Factory for a specialized DeferredRegister for {@link DataComponentType DataComponentTypes}. + * + * @param registryKey The key for the data component type registry, like {@link Registries#DATA_COMPONENT_TYPE} for item data components + * @param modid The namespace for all objects registered to this DeferredRegister + * @see #create(Registry, String) + * @see #create(ResourceKey, String) + * @see #create(ResourceLocation, String) + * @see #createItems(String) + */ + public static DataComponents createDataComponents(ResourceKey>> registryKey, String modid) { + return new DataComponents(registryKey, modid); + } + /** * Factory for a specialized DeferredRegister for {@link DataComponentType DataComponentTypes}. * @@ -164,7 +178,9 @@ public static DeferredRegister.Blocks createBlocks(String modid) { * @see #create(ResourceKey, String) * @see #create(ResourceLocation, String) * @see #createItems(String) + * @deprecated Scheduled for removal in 1.21.2; use {@link DeferredRegister#createDataComponents(ResourceKey, String)} with {@link Registries#DATA_COMPONENT_TYPE} instead */ + @Deprecated(since = "1.21.1", forRemoval = true) public static DataComponents createDataComponents(String modid) { return new DataComponents(modid); } @@ -599,6 +615,12 @@ protected DeferredItem createHolder(ResourceKey> { + protected DataComponents(ResourceKey>> registryKey, String namespace) { + super(registryKey, namespace); + } + + /** @deprecated Scheduled for removal in 1.21.2; use {@link DataComponents#DataComponents(ResourceKey, String)} */ + @Deprecated(since = "1.21.1", forRemoval = true) protected DataComponents(String namespace) { super(Registries.DATA_COMPONENT_TYPE, namespace); } diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/DeferredRegistryTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/DeferredRegistryTest.java index 3cd673b8fc..6f85a772e3 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/DeferredRegistryTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/DeferredRegistryTest.java @@ -41,7 +41,7 @@ public class DeferredRegistryTest { private static final Logger LOGGER = LogManager.getLogger(); private static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(MODID); - private static final DeferredRegister.DataComponents COMPONENTS = DeferredRegister.createDataComponents(MODID); + private static final DeferredRegister.DataComponents COMPONENTS = DeferredRegister.createDataComponents(Registries.DATA_COMPONENT_TYPE, MODID); private static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MODID); private static final ResourceKey> CUSTOM_REGISTRY_KEY = ResourceKey.createRegistryKey(ResourceLocation.fromNamespaceAndPath(MODID, "test_registry")); private static final DeferredRegister CUSTOMS = DeferredRegister.create(CUSTOM_REGISTRY_KEY, MODID); From 8fc8eef3d0f93cb64a365d0b16c15108d01195ec Mon Sep 17 00:00:00 2001 From: Davide Albiero Date: Tue, 10 Sep 2024 19:11:28 +0200 Subject: [PATCH 068/125] Added `c:animal_foods` tag for all foods that can be eaten by animals (#1465) --- .../resources/assets/c/lang/en_us.json | 1 + .../data/c/tags/item/animal_foods.json | 28 +++++++++++++++++++ .../net/neoforged/neoforge/common/Tags.java | 5 ++++ .../internal/NeoForgeItemTagsProvider.java | 6 ++++ .../internal/NeoForgeLanguageProvider.java | 1 + 5 files changed, 41 insertions(+) create mode 100644 src/generated/resources/data/c/tags/item/animal_foods.json diff --git a/src/generated/resources/assets/c/lang/en_us.json b/src/generated/resources/assets/c/lang/en_us.json index 172b6898c8..1988c30b51 100644 --- a/src/generated/resources/assets/c/lang/en_us.json +++ b/src/generated/resources/assets/c/lang/en_us.json @@ -136,6 +136,7 @@ "tag.fluid.c.rabbit_stew": "Rabbit Stew", "tag.fluid.c.suspicious_stew": "Suspicious Stew", "tag.fluid.c.water": "Water", + "tag.item.c.animal_foods": "Animal Foods", "tag.item.c.armors": "Armors", "tag.item.c.barrels": "Barrels", "tag.item.c.barrels.wooden": "Wooden Barrels", diff --git a/src/generated/resources/data/c/tags/item/animal_foods.json b/src/generated/resources/data/c/tags/item/animal_foods.json new file mode 100644 index 0000000000..f302cacb92 --- /dev/null +++ b/src/generated/resources/data/c/tags/item/animal_foods.json @@ -0,0 +1,28 @@ +{ + "values": [ + "#minecraft:armadillo_food", + "#minecraft:axolotl_food", + "#minecraft:bee_food", + "#minecraft:camel_food", + "#minecraft:cat_food", + "#minecraft:chicken_food", + "#minecraft:cow_food", + "#minecraft:fox_food", + "#minecraft:frog_food", + "#minecraft:goat_food", + "#minecraft:hoglin_food", + "#minecraft:horse_food", + "#minecraft:llama_food", + "#minecraft:ocelot_food", + "#minecraft:panda_food", + "#minecraft:parrot_food", + "#minecraft:pig_food", + "#minecraft:piglin_food", + "#minecraft:rabbit_food", + "#minecraft:sheep_food", + "#minecraft:sniffer_food", + "#minecraft:strider_food", + "#minecraft:turtle_food", + "#minecraft:wolf_food" + ] +} \ No newline at end of file diff --git a/src/main/java/net/neoforged/neoforge/common/Tags.java b/src/main/java/net/neoforged/neoforge/common/Tags.java index de73509989..c02af99a73 100644 --- a/src/main/java/net/neoforged/neoforge/common/Tags.java +++ b/src/main/java/net/neoforged/neoforge/common/Tags.java @@ -436,6 +436,11 @@ public static class Items { * Examples are Rotten Flesh's Hunger or Pufferfish's Nausea, or Poisonous Potato's Poison. */ public static final TagKey FOODS_FOOD_POISONING = tag("foods/food_poisoning"); + /** + * All foods edible by animals excluding poisonous foods. + * (Does not include {@link ItemTags#PARROT_POISONOUS_FOOD}) + */ + public static final TagKey ANIMAL_FOODS = tag("animal_foods"); public static final TagKey GEMS = tag("gems"); public static final TagKey GEMS_DIAMOND = tag("gems/diamond"); public static final TagKey GEMS_EMERALD = tag("gems/emerald"); diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java index 34fb5799d9..b717c155ad 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java @@ -130,6 +130,12 @@ public void addTags(HolderLookup.Provider lookupProvider) { Tags.Items.FOODS_RAW_MEAT, Tags.Items.FOODS_RAW_FISH, Tags.Items.FOODS_COOKED_MEAT, Tags.Items.FOODS_COOKED_FISH, Tags.Items.FOODS_SOUP, Tags.Items.FOODS_CANDY, Tags.Items.FOODS_GOLDEN, Tags.Items.FOODS_EDIBLE_WHEN_PLACED, Tags.Items.FOODS_FOOD_POISONING); + tag(Tags.Items.ANIMAL_FOODS) + .addTags(ItemTags.ARMADILLO_FOOD, ItemTags.AXOLOTL_FOOD, ItemTags.BEE_FOOD, ItemTags.CAMEL_FOOD, + ItemTags.CAT_FOOD, ItemTags.CHICKEN_FOOD, ItemTags.COW_FOOD, ItemTags.FOX_FOOD, ItemTags.FROG_FOOD, + ItemTags.GOAT_FOOD, ItemTags.HOGLIN_FOOD, ItemTags.HORSE_FOOD, ItemTags.LLAMA_FOOD, ItemTags.OCELOT_FOOD, + ItemTags.PANDA_FOOD, ItemTags.PARROT_FOOD, ItemTags.PIG_FOOD, ItemTags.PIGLIN_FOOD, ItemTags.RABBIT_FOOD, + ItemTags.SHEEP_FOOD, ItemTags.SNIFFER_FOOD, ItemTags.STRIDER_FOOD, ItemTags.TURTLE_FOOD, ItemTags.WOLF_FOOD); tag(Tags.Items.GEMS).addTags(Tags.Items.GEMS_AMETHYST, Tags.Items.GEMS_DIAMOND, Tags.Items.GEMS_EMERALD, Tags.Items.GEMS_LAPIS, Tags.Items.GEMS_PRISMARINE, Tags.Items.GEMS_QUARTZ); tag(Tags.Items.GEMS_AMETHYST).add(Items.AMETHYST_SHARD); tag(Tags.Items.GEMS_DIAMOND).add(Items.DIAMOND); diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java index 75d947020c..bb2a30e4f2 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java @@ -215,6 +215,7 @@ protected void addTranslations() { add(Tags.Items.FOODS_RAW_MEAT, "Raw Meats"); add(Tags.Items.FOODS_SOUP, "Soups"); add(Tags.Items.FOODS_VEGETABLE, "Vegetables"); + add(Tags.Items.ANIMAL_FOODS, "Animal Foods"); add(Tags.Items.GEMS, "Gems"); add(Tags.Items.GEMS_AMETHYST, "Amethyst Gems"); add(Tags.Items.GEMS_DIAMOND, "Diamond Gems"); From bdda6d296dcc96f01325e195d2362c737b1a42aa Mon Sep 17 00:00:00 2001 From: Dennis C Date: Thu, 12 Sep 2024 15:10:47 +0200 Subject: [PATCH 069/125] [1.21] Allow requesting entity outline processing for custom renderers outside of entity and blockentity rendering (#1517) --- .../client/renderer/LevelRenderer.java.patch | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/patches/net/minecraft/client/renderer/LevelRenderer.java.patch b/patches/net/minecraft/client/renderer/LevelRenderer.java.patch index 07706e5c30..82e084e8b4 100644 --- a/patches/net/minecraft/client/renderer/LevelRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/LevelRenderer.java.patch @@ -1,5 +1,16 @@ --- a/net/minecraft/client/renderer/LevelRenderer.java +++ b/net/minecraft/client/renderer/LevelRenderer.java +@@ -233,6 +_,10 @@ + private int rainSoundTime; + private final float[] rainSizeX = new float[1024]; + private final float[] rainSizeZ = new float[1024]; ++ /** ++ * Neo: Indicates whether outline effect post-processing was requested for the current frame outside of vanilla codepaths ++ */ ++ private boolean outlineEffectRequested = false; + + public LevelRenderer(Minecraft p_234245_, EntityRenderDispatcher p_234246_, BlockEntityRenderDispatcher p_234247_, RenderBuffers p_234248_) { + this.minecraft = p_234245_; @@ -256,6 +_,8 @@ } @@ -98,7 +109,17 @@ this.blockEntityRenderDispatcher.render(blockentity, f, posestack, multibuffersource$buffersource); posestack.popPose(); } -@@ -1085,6 +_,7 @@ +@@ -1080,11 +_,17 @@ + multibuffersource$buffersource.endBatch(Sheets.hangingSignSheet()); + multibuffersource$buffersource.endBatch(Sheets.chestSheet()); + this.renderBuffers.outlineBufferSource().endOutlineBatch(); ++ // Neo: handle outline effect requests outside glowing entities ++ if (this.outlineEffectRequested) { ++ flag2 |= this.shouldShowEntityOutlines(); ++ this.outlineEffectRequested = false; ++ } + if (flag2) { + this.entityEffect.process(p_348530_.getGameTimeDeltaTicks()); this.minecraft.getMainRenderTarget().bindWrite(false); } @@ -199,7 +220,7 @@ float f = this.level.effects().getCloudHeight(); if (!Float.isNaN(f)) { float f1 = 12.0F; -@@ -2488,6 +_,23 @@ +@@ -2488,6 +_,31 @@ this.viewArea.setDirty(p_109502_, p_109503_, p_109504_, p_109505_); } @@ -219,6 +240,14 @@ + this.globalBlockEntities.forEach(blockEntityConsumer); + } + } ++ ++ /** ++ * Neo: Request outline effect post-processing to be enabled for the current frame. Must be called before block ++ * entities are done rendering, ideally early during the frame ++ */ ++ public void requestOutlineEffect() { ++ this.outlineEffectRequested = true; ++ } + public void playJukeboxSong(Holder p_350918_, BlockPos p_350830_) { if (this.level != null) { From 237b2942943865c3e1d5620e2d6ef899795826a5 Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Sun, 15 Sep 2024 12:25:07 -0400 Subject: [PATCH 070/125] Add Crying Obsidian to `c:obsidians` tag (#1536) --- src/generated/resources/data/c/tags/block/obsidians.json | 1 + src/generated/resources/data/c/tags/item/obsidians.json | 1 + .../common/data/internal/NeoForgeBlockTagsProvider.java | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/generated/resources/data/c/tags/block/obsidians.json b/src/generated/resources/data/c/tags/block/obsidians.json index aa3315f6bf..8c712061d7 100644 --- a/src/generated/resources/data/c/tags/block/obsidians.json +++ b/src/generated/resources/data/c/tags/block/obsidians.json @@ -1,6 +1,7 @@ { "values": [ "minecraft:obsidian", + "minecraft:crying_obsidian", { "id": "#forge:obsidian", "required": false diff --git a/src/generated/resources/data/c/tags/item/obsidians.json b/src/generated/resources/data/c/tags/item/obsidians.json index aa3315f6bf..8c712061d7 100644 --- a/src/generated/resources/data/c/tags/item/obsidians.json +++ b/src/generated/resources/data/c/tags/item/obsidians.json @@ -1,6 +1,7 @@ { "values": [ "minecraft:obsidian", + "minecraft:crying_obsidian", { "id": "#forge:obsidian", "required": false diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java index 71da6a581c..5d2267f05e 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java @@ -80,7 +80,7 @@ public void addTags(HolderLookup.Provider p_256380_) { tag(Tags.Blocks.SKULLS).add(Blocks.SKELETON_SKULL, Blocks.SKELETON_WALL_SKULL, Blocks.WITHER_SKELETON_SKULL, Blocks.WITHER_SKELETON_WALL_SKULL, Blocks.PLAYER_HEAD, Blocks.PLAYER_WALL_HEAD, Blocks.ZOMBIE_HEAD, Blocks.ZOMBIE_WALL_HEAD, Blocks.CREEPER_HEAD, Blocks.CREEPER_WALL_HEAD, Blocks.PIGLIN_HEAD, Blocks.PIGLIN_WALL_HEAD, Blocks.DRAGON_HEAD, Blocks.DRAGON_WALL_HEAD); tag(Tags.Blocks.HIDDEN_FROM_RECIPE_VIEWERS); tag(Tags.Blocks.NETHERRACKS).add(Blocks.NETHERRACK); - tag(Tags.Blocks.OBSIDIANS).add(Blocks.OBSIDIAN); + tag(Tags.Blocks.OBSIDIANS).add(Blocks.OBSIDIAN).add(Blocks.CRYING_OBSIDIAN); tag(Tags.Blocks.ORE_BEARING_GROUND_DEEPSLATE).add(Blocks.DEEPSLATE); tag(Tags.Blocks.ORE_BEARING_GROUND_NETHERRACK).add(Blocks.NETHERRACK); tag(Tags.Blocks.ORE_BEARING_GROUND_STONE).add(Blocks.STONE); From f3bea96194a8c2b7668bd62a93ae155a5d4e3c43 Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Sun, 15 Sep 2024 15:14:02 -0400 Subject: [PATCH 071/125] Render hover tooltip after creative menu page size rendering (#1544) --- .../CreativeModeInventoryScreen.java.patch | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch b/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch index 67ef56cafb..525825a442 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch @@ -160,16 +160,19 @@ this.refreshSearchResults(); } else { -@@ -665,7 +_,7 @@ +@@ -665,18 +_,27 @@ public void render(GuiGraphics p_283000_, int p_281317_, int p_282770_, float p_281295_) { super.render(p_283000_, p_281317_, p_282770_, p_281295_); - for (CreativeModeTab creativemodetab : CreativeModeTabs.tabs()) { -+ for(CreativeModeTab creativemodetab : currentPage.getVisibleTabs()) { - if (this.checkTabHovering(p_283000_, creativemodetab, p_281317_, p_282770_)) { - break; - } -@@ -677,6 +_,15 @@ +- if (this.checkTabHovering(p_283000_, creativemodetab, p_281317_, p_282770_)) { +- break; +- } +- } +- + if (this.destroyItemSlot != null + && selectedTab.getType() == CreativeModeTab.Type.INVENTORY + && this.isHovering(this.destroyItemSlot.x, this.destroyItemSlot.y, 16, 16, (double)p_281317_, (double)p_282770_)) { p_283000_.renderTooltip(this.font, TRASH_SLOT_TOOLTIP, p_281317_, p_282770_); } @@ -181,6 +184,12 @@ + p_283000_.pose().popPose(); + } + ++ for (CreativeModeTab creativemodetab : currentPage.getVisibleTabs()) { ++ if (this.checkTabHovering(p_283000_, creativemodetab, p_281317_, p_282770_)) { ++ break; ++ } ++ } ++ + com.mojang.blaze3d.systems.RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); this.renderTooltip(p_283000_, p_281317_, p_282770_); } From 3ae5774cdd9ed72d829e450bb05e67244408ce96 Mon Sep 17 00:00:00 2001 From: Dennis C Date: Sun, 15 Sep 2024 21:23:00 +0200 Subject: [PATCH 072/125] [1.21.1] Fix WeightedBakedModel not calling getModelData() on the nested model (#1539) --- .../client/resources/model/WeightedBakedModel.java.patch | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/patches/net/minecraft/client/resources/model/WeightedBakedModel.java.patch b/patches/net/minecraft/client/resources/model/WeightedBakedModel.java.patch index f96aeedb0e..3483772f34 100644 --- a/patches/net/minecraft/client/resources/model/WeightedBakedModel.java.patch +++ b/patches/net/minecraft/client/resources/model/WeightedBakedModel.java.patch @@ -34,7 +34,7 @@ public boolean isGui3d() { return this.wrapped.isGui3d(); } -@@ -61,8 +_,25 @@ +@@ -61,8 +_,30 @@ } @Override @@ -57,6 +57,11 @@ + return WeightedRandom.getWeightedItem(this.list, Math.abs((int)rand.nextLong()) % this.totalWeight) + .map((p_235065_) -> p_235065_.data().getRenderTypes(state, rand, data)) + .orElse(net.neoforged.neoforge.client.ChunkRenderTypeSet.none()); ++ } ++ ++ @Override ++ public net.neoforged.neoforge.client.model.data.ModelData getModelData(net.minecraft.world.level.BlockAndTintGetter level, net.minecraft.core.BlockPos pos, BlockState state, net.neoforged.neoforge.client.model.data.ModelData modelData) { ++ return this.wrapped.getModelData(level, pos, state, modelData); } @Override From e65f2b5373dfa9f01ce36198b54604410a980a2e Mon Sep 17 00:00:00 2001 From: "neoforged-renovate[bot]" <174042230+neoforged-renovate[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:37:06 +0200 Subject: [PATCH 073/125] Update dependency net.neoforged:bus to v8.0.2 (#1552) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index ce5c12aeb9..270ebe4a68 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,7 +17,7 @@ neoforge_snapshot_next_stable=22.0 mergetool_version=2.0.0 accesstransformers_version=10.0.1 coremods_version=6.0.4 -eventbus_version=8.0.1 +eventbus_version=8.0.2 modlauncher_version=11.0.4 securejarhandler_version=3.0.8 bootstraplauncher_version=2.0.2 From 46112b3f13c0109a8bb7e3c990ebe251c473957a Mon Sep 17 00:00:00 2001 From: shartte Date: Thu, 19 Sep 2024 21:37:57 +0200 Subject: [PATCH 074/125] Convert Coremods from JS to Java (#785) --- coremods/build.gradle | 46 ++++++++ .../neoforge/coremods/CoremodUtils.java | 79 ++++++++++++++ .../neoforge/coremods/MethodRedirector.java | 102 ++++++++++++++++++ .../neoforge/coremods/NeoForgeCoreMod.java | 30 ++++++ .../ReplaceFieldComparisonWithInstanceOf.java | 88 +++++++++++++++ .../ReplaceFieldWithGetterAccess.java | 92 ++++++++++++++++ .../neoforge/coremods/package-info.java | 11 ++ .../src/main/resources/META-INF/MANIFEST.MF | 3 + ...net.neoforged.neoforgespi.coremod.ICoreMod | 1 + .../coremods/finalize_spawn_targets.json | 0 projects/neoforge/build.gradle | 3 + settings.gradle | 4 + src/main/resources/META-INF/coremods.json | 6 -- .../resources/coremods/add_bouncer_method.js | 44 -------- .../resources/coremods/field_to_instanceof.js | 58 ---------- .../coremods/field_to_instanceof.json | 3 - .../resources/coremods/field_to_method.js | 40 ------- .../resources/coremods/method_redirector.js | 77 ------------- tests/build.gradle | 2 + .../debug/entity/EntityEventTests.java | 39 +++++++ .../neoforge/oldtest/FinalizeSpawnTest.java | 35 ------ 21 files changed, 500 insertions(+), 263 deletions(-) create mode 100644 coremods/build.gradle create mode 100644 coremods/src/main/java/net/neoforged/neoforge/coremods/CoremodUtils.java create mode 100644 coremods/src/main/java/net/neoforged/neoforge/coremods/MethodRedirector.java create mode 100644 coremods/src/main/java/net/neoforged/neoforge/coremods/NeoForgeCoreMod.java create mode 100644 coremods/src/main/java/net/neoforged/neoforge/coremods/ReplaceFieldComparisonWithInstanceOf.java create mode 100644 coremods/src/main/java/net/neoforged/neoforge/coremods/ReplaceFieldWithGetterAccess.java create mode 100644 coremods/src/main/java/net/neoforged/neoforge/coremods/package-info.java create mode 100644 coremods/src/main/resources/META-INF/MANIFEST.MF create mode 100644 coremods/src/main/resources/META-INF/services/net.neoforged.neoforgespi.coremod.ICoreMod rename {src/main/resources => coremods/src/main/resources/net/neoforged/neoforge}/coremods/finalize_spawn_targets.json (100%) delete mode 100644 src/main/resources/META-INF/coremods.json delete mode 100644 src/main/resources/coremods/add_bouncer_method.js delete mode 100644 src/main/resources/coremods/field_to_instanceof.js delete mode 100644 src/main/resources/coremods/field_to_instanceof.json delete mode 100644 src/main/resources/coremods/field_to_method.js delete mode 100644 src/main/resources/coremods/method_redirector.js delete mode 100644 tests/src/main/java/net/neoforged/neoforge/oldtest/FinalizeSpawnTest.java diff --git a/coremods/build.gradle b/coremods/build.gradle new file mode 100644 index 0000000000..3d942a4701 --- /dev/null +++ b/coremods/build.gradle @@ -0,0 +1,46 @@ +plugins { + id 'java-library' + id 'com.diffplug.spotless' + id 'net.neoforged.licenser' + id 'neoforge.formatting-conventions' +} + +repositories { + maven { url = 'https://maven.neoforged.net/releases' } + maven { + name 'Mojang' + url 'https://libraries.minecraft.net' + } + mavenCentral() +} + +jar { + manifest { + attributes( + "Automatic-Module-Name": "neoforge.coremods", + FMLModType: "LIBRARY", + ) + } +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(project.java_version)) + } +} + +dependencies { + compileOnly "org.jetbrains:annotations:${project.jetbrains_annotations_version}" + compileOnly "com.google.code.gson:gson:${gson_version}" + compileOnly "org.slf4j:slf4j-api:${slf4j_api_version}" + compileOnly "net.neoforged.fancymodloader:loader:${project.fancy_mod_loader_version}" +} + +license { + header = rootProject.file('codeformat/HEADER.txt') + include '**/*.java' +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' +} diff --git a/coremods/src/main/java/net/neoforged/neoforge/coremods/CoremodUtils.java b/coremods/src/main/java/net/neoforged/neoforge/coremods/CoremodUtils.java new file mode 100644 index 0000000000..52a63c2ee4 --- /dev/null +++ b/coremods/src/main/java/net/neoforged/neoforge/coremods/CoremodUtils.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.coremods; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import org.jetbrains.annotations.Nullable; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldNode; +import org.objectweb.asm.tree.MethodNode; + +final class CoremodUtils { + private static final Gson GSON = new Gson(); + + CoremodUtils() {} + + static T loadResource(String filename, TypeToken type) { + var stream = NeoForgeCoreMod.class.getResourceAsStream(filename); + if (stream == null) { + throw new IllegalStateException("Missing resource: " + filename); + } + try (var reader = new InputStreamReader(stream, StandardCharsets.UTF_8)) { + return GSON.fromJson(reader, type); + } catch (IOException e) { + throw new IllegalStateException("Failed to read JSON resource " + filename); + } + } + + static T loadResource(String filename, Class type) { + return loadResource(filename, TypeToken.get(type)); + } + + static FieldNode getFieldByName(ClassNode classNode, String fieldName) { + FieldNode foundField = null; + for (var fieldNode : classNode.fields) { + if (Objects.equals(fieldNode.name, fieldName)) { + if (foundField == null) { + foundField = fieldNode; + } else { + throw new IllegalStateException("Found multiple fields with name " + fieldName + " in " + classNode.name); + } + } + } + if (foundField == null) { + throw new IllegalStateException("No field with name " + fieldName + " found in class " + classNode.name); + } + return foundField; + } + + static MethodNode getMethodByDescriptor(ClassNode classNode, @Nullable String methodName, String methodSignature) { + MethodNode foundMethod = null; + for (var methodNode : classNode.methods) { + if (Objects.equals(methodNode.desc, methodSignature) + && (methodName == null || Objects.equals(methodNode.name, methodName))) { + if (foundMethod == null) { + foundMethod = methodNode; + } else { + throw new IllegalStateException("Found duplicate method with signature " + methodSignature + " in " + classNode.name); + } + } + } + + if (foundMethod == null) { + if (methodName != null) { + throw new IllegalStateException("Unable to find method " + methodSignature + " with name " + methodName + " in " + classNode.name); + } else { + throw new IllegalStateException("Unable to find method " + methodSignature + " in " + classNode.name); + } + } + return foundMethod; + } +} diff --git a/coremods/src/main/java/net/neoforged/neoforge/coremods/MethodRedirector.java b/coremods/src/main/java/net/neoforged/neoforge/coremods/MethodRedirector.java new file mode 100644 index 0000000000..8db3d7486d --- /dev/null +++ b/coremods/src/main/java/net/neoforged/neoforge/coremods/MethodRedirector.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.coremods; + +import cpw.mods.modlauncher.api.ITransformer; +import cpw.mods.modlauncher.api.ITransformerVotingContext; +import cpw.mods.modlauncher.api.TargetType; +import cpw.mods.modlauncher.api.TransformerVoteResult; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.MethodInsnNode; + +/** + * Redirect calls to one method to another. + */ +public class MethodRedirector implements ITransformer { + private final Map> redirectionsByClass = new HashMap<>(); + private final Set> targets = new HashSet<>(); + + private static final List REDIRECTIONS = List.of( + new MethodRedirection( + Opcodes.INVOKEVIRTUAL, + "finalizeSpawn", + "(Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/world/DifficultyInstance;Lnet/minecraft/world/entity/MobSpawnType;Lnet/minecraft/world/entity/SpawnGroupData;)Lnet/minecraft/world/entity/SpawnGroupData;", + "finalize_spawn_targets.json", + methodInsnNode -> new MethodInsnNode( + Opcodes.INVOKESTATIC, + "net/neoforged/neoforge/event/EventHooks", + "finalizeMobSpawn", + "(Lnet/minecraft/world/entity/Mob;Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/world/DifficultyInstance;Lnet/minecraft/world/entity/MobSpawnType;Lnet/minecraft/world/entity/SpawnGroupData;)Lnet/minecraft/world/entity/SpawnGroupData;", + false))); + + public MethodRedirector() { + for (var redirection : REDIRECTIONS) { + var targetClassNames = CoremodUtils.loadResource(redirection.targetClassListFile, String[].class); + for (var targetClassName : targetClassNames) { + targets.add(Target.targetClass(targetClassName)); + var redirections = redirectionsByClass.computeIfAbsent(targetClassName, s -> new ArrayList<>()); + redirections.add(redirection); + } + } + } + + @Override + public TargetType getTargetType() { + return TargetType.CLASS; + } + + @Override + public Set> targets() { + return targets; + } + + @Override + public ClassNode transform(ClassNode classNode, ITransformerVotingContext votingContext) { + var redirections = redirectionsByClass.getOrDefault(classNode.name, Collections.emptyList()); + + var methods = classNode.methods; + for (var method : methods) { + var instr = method.instructions; + for (var i = 0; i < instr.size(); i++) { + var node = instr.get(i); + if (node instanceof MethodInsnNode methodInsnNode) { + for (var redirection : redirections) { + if (redirection.invokeOpCode == methodInsnNode.getOpcode() + && redirection.methodName.equals(methodInsnNode.name) + && redirection.methodDescriptor.equals(methodInsnNode.desc)) { + // Found a match for the target method + instr.set( + methodInsnNode, + redirection.redirector.apply(methodInsnNode)); + } + } + } + } + } + return classNode; + } + + @Override + public TransformerVoteResult castVote(ITransformerVotingContext context) { + return TransformerVoteResult.YES; + } + + private record MethodRedirection( + int invokeOpCode, + String methodName, + String methodDescriptor, + String targetClassListFile, + Function redirector) {} +} diff --git a/coremods/src/main/java/net/neoforged/neoforge/coremods/NeoForgeCoreMod.java b/coremods/src/main/java/net/neoforged/neoforge/coremods/NeoForgeCoreMod.java new file mode 100644 index 0000000000..ba68da09ff --- /dev/null +++ b/coremods/src/main/java/net/neoforged/neoforge/coremods/NeoForgeCoreMod.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.coremods; + +import cpw.mods.modlauncher.api.ITransformer; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import net.neoforged.neoforgespi.coremod.ICoreMod; + +public class NeoForgeCoreMod implements ICoreMod { + @Override + public Iterable> getTransformers() { + List> transformers = new ArrayList<>(); + transformers.add(new ReplaceFieldWithGetterAccess("net.minecraft.world.level.biome.Biome", Map.of( + "climateSettings", "getModifiedClimateSettings", + "specialEffects", "getModifiedSpecialEffects"))); + transformers.add(new ReplaceFieldWithGetterAccess("net.minecraft.world.level.levelgen.structure.Structure", Map.of( + "settings", "getModifiedStructureSettings"))); + transformers.add(new ReplaceFieldWithGetterAccess("net.minecraft.world.level.block.FlowerPotBlock", Map.of( + "potted", "getPotted"))); + + transformers.add(new MethodRedirector()); + + return transformers; + } +} diff --git a/coremods/src/main/java/net/neoforged/neoforge/coremods/ReplaceFieldComparisonWithInstanceOf.java b/coremods/src/main/java/net/neoforged/neoforge/coremods/ReplaceFieldComparisonWithInstanceOf.java new file mode 100644 index 0000000000..6c8e9ff121 --- /dev/null +++ b/coremods/src/main/java/net/neoforged/neoforge/coremods/ReplaceFieldComparisonWithInstanceOf.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.coremods; + +import cpw.mods.modlauncher.api.ITransformer; +import cpw.mods.modlauncher.api.ITransformerVotingContext; +import cpw.mods.modlauncher.api.TargetType; +import cpw.mods.modlauncher.api.TransformerVoteResult; +import java.util.List; +import java.util.Set; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.FieldInsnNode; +import org.objectweb.asm.tree.JumpInsnNode; +import org.objectweb.asm.tree.MethodNode; +import org.objectweb.asm.tree.TypeInsnNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Replaces code such as {@code itemstack.getItem() == Items.CROSSBOW} with instanceof checks such + * as {@code itemstack.getItem() instanceof CrossbowItem}. + * This transformer targets a set of methods to replace the occurrence of a single field-comparison. + */ +public class ReplaceFieldComparisonWithInstanceOf implements ITransformer { + private static final Logger LOG = LoggerFactory.getLogger(ReplaceFieldComparisonWithInstanceOf.class); + + private final Set> targets; + private final String fieldOwner; + private final String fieldName; + private final String replacementClassName; + + /** + * @param fieldOwner The class that owns {@code fieldName} + * @param fieldName The name of a field in {@code fieldOwner} + * @param replacementClassName Reference comparisons against {@code fieldName} in {@code fieldOwner} are replaced + * by instanceof checks against this class. + * @param methodsToScan The methods to scan + */ + public ReplaceFieldComparisonWithInstanceOf(String fieldOwner, + String fieldName, + String replacementClassName, + List> methodsToScan) { + this.targets = Set.copyOf(methodsToScan); + + this.fieldOwner = fieldOwner; + this.fieldName = fieldName; + this.replacementClassName = replacementClassName; + } + + @Override + public TargetType getTargetType() { + return TargetType.METHOD; + } + + @Override + public Set> targets() { + return targets; + } + + @Override + public MethodNode transform(MethodNode methodNode, ITransformerVotingContext votingContext) { + var count = 0; + for (var node = methodNode.instructions.getFirst(); node != null; node = node.getNext()) { + if (node instanceof JumpInsnNode jumpNode && (jumpNode.getOpcode() == Opcodes.IF_ACMPEQ || jumpNode.getOpcode() == Opcodes.IF_ACMPNE)) { + if (node.getPrevious() instanceof FieldInsnNode fieldAccessNode && (fieldAccessNode.getOpcode() == Opcodes.GETSTATIC || fieldAccessNode.getOpcode() == Opcodes.GETFIELD)) { + if (fieldAccessNode.owner.equals(fieldOwner) && fieldAccessNode.name.equals(fieldName)) { + methodNode.instructions.set(fieldAccessNode, new TypeInsnNode(Opcodes.INSTANCEOF, replacementClassName)); + methodNode.instructions.set(jumpNode, new JumpInsnNode(jumpNode.getOpcode() == Opcodes.IF_ACMPEQ ? Opcodes.IFNE : Opcodes.IFEQ, jumpNode.label)); + count++; + } + } + } + } + + LOG.trace("Transforming: {}.", methodNode.name); + LOG.trace("field_to_instance: Replaced {} checks", count); + + return methodNode; + } + + @Override + public TransformerVoteResult castVote(ITransformerVotingContext context) { + return TransformerVoteResult.YES; + } +} diff --git a/coremods/src/main/java/net/neoforged/neoforge/coremods/ReplaceFieldWithGetterAccess.java b/coremods/src/main/java/net/neoforged/neoforge/coremods/ReplaceFieldWithGetterAccess.java new file mode 100644 index 0000000000..44c8f8a57e --- /dev/null +++ b/coremods/src/main/java/net/neoforged/neoforge/coremods/ReplaceFieldWithGetterAccess.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.coremods; + +import cpw.mods.modlauncher.api.ITransformer; +import cpw.mods.modlauncher.api.ITransformerVotingContext; +import cpw.mods.modlauncher.api.TargetType; +import cpw.mods.modlauncher.api.TransformerVoteResult; +import java.lang.reflect.Modifier; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import org.jetbrains.annotations.Nullable; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldInsnNode; +import org.objectweb.asm.tree.MethodInsnNode; + +/** + * Replaces direct field access in a class with access to the getter. + *

+ * The field specified by fieldName must be private and non-static. + * The method-call the field-access is redirected to does not take any parameters and returns an object of the + * same type as the field. + * If no methodName is passed, any method matching the described signature will be used as callable method. + */ +public class ReplaceFieldWithGetterAccess implements ITransformer { + private final Map fieldToMethod; + private final Set> targets; + + public ReplaceFieldWithGetterAccess(String className, Map fieldToMethod) { + this.targets = Set.of(Target.targetClass(className)); + this.fieldToMethod = fieldToMethod; + } + + @Override + public TargetType getTargetType() { + return TargetType.CLASS; + } + + @Override + public Set> targets() { + return targets; + } + + @Override + public ClassNode transform(ClassNode input, ITransformerVotingContext context) { + for (var entry : fieldToMethod.entrySet()) { + redirectFieldToMethod(input, entry.getKey(), entry.getValue()); + } + + return input; + } + + @Override + public TransformerVoteResult castVote(ITransformerVotingContext context) { + return TransformerVoteResult.YES; + } + + private static void redirectFieldToMethod(ClassNode classNode, String fieldName, @Nullable String methodName) { + var foundField = CoremodUtils.getFieldByName(classNode, fieldName); + + if (!Modifier.isPrivate(foundField.access) || Modifier.isStatic(foundField.access)) { + throw new IllegalStateException("Field " + fieldName + " in " + classNode.name + " is not private and an instance field"); + } + + String methodDescriptor = "()" + foundField.desc; + + var foundMethod = CoremodUtils.getMethodByDescriptor(classNode, methodName, methodDescriptor); + + for (var methodNode : classNode.methods) { + // skip the found getter method + if (methodNode != foundMethod && !Objects.equals(methodNode.desc, methodDescriptor)) { + var iterator = methodNode.instructions.iterator(); + while (iterator.hasNext()) { + var insnNode = iterator.next(); + if (insnNode.getOpcode() == Opcodes.GETFIELD) { + FieldInsnNode fieldInsnNode = (FieldInsnNode) insnNode; + if (Objects.equals(fieldInsnNode.name, fieldName)) { + iterator.remove(); + MethodInsnNode replace = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classNode.name, foundMethod.name, foundMethod.desc, false); + iterator.add(replace); + } + } + } + } + } + } +} diff --git a/coremods/src/main/java/net/neoforged/neoforge/coremods/package-info.java b/coremods/src/main/java/net/neoforged/neoforge/coremods/package-info.java new file mode 100644 index 0000000000..4bf00aa98a --- /dev/null +++ b/coremods/src/main/java/net/neoforged/neoforge/coremods/package-info.java @@ -0,0 +1,11 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +@ParametersAreNonnullByDefault +@ApiStatus.Internal +package net.neoforged.neoforge.coremods; + +import javax.annotation.ParametersAreNonnullByDefault; +import org.jetbrains.annotations.ApiStatus; diff --git a/coremods/src/main/resources/META-INF/MANIFEST.MF b/coremods/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..72a31477b2 --- /dev/null +++ b/coremods/src/main/resources/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Automatic-Module-Name: neoforge.coremods +FMLModType: LIBRARY diff --git a/coremods/src/main/resources/META-INF/services/net.neoforged.neoforgespi.coremod.ICoreMod b/coremods/src/main/resources/META-INF/services/net.neoforged.neoforgespi.coremod.ICoreMod new file mode 100644 index 0000000000..a1990f6369 --- /dev/null +++ b/coremods/src/main/resources/META-INF/services/net.neoforged.neoforgespi.coremod.ICoreMod @@ -0,0 +1 @@ +net.neoforged.neoforge.coremods.NeoForgeCoreMod \ No newline at end of file diff --git a/src/main/resources/coremods/finalize_spawn_targets.json b/coremods/src/main/resources/net/neoforged/neoforge/coremods/finalize_spawn_targets.json similarity index 100% rename from src/main/resources/coremods/finalize_spawn_targets.json rename to coremods/src/main/resources/net/neoforged/neoforge/coremods/finalize_spawn_targets.json diff --git a/projects/neoforge/build.gradle b/projects/neoforge/build.gradle index 24a2c688ca..669b21be2a 100644 --- a/projects/neoforge/build.gradle +++ b/projects/neoforge/build.gradle @@ -135,6 +135,7 @@ dependencies { } userdevTestImplementation("net.neoforged.fancymodloader:junit-fml:${project.fancy_mod_loader_version}") + compileOnly(jarJar(project(":neoforge-coremods"))) } runTypes { @@ -205,6 +206,8 @@ runs { } runs.configureEach { it -> + modSources.add project(":neoforge-coremods").sourceSets.main + final File gameDir = project.file("run/${it.name}") as File gameDir.mkdirs(); diff --git a/settings.gradle b/settings.gradle index f6be0883b4..74b177945e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -24,3 +24,7 @@ include ':tests' project(":tests").projectDir = file("tests") include ':testframework' +include ':coremods' +// Ensure a unique artifact id within JIJ that does not conflict with net.neoforged:coremods, which is +// another external dependency. +project(":coremods").name = "neoforge-coremods" diff --git a/src/main/resources/META-INF/coremods.json b/src/main/resources/META-INF/coremods.json deleted file mode 100644 index 98eab2a142..0000000000 --- a/src/main/resources/META-INF/coremods.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "field_to_method": "coremods/field_to_method.js", - "field_to_instanceof": "coremods/field_to_instanceof.js", - "add_bouncer_method": "coremods/add_bouncer_method.js", - "method_redirector": "coremods/method_redirector.js" -} diff --git a/src/main/resources/coremods/add_bouncer_method.js b/src/main/resources/coremods/add_bouncer_method.js deleted file mode 100644 index b4a25494dd..0000000000 --- a/src/main/resources/coremods/add_bouncer_method.js +++ /dev/null @@ -1,44 +0,0 @@ -var ASMAPI = Java.type('net.neoforged.coremod.api.ASMAPI') -var Opcodes = Java.type('org.objectweb.asm.Opcodes') -var MethodNode = Java.type('org.objectweb.asm.tree.MethodNode') -var VarInsnNode = Java.type('org.objectweb.asm.tree.VarInsnNode') -var MethodInsnNode = Java.type('org.objectweb.asm.tree.MethodInsnNode') -var InsnNode = Java.type('org.objectweb.asm.tree.InsnNode') - -function initializeCoreMod() { - return { - "getLanguage_bouncer": addBouncer("net.minecraft.network.play.client.CClientSettingsPacket", "func_149524_c", "getLanguage", "()Ljava/lang/String;"), - } -} - -function addBouncer(className, conflictedName, expectedName, descriptor, signature) { - if (signature == null) - signature = descriptor; - return { - 'target': { - 'type': 'CLASS', - 'name': className - }, - 'transformer': function(node) { - var mappedName = ASMAPI.mapMethod(conflictedName); - if (mappedName == expectedName) - return node; // No work to do! - - var method = new MethodNode( - /* access = */ Opcodes.ACC_PUBLIC, - /* name = */ expectedName, - /* descriptor = */ descriptor, - /* signature = */ signature, - /* exceptions = */ null - ); - - method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); /*this*/ - method.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, className.replaceAll("\\.","/"), mappedName, descriptor)); - method.instructions.add(new InsnNode(Opcodes.ARETURN)); - - node.methods.add(method); - - return node; - } - } -} \ No newline at end of file diff --git a/src/main/resources/coremods/field_to_instanceof.js b/src/main/resources/coremods/field_to_instanceof.js deleted file mode 100644 index b7a12fa546..0000000000 --- a/src/main/resources/coremods/field_to_instanceof.js +++ /dev/null @@ -1,58 +0,0 @@ -var ASMAPI = Java.type('net.neoforged.coremod.api.ASMAPI') -var Opcodes = Java.type('org.objectweb.asm.Opcodes') - -function initializeCoreMod() { - var data = ASMAPI.loadData('coremods/field_to_instanceof.json') - //ASMAPI.log('DEBUG', JSON.stringify(data, null, 2)) - - var ret = {} - for (name in data) { - addTargets(ret, name, data[name]) - } - return ret -} - -function addTargets(ret, name, data) { - var owner = data.cls - var field = ASMAPI.mapField(data.name) - var replacement = data.replacement - for (x = 0; x < data.targets.length; x++) { - var key = name + '.' + x - var entry = data.targets[x] - - //ASMAPI.log('DEBUG', 'Entry ' + key + ' ' + JSON.stringify(entry)) - - ret[key] = { - 'target': { - 'type': 'METHOD', - 'class': entry.owner, - 'methodName': entry.name, - 'methodDesc': entry.desc - }, - 'transformer': function(entry) { return function(node) { - return transform(node, entry.owner, owner, field, replacement) - }}(entry) // We have to do this annoying double function imediate call, so that JS will capture the entry value - } - } -} - -function transform(node, parent, owner, field, replacement) { - var count = 0 - var last = null - for (x = 0; x < node.instructions.size(); x++) { - var current = node.instructions.get(x) - if (current.getOpcode() == Opcodes.IF_ACMPEQ || current.getOpcode() == Opcodes.IF_ACMPNE) { - if (last != null && (last.getOpcode() == Opcodes.GETSTATIC || last.getOpcode() == Opcodes.GETFIELD)) { - if (last.owner.equals(owner) && last.name.equals(field)) { - node.instructions.set(last, new org.objectweb.asm.tree.TypeInsnNode(Opcodes.INSTANCEOF, replacement)) - node.instructions.set(current, new org.objectweb.asm.tree.JumpInsnNode(current.getOpcode() == Opcodes.IF_ACMPEQ ? Opcodes.IFNE: Opcodes.IFEQ, current.label)) - count++ - } - } - } - last = current - } - //ASMAPI.log('DEBUG', 'Transforming: ' + parent + '.' + node.name + node.desc) - //ASMAPI.log('DEBUG', 'field_to_instance: Replaced {} checks', count) - return node -} diff --git a/src/main/resources/coremods/field_to_instanceof.json b/src/main/resources/coremods/field_to_instanceof.json deleted file mode 100644 index 544b7b4ddd..0000000000 --- a/src/main/resources/coremods/field_to_instanceof.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - -} \ No newline at end of file diff --git a/src/main/resources/coremods/field_to_method.js b/src/main/resources/coremods/field_to_method.js deleted file mode 100644 index 98f4d556ba..0000000000 --- a/src/main/resources/coremods/field_to_method.js +++ /dev/null @@ -1,40 +0,0 @@ -var ASMAPI = Java.type('net.neoforged.coremod.api.ASMAPI') - -// If you add or remove a new field, -// please also add or remove a corresponding comment in the source code, -// in the interest of modders reading it. -function initializeCoreMod() { - return { - 'biome': { - 'target': { - 'type': 'CLASS', - 'name': 'net.minecraft.world.level.biome.Biome' - }, - 'transformer': function(classNode) { - ASMAPI.redirectFieldToMethod(classNode, 'climateSettings', 'getModifiedClimateSettings') - ASMAPI.redirectFieldToMethod(classNode, 'specialEffects', 'getModifiedSpecialEffects') - return classNode; - } - }, - 'structure': { - 'target': { - 'type': 'CLASS', - 'name': 'net.minecraft.world.level.levelgen.structure.Structure' - }, - 'transformer': function(classNode) { - ASMAPI.redirectFieldToMethod(classNode, 'settings', 'getModifiedStructureSettings') - return classNode; - } - }, - 'flowerpotblock': { - 'target': { - 'type': 'CLASS', - 'name': 'net.minecraft.world.level.block.FlowerPotBlock' - }, - 'transformer': function(classNode) { - ASMAPI.redirectFieldToMethod(classNode, 'potted', 'getPotted') // flower - return classNode; - } - } - } -} diff --git a/src/main/resources/coremods/method_redirector.js b/src/main/resources/coremods/method_redirector.js deleted file mode 100644 index 80417a48ee..0000000000 --- a/src/main/resources/coremods/method_redirector.js +++ /dev/null @@ -1,77 +0,0 @@ -var ASMAPI = Java.type('net.neoforged.coremod.api.ASMAPI'); -var Opcodes = Java.type('org.objectweb.asm.Opcodes'); -var Handle = Java.type('org.objectweb.asm.Handle'); -var MethodInsnNode = Java.type('org.objectweb.asm.tree.MethodInsnNode'); - -function finalizeSpawnNode(node){ - return new MethodInsnNode( - Opcodes.INVOKESTATIC, - "net/neoforged/neoforge/event/EventHooks", - "finalizeMobSpawn", - "(Lnet/minecraft/world/entity/Mob;Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/world/DifficultyInstance;Lnet/minecraft/world/entity/MobSpawnType;Lnet/minecraft/world/entity/SpawnGroupData;)Lnet/minecraft/world/entity/SpawnGroupData;", - false); -} - -function contains(list, target) { - for(var i = 0; i < list.length; i++) { - if(list[i] == target) return true; - } - return false; -} - -function search(className, node, replacements) { - for(var i = 0; i < replacements.length; i++){ - var r = replacements[i]; - if(contains(r.targets, className) && node.getOpcode() == r.opcode && node.name == r.name && node.desc == r.desc) { - return r; - } - } - return null; -} - -var replacements = [ - { - 'opcode': Opcodes.INVOKEVIRTUAL, - 'name': 'finalizeSpawn', - 'desc': '(Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/world/DifficultyInstance;Lnet/minecraft/world/entity/MobSpawnType;Lnet/minecraft/world/entity/SpawnGroupData;)Lnet/minecraft/world/entity/SpawnGroupData;', - 'targets': 'coremods/finalize_spawn_targets.json', - 'factory': finalizeSpawnNode - } -]; - -function initializeCoreMod() { - var mergedTargets = []; - for(var i = 0; i < replacements.length; i++){ - var r = replacements[i]; - r.targets = ASMAPI.loadData(r.targets); - for(var k = 0; k < r.targets.length; k++){ - mergedTargets.push(r.targets[k]); - } - } - - return { - 'neoforge_method_redirector': { - 'target': { - 'type': 'CLASS', - 'names': function(listofclasses) { - return mergedTargets - } - }, - 'transformer': function(classNode) { - var methods = classNode.methods; - var count = 0; - for(var i = 0; i < methods.size(); i++){ - var instr = methods.get(i).instructions; - for(var ix = 0; ix < instr.size(); ix++){ - var node = instr.get(ix); - var temp = search(classNode.name, node, replacements); - if (temp != null) { - instr.set(node, temp.factory(node)); - } - } - } - return classNode; - } - } - } -} diff --git a/tests/build.gradle b/tests/build.gradle index d724be0976..2da20a4e40 100644 --- a/tests/build.gradle +++ b/tests/build.gradle @@ -8,6 +8,7 @@ plugins { def neoforgeProject = project(':neoforge') def testframeworkProject = project(':testframework') +def coremodsProject = project(':neoforge-coremods') repositories { mavenLocal() @@ -99,6 +100,7 @@ runs.configureEach { dependsOn.add(neoforgeProject.runtime.assets) dependsOn.add(neoforgeProject.runtime.natives) modSource neoforgeProject.sourceSets.main + modSource coremodsProject.sourceSets.main modSource testframeworkProject.sourceSets.main } diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/entity/EntityEventTests.java b/tests/src/main/java/net/neoforged/neoforge/debug/entity/EntityEventTests.java index b57efcec2e..7099e33cca 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/entity/EntityEventTests.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/entity/EntityEventTests.java @@ -6,6 +6,7 @@ package net.neoforged.neoforge.debug.entity; import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; import net.minecraft.core.BlockPos; import net.minecraft.core.registries.Registries; import net.minecraft.gametest.framework.GameTest; @@ -13,6 +14,7 @@ import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobSpawnType; import net.minecraft.world.entity.ai.attributes.RangedAttribute; import net.minecraft.world.entity.animal.Cow; import net.minecraft.world.entity.animal.Pig; @@ -27,8 +29,10 @@ import net.neoforged.neoforge.event.entity.EntityInvulnerabilityCheckEvent; import net.neoforged.neoforge.event.entity.EntityTeleportEvent; import net.neoforged.neoforge.event.entity.EntityTravelToDimensionEvent; +import net.neoforged.neoforge.event.entity.living.FinalizeSpawnEvent; import net.neoforged.neoforge.event.level.ExplosionKnockbackEvent; import net.neoforged.testframework.DynamicTest; +import net.neoforged.testframework.Test; import net.neoforged.testframework.annotation.ForEachTest; import net.neoforged.testframework.annotation.TestHolder; import net.neoforged.testframework.gametest.EmptyTemplate; @@ -165,4 +169,39 @@ static void entityTravelToDimensionEvent(final DynamicTest test) { .thenExecute(helper::killAllEntities) .thenSucceed()); } + + @GameTest + @EmptyTemplate(floor = true) + @TestHolder(description = "Tests that the FinalizeSpawnEvent is emitted at all") + static void entityFinalizeSpawnEvent(final DynamicTest test) { + // Identify the entity we spawn in this test by their spawn location, since we do not have + // access to the entity object at all before the event is emitted. + AtomicReference spawnPosRef = new AtomicReference<>(); + test.eventListeners().forge().addListener((final FinalizeSpawnEvent event) -> { + if (Objects.equals(spawnPosRef.get(), event.getEntity().blockPosition())) { + event.setSpawnCancelled(true); + test.pass(); + } + }); + + test.onGameTest(helper -> helper.startSequence() + .thenExecute(() -> { + var spawnPos = helper.absolutePos(BlockPos.ZERO); + spawnPosRef.set(spawnPos); + EntityType.PIG.create( + helper.getLevel(), + ignored -> {}, + spawnPos, + MobSpawnType.SPAWN_EGG, + false, + false); + }) + .thenExecute(() -> { + // The event handler canceled the spawn + helper.assertEntityNotPresent(EntityType.PIG); + }) + .thenWaitUntil(() -> helper.assertValueEqual(test.status(), Test.Status.PASSED, "listener called")) + .thenExecute(helper::killAllEntities) + .thenSucceed()); + } } diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/FinalizeSpawnTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/FinalizeSpawnTest.java deleted file mode 100644 index 8c440fcff6..0000000000 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/FinalizeSpawnTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.oldtest; - -import net.minecraft.network.chat.Component; -import net.minecraft.world.entity.EntityType; -import net.neoforged.fml.common.Mod; -import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.event.entity.living.FinalizeSpawnEvent; - -@Mod(FinalizeSpawnTest.ID) -public class FinalizeSpawnTest { - public static final String ID = "finalize_spawn_fix_test"; - public static final boolean ENABLED = false; - - public FinalizeSpawnTest() { - NeoForge.EVENT_BUS.addListener(FinalizeSpawnEvent.class, event -> { - var entityType = EntityType.WANDERING_TRADER; - var entity = event.getEntity(); - - // testing with wandering trader to validate the following - // - ambient sounds dont play for cancelled mob spawns - // - llamas dont spawn for cancelled trader spawns - // but this test is not specific to wandering traders - if (ENABLED && entity.getType() == entityType) { - // some debug message to say entity spawn was cancelled - event.getLevel().players().forEach(player -> player.displayClientMessage(Component.literal("Cancelled %s spawn @ %s".formatted(entityType.getDescription().getString(), entity.position())), true)); - event.setSpawnCancelled(true); - } - }); - } -} From 42023dc3e3284b7046791403db04649999389ba3 Mon Sep 17 00:00:00 2001 From: Henry Loenwind Date: Fri, 20 Sep 2024 07:45:13 +0200 Subject: [PATCH 075/125] Fix GrindstoneEvent.OnPlaceItem patch (#1549) --- .../world/inventory/GrindstoneMenu.java.patch | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/patches/net/minecraft/world/inventory/GrindstoneMenu.java.patch b/patches/net/minecraft/world/inventory/GrindstoneMenu.java.patch index 55e782bb5c..9c769897c2 100644 --- a/patches/net/minecraft/world/inventory/GrindstoneMenu.java.patch +++ b/patches/net/minecraft/world/inventory/GrindstoneMenu.java.patch @@ -40,15 +40,15 @@ int l = 0; l += this.getExperienceFromItem(GrindstoneMenu.this.repairSlots.getItem(0)); l += this.getExperienceFromItem(GrindstoneMenu.this.repairSlots.getItem(1)); -@@ -131,6 +_,8 @@ +@@ -125,6 +_,8 @@ + } - private ItemStack computeResult(ItemStack p_332654_, ItemStack p_332736_) { - boolean flag = !p_332654_.isEmpty() || !p_332736_.isEmpty(); -+ this.xp = net.neoforged.neoforge.common.CommonHooks.onGrindstoneChange(p_332654_, p_332736_, this.resultSlots, -1); -+ if (this.xp != Integer.MIN_VALUE) return ItemStack.EMPTY; // Porting 1.20.5 check if this is correct - if (!flag) { - return ItemStack.EMPTY; - } else if (p_332654_.getCount() <= 1 && p_332736_.getCount() <= 1) { + private void createResult() { ++ this.xp = net.neoforged.neoforge.common.CommonHooks.onGrindstoneChange(this.repairSlots.getItem(0), this.repairSlots.getItem(1), this.resultSlots, -1); ++ if (this.xp == Integer.MIN_VALUE) + this.resultSlots.setItem(0, this.computeResult(this.repairSlots.getItem(0), this.repairSlots.getItem(1))); + this.broadcastChanges(); + } @@ -155,7 +_,7 @@ int k = p_332686_.getMaxDamage() - p_332686_.getDamageValue(); int l = j + k + i * 5 / 100; From 600c87012e3c9ebb5797ad4d1d4ff75f54fbe2cf Mon Sep 17 00:00:00 2001 From: AR <1516775492@qq.com> Date: Mon, 23 Sep 2024 08:49:03 +0800 Subject: [PATCH 076/125] Allow Datapack Registries to be configured by RegistryBuilder (#1447) This PR allows data registries to be configured through RegistryBuilder, which permits adding callbacks and setting a default return value. --- .../resources/RegistryDataLoader.java.patch | 23 ++++++++++++++++++ .../registries/DataPackRegistryEvent.java | 24 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/patches/net/minecraft/resources/RegistryDataLoader.java.patch b/patches/net/minecraft/resources/RegistryDataLoader.java.patch index 0453b55915..13d15f4bb3 100644 --- a/patches/net/minecraft/resources/RegistryDataLoader.java.patch +++ b/patches/net/minecraft/resources/RegistryDataLoader.java.patch @@ -46,3 +46,26 @@ for (Entry entry : filetoidconverter.listMatchingResources(p_321535_).entrySet()) { ResourceLocation resourcelocation = entry.getKey(); +@@ -304,13 +_,20 @@ + void apply(RegistryDataLoader.Loader p_321864_, RegistryOps.RegistryInfoLookup p_321656_); + } + +- public static record RegistryData(ResourceKey> key, Codec elementCodec, boolean requiredNonEmpty) { ++ public static record RegistryData(ResourceKey> key, Codec elementCodec, boolean requiredNonEmpty, java.util.function.Consumer> registryBuilderConsumer) { ++ public RegistryData(ResourceKey> key, Codec elementCodec, boolean requiredNonEmpty) { ++ this(key, elementCodec, requiredNonEmpty, registryBuilder -> {}); ++ } ++ + RegistryData(ResourceKey> p_251360_, Codec p_248976_) { + this(p_251360_, p_248976_, false); + } + + RegistryDataLoader.Loader create(Lifecycle p_251662_, Map, Exception> p_251565_) { +- WritableRegistry writableregistry = new MappedRegistry<>(this.key, p_251662_); ++ net.neoforged.neoforge.registries.RegistryBuilder registryBuilder = new net.neoforged.neoforge.registries.RegistryBuilder<>(key); ++ registryBuilderConsumer.accept(registryBuilder); ++ ++ WritableRegistry writableregistry = (WritableRegistry) registryBuilder.disableRegistrationCheck().create(); + return new RegistryDataLoader.Loader<>(this, writableregistry, p_251565_); + } + diff --git a/src/main/java/net/neoforged/neoforge/registries/DataPackRegistryEvent.java b/src/main/java/net/neoforged/neoforge/registries/DataPackRegistryEvent.java index b316e643a2..8fee27ff8e 100644 --- a/src/main/java/net/neoforged/neoforge/registries/DataPackRegistryEvent.java +++ b/src/main/java/net/neoforged/neoforge/registries/DataPackRegistryEvent.java @@ -8,6 +8,7 @@ import com.mojang.serialization.Codec; import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.core.Registry; import net.minecraft.resources.RegistryDataLoader; @@ -74,6 +75,29 @@ public void dataPackRegistry(ResourceKey> registryKey, Codec this.registryDataList.add(new DataPackRegistryData<>(new RegistryDataLoader.RegistryData<>(registryKey, codec, false), networkCodec)); } + /** + * Registers the registry key as a datapack registry with a {@link RegistryBuilder} configurator, which will cause data to be loaded from + * a datapack folder based on the registry's name. + *

+ * Data JSONs will be loaded from {@code data//modid/registryname/}, where {@code modid} is the namespace of the registry key. + * + * @param registryKey the root registry key of the new datapack registry + * @param codec the codec to be used for loading data from datapacks on servers + * @param networkCodec the codec to be used for syncing loaded data to clients. + * If {@code networkCodec} is null, data will not be synced, and clients are not required to have this + * datapack registry to join a server. + *

+ * If {@code networkCodec} is not null, clients must have this datapack registry/mod + * when joining a server that has this datapack registry/mod. + * The data will be synced using the network codec and accessible via {@link ClientPacketListener#registryAccess()}. + * @param consumer A consumer that configures the provided RegistryBuilder + * @see #dataPackRegistry(ResourceKey, Codec) + * @see #dataPackRegistry(ResourceKey, Codec, Codec) + */ + public void dataPackRegistry(ResourceKey> registryKey, Codec codec, @Nullable Codec networkCodec, Consumer> consumer) { + this.registryDataList.add(new DataPackRegistryData<>(new RegistryDataLoader.RegistryData<>(registryKey, codec, false, consumer), networkCodec)); + } + void process() { for (DataPackRegistryData registryData : this.registryDataList) { DataPackRegistriesHooks.addRegistryCodec(registryData); From 762725e95def8b5bb1bf168a4ead233d7e0f686e Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Mon, 23 Sep 2024 19:34:48 -0400 Subject: [PATCH 077/125] Add `c:obsidians/normal` and `c:obsidians/crying` subtags (#1556) --- src/generated/resources/assets/c/lang/en_us.json | 4 ++++ .../resources/data/c/tags/block/obsidians.json | 4 ++-- .../data/c/tags/block/obsidians/crying.json | 5 +++++ .../data/c/tags/block/obsidians/normal.json | 5 +++++ .../resources/data/c/tags/item/obsidians.json | 4 ++-- .../resources/data/c/tags/item/obsidians/crying.json | 5 +++++ .../resources/data/c/tags/item/obsidians/normal.json | 5 +++++ .../java/net/neoforged/neoforge/common/Tags.java | 12 ++++++++++++ .../data/internal/NeoForgeBlockTagsProvider.java | 4 +++- .../data/internal/NeoForgeItemTagsProvider.java | 2 ++ .../data/internal/NeoForgeLanguageProvider.java | 4 ++++ 11 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 src/generated/resources/data/c/tags/block/obsidians/crying.json create mode 100644 src/generated/resources/data/c/tags/block/obsidians/normal.json create mode 100644 src/generated/resources/data/c/tags/item/obsidians/crying.json create mode 100644 src/generated/resources/data/c/tags/item/obsidians/normal.json diff --git a/src/generated/resources/assets/c/lang/en_us.json b/src/generated/resources/assets/c/lang/en_us.json index 1988c30b51..73ff339a03 100644 --- a/src/generated/resources/assets/c/lang/en_us.json +++ b/src/generated/resources/assets/c/lang/en_us.json @@ -53,6 +53,8 @@ "tag.block.c.hidden_from_recipe_viewers": "Hidden From Recipe Viewers", "tag.block.c.netherracks": "Netherracks", "tag.block.c.obsidians": "Obsidians", + "tag.block.c.obsidians.crying": "Crying Obsidians", + "tag.block.c.obsidians.normal": "Normal Obsidians", "tag.block.c.ore_bearing_ground.deepslate": "Deepslate Ore Bearing Ground", "tag.block.c.ore_bearing_ground.netherrack": "Netherrack Ore Bearing Ground", "tag.block.c.ore_bearing_ground.stone": "Stone Ore Bearing Ground", @@ -272,6 +274,8 @@ "tag.item.c.nuggets.gold": "Gold Nuggets", "tag.item.c.nuggets.iron": "Iron Nuggets", "tag.item.c.obsidians": "Obsidians", + "tag.item.c.obsidians.crying": "Crying Obsidians", + "tag.item.c.obsidians.normal": "Normal Obsidians", "tag.item.c.ore_bearing_ground.deepslate": "Deepslate Ore Bearing Ground", "tag.item.c.ore_bearing_ground.netherrack": "Netherrack Ore Bearing Ground", "tag.item.c.ore_bearing_ground.stone": "Stone Ore Bearing Ground", diff --git a/src/generated/resources/data/c/tags/block/obsidians.json b/src/generated/resources/data/c/tags/block/obsidians.json index 8c712061d7..3986b73df1 100644 --- a/src/generated/resources/data/c/tags/block/obsidians.json +++ b/src/generated/resources/data/c/tags/block/obsidians.json @@ -1,7 +1,7 @@ { "values": [ - "minecraft:obsidian", - "minecraft:crying_obsidian", + "#c:obsidians/normal", + "#c:obsidians/crying", { "id": "#forge:obsidian", "required": false diff --git a/src/generated/resources/data/c/tags/block/obsidians/crying.json b/src/generated/resources/data/c/tags/block/obsidians/crying.json new file mode 100644 index 0000000000..2e8b37a1bc --- /dev/null +++ b/src/generated/resources/data/c/tags/block/obsidians/crying.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:crying_obsidian" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/obsidians/normal.json b/src/generated/resources/data/c/tags/block/obsidians/normal.json new file mode 100644 index 0000000000..170248454b --- /dev/null +++ b/src/generated/resources/data/c/tags/block/obsidians/normal.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:obsidian" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/obsidians.json b/src/generated/resources/data/c/tags/item/obsidians.json index 8c712061d7..3986b73df1 100644 --- a/src/generated/resources/data/c/tags/item/obsidians.json +++ b/src/generated/resources/data/c/tags/item/obsidians.json @@ -1,7 +1,7 @@ { "values": [ - "minecraft:obsidian", - "minecraft:crying_obsidian", + "#c:obsidians/normal", + "#c:obsidians/crying", { "id": "#forge:obsidian", "required": false diff --git a/src/generated/resources/data/c/tags/item/obsidians/crying.json b/src/generated/resources/data/c/tags/item/obsidians/crying.json new file mode 100644 index 0000000000..2e8b37a1bc --- /dev/null +++ b/src/generated/resources/data/c/tags/item/obsidians/crying.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:crying_obsidian" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/obsidians/normal.json b/src/generated/resources/data/c/tags/item/obsidians/normal.json new file mode 100644 index 0000000000..170248454b --- /dev/null +++ b/src/generated/resources/data/c/tags/item/obsidians/normal.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:obsidian" + ] +} \ No newline at end of file diff --git a/src/main/java/net/neoforged/neoforge/common/Tags.java b/src/main/java/net/neoforged/neoforge/common/Tags.java index c02af99a73..56620f22d4 100644 --- a/src/main/java/net/neoforged/neoforge/common/Tags.java +++ b/src/main/java/net/neoforged/neoforge/common/Tags.java @@ -115,6 +115,12 @@ public static class Blocks { public static final TagKey HIDDEN_FROM_RECIPE_VIEWERS = tag("hidden_from_recipe_viewers"); public static final TagKey NETHERRACKS = tag("netherracks"); public static final TagKey OBSIDIANS = tag("obsidians"); + /** + * For common obsidian that has no special quirks or behaviors. Ideal for recipe use. + * Crying Obsidian, for example, is a light block and harder to obtain. So it gets its own tag instead of being under normal tag. + */ + public static final TagKey OBSIDIANS_NORMAL = tag("obsidians/normal"); + public static final TagKey OBSIDIANS_CRYING = tag("obsidians/crying"); /** * Blocks which are often replaced by deepslate ores, i.e. the ores in the tag {@link #ORES_IN_GROUND_DEEPSLATE}, during world generation */ @@ -485,6 +491,12 @@ public static class Items { public static final TagKey NUGGETS_GOLD = tag("nuggets/gold"); public static final TagKey NUGGETS_IRON = tag("nuggets/iron"); public static final TagKey OBSIDIANS = tag("obsidians"); + /** + * For common obsidian that has no special quirks or behaviors. Ideal for recipe use. + * Crying Obsidian, for example, is a light block and harder to obtain. So it gets its own tag instead of being under normal tag. + */ + public static final TagKey OBSIDIANS_NORMAL = tag("obsidians/normal"); + public static final TagKey OBSIDIANS_CRYING = tag("obsidians/crying"); /** * Blocks which are often replaced by deepslate ores, i.e. the ores in the tag {@link #ORES_IN_GROUND_DEEPSLATE}, during world generation */ diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java index 5d2267f05e..8a689441d4 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java @@ -80,7 +80,9 @@ public void addTags(HolderLookup.Provider p_256380_) { tag(Tags.Blocks.SKULLS).add(Blocks.SKELETON_SKULL, Blocks.SKELETON_WALL_SKULL, Blocks.WITHER_SKELETON_SKULL, Blocks.WITHER_SKELETON_WALL_SKULL, Blocks.PLAYER_HEAD, Blocks.PLAYER_WALL_HEAD, Blocks.ZOMBIE_HEAD, Blocks.ZOMBIE_WALL_HEAD, Blocks.CREEPER_HEAD, Blocks.CREEPER_WALL_HEAD, Blocks.PIGLIN_HEAD, Blocks.PIGLIN_WALL_HEAD, Blocks.DRAGON_HEAD, Blocks.DRAGON_WALL_HEAD); tag(Tags.Blocks.HIDDEN_FROM_RECIPE_VIEWERS); tag(Tags.Blocks.NETHERRACKS).add(Blocks.NETHERRACK); - tag(Tags.Blocks.OBSIDIANS).add(Blocks.OBSIDIAN).add(Blocks.CRYING_OBSIDIAN); + tag(Tags.Blocks.OBSIDIANS_NORMAL).add(Blocks.OBSIDIAN); + tag(Tags.Blocks.OBSIDIANS_CRYING).add(Blocks.CRYING_OBSIDIAN); + tag(Tags.Blocks.OBSIDIANS).addTags(Tags.Blocks.OBSIDIANS_NORMAL, Tags.Blocks.OBSIDIANS_CRYING); tag(Tags.Blocks.ORE_BEARING_GROUND_DEEPSLATE).add(Blocks.DEEPSLATE); tag(Tags.Blocks.ORE_BEARING_GROUND_NETHERRACK).add(Blocks.NETHERRACK); tag(Tags.Blocks.ORE_BEARING_GROUND_STONE).add(Blocks.STONE); diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java index b717c155ad..13013eb54d 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java @@ -171,6 +171,8 @@ public void addTags(HolderLookup.Provider lookupProvider) { tag(Tags.Items.NUGGETS_IRON).add(Items.IRON_NUGGET); tag(Tags.Items.NUGGETS_GOLD).add(Items.GOLD_NUGGET); copy(Tags.Blocks.OBSIDIANS, Tags.Items.OBSIDIANS); + copy(Tags.Blocks.OBSIDIANS_NORMAL, Tags.Items.OBSIDIANS_NORMAL); + copy(Tags.Blocks.OBSIDIANS_CRYING, Tags.Items.OBSIDIANS_CRYING); copy(Tags.Blocks.ORE_BEARING_GROUND_DEEPSLATE, Tags.Items.ORE_BEARING_GROUND_DEEPSLATE); copy(Tags.Blocks.ORE_BEARING_GROUND_NETHERRACK, Tags.Items.ORE_BEARING_GROUND_NETHERRACK); copy(Tags.Blocks.ORE_BEARING_GROUND_STONE, Tags.Items.ORE_BEARING_GROUND_STONE); diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java index bb2a30e4f2..ebac817994 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java @@ -69,6 +69,8 @@ protected void addTranslations() { add(Tags.Blocks.NEEDS_GOLD_TOOL, "Needs Gold Tools"); add(Tags.Blocks.NEEDS_NETHERITE_TOOL, "Needs Netherite Tools"); add(Tags.Blocks.OBSIDIANS, "Obsidians"); + add(Tags.Blocks.OBSIDIANS_NORMAL, "Normal Obsidians"); + add(Tags.Blocks.OBSIDIANS_CRYING, "Crying Obsidians"); add(Tags.Blocks.ORE_BEARING_GROUND_DEEPSLATE, "Deepslate Ore Bearing Ground"); add(Tags.Blocks.ORE_BEARING_GROUND_NETHERRACK, "Netherrack Ore Bearing Ground"); add(Tags.Blocks.ORE_BEARING_GROUND_STONE, "Stone Ore Bearing Ground"); @@ -247,6 +249,8 @@ protected void addTranslations() { add(Tags.Items.NUGGETS_IRON, "Iron Nuggets"); add(Tags.Items.NUGGETS_GOLD, "Gold Nuggets"); add(Tags.Items.OBSIDIANS, "Obsidians"); + add(Tags.Items.OBSIDIANS_NORMAL, "Normal Obsidians"); + add(Tags.Items.OBSIDIANS_CRYING, "Crying Obsidians"); add(Tags.Items.ORE_BEARING_GROUND_DEEPSLATE, "Deepslate Ore Bearing Ground"); add(Tags.Items.ORE_BEARING_GROUND_NETHERRACK, "Netherrack Ore Bearing Ground"); add(Tags.Items.ORE_BEARING_GROUND_STONE, "Stone Ore Bearing Ground"); From 5a2503ed44274cfcc825f93c7df87348357c0644 Mon Sep 17 00:00:00 2001 From: Brennan Ward Date: Mon, 23 Sep 2024 22:24:30 -0700 Subject: [PATCH 078/125] [1.21] Add an Attribute formatting API for better control of attribute tooltips (#1551) This PR adds `IAttributeExtension`, which supplies many methods allowing attributes to control their own formatting. It updates `BooleanAttribute` to use this formatting system, and also adds `PercentageAttribute` for use by attributes better displayed as percentages. It also adds support for attribute tooltip merging (which must be enabled by a mod), and two new events: `GatherSkippedAttributeTooltipsEvent` and `AddAttributeTooltipsEvent`. --- .../entity/ai/attributes/Attribute.java.patch | 33 ++ .../ai/attributes/Attributes.java.patch | 22 ++ .../minecraft/world/item/ItemStack.java.patch | 20 +- .../item/alchemy/PotionContents.java.patch | 13 + .../event/AddAttributeTooltipsEvent.java | 66 ++++ .../GatherSkippedAttributeTooltipsEvent.java | 118 ++++++ .../neoforge/common/BooleanAttribute.java | 29 ++ .../neoforge/common/NeoForgeMod.java | 18 +- .../neoforge/common/PercentageAttribute.java | 51 +++ .../extensions/IAttributeExtension.java | 155 ++++++++ .../common/util/AttributeTooltipContext.java | 67 ++++ .../neoforge/common/util/AttributeUtil.java | 356 ++++++++++++++++++ .../resources/assets/neoforge/lang/en_us.json | 17 +- 13 files changed, 958 insertions(+), 7 deletions(-) create mode 100644 patches/net/minecraft/world/entity/ai/attributes/Attribute.java.patch create mode 100644 patches/net/minecraft/world/entity/ai/attributes/Attributes.java.patch create mode 100644 patches/net/minecraft/world/item/alchemy/PotionContents.java.patch create mode 100644 src/main/java/net/neoforged/neoforge/client/event/AddAttributeTooltipsEvent.java create mode 100644 src/main/java/net/neoforged/neoforge/client/event/GatherSkippedAttributeTooltipsEvent.java create mode 100644 src/main/java/net/neoforged/neoforge/common/PercentageAttribute.java create mode 100644 src/main/java/net/neoforged/neoforge/common/extensions/IAttributeExtension.java create mode 100644 src/main/java/net/neoforged/neoforge/common/util/AttributeTooltipContext.java create mode 100644 src/main/java/net/neoforged/neoforge/common/util/AttributeUtil.java diff --git a/patches/net/minecraft/world/entity/ai/attributes/Attribute.java.patch b/patches/net/minecraft/world/entity/ai/attributes/Attribute.java.patch new file mode 100644 index 0000000000..3863a37e98 --- /dev/null +++ b/patches/net/minecraft/world/entity/ai/attributes/Attribute.java.patch @@ -0,0 +1,33 @@ +--- a/net/minecraft/world/entity/ai/attributes/Attribute.java ++++ b/net/minecraft/world/entity/ai/attributes/Attribute.java +@@ -9,7 +_,7 @@ + import net.minecraft.network.codec.ByteBufCodecs; + import net.minecraft.network.codec.StreamCodec; + +-public class Attribute { ++public class Attribute implements net.neoforged.neoforge.common.extensions.IAttributeExtension { + public static final Codec> CODEC = BuiltInRegistries.ATTRIBUTE.holderByNameCodec(); + public static final StreamCodec> STREAM_CODEC = ByteBufCodecs.holderRegistry(Registries.ATTRIBUTE); + private final double defaultValue; +@@ -50,6 +_,21 @@ + + public ChatFormatting getStyle(boolean p_347715_) { + return this.sentiment.getStyle(p_347715_); ++ } ++ ++ // Neo: Patch in the default implementation of IAttributeExtension#getMergedStyle since we need access to Attribute#sentiment ++ ++ protected static final net.minecraft.network.chat.TextColor MERGED_RED = net.minecraft.network.chat.TextColor.fromRgb(0xF93131); ++ protected static final net.minecraft.network.chat.TextColor MERGED_BLUE = net.minecraft.network.chat.TextColor.fromRgb(0x7A7AF9); ++ protected static final net.minecraft.network.chat.TextColor MERGED_GRAY = net.minecraft.network.chat.TextColor.fromRgb(0xCCCCCC); ++ ++ @Override ++ public net.minecraft.network.chat.TextColor getMergedStyle(boolean isPositive) { ++ return switch (this.sentiment) { ++ case POSITIVE -> isPositive ? MERGED_BLUE : MERGED_RED; ++ case NEGATIVE -> isPositive ? MERGED_RED : MERGED_BLUE; ++ case NEUTRAL -> MERGED_GRAY; ++ }; + } + + public static enum Sentiment { diff --git a/patches/net/minecraft/world/entity/ai/attributes/Attributes.java.patch b/patches/net/minecraft/world/entity/ai/attributes/Attributes.java.patch new file mode 100644 index 0000000000..ebf3e8fe30 --- /dev/null +++ b/patches/net/minecraft/world/entity/ai/attributes/Attributes.java.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/world/entity/ai/attributes/Attributes.java ++++ b/net/minecraft/world/entity/ai/attributes/Attributes.java +@@ -54,7 +_,8 @@ + "generic.jump_strength", new RangedAttribute("attribute.name.generic.jump_strength", 0.42F, 0.0, 32.0).setSyncable(true) + ); + public static final Holder KNOCKBACK_RESISTANCE = register( +- "generic.knockback_resistance", new RangedAttribute("attribute.name.generic.knockback_resistance", 0.0, 0.0, 1.0) ++ // Neo: Convert Knockback Resistance to percent-based for more appropriate display using IAttributeExtension. ++ "generic.knockback_resistance", new net.neoforged.neoforge.common.PercentageAttribute("attribute.name.generic.knockback_resistance", 0.0, 0.0, 1.0) + ); + public static final Holder LUCK = register( + "generic.luck", new RangedAttribute("attribute.name.generic.luck", 0.0, -1024.0, 1024.0).setSyncable(true) +@@ -72,7 +_,8 @@ + "generic.movement_efficiency", new RangedAttribute("attribute.name.generic.movement_efficiency", 0.0, 0.0, 1.0).setSyncable(true) + ); + public static final Holder MOVEMENT_SPEED = register( +- "generic.movement_speed", new RangedAttribute("attribute.name.generic.movement_speed", 0.7, 0.0, 1024.0).setSyncable(true) ++ // Neo: Convert Movement Speed to percent-based for more appropriate display using IAttributeExtension. Use a scale factor of 1000 since movement speed has 0.001 units. ++ "generic.movement_speed", new net.neoforged.neoforge.common.PercentageAttribute("attribute.name.generic.movement_speed", 0.7, 0.0, 1024.0, 1000).setSyncable(true) + ); + public static final Holder OXYGEN_BONUS = register( + "generic.oxygen_bonus", new RangedAttribute("attribute.name.generic.oxygen_bonus", 0.0, 0.0, 1024.0).setSyncable(true) diff --git a/patches/net/minecraft/world/item/ItemStack.java.patch b/patches/net/minecraft/world/item/ItemStack.java.patch index 4c1f77b59b..7f753b99da 100644 --- a/patches/net/minecraft/world/item/ItemStack.java.patch +++ b/patches/net/minecraft/world/item/ItemStack.java.patch @@ -148,7 +148,18 @@ if (this.has(DataComponents.CUSTOM_NAME)) { mutablecomponent.withStyle(ChatFormatting.ITALIC); } -@@ -784,12 +_,14 @@ +@@ -752,7 +_,9 @@ + this.addToTooltip(DataComponents.ENCHANTMENTS, p_339637_, consumer, p_41653_); + this.addToTooltip(DataComponents.DYED_COLOR, p_339637_, consumer, p_41653_); + this.addToTooltip(DataComponents.LORE, p_339637_, consumer, p_41653_); +- this.addAttributeTooltips(consumer, p_41652_); ++ // Neo: Replace attribute tooltips with custom handling ++ net.neoforged.neoforge.common.util.AttributeUtil.addAttributeTooltips(this, consumer, ++ net.neoforged.neoforge.common.util.AttributeTooltipContext.of(p_41652_, p_339637_, p_41653_)); + this.addToTooltip(DataComponents.UNBREAKABLE, p_339637_, consumer, p_41653_); + AdventureModePredicate adventuremodepredicate = this.get(DataComponents.CAN_BREAK); + if (adventuremodepredicate != null && adventuremodepredicate.showInTooltip()) { +@@ -784,10 +_,15 @@ list.add(DISABLED_ITEM_TOOLTIP); } @@ -157,12 +168,13 @@ } } ++ /** ++ * @deprecated Neo: Use {@link net.neoforged.neoforge.client.util.TooltipUtil#addAttributeTooltips} ++ */ ++ @Deprecated private void addAttributeTooltips(Consumer p_330796_, @Nullable Player p_330530_) { ItemAttributeModifiers itemattributemodifiers = this.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY); -+ // Neo: We don't need to call IItemStackExtension#getAttributeModifiers here, since it will be done in forEachModifier. if (itemattributemodifiers.showInTooltip()) { - for (EquipmentSlotGroup equipmentslotgroup : EquipmentSlotGroup.values()) { - MutableBoolean mutableboolean = new MutableBoolean(true); @@ -897,6 +_,17 @@ return !this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY).isEmpty(); } diff --git a/patches/net/minecraft/world/item/alchemy/PotionContents.java.patch b/patches/net/minecraft/world/item/alchemy/PotionContents.java.patch new file mode 100644 index 0000000000..90c51e7d35 --- /dev/null +++ b/patches/net/minecraft/world/item/alchemy/PotionContents.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/world/item/alchemy/PotionContents.java ++++ b/net/minecraft/world/item/alchemy/PotionContents.java +@@ -173,6 +_,10 @@ + p_331296_.accept(CommonComponents.EMPTY); + p_331296_.accept(Component.translatable("potion.whenDrank").withStyle(ChatFormatting.DARK_PURPLE)); + ++ // Neo: Override handling of potion attribute tooltips to support IAttributeExtension ++ net.neoforged.neoforge.common.util.AttributeUtil.addPotionTooltip(list, p_331296_); ++ if (true) return; ++ + for (Pair, AttributeModifier> pair : list) { + AttributeModifier attributemodifier = pair.getSecond(); + double d1 = attributemodifier.amount(); diff --git a/src/main/java/net/neoforged/neoforge/client/event/AddAttributeTooltipsEvent.java b/src/main/java/net/neoforged/neoforge/client/event/AddAttributeTooltipsEvent.java new file mode 100644 index 0000000000..b39ffb1fe5 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/event/AddAttributeTooltipsEvent.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import java.util.function.Consumer; +import net.minecraft.core.component.DataComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.ItemAttributeModifiers; +import net.neoforged.bus.api.Event; +import net.neoforged.neoforge.common.util.AttributeTooltipContext; +import net.neoforged.neoforge.common.util.AttributeUtil; + +/** + * This event is fired after attribute tooltip lines have been added to an item stack's tooltip in {@link AttributeUtil#addAttributeTooltips}. + *

+ * It can be used to add additional tooltip lines adjacent to the attribute lines without having to manually locate the inject point. + *

+ * This event may be fired on both the logical client and logical server. + */ +public class AddAttributeTooltipsEvent extends Event { + protected final ItemStack stack; + protected final Consumer tooltip; + protected final AttributeTooltipContext ctx; + + public AddAttributeTooltipsEvent(ItemStack stack, Consumer tooltip, AttributeTooltipContext ctx) { + this.stack = stack; + this.tooltip = tooltip; + this.ctx = ctx; + } + + /** + * The current tooltip context. + */ + public AttributeTooltipContext getContext() { + return this.ctx; + } + + /** + * The {@link ItemStack} with the tooltip. + */ + public ItemStack getStack() { + return this.stack; + } + + /** + * Adds one or more {@link Component}s to the tooltip. + */ + public void addTooltipLines(Component... comps) { + for (Component comp : comps) { + this.tooltip.accept(comp); + } + } + + /** + * Checks if the attribute tooltips should be shown on the current item stack. + *

+ * This event is fired even if the component would prevent the normal tooltip lines from showing. + */ + public boolean shouldShow() { + return this.stack.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY).showInTooltip(); + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/event/GatherSkippedAttributeTooltipsEvent.java b/src/main/java/net/neoforged/neoforge/client/event/GatherSkippedAttributeTooltipsEvent.java new file mode 100644 index 0000000000..851439e16d --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/event/GatherSkippedAttributeTooltipsEvent.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Set; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EquipmentSlotGroup; +import net.minecraft.world.item.ItemStack; +import net.neoforged.bus.api.Event; +import net.neoforged.neoforge.common.util.AttributeTooltipContext; +import org.jetbrains.annotations.Nullable; + +/** + * This event is used to collect the IDs of attribute modifiers that will not be displayed in item tooltips. + *

+ * It allows hiding some (or all) of the modifiers, potentially for displaying them in an alternative way (or for hiding information from the player). + *

+ * This event may be fired on both the logical client and logical server. + */ +public class GatherSkippedAttributeTooltipsEvent extends Event { + protected final ItemStack stack; + protected final AttributeTooltipContext ctx; + + @Nullable + private Set skippedIds = null; + + @Nullable + private Set skippedGroups = null; + + private boolean skipAll = false; + + public GatherSkippedAttributeTooltipsEvent(ItemStack stack, AttributeTooltipContext ctx) { + this.stack = stack; + this.ctx = ctx; + // Skip sets are lazily initialized by the getter functions to avoid memory churn + } + + /** + * The current tooltip context. + */ + public AttributeTooltipContext getContext() { + return this.ctx; + } + + /** + * The {@link ItemStack} with the tooltip. + */ + public ItemStack getStack() { + return this.stack; + } + + /** + * Marks the id of a specific attribute modifier as skipped, causing it to not be displayed in the tooltip. + */ + public void skipId(ResourceLocation id) { + this.getSkippedIds().add(id); + } + + /** + * Marks an entire {@link EquipmentSlotGroup} as skipped, preventing all modifiers for that group from showing. + */ + public void skipGroup(EquipmentSlotGroup group) { + this.getSkippedGroups().add(group); + } + + /** + * Checks if a given id is skipped or not. If all modifiers are skipped, this method always returns true. + */ + public boolean isSkipped(ResourceLocation id) { + return this.skipAll || (this.skippedIds != null && this.skippedIds.contains(id)); + } + + /** + * Checks if a given group is skipped or not. If all modifiers are skipped, this method always returns true. + */ + public boolean isSkipped(EquipmentSlotGroup group) { + return this.skipAll || (this.skippedGroups != null && this.skippedGroups.contains(group)); + } + + /** + * Sets if the event should skip displaying all attribute modifiers. + */ + public void setSkipAll(boolean skip) { + this.skipAll = skip; + } + + /** + * Checks if the event will cause all attribute modifiers to be skipped. + */ + public boolean isSkippingAll() { + return this.skipAll; + } + + /** + * Initializes {@link #skippedIds} if necessary, and returns it. + */ + protected Set getSkippedIds() { + if (this.skippedIds == null) { + this.skippedIds = new HashSet<>(); + } + return this.skippedIds; + } + + /** + * Initializes {@link #skippedGroups} if necessary, and returns it. + */ + protected Set getSkippedGroups() { + if (this.skippedGroups == null) { + this.skippedGroups = EnumSet.noneOf(EquipmentSlotGroup.class); + } + return this.skippedGroups; + } +} diff --git a/src/main/java/net/neoforged/neoforge/common/BooleanAttribute.java b/src/main/java/net/neoforged/neoforge/common/BooleanAttribute.java index 453cb3ba31..faf7277198 100644 --- a/src/main/java/net/neoforged/neoforge/common/BooleanAttribute.java +++ b/src/main/java/net/neoforged/neoforge/common/BooleanAttribute.java @@ -5,8 +5,14 @@ package net.neoforged.neoforge.common; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.entity.ai.attributes.Attribute; import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.AttributeModifier.Operation; +import net.minecraft.world.item.TooltipFlag; +import org.jetbrains.annotations.Nullable; /** * A boolean attribute only has two states, on or off, represented by a value of 0 (false) or 1 (true). @@ -34,4 +40,27 @@ public double sanitizeValue(double value) { } return value > 0 ? 1 : 0; } + + @Override + public MutableComponent toValueComponent(@Nullable Operation op, double value, TooltipFlag flag) { + if (op == null) { + return Component.translatable("neoforge.value.boolean." + (value > 0 ? "enabled" : "disabled")); + } else if (op == Operation.ADD_VALUE && value > 0) { + return Component.translatable("neoforge.value.boolean.enable"); + } else if (op == Operation.ADD_MULTIPLIED_TOTAL && (int) value == -1) { + return Component.translatable("neoforge.value.boolean.disable"); + } else { + return Component.translatable("neoforge.value.boolean.invalid"); + } + } + + @Override + public MutableComponent toComponent(AttributeModifier modif, TooltipFlag flag) { + double value = modif.amount(); + + ChatFormatting color = this.getStyle(value > 0); + MutableComponent comp = Component.translatable("neoforge.modifier.bool", this.toValueComponent(modif.operation(), value, flag), Component.translatable(this.getDescriptionId())).withStyle(color); + + return comp.append(this.getDebugInfo(modif, flag)); + } } diff --git a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java index 3c0ca35bb5..46b0696bf4 100644 --- a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java @@ -47,6 +47,7 @@ import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.Attribute.Sentiment; import net.minecraft.world.entity.ai.attributes.RangedAttribute; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.Items; @@ -194,8 +195,8 @@ public class NeoForgeMod { private static final DeferredHolder, SingletonArgumentInfo> MODID_COMMAND_ARGUMENT_TYPE = COMMAND_ARGUMENT_TYPES.register("modid", () -> ArgumentTypeInfos.registerByClass(ModIdArgument.class, SingletonArgumentInfo.contextFree(ModIdArgument::modIdArgument))); - public static final Holder SWIM_SPEED = ATTRIBUTES.register("swim_speed", () -> new RangedAttribute("neoforge.swim_speed", 1.0D, 0.0D, 1024.0D).setSyncable(true)); - public static final Holder NAMETAG_DISTANCE = ATTRIBUTES.register("nametag_distance", () -> new RangedAttribute("neoforge.name_tag_distance", 64.0D, 0.0D, 64.0).setSyncable(true)); + public static final Holder SWIM_SPEED = ATTRIBUTES.register("swim_speed", () -> new PercentageAttribute("neoforge.swim_speed", 1.0D, 0.0D, 1024.0D).setSyncable(true)); + public static final Holder NAMETAG_DISTANCE = ATTRIBUTES.register("nametag_distance", () -> new RangedAttribute("neoforge.name_tag_distance", 64.0D, 0.0D, 64.0).setSyncable(true).setSentiment(Sentiment.NEUTRAL)); /** * This attribute controls if the player may use creative flight when not in creative mode. @@ -471,6 +472,8 @@ public void setItemMovement(ItemEntity entity) { private static boolean enableProperFilenameValidation = false; private static boolean enableMilkFluid = false; + private static boolean enableMergedAttributeTooltips = false; + public static final DeferredHolder BUCKET_EMPTY_MILK = DeferredHolder.create(Registries.SOUND_EVENT, ResourceLocation.withDefaultNamespace("item.bucket.empty_milk")); public static final DeferredHolder BUCKET_FILL_MILK = DeferredHolder.create(Registries.SOUND_EVENT, ResourceLocation.withDefaultNamespace("item.bucket.fill_milk")); public static final DeferredHolder MILK_TYPE = DeferredHolder.create(NeoForgeRegistries.Keys.FLUID_TYPES, ResourceLocation.withDefaultNamespace("milk")); @@ -493,6 +496,13 @@ public static void enableMilkFluid() { enableMilkFluid = true; } + /** + * Run this during mod construction to enable merged attribute tooltip functionality. + */ + public static void enableMergedAttributeTooltips() { + enableMergedAttributeTooltips = true; + } + /** * Run this method during mod constructor to enable {@link net.minecraft.FileUtil#RESERVED_WINDOWS_FILENAMES_NEOFORGE} regex being used for filepath validation. * Fixes MC-268617 at cost of vanilla incompat edge cases with files generated with this activated and them migrated to vanilla instance - See PR #767 @@ -505,6 +515,10 @@ public static boolean getProperFilenameValidation() { return enableProperFilenameValidation; } + public static boolean shouldMergeAttributeTooltips() { + return enableMergedAttributeTooltips; + } + public NeoForgeMod(IEventBus modEventBus, Dist dist, ModContainer container) { LOGGER.info(NEOFORGEMOD, "NeoForge mod loading, version {}, for MC {}", NeoForgeVersion.getVersion(), DetectedVersion.BUILT_IN.getName()); ForgeSnapshotsMod.logStartupWarning(); diff --git a/src/main/java/net/neoforged/neoforge/common/PercentageAttribute.java b/src/main/java/net/neoforged/neoforge/common/PercentageAttribute.java new file mode 100644 index 0000000000..75a845fea8 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/common/PercentageAttribute.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.common; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.entity.ai.attributes.AttributeModifier.Operation; +import net.minecraft.world.entity.ai.attributes.RangedAttribute; +import net.minecraft.world.item.TooltipFlag; + +/** + * A Percentage Attribute is one which always displays modifiers as percentages, including for {@link Operation#ADD_VALUE}. + *

+ * This is used for attributes that would not make sense being displayed as flat additions (ex: +0.05 Swim Speed). + */ +public class PercentageAttribute extends RangedAttribute { + protected final double scaleFactor; + + /** + * Creates a new PercentageAttribute with the given description, value information, and scale factor. + *

+ * If your attribute's "real" value correlates 1 == 100%, you would use a scale factor of 100 to convert to 1 to 100%. + * + * @param pDescriptionId The description id used for generating the attribute's lang key. + * @param pDefaultValue The default value of the attribute + * @param pMin The minimum value + * @param pMax The maximum value + * @param scaleFactor The scale factor, used to convert the literal value to a percentage value. + */ + public PercentageAttribute(String pDescriptionId, double pDefaultValue, double pMin, double pMax, double scaleFactor) { + super(pDescriptionId, pDefaultValue, pMin, pMax); + this.scaleFactor = scaleFactor; + } + + /** + * Creates a new PercentageAttribute with the default scale factor of 100. + * + * @see #PercentageAttribute(String, double, double, double, double) + */ + public PercentageAttribute(String pDescriptionId, double pDefaultValue, double pMin, double pMax) { + this(pDescriptionId, pDefaultValue, pMin, pMax, 100); + } + + @Override + public MutableComponent toValueComponent(Operation op, double value, TooltipFlag flag) { + return Component.translatable("neoforge.value.percent", FORMAT.format(value * this.scaleFactor)); + } +} diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IAttributeExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IAttributeExtension.java new file mode 100644 index 0000000000..6a5c51564d --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IAttributeExtension.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.common.extensions; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Locale; +import net.minecraft.ChatFormatting; +import net.minecraft.Util; +import net.minecraft.core.Holder; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.TextColor; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.Attribute.Sentiment; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.AttributeModifier.Operation; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.item.TooltipFlag; +import net.neoforged.neoforge.common.NeoForgeMod; +import net.neoforged.neoforge.common.util.AttributeUtil; +import org.jetbrains.annotations.Nullable; + +public interface IAttributeExtension { + public static final DecimalFormat FORMAT = Util.make(new DecimalFormat("#.##"), fmt -> fmt.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT)));; + + /** + * Converts the value of an attribute modifier to the value that will be displayed. + *

+ * For multiplicative modifiers, this method is responsible for converting the value to percentage form. + * + * @param op The operation of the modifier. Null if we are just displaying the raw value and not a modifier. + * @param value The value to convert. Either the current attribute value (if null operation) or the attribute modifier's amount. + * @param flag The tooltip flag. + * @return The component form of the formatted value. + */ + default MutableComponent toValueComponent(@Nullable Operation op, double value, TooltipFlag flag) { + if (isNullOrAddition(op)) { + return Component.translatable("neoforge.value.flat", FORMAT.format(value)); + } + + return Component.translatable("neoforge.value.percent", FORMAT.format(value * 100)); + } + + /** + * Converts an attribute modifier into its tooltip representation. + *

+ * This method does not handle formatting of "base" modifiers, such as Attack Damage or Attack Speed. + *

+ * The returned component may append additional debug information based on the tooltip flag. + * + * @param modif The attribute modifier being converted to a component. + * @param flag The tooltip flag. + * @return The component representation of the passed attribute modifier, with debug info appended if enabled. + */ + default MutableComponent toComponent(AttributeModifier modif, TooltipFlag flag) { + Attribute attr = self(); + double value = modif.amount(); + String key = value > 0 ? "neoforge.modifier.plus" : "neoforge.modifier.take"; + ChatFormatting color = attr.getStyle(value > 0); + + Component attrDesc = Component.translatable(attr.getDescriptionId()); + Component valueComp = this.toValueComponent(modif.operation(), value, flag); + MutableComponent comp = Component.translatable(key, valueComp, attrDesc).withStyle(color); + + return comp.append(this.getDebugInfo(modif, flag)); + } + + /** + * Computes the additional debug information for a given attribute modifier, if the flag {@linkplain TooltipFlag#isAdvanced() is advanced}. + * + * @param modif The attribute modifier being converted to a component. + * @param flag The tooltip flag. + * @return The debug component, or {@link CommonComponents#EMPTY} if disabled. + * @apiNote This information is automatically appended to {@link #toComponent(AttributeModifier, TooltipFlag)}. + */ + default Component getDebugInfo(AttributeModifier modif, TooltipFlag flag) { + Component debugInfo = CommonComponents.EMPTY; + + if (flag.isAdvanced()) { + // Advanced Tooltips show the underlying operation and the "true" value. We offset MULTIPLY_TOTAL by 1 due to how the operation is calculated. + double advValue = (modif.operation() == Operation.ADD_MULTIPLIED_TOTAL ? 1 : 0) + modif.amount(); + String valueStr = FORMAT.format(advValue); + String txt = switch (modif.operation()) { + case ADD_VALUE -> String.format(Locale.ROOT, advValue > 0 ? "[+%s]" : "[%s]", valueStr); + case ADD_MULTIPLIED_BASE -> String.format(Locale.ROOT, advValue > 0 ? "[+%sx]" : "[%sx]", valueStr); + case ADD_MULTIPLIED_TOTAL -> String.format(Locale.ROOT, "[x%s]", valueStr); + }; + debugInfo = Component.literal(" ").append(Component.literal(txt).withStyle(ChatFormatting.GRAY)); + } + return debugInfo; + } + + /** + * Gets the specific ID that represents a "base" (green) modifier for this attribute. + * + * @return The ID of the "base" modifier, or null, if no such modifier may exist. + */ + @Nullable + default ResourceLocation getBaseId() { + if (this == Attributes.ATTACK_DAMAGE.value()) return AttributeUtil.BASE_ATTACK_DAMAGE_ID; + else if (this == Attributes.ATTACK_SPEED.value()) return AttributeUtil.BASE_ATTACK_SPEED_ID; + else if (this == Attributes.ENTITY_INTERACTION_RANGE.value()) return AttributeUtil.BASE_ENTITY_REACH_ID; + return null; + } + + /** + * Converts a "base" attribute modifier (as dictated by {@link #getBaseId()}) into a text component. + *

+ * Similar to {@link #toComponent}, this method is responsible for adding debug information when the tooltip flag {@linkplain TooltipFlag#isAdvanced() is advanced}. + * + * @param value The value to be shown (after having been added to the entity's base value) + * @param entityBase The entity's base value for this attribute from {@link LivingEntity#getAttributeBaseValue(Holder)}. + * @param merged If we are displaying a merged base component (which will have a non-merged base component as a child). + * @param flag The tooltip flag. + * @return The component representation of the passed attribute modifier. + */ + default MutableComponent toBaseComponent(double value, double entityBase, boolean merged, TooltipFlag flag) { + Attribute attr = self(); + MutableComponent comp = Component.translatable("attribute.modifier.equals.0", FORMAT.format(value), Component.translatable(attr.getDescriptionId())); + + // Emit both the value of the modifier, and the entity's base value as debug information, since both are flattened into the modifier. + // Skip showing debug information here when displaying a merged modifier, since it will be shown if the user holds shift to display the un-merged modifier. + if (flag.isAdvanced() && !merged) { + Component debugInfo = Component.literal(" ").append(Component.translatable("neoforge.attribute.debug.base", FORMAT.format(entityBase), FORMAT.format(value - entityBase)).withStyle(ChatFormatting.GRAY)); + comp.append(debugInfo); + } + + return comp; + } + + /** + * Returns the color used by merged attribute modifiers. Only used when {@link NeoForgeMod#enableMergedAttributeTooltips()} is active. + *

+ * Similarly to {@link Attribute#getStyle(boolean)}, this method should return a color based on the attribute's {@link Sentiment}. + * The returned color should be distinguishable from the color used by {@link Attribute#getStyle(boolean)}. + * + * @param positive If the attribute modifier value is positive or not. + */ + TextColor getMergedStyle(boolean isPositive); + + public static boolean isNullOrAddition(@Nullable Operation op) { + return op == null || op == Operation.ADD_VALUE; + } + + private Attribute self() { + return (Attribute) this; + } +} diff --git a/src/main/java/net/neoforged/neoforge/common/util/AttributeTooltipContext.java b/src/main/java/net/neoforged/neoforge/common/util/AttributeTooltipContext.java new file mode 100644 index 0000000000..e21ee1ff52 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/common/util/AttributeTooltipContext.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.common.util; + +import net.minecraft.core.HolderLookup.Provider; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Item.TooltipContext; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.saveddata.maps.MapId; +import net.minecraft.world.level.saveddata.maps.MapItemSavedData; +import org.jetbrains.annotations.Nullable; + +/** + * Extended {@link TooltipContext} used when generating attribute tooltips. + */ +public interface AttributeTooltipContext extends Item.TooltipContext { + /** + * {@return the player for whom tooltips are being generated for, if known} + */ + @Nullable + Player player(); + + /** + * {@return the current tooltip flag} + */ + TooltipFlag flag(); + + public static AttributeTooltipContext of(@Nullable Player player, Item.TooltipContext itemCtx, TooltipFlag flag) { + return new AttributeTooltipContext() { + @Override + public Provider registries() { + return itemCtx.registries(); + } + + @Override + public float tickRate() { + return itemCtx.tickRate(); + } + + @Override + public MapItemSavedData mapData(MapId id) { + return itemCtx.mapData(id); + } + + @Override + public Level level() { + return itemCtx.level(); + } + + @Nullable + @Override + public Player player() { + return player; + } + + @Override + public TooltipFlag flag() { + return flag; + } + }; + } +} diff --git a/src/main/java/net/neoforged/neoforge/common/util/AttributeUtil.java b/src/main/java/net/neoforged/neoforge/common/util/AttributeUtil.java new file mode 100644 index 0000000000..160626a669 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/common/util/AttributeUtil.java @@ -0,0 +1,356 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.common.util; + +import com.google.common.collect.Multimap; +import com.google.common.collect.TreeMultimap; +import com.mojang.datafixers.util.Pair; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.EnumMap; +import java.util.IdentityHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.function.Consumer; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.core.Holder; +import net.minecraft.core.component.DataComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.TextColor; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.entity.EquipmentSlotGroup; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.AttributeModifier.Operation; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.alchemy.PotionContents; +import net.minecraft.world.item.component.ItemAttributeModifiers; +import net.neoforged.fml.loading.FMLEnvironment; +import net.neoforged.neoforge.client.event.AddAttributeTooltipsEvent; +import net.neoforged.neoforge.client.event.GatherSkippedAttributeTooltipsEvent; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.common.NeoForgeMod; +import net.neoforged.neoforge.common.extensions.IAttributeExtension; +import net.neoforged.neoforge.event.ItemAttributeModifierEvent; +import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * Utility code to support {@link IAttributeExtension}. + */ +public class AttributeUtil { + /** + * ID of the base modifier for Attack Damage + */ + public static final ResourceLocation BASE_ATTACK_DAMAGE_ID = Item.BASE_ATTACK_DAMAGE_ID; + + /** + * ID of the base modifier for Attack Speed + */ + public static final ResourceLocation BASE_ATTACK_SPEED_ID = Item.BASE_ATTACK_SPEED_ID; + + /** + * ID of the base modifier for Attack Range + */ + public static final ResourceLocation BASE_ENTITY_REACH_ID = ResourceLocation.withDefaultNamespace("base_entity_reach"); + + /** + * ID used for attribute modifiers used to hold merged values when {@link NeoForgeMod#enableMergedAttributeTooltips()} is active. + *

+ * Should not be used by any real attribute modifiers for gameplay purposes. + */ + public static final ResourceLocation FAKE_MERGED_ID = ResourceLocation.fromNamespaceAndPath(NeoForgeVersion.MOD_ID, "fake_merged_modifier"); + + /** + * Comparator for {@link AttributeModifier}. First compares by operation, then amount, then the ID. + */ + public static final Comparator ATTRIBUTE_MODIFIER_COMPARATOR = Comparator.comparing(AttributeModifier::operation) + .thenComparingDouble(a -> -Math.abs(a.amount())) // Sort most impactful modifiers first + .thenComparing(AttributeModifier::id); + + private static final Logger LOGGER = LogManager.getLogger(); + + /** + * Checks if attribute modifier tooltips should show, and if they should, adds tooltips for all attribute modifiers present on an item stack to the stack's tooltip lines. + *

+ * After the tooltip lines have been added, fires the {@link AddAttributeTooltipsEvent} to allow mods to add additional attribute-related lines. + * + * @param tooltip A consumer to add the tooltip lines to. + * @param ctx The tooltip context. + */ + public static void addAttributeTooltips(ItemStack stack, Consumer tooltip, AttributeTooltipContext ctx) { + ItemAttributeModifiers modifiers = stack.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY); + if (modifiers.showInTooltip()) { + applyModifierTooltips(stack, tooltip, ctx); + } + NeoForge.EVENT_BUS.post(new AddAttributeTooltipsEvent(stack, tooltip, ctx)); + } + + /** + * Applies the attribute modifier tooltips for all attribute modifiers present on the item stack. + *

+ * Before application, this method posts the {@link GatherSkippedAttributeTooltipsEvent} to determine which tooltips should be skipped. + *

+ * This method is also responsible for adding the modifier group category labels. + * + * @param tooltip A consumer to add the tooltip lines to. + * @param ctx The tooltip context. + */ + public static void applyModifierTooltips(ItemStack stack, Consumer tooltip, AttributeTooltipContext ctx) { + var event = NeoForge.EVENT_BUS.post(new GatherSkippedAttributeTooltipsEvent(stack, ctx)); + if (event.isSkippingAll()) { + return; + } + + for (EquipmentSlotGroup group : EquipmentSlotGroup.values()) { + if (event.isSkipped(group)) { + continue; + } + + Multimap, AttributeModifier> modifiers = getSortedModifiers(stack, group); + + // Remove any skipped modifiers before doing any logic + modifiers.values().removeIf(m -> event.isSkipped(m.id())); + + if (modifiers.isEmpty()) { + continue; + } + + // Add an empty line, then the name of the group, then the modifiers. + tooltip.accept(Component.empty()); + tooltip.accept(Component.translatable("item.modifiers." + group.getSerializedName()).withStyle(ChatFormatting.GRAY)); + + applyTextFor(stack, tooltip, modifiers, ctx); + } + } + + /** + * Applies the text for the provided attribute modifiers to the tooltip for a given item stack. + *

+ * This method will attempt to merge multiple modifiers for a single attribute into a single modifier if {@linkplain NeoForgeMod#enableMergedAttributeTooltips()} was called. + * + * @param stack The item stack that owns the modifiers. + * @param tooltip The consumer to append tooltip components to. + * @param modifierMap A mutable map of modifiers to convert into tooltip lines. + * @param ctx The tooltip context. + */ + public static void applyTextFor(ItemStack stack, Consumer tooltip, Multimap, AttributeModifier> modifierMap, AttributeTooltipContext ctx) { + // Don't add anything if there is nothing in the group + if (modifierMap.isEmpty()) { + return; + } + + // Collect all the base modifiers + Map, BaseModifier> baseModifs = new IdentityHashMap<>(); + + var it = modifierMap.entries().iterator(); + while (it.hasNext()) { + Entry, AttributeModifier> entry = it.next(); + Holder attr = entry.getKey(); + AttributeModifier modif = entry.getValue(); + if (modif.id().equals(attr.value().getBaseId())) { + baseModifs.put(attr, new BaseModifier(modif, new ArrayList<>())); + // Remove base modifiers from the main map after collection so we don't need to check for them later. + it.remove(); + } + } + + // Collect children of all base modifiers for merging logic + for (Map.Entry, AttributeModifier> entry : modifierMap.entries()) { + BaseModifier base = baseModifs.get(entry.getKey()); + if (base != null) { + base.children.add(entry.getValue()); + } + } + + // Add tooltip lines for base modifiers + for (Map.Entry, BaseModifier> entry : baseModifs.entrySet()) { + Holder attr = entry.getKey(); + BaseModifier baseModif = entry.getValue(); + double entityBase = ctx.player() == null ? 0 : ctx.player().getAttributeBaseValue(attr); + double base = baseModif.base.amount() + entityBase; + final double rawBase = base; + double amt = base; + + // Compute the base value including merged modifiers if merging is enabled + if (NeoForgeMod.shouldMergeAttributeTooltips()) { + for (AttributeModifier modif : baseModif.children) { + switch (modif.operation()) { + case ADD_VALUE: + base = amt = amt + modif.amount(); + break; + case ADD_MULTIPLIED_BASE: + amt += modif.amount() * base; + break; + case ADD_MULTIPLIED_TOTAL: + amt *= 1 + modif.amount(); + break; + } + } + } + + boolean isMerged = NeoForgeMod.shouldMergeAttributeTooltips() && !baseModif.children.isEmpty(); + MutableComponent text = attr.value().toBaseComponent(amt, entityBase, isMerged, ctx.flag()); + tooltip.accept(Component.literal(" ").append(text).withStyle(isMerged ? ChatFormatting.GOLD : ChatFormatting.DARK_GREEN)); + if (ctx.flag().hasShiftDown() && isMerged) { + // Display the raw base value, and then all children modifiers. + text = attr.value().toBaseComponent(rawBase, entityBase, false, ctx.flag()); + tooltip.accept(listHeader().append(text.withStyle(ChatFormatting.DARK_GREEN))); + for (AttributeModifier modifier : baseModif.children) { + tooltip.accept(listHeader().append(attr.value().toComponent(modifier, ctx.flag()))); + } + } + } + + for (Holder attr : modifierMap.keySet()) { + // Skip attributes who have already been processed during the base modifier stage + if (NeoForgeMod.shouldMergeAttributeTooltips() && baseModifs.containsKey(attr)) { + continue; + } + + Collection modifs = modifierMap.get(attr); + // Initiate merged-tooltip logic if we have more than one modifier for a given attribute. + if (NeoForgeMod.shouldMergeAttributeTooltips() && modifs.size() > 1) { + Map mergeData = new EnumMap<>(Operation.class); + + for (AttributeModifier modifier : modifs) { + if (modifier.amount() == 0) { + continue; + } + + MergedModifierData data = mergeData.computeIfAbsent(modifier.operation(), op -> new MergedModifierData()); + if (data.sum != 0) { + // If the sum for this operation is non-zero, we've already consumed one modifier. Consuming a second means we've merged. + data.isMerged = true; + } + data.sum += modifier.amount(); + data.children.add(modifier); + } + + for (Operation op : Operation.values()) { + MergedModifierData data = mergeData.get(op); + + // If the merged value comes out to 0, just ignore the whole stack + if (data == null || data.sum == 0) { + continue; + } + + // Handle merged modifier stacks by creating a "fake" merged modifier with the underlying value. + if (data.isMerged) { + TextColor color = attr.value().getMergedStyle(data.sum > 0); + var fakeModif = new AttributeModifier(FAKE_MERGED_ID, data.sum, op); + MutableComponent comp = attr.value().toComponent(fakeModif, ctx.flag()); + tooltip.accept(comp.withStyle(comp.getStyle().withColor(color))); + if (ctx.flag().hasShiftDown()) { + data.children.forEach(modif -> tooltip.accept(listHeader().append(attr.value().toComponent(modif, ctx.flag())))); + } + } else { + var fakeModif = new AttributeModifier(FAKE_MERGED_ID, data.sum, op); + tooltip.accept(attr.value().toComponent(fakeModif, ctx.flag())); + } + } + } else { + for (AttributeModifier m : modifs) { + if (m.amount() != 0) { + tooltip.accept(attr.value().toComponent(m, ctx.flag())); + } + } + } + } + } + + /** + * Adds tooltip lines for the attribute modifiers contained in a {@link PotionContents}. + * + * @param list The list of attribute modifiers generated by calling {@link MobEffect#createModifiers} for each mob effect instance on the potion. + * @param tooltips The tooltip consumer to add lines to. + */ + public static void addPotionTooltip(List, AttributeModifier>> list, Consumer tooltips) { + for (Pair, AttributeModifier> pair : list) { + tooltips.accept(pair.getFirst().value().toComponent(pair.getSecond(), getTooltipFlag())); + } + } + + /** + * Creates a sorted {@link TreeMultimap} used to ensure a stable iteration order of item attribute modifiers. + */ + public static Multimap, AttributeModifier> sortedMap() { + return TreeMultimap.create(Comparator.comparing(Holder::getKey), ATTRIBUTE_MODIFIER_COMPARATOR); + } + + /** + * Returns a sorted, mutable {@link Multimap} containing all the attribute modifiers on an item stack for the given group. + *

+ * This includes attribute modifiers from components (or default modifiers, if not present), enchantments, and the {@link ItemAttributeModifierEvent}. + * + * @param stack The stack to query modifiers for. + * @param slot The slot group to query modifiers for. + */ + public static Multimap, AttributeModifier> getSortedModifiers(ItemStack stack, EquipmentSlotGroup slot) { + Multimap, AttributeModifier> map = sortedMap(); + stack.forEachModifier(slot, (attr, modif) -> { + if (attr != null && modif != null) { + map.put(attr, modif); + } else { + LOGGER.debug("Detected broken attribute modifier entry on item {}. Attr={}, Modif={}", stack, attr, modif); + } + }); + return map; + } + + /** + * Creates a mutable component starting with the char used to represent a drop-down list. + */ + private static MutableComponent listHeader() { + return Component.literal(" \u2507 ").withStyle(ChatFormatting.GRAY); + } + + /** + * Gets the current global tooltip flag. Used by {@link AttributeUtil#addPotionTooltip} since one isn't available locally. + * + * @return If called on the client, the current tooltip flag, otherwise {@link TooltipFlag#NORMAL} + */ + private static TooltipFlag getTooltipFlag() { + if (FMLEnvironment.dist.isClient()) { + return ClientAccess.getTooltipFlag(); + } + return TooltipFlag.NORMAL; + } + + /** + * Stores a single base modifier (determined by {@link IAttributeExtension#getBaseId()}) and any other children non-base modifiers for the same attribute. + *

+ * Used during attribute merging logic within {@link AttributeUtil#applyTextFor}. + */ + private static record BaseModifier(AttributeModifier base, List children) {} + + /** + * State-tracking object used to merge attribute modifier tooltips in {@link AttributeUtil#applyTextFor}. + */ + private static class MergedModifierData { + double sum = 0; + boolean isMerged = false; + private List children = new LinkedList<>(); + } + + /** + * Client bouncer class to avoid class loading issues. Access to this class still needs a dist check. + */ + private static class ClientAccess { + static TooltipFlag getTooltipFlag() { + return Minecraft.getInstance().options.advancedItemTooltips ? TooltipFlag.ADVANCED : TooltipFlag.NORMAL; + } + } +} diff --git a/src/main/resources/assets/neoforge/lang/en_us.json b/src/main/resources/assets/neoforge/lang/en_us.json index 0d78311974..484a2b29f3 100644 --- a/src/main/resources/assets/neoforge/lang/en_us.json +++ b/src/main/resources/assets/neoforge/lang/en_us.json @@ -263,5 +263,20 @@ "neoforge.network.extensible_enums.no_vanilla_server": "This client does not support vanilla servers as it has extended enums used in serverbound networking", "neoforge.network.extensible_enums.enum_set_mismatch": "The set of extensible enums on the client and server do not match. Make sure you are using the same NeoForge version as the server", - "neoforge.network.extensible_enums.enum_entry_mismatch": "The set of values added to extensible enums on the client and server do not match. Make sure you are using the same mod and NeoForge versions as the server. See the log for more details" + "neoforge.network.extensible_enums.enum_entry_mismatch": "The set of values added to extensible enums on the client and server do not match. Make sure you are using the same mod and NeoForge versions as the server. See the log for more details", + + "neoforge.attribute.debug.base": "[Entity: %s | Item: %s]", + + "neoforge.value.flat": "%s", + "neoforge.value.percent": "%s%%", + + "neoforge.value.boolean.enabled": "Enabled", + "neoforge.value.boolean.disabled": "Disabled", + "neoforge.value.boolean.enable": "Enables", + "neoforge.value.boolean.disable": "Disables", + "neoforge.value.boolean.invalid": "Invalid", + + "neoforge.modifier.plus": "+%s %s", + "neoforge.modifier.take": "%s %s", + "neoforge.modifier.bool": "%s %s" } From 8ec872a4e04b30ef7b8b3e3af09b6819615a2c6f Mon Sep 17 00:00:00 2001 From: lcy0x1 Date: Tue, 24 Sep 2024 12:31:25 +0700 Subject: [PATCH 079/125] Allow setting if the critical hit should disable sweep attack in CriticalHitEvent, adding SweepAttackEvent (#1496) This allows mods to have better handling over crit-sweep behavior through a new flag in `CriticalHitEvent` as well as providing full sweep control via `SweepAttackEvent`. --- .../world/entity/player/Player.java.patch | 17 +++- .../neoforge/common/CommonHooks.java | 12 +++ .../event/entity/player/CriticalHitEvent.java | 42 +++++++--- .../event/entity/player/SweepAttackEvent.java | 78 +++++++++++++++++++ 4 files changed, 136 insertions(+), 13 deletions(-) create mode 100644 src/main/java/net/neoforged/neoforge/event/entity/player/SweepAttackEvent.java diff --git a/patches/net/minecraft/world/entity/player/Player.java.patch b/patches/net/minecraft/world/entity/player/Player.java.patch index f3804ed582..b56eec23b3 100644 --- a/patches/net/minecraft/world/entity/player/Player.java.patch +++ b/patches/net/minecraft/world/entity/player/Player.java.patch @@ -254,12 +254,12 @@ if (p_36347_.getType().is(EntityTypeTags.REDIRECTABLE_PROJECTILE) && p_36347_ instanceof Projectile projectile && projectile.deflect(ProjectileDeflection.AIM_DEFLECT, this, this, true)) { -@@ -1170,8 +_,12 @@ +@@ -1170,19 +_,28 @@ && !this.isPassenger() && p_36347_ instanceof LivingEntity && !this.isSprinting(); + // Neo: Fire the critical hit event and override the critical hit status and damage multiplier based on the event. -+ // The boolean local above (flag2) is the vanilla critical hit result. ++ // The boolean local above (flag1) is the vanilla critical hit result. + var critEvent = net.neoforged.neoforge.common.CommonHooks.fireCriticalHit(this, p_36347_, flag1, flag1 ? 1.5F : 1.0F); + flag1 = critEvent.isCriticalHit(); if (flag1) { @@ -268,17 +268,26 @@ } float f3 = f + f1; -@@ -1179,9 +_,7 @@ + boolean flag2 = false; double d0 = (double)(this.walkDist - this.walkDistO); - if (flag4 && !flag1 && !flag && this.onGround() && d0 < (double)this.getSpeed()) { +- if (flag4 && !flag1 && !flag && this.onGround() && d0 < (double)this.getSpeed()) { ++ // Neo: Replace !flag1 (!isCriticalHit) with the logic from the CriticalHitEvent. ++ boolean critBlocksSweep = critEvent.isCriticalHit() && critEvent.disableSweep(); ++ if (flag4 && !critBlocksSweep && !flag && this.onGround() && d0 < (double)this.getSpeed()) { ++ // Neo: Make sweep attacks check SWORD_SWEEP instead of instanceof SwordItem. ItemStack itemstack1 = this.getItemInHand(InteractionHand.MAIN_HAND); - if (itemstack1.getItem() instanceof SwordItem) { - flag2 = true; - } + flag2 = itemstack1.canPerformAction(net.neoforged.neoforge.common.ItemAbilities.SWORD_SWEEP); } ++ ++ // Neo: Fire the SweepAttackEvent and overwrite the value of flag2 (the local controlling if a sweep will occur). ++ var sweepEvent = net.neoforged.neoforge.common.CommonHooks.fireSweepAttack(this, p_36347_, flag2); ++ flag2 = sweepEvent.isSweeping(); float f6 = 0.0F; + if (p_36347_ instanceof LivingEntity livingentity) { @@ -1217,11 +_,12 @@ for (LivingEntity livingentity2 : this.level() diff --git a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java index e434bbb54f..5c7e2f992f 100644 --- a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java +++ b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java @@ -205,6 +205,7 @@ import net.neoforged.neoforge.event.entity.player.PlayerEnchantItemEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; +import net.neoforged.neoforge.event.entity.player.SweepAttackEvent; import net.neoforged.neoforge.event.level.BlockDropsEvent; import net.neoforged.neoforge.event.level.BlockEvent; import net.neoforged.neoforge.event.level.NoteBlockEvent; @@ -923,6 +924,17 @@ public static CriticalHitEvent fireCriticalHit(Player player, Entity target, boo return NeoForge.EVENT_BUS.post(new CriticalHitEvent(player, target, damageModifier, vanillaCritical)); } + /** + * Fires the {@link SweepAttackEvent} and returns the resulting event. + * + * @param player The attacking player. + * @param target The attack target. + * @param isVanillaSweep If the attack would have been a sweep attack by vanilla's rules in {@link Player#attack(Entity)}. + */ + public static SweepAttackEvent fireSweepAttack(Player player, Entity target, boolean isVanillaSweep) { + return NeoForge.EVENT_BUS.post(new SweepAttackEvent(player, target, isVanillaSweep)); + } + /** * Hook to fire {@link ItemAttributeModifierEvent}. Modders should use {@link ItemStack#forEachModifier(EquipmentSlot, BiConsumer)} instead. */ diff --git a/src/main/java/net/neoforged/neoforge/event/entity/player/CriticalHitEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/player/CriticalHitEvent.java index 03b4c3e32b..53c6d5ba52 100644 --- a/src/main/java/net/neoforged/neoforge/event/entity/player/CriticalHitEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/entity/player/CriticalHitEvent.java @@ -11,10 +11,12 @@ /** * This event is fired when a player attacks an entity in {@link Player#attack(Entity)}. - * It can be used to change the critical hit status and damage modifier *

- * In the event the attack was not a critical hit, the event will still be fired, but it will be preemptively cancelled. - **/ + * It can be used to change the critical hit status and the critical damage multiplier. + * Additionally, this event allows controlling if the critical hit will impact sweep conditions. + *

+ * This event is fired on both the logical client and logical server. + */ public class CriticalHitEvent extends PlayerEvent { private final Entity target; private final float vanillaDmgMultiplier; @@ -22,6 +24,7 @@ public class CriticalHitEvent extends PlayerEvent { private float dmgMultiplier; private boolean isCriticalHit; + private boolean disableSweep = true; /** * Fire via {@link CommonHooks#fireCriticalHit(Player, Entity, boolean, float)} @@ -44,8 +47,6 @@ public Entity getTarget() { * The damage multiplier is applied to the base attack's damage if the attack {@linkplain #isCriticalHit() critically hits}. *

* A damage multiplier of 1.0 will not change the damage, a value of 1.5 will increase the damage by 50%, and so on. - * - * @param modifier The new damage modifier. */ public float getDamageMultiplier() { return this.dmgMultiplier; @@ -55,8 +56,8 @@ public float getDamageMultiplier() { * Sets the damage multiplier for the critical hit. Not used if {@link #isCriticalHit()} is false. *

* Changing the damage modifier to zero does not guarantee that the attack does zero damage. - * - * @param modifier The new damage modifier. Must not be negative. + * + * @param dmgMultiplier The new damage modifier. Must not be negative. * @see #getDamageMultiplier() */ public void setDamageMultiplier(float dmgMultiplier) { @@ -75,7 +76,7 @@ public boolean isCriticalHit() { /** * Changes the critical hit state. - * + * * @param isCriticalHit true if the attack should critically hit */ public void setCriticalHit(boolean isCriticalHit) { @@ -86,7 +87,7 @@ public void setCriticalHit(boolean isCriticalHit) { * Gets the original damage multiplier set by vanilla. *

* If the event {@link #isVanillaCritical()}, the damage multiplier will be 1.5, otherwise it will be 1.0 - * + * * @see #getDamageMultiplier() */ public float getVanillaMultiplier() { @@ -99,4 +100,27 @@ public float getVanillaMultiplier() { public boolean isVanillaCritical() { return this.isVanillaCritical; } + + /** + * Sets if this attack should prevent a sweep from occurring. + *

+ * In vanilla, a critical hit always prevents a sweep from occurring. + * This method can allow an attack to both critically hit and sweep without having to validate the other sweep conditions. + * + * @see {@link SweepAttackEvent} for more advanced sweep attack handling. + */ + public void setDisableSweep(boolean disableSweep) { + this.disableSweep = disableSweep; + } + + /** + * If this attack is a {@linkplain #isCriticalHit() critical hit}, returns if a sweep should be prevented. + *

+ * If this attack is not a critical hit, the return value of this method is meaningless. + * + * @see {@link SweepAttackEvent} for more advanced sweep attack handling. + */ + public boolean disableSweep() { + return disableSweep; + } } diff --git a/src/main/java/net/neoforged/neoforge/event/entity/player/SweepAttackEvent.java b/src/main/java/net/neoforged/neoforge/event/entity/player/SweepAttackEvent.java new file mode 100644 index 0000000000..eb07599ef1 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/event/entity/player/SweepAttackEvent.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.event.entity.player; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.neoforged.bus.api.ICancellableEvent; +import net.neoforged.neoforge.common.ItemAbilities; + +/** + * The SweepAttackEvent is fired when a {@link Player} attacks a target, after the {@link CriticalHitEvent} has been fired. + *

+ * This event can be used to force an attack to trigger a sweep, or to prevent a sweep from occurring. + *

+ * This event is fired on both the logical client and logical server. + */ +public class SweepAttackEvent extends PlayerEvent implements ICancellableEvent { + private final Entity target; + private final boolean isVanillaSweep; + + private boolean isSweeping; + + public SweepAttackEvent(Player player, Entity target, boolean isVanillaSweep) { + super(player); + this.target = target; + this.isSweeping = this.isVanillaSweep = isVanillaSweep; + } + + /** + * Returns the target of the attack, which is guaranteed to be a valid attack target. + */ + public Entity getTarget() { + return this.target; + } + + /** + * Returns true if the attack would cause a sweep by utilizing the vanilla rules. + *

+ * The vanilla rules are as follows. All of them must be true for a vanilla sweep to occur: + *

    + *
  1. The player's attack strength is greater than 90%.
  2. + *
  3. The attack is not a critical hit, or is a critical hit which does not {@linkplain CriticalHitEvent#disableSweep() disable the sweep attack}.
  4. + *
  5. The player is on the ground.
  6. + *
  7. The distance the player has traveled this tick is less than their speed.
  8. + *
  9. The player's weapon supports sweep attacks via {@link ItemAbilities#SWORD_SWEEP}.
  10. + *
+ */ + public boolean isVanillaSweep() { + return this.isVanillaSweep; + } + + /** + * Returns true if the attack will be trigger a sweep. + */ + public boolean isSweeping() { + return this.isSweeping; + } + + /** + * @param sweep Whether to enable a sweep for this attack. + */ + public void setSweeping(boolean sweep) { + this.isSweeping = sweep; + } + + /** + * Cancels the event, preventing further event handlers from acting. Canceling the event will use the current value of {@link #isSweeping()}. + *

+ * If you intend to perform a custom sweep attack, you should cancel the event and {@link #setSweeping} to false before performing your handling. + */ + @Override + public void setCanceled(boolean canceled) { + ICancellableEvent.super.setCanceled(canceled); + } +} From b92c510d64ed9506140d74538f4699277e8193bd Mon Sep 17 00:00:00 2001 From: GizmoTheMoonPig <67468252+GizmoTheMoonPig@users.noreply.github.com> Date: Thu, 26 Sep 2024 08:56:07 -0600 Subject: [PATCH 080/125] Add a way to animate armor models in HumanoidArmorLayer (#1541) --- .../layers/HumanoidArmorLayer.java.patch | 25 ++++++++++++++++++- .../common/IClientItemExtensions.java | 16 ++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/patches/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java.patch b/patches/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java.patch index 545f030b2f..b6db566e31 100644 --- a/patches/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java.patch @@ -1,6 +1,28 @@ --- a/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java +++ b/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java -@@ -66,22 +_,28 @@ +@@ -54,34 +_,47 @@ + float p_117104_, + float p_117105_ + ) { +- this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.CHEST, p_117098_, this.getArmorModel(EquipmentSlot.CHEST)); +- this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.LEGS, p_117098_, this.getArmorModel(EquipmentSlot.LEGS)); +- this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.FEET, p_117098_, this.getArmorModel(EquipmentSlot.FEET)); +- this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.HEAD, p_117098_, this.getArmorModel(EquipmentSlot.HEAD)); ++ this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.CHEST, p_117098_, this.getArmorModel(EquipmentSlot.CHEST), p_117100_, p_117101_, p_117102_, p_117103_, p_117104_, p_117105_); ++ this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.LEGS, p_117098_, this.getArmorModel(EquipmentSlot.LEGS), p_117100_, p_117101_, p_117102_, p_117103_, p_117104_, p_117105_); ++ this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.FEET, p_117098_, this.getArmorModel(EquipmentSlot.FEET), p_117100_, p_117101_, p_117102_, p_117103_, p_117104_, p_117105_); ++ this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.HEAD, p_117098_, this.getArmorModel(EquipmentSlot.HEAD), p_117100_, p_117101_, p_117102_, p_117103_, p_117104_, p_117105_); + } + ++ /** @deprecated Neo: use {@link #renderArmorPiece(PoseStack, MultiBufferSource, LivingEntity, EquipmentSlot, int, HumanoidModel, float, float, float, float, float, float)} instead. */ ++ @Deprecated + private void renderArmorPiece(PoseStack p_117119_, MultiBufferSource p_117120_, T p_117121_, EquipmentSlot p_117122_, int p_117123_, A p_117124_) { ++ this.renderArmorPiece(p_117119_, p_117120_, p_117121_, p_117122_, p_117123_, p_117124_, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F); ++ } ++ ++ private void renderArmorPiece(PoseStack p_117119_, MultiBufferSource p_117120_, T p_117121_, EquipmentSlot p_117122_, int p_117123_, A p_117124_, float limbSwing, float limbSwingAmount, float partialTick, float ageInTicks, float netHeadYaw, float headPitch) { + ItemStack itemstack = p_117121_.getItemBySlot(p_117122_); + if (itemstack.getItem() instanceof ArmorItem armoritem) { if (armoritem.getEquipmentSlot() == p_117122_) { this.getParentModel().copyPropertiesTo(p_117124_); this.setPartVisibility(p_117124_, p_117122_); @@ -13,6 +35,7 @@ - int j = armormaterial$layer.dyeable() ? i : -1; - this.renderModel(p_117119_, p_117120_, p_117123_, p_117124_, j, armormaterial$layer.texture(flag)); + net.neoforged.neoforge.client.extensions.common.IClientItemExtensions extensions = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(itemstack); ++ extensions.setupModelAnimations(p_117121_, itemstack, p_117122_, model, limbSwing, limbSwingAmount, partialTick, ageInTicks, netHeadYaw, headPitch); + int fallbackColor = extensions.getDefaultDyeColor(itemstack); + for (int layerIdx = 0; layerIdx < armormaterial.layers().size(); layerIdx++) { + ArmorMaterial.Layer armormaterial$layer = armormaterial.layers().get(layerIdx); diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java b/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java index 385d45a6c7..16ac6d3853 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java @@ -127,6 +127,22 @@ default Model getGenericArmorModel(LivingEntity livingEntity, ItemStack itemStac return original; } + /** + * Called when an armor piece is about to be rendered, allowing parts of the model to be animated or changed. + * + * @param itemStack The item stack being worn + * @param livingEntity The entity wearing the armor + * @param equipmentSlot The slot the armor stack is being worn in + * @param model The armor model being rendered + * @param limbSwing The swing position of the entity's walk animation + * @param limbSwingAmount The swing speed of the entity's walk animation + * @param partialTick The partial tick time + * @param ageInTicks The total age of the entity, with partialTick already applied + * @param netHeadYaw The yaw (Y rotation) of the entity's head + * @param headPitch The pitch (X rotation) of the entity's head + */ + default void setupModelAnimations(LivingEntity livingEntity, ItemStack itemStack, EquipmentSlot equipmentSlot, Model model, float limbSwing, float limbSwingAmount, float partialTick, float ageInTicks, float netHeadYaw, float headPitch) {} + /** * Called when the client starts rendering the HUD, and is wearing this item in the helmet slot. *

From aad7f81200e1512646f289b2a26d3c9c5997a2a2 Mon Sep 17 00:00:00 2001 From: ZestyBlaze <68081568+ZestyBlaze@users.noreply.github.com> Date: Sat, 28 Sep 2024 22:31:52 +0100 Subject: [PATCH 081/125] Passing `RegistryAccess` to more Events! (#1529) --- .../multiplayer/ClientPacketListener.java.patch | 6 ++++-- .../minecraft/server/MinecraftServer.java.patch | 9 +++++++++ .../world/item/alchemy/PotionBrewing.java.patch | 15 +++++++++++++-- .../neoforge/common/VillagerTradingManager.java | 13 +++++++------ .../brewing/RegisterBrewingRecipesEvent.java | 9 ++++++++- .../event/village/VillagerTradesEvent.java | 17 +++++++++++++++++ .../event/village/WandererTradesEvent.java | 17 +++++++++++++++++ 7 files changed, 75 insertions(+), 11 deletions(-) diff --git a/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch b/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch index ba17981ad6..c244326521 100644 --- a/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch @@ -8,14 +8,16 @@ @Nullable private LevelLoadStatusManager levelLoadStatusManager; private boolean serverEnforcesSecureChat; -@@ -366,6 +_,7 @@ +@@ -366,7 +_,8 @@ p_253924_.gui.getChat().restoreState(p_295121_.chatState()); } +- this.potionBrewing = PotionBrewing.bootstrap(this.enabledFeatures); + this.connectionType = p_295121_.connectionType(); - this.potionBrewing = PotionBrewing.bootstrap(this.enabledFeatures); ++ this.potionBrewing = PotionBrewing.bootstrap(this.enabledFeatures, this.registryAccess); } + public ClientSuggestionProvider getSuggestionsProvider() { @@ -427,12 +_,13 @@ this.minecraft.debugRenderer.clear(); diff --git a/patches/net/minecraft/server/MinecraftServer.java.patch b/patches/net/minecraft/server/MinecraftServer.java.patch index 5d60f55f4d..cebd24b556 100644 --- a/patches/net/minecraft/server/MinecraftServer.java.patch +++ b/patches/net/minecraft/server/MinecraftServer.java.patch @@ -9,6 +9,15 @@ thread.setUncaughtExceptionHandler((p_177909_, p_177910_) -> LOGGER.error("Uncaught exception in server thread", p_177910_)); if (Runtime.getRuntime().availableProcessors() > 4) { thread.setPriority(8); +@@ -315,7 +_,7 @@ + this.structureTemplateManager = new StructureTemplateManager(p_236726_.resourceManager(), p_236724_, p_236728_, holdergetter); + this.serverThread = p_236723_; + this.executor = Util.backgroundExecutor(); +- this.potionBrewing = PotionBrewing.bootstrap(this.worldData.enabledFeatures()); ++ this.potionBrewing = PotionBrewing.bootstrap(this.worldData.enabledFeatures(), this.registryAccess()); + } + } + @@ -372,6 +_,7 @@ this.readScoreboard(dimensiondatastorage); this.commandStorage = new CommandStorage(dimensiondatastorage); diff --git a/patches/net/minecraft/world/item/alchemy/PotionBrewing.java.patch b/patches/net/minecraft/world/item/alchemy/PotionBrewing.java.patch index 9c3be6f23f..7612a5fff4 100644 --- a/patches/net/minecraft/world/item/alchemy/PotionBrewing.java.patch +++ b/patches/net/minecraft/world/item/alchemy/PotionBrewing.java.patch @@ -56,11 +56,22 @@ Optional> optional = p_43531_.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY).potion(); if (optional.isEmpty()) { return p_43531_; -@@ -127,6 +_,7 @@ +@@ -124,9 +_,18 @@ + } + } + ++ /** ++ * @deprecated Use {@link #bootstrap(FeatureFlagSet, net.minecraft.core.RegistryAccess)} instead ++ */ ++ @Deprecated public static PotionBrewing bootstrap(FeatureFlagSet p_341301_) { ++ return bootstrap(p_341301_, net.minecraft.core.RegistryAccess.EMPTY); ++ } ++ ++ public static PotionBrewing bootstrap(FeatureFlagSet p_341301_, net.minecraft.core.RegistryAccess registryAccess) { PotionBrewing.Builder potionbrewing$builder = new PotionBrewing.Builder(p_341301_); addVanillaMixes(potionbrewing$builder); -+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.brewing.RegisterBrewingRecipesEvent(potionbrewing$builder)); ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.brewing.RegisterBrewingRecipesEvent(potionbrewing$builder, registryAccess)); return potionbrewing$builder.build(); } diff --git a/src/main/java/net/neoforged/neoforge/common/VillagerTradingManager.java b/src/main/java/net/neoforged/neoforge/common/VillagerTradingManager.java index 92a0a16b4e..b36bbdb53b 100644 --- a/src/main/java/net/neoforged/neoforge/common/VillagerTradingManager.java +++ b/src/main/java/net/neoforged/neoforge/common/VillagerTradingManager.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.Map; import net.minecraft.core.NonNullList; +import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.entity.npc.VillagerProfession; import net.minecraft.world.entity.npc.VillagerTrades; @@ -35,20 +36,20 @@ public class VillagerTradingManager { static void loadTrades(TagsUpdatedEvent e) { if (e.getUpdateCause() == TagsUpdatedEvent.UpdateCause.SERVER_DATA_LOAD) { - postWandererEvent(); - postVillagerEvents(); + postWandererEvent(e.getRegistryAccess()); + postVillagerEvents(e.getRegistryAccess()); } } /** * Posts the WandererTradesEvent. */ - private static void postWandererEvent() { + private static void postWandererEvent(RegistryAccess registryAccess) { List generic = NonNullList.create(); List rare = NonNullList.create(); Arrays.stream(WANDERER_TRADES.get(1)).forEach(generic::add); Arrays.stream(WANDERER_TRADES.get(2)).forEach(rare::add); - NeoForge.EVENT_BUS.post(new WandererTradesEvent(generic, rare)); + NeoForge.EVENT_BUS.post(new WandererTradesEvent(generic, rare, registryAccess)); VillagerTrades.WANDERING_TRADER_TRADES.put(1, generic.toArray(new ItemListing[0])); VillagerTrades.WANDERING_TRADER_TRADES.put(2, rare.toArray(new ItemListing[0])); } @@ -56,7 +57,7 @@ private static void postWandererEvent() { /** * Posts a VillagerTradesEvent for each registered profession. */ - private static void postVillagerEvents() { + private static void postVillagerEvents(RegistryAccess registryAccess) { for (VillagerProfession prof : BuiltInRegistries.VILLAGER_PROFESSION) { Int2ObjectMap trades = VANILLA_TRADES.getOrDefault(prof, new Int2ObjectOpenHashMap<>()); Int2ObjectMap> mutableTrades = new Int2ObjectOpenHashMap<>(); @@ -66,7 +67,7 @@ private static void postVillagerEvents() { trades.int2ObjectEntrySet().forEach(e -> { Arrays.stream(e.getValue()).forEach(mutableTrades.get(e.getIntKey())::add); }); - NeoForge.EVENT_BUS.post(new VillagerTradesEvent(mutableTrades, prof)); + NeoForge.EVENT_BUS.post(new VillagerTradesEvent(mutableTrades, prof, registryAccess)); Int2ObjectMap newTrades = new Int2ObjectOpenHashMap<>(); mutableTrades.int2ObjectEntrySet().forEach(e -> newTrades.put(e.getIntKey(), e.getValue().toArray(new ItemListing[0]))); VillagerTrades.TRADES.put(prof, newTrades); diff --git a/src/main/java/net/neoforged/neoforge/event/brewing/RegisterBrewingRecipesEvent.java b/src/main/java/net/neoforged/neoforge/event/brewing/RegisterBrewingRecipesEvent.java index 53ff0f6af2..669e61cedd 100644 --- a/src/main/java/net/neoforged/neoforge/event/brewing/RegisterBrewingRecipesEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/brewing/RegisterBrewingRecipesEvent.java @@ -5,6 +5,7 @@ package net.neoforged.neoforge.event.brewing; +import net.minecraft.core.RegistryAccess; import net.minecraft.world.item.alchemy.PotionBrewing; import net.neoforged.bus.api.Event; import org.jetbrains.annotations.ApiStatus; @@ -16,13 +17,19 @@ */ public class RegisterBrewingRecipesEvent extends Event { private final PotionBrewing.Builder builder; + private final RegistryAccess registryAccess; @ApiStatus.Internal - public RegisterBrewingRecipesEvent(PotionBrewing.Builder builder) { + public RegisterBrewingRecipesEvent(PotionBrewing.Builder builder, RegistryAccess registryAccess) { this.builder = builder; + this.registryAccess = registryAccess; } public PotionBrewing.Builder getBuilder() { return builder; } + + public RegistryAccess getRegistryAccess() { + return registryAccess; + } } diff --git a/src/main/java/net/neoforged/neoforge/event/village/VillagerTradesEvent.java b/src/main/java/net/neoforged/neoforge/event/village/VillagerTradesEvent.java index 58adf8c425..4fb6c4c2fb 100644 --- a/src/main/java/net/neoforged/neoforge/event/village/VillagerTradesEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/village/VillagerTradesEvent.java @@ -7,6 +7,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import java.util.List; +import net.minecraft.core.RegistryAccess; import net.minecraft.world.entity.npc.VillagerData; import net.minecraft.world.entity.npc.VillagerProfession; import net.minecraft.world.entity.npc.VillagerTrades.ItemListing; @@ -14,6 +15,7 @@ import net.neoforged.neoforge.common.BasicItemListing; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.event.TagsUpdatedEvent; +import org.jetbrains.annotations.ApiStatus; /** * VillagerTradesEvent is fired during reload by {@link TagsUpdatedEvent}. It is used to gather the trade lists for each profession. @@ -28,10 +30,21 @@ public class VillagerTradesEvent extends Event { protected Int2ObjectMap> trades; protected VillagerProfession type; + private final RegistryAccess registryAccess; + /** + * @deprecated Use {@link #VillagerTradesEvent(Int2ObjectMap, VillagerProfession, RegistryAccess)} instead + */ + @Deprecated(forRemoval = true, since = "1.21.1") public VillagerTradesEvent(Int2ObjectMap> trades, VillagerProfession type) { + this(trades, type, RegistryAccess.EMPTY); + } + + @ApiStatus.Internal + public VillagerTradesEvent(Int2ObjectMap> trades, VillagerProfession type, RegistryAccess registryAccess) { this.trades = trades; this.type = type; + this.registryAccess = registryAccess; } public Int2ObjectMap> getTrades() { @@ -41,4 +54,8 @@ public Int2ObjectMap> getTrades() { public VillagerProfession getType() { return type; } + + public RegistryAccess getRegistryAccess() { + return registryAccess; + } } diff --git a/src/main/java/net/neoforged/neoforge/event/village/WandererTradesEvent.java b/src/main/java/net/neoforged/neoforge/event/village/WandererTradesEvent.java index 4c9880952c..ba3766f6d9 100644 --- a/src/main/java/net/neoforged/neoforge/event/village/WandererTradesEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/village/WandererTradesEvent.java @@ -6,11 +6,13 @@ package net.neoforged.neoforge.event.village; import java.util.List; +import net.minecraft.core.RegistryAccess; import net.minecraft.world.entity.npc.VillagerTrades.ItemListing; import net.neoforged.bus.api.Event; import net.neoforged.neoforge.common.BasicItemListing; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.event.TagsUpdatedEvent; +import org.jetbrains.annotations.ApiStatus; /** * WandererTradesEvent is fired during reload by {@link TagsUpdatedEvent}. It is used to gather the trade lists for the wandering merchant. @@ -21,10 +23,21 @@ public class WandererTradesEvent extends Event { protected List generic; protected List rare; + private final RegistryAccess registryAccess; + /** + * @deprecated Use {@link #WandererTradesEvent(List, List, RegistryAccess)} instead + */ + @Deprecated(forRemoval = true, since = "1.21.1") public WandererTradesEvent(List generic, List rare) { + this(generic, rare, RegistryAccess.EMPTY); + } + + @ApiStatus.Internal + public WandererTradesEvent(List generic, List rare, RegistryAccess registryAccess) { this.generic = generic; this.rare = rare; + this.registryAccess = registryAccess; } public List getGenericTrades() { @@ -34,4 +47,8 @@ public List getGenericTrades() { public List getRareTrades() { return rare; } + + public RegistryAccess getRegistryAccess() { + return registryAccess; + } } From 85e7ec0af2ed4bb9678d54b79b6a33c4c3935cf7 Mon Sep 17 00:00:00 2001 From: "Joseph T. McQuigg" Date: Sun, 29 Sep 2024 06:34:54 -0400 Subject: [PATCH 082/125] Add Pie Item Tag c:foods/pie (#1560) Co-authored-by: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> --- src/generated/resources/assets/c/lang/en_us.json | 1 + src/generated/resources/data/c/tags/item/foods.json | 1 + src/generated/resources/data/c/tags/item/foods/pie.json | 5 +++++ .../neoforged/neoforge/common/TagConventionLogWarning.java | 3 +++ src/main/java/net/neoforged/neoforge/common/Tags.java | 4 ++++ .../common/data/internal/NeoForgeItemTagsProvider.java | 3 ++- .../common/data/internal/NeoForgeLanguageProvider.java | 1 + 7 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 src/generated/resources/data/c/tags/item/foods/pie.json diff --git a/src/generated/resources/assets/c/lang/en_us.json b/src/generated/resources/assets/c/lang/en_us.json index 73ff339a03..626b385a89 100644 --- a/src/generated/resources/assets/c/lang/en_us.json +++ b/src/generated/resources/assets/c/lang/en_us.json @@ -239,6 +239,7 @@ "tag.item.c.foods.food_poisoning": "Food Poisoning Foods", "tag.item.c.foods.fruit": "Fruits", "tag.item.c.foods.golden": "Golden Foods", + "tag.item.c.foods.pie": "Pies", "tag.item.c.foods.raw_fish": "Raw Fishes", "tag.item.c.foods.raw_meat": "Raw Meats", "tag.item.c.foods.soup": "Soups", diff --git a/src/generated/resources/data/c/tags/item/foods.json b/src/generated/resources/data/c/tags/item/foods.json index 78e6a1945b..401cd7e0e9 100644 --- a/src/generated/resources/data/c/tags/item/foods.json +++ b/src/generated/resources/data/c/tags/item/foods.json @@ -16,6 +16,7 @@ "#c:foods/cooked_fish", "#c:foods/soup", "#c:foods/candy", + "#c:foods/pie", "#c:foods/golden", "#c:foods/edible_when_placed", "#c:foods/food_poisoning" diff --git a/src/generated/resources/data/c/tags/item/foods/pie.json b/src/generated/resources/data/c/tags/item/foods/pie.json new file mode 100644 index 0000000000..7589c5f241 --- /dev/null +++ b/src/generated/resources/data/c/tags/item/foods/pie.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:pumpkin_pie" + ] +} \ No newline at end of file diff --git a/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java b/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java index f874d45787..8802212cbf 100644 --- a/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java +++ b/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java @@ -411,6 +411,9 @@ public enum LogWarningMode { createForgeMapEntry(Registries.ITEM, "candy", Tags.Items.FOODS_CANDY), createForgeMapEntry(Registries.ITEM, "candies", Tags.Items.FOODS_CANDY), createMapEntry(Registries.ITEM, "c", "foods/candies", Tags.Items.FOODS_CANDY), + createForgeMapEntry(Registries.ITEM, "pie", Tags.Items.FOODS_PIE), + createForgeMapEntry(Registries.ITEM, "pies", Tags.Items.FOODS_PIE), + createMapEntry(Registries.ITEM, "c", "foods/pies", Tags.Items.FOODS_PIE), createForgeMapEntry(Registries.FLUID, "water", Tags.Fluids.WATER), createForgeMapEntry(Registries.FLUID, "lava", Tags.Fluids.LAVA), diff --git a/src/main/java/net/neoforged/neoforge/common/Tags.java b/src/main/java/net/neoforged/neoforge/common/Tags.java index 56620f22d4..c4dfe263b7 100644 --- a/src/main/java/net/neoforged/neoforge/common/Tags.java +++ b/src/main/java/net/neoforged/neoforge/common/Tags.java @@ -429,6 +429,10 @@ public static class Items { * Sweets and candies like lollipops or chocolate belong in this tag. */ public static final TagKey FOODS_CANDY = tag("foods/candy"); + /** + * Pies and other pie-like foods belong in this tag. + */ + public static final TagKey FOODS_PIE = tag("foods/pie"); /** * Any gold-based foods would go in this tag. Such as Golden Apples or Glistering Melon Slice. */ diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java index 13013eb54d..f683fa8a72 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java @@ -121,6 +121,7 @@ public void addTags(HolderLookup.Provider lookupProvider) { tag(Tags.Items.FOODS_COOKED_FISH).add(Items.COOKED_COD, Items.COOKED_SALMON); tag(Tags.Items.FOODS_SOUP).add(Items.BEETROOT_SOUP, Items.MUSHROOM_STEW, Items.RABBIT_STEW, Items.SUSPICIOUS_STEW); tag(Tags.Items.FOODS_CANDY); + tag(Tags.Items.FOODS_PIE).add(Items.PUMPKIN_PIE); tag(Tags.Items.FOODS_GOLDEN).add(Items.GOLDEN_APPLE).add(Items.ENCHANTED_GOLDEN_APPLE).add(Items.GOLDEN_CARROT); tag(Tags.Items.FOODS_EDIBLE_WHEN_PLACED).add(Items.CAKE); tag(Tags.Items.FOODS_FOOD_POISONING).add(Items.POISONOUS_POTATO, Items.PUFFERFISH, Items.SPIDER_EYE, Items.CHICKEN, Items.ROTTEN_FLESH); @@ -128,7 +129,7 @@ public void addTags(HolderLookup.Provider lookupProvider) { .add(Items.BAKED_POTATO, Items.PUMPKIN_PIE, Items.HONEY_BOTTLE, Items.OMINOUS_BOTTLE, Items.DRIED_KELP) .addTags(Tags.Items.FOODS_FRUIT, Tags.Items.FOODS_VEGETABLE, Tags.Items.FOODS_BERRY, Tags.Items.FOODS_BREAD, Tags.Items.FOODS_COOKIE, Tags.Items.FOODS_RAW_MEAT, Tags.Items.FOODS_RAW_FISH, Tags.Items.FOODS_COOKED_MEAT, Tags.Items.FOODS_COOKED_FISH, - Tags.Items.FOODS_SOUP, Tags.Items.FOODS_CANDY, Tags.Items.FOODS_GOLDEN, + Tags.Items.FOODS_SOUP, Tags.Items.FOODS_CANDY, Tags.Items.FOODS_PIE, Tags.Items.FOODS_GOLDEN, Tags.Items.FOODS_EDIBLE_WHEN_PLACED, Tags.Items.FOODS_FOOD_POISONING); tag(Tags.Items.ANIMAL_FOODS) .addTags(ItemTags.ARMADILLO_FOOD, ItemTags.AXOLOTL_FOOD, ItemTags.BEE_FOOD, ItemTags.CAMEL_FOOD, diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java index ebac817994..f8cb9f9f26 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java @@ -206,6 +206,7 @@ protected void addTranslations() { add(Tags.Items.FOODS_BERRY, "Berries"); add(Tags.Items.FOODS_BREAD, "Breads"); add(Tags.Items.FOODS_CANDY, "Candies"); + add(Tags.Items.FOODS_PIE, "Pies"); add(Tags.Items.FOODS_COOKED_FISH, "Cooked Fishes"); add(Tags.Items.FOODS_COOKED_MEAT, "Cooked Meats"); add(Tags.Items.FOODS_COOKIE, "Cookies"); From e8b9d12add0b181f00f537d4d842bc47b15f23a4 Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Mon, 30 Sep 2024 07:58:14 -0400 Subject: [PATCH 083/125] Make Biome and Structure Modifiers not crash when attempted to be re-applied (#1545) --- .../neoforge/common/world/ModifiableBiomeInfo.java | 7 ++----- .../neoforge/common/world/ModifiableStructureInfo.java | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/main/java/net/neoforged/neoforge/common/world/ModifiableBiomeInfo.java b/src/main/java/net/neoforged/neoforge/common/world/ModifiableBiomeInfo.java index 8099df85c6..74d844fdbf 100644 --- a/src/main/java/net/neoforged/neoforge/common/world/ModifiableBiomeInfo.java +++ b/src/main/java/net/neoforged/neoforge/common/world/ModifiableBiomeInfo.java @@ -10,7 +10,6 @@ import com.mojang.serialization.DynamicOps; import com.mojang.serialization.JsonOps; import java.util.List; -import java.util.Locale; import net.minecraft.core.Holder; import net.minecraft.core.RegistryAccess; import net.minecraft.resources.RegistryOps; @@ -67,20 +66,18 @@ public BiomeInfo getModifiedBiomeInfo() { } /** - * Internal forge method; the game will crash if mods invoke this. + * Internal NeoForge method. Will do nothing if this modifier had already been applied. * Creates and caches the modified biome info. * * @param biome named biome with original data. * @param biomeModifiers biome modifiers to apply. * * @return whether the biome's network-synced data was modified - * - * @throws IllegalStateException if invoked more than once. */ @ApiStatus.Internal public boolean applyBiomeModifiers(final Holder biome, final List biomeModifiers, RegistryAccess registryAccess) { if (this.modifiedBiomeInfo != null) - throw new IllegalStateException(String.format(Locale.ENGLISH, "Biome %s already modified", biome)); + return true; BiomeInfo original = this.getOriginalBiomeInfo(); final BiomeInfo.Builder builder = BiomeInfo.Builder.copyOf(original); diff --git a/src/main/java/net/neoforged/neoforge/common/world/ModifiableStructureInfo.java b/src/main/java/net/neoforged/neoforge/common/world/ModifiableStructureInfo.java index 3247d5f903..55371a81f9 100644 --- a/src/main/java/net/neoforged/neoforge/common/world/ModifiableStructureInfo.java +++ b/src/main/java/net/neoforged/neoforge/common/world/ModifiableStructureInfo.java @@ -6,7 +6,6 @@ package net.neoforged.neoforge.common.world; import java.util.List; -import java.util.Locale; import net.minecraft.core.Holder; import net.minecraft.world.level.levelgen.structure.Structure; import net.minecraft.world.level.levelgen.structure.Structure.StructureSettings; @@ -55,18 +54,16 @@ public StructureInfo getModifiedStructureInfo() { } /** - * Internal neoforge method; the game will crash if mods invoke this. + * Internal NeoForge method. Will do nothing if this modifier had already been applied. * Creates and caches the modified structure info. * * @param structure named structure with original data. * @param structureModifiers structure modifiers to apply. - * - * @throws IllegalStateException if invoked more than once. */ @ApiStatus.Internal public void applyStructureModifiers(final Holder structure, final List structureModifiers) { if (this.modifiedStructureInfo != null) - throw new IllegalStateException(String.format(Locale.ENGLISH, "Structure %s already modified", structure)); + return; StructureInfo original = this.getOriginalStructureInfo(); final StructureInfo.Builder builder = StructureInfo.Builder.copyOf(original); From 06b9d4708ef76a14031e3cb9712a194ba8002206 Mon Sep 17 00:00:00 2001 From: Brennan Ward Date: Sat, 5 Oct 2024 19:35:21 -0700 Subject: [PATCH 084/125] [1.21] Allow for custom components in enchantment datagen (#1421) --- .../item/enchantment/Enchantment.java.patch | 47 +++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch b/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch index 8237cc26e6..86a3a016cf 100644 --- a/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch +++ b/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch @@ -43,11 +43,10 @@ public boolean canEnchant(ItemStack p_44689_) { return this.definition.supportedItems().contains(p_44689_.getItemHolder()); } -@@ -503,6 +_,15 @@ - public static Enchantment.Builder enchantment(Enchantment.EnchantmentDefinition p_345873_) { +@@ -504,12 +_,26 @@ return new Enchantment.Builder(p_345873_); } -+ + +// TODO: Reimplement. Not sure if we want to patch EnchantmentDefinition or hack this in as an EnchantmentEffectComponent. +// /** +// * Is this enchantment allowed to be enchanted on books via Enchantment Table @@ -56,6 +55,46 @@ +// public boolean isAllowedOnBooks() { +// return true; +// } - ++ public static class Builder { private final Enchantment.EnchantmentDefinition definition; + private HolderSet exclusiveSet = HolderSet.direct(); + private final Map, List> effectLists = new HashMap<>(); + private final DataComponentMap.Builder effectMapBuilder = DataComponentMap.builder(); + ++ /** ++ * Neo: Allow customizing or changing the {@link Component} created by the enchantment builder. ++ */ ++ protected java.util.function.UnaryOperator nameFactory = java.util.function.UnaryOperator.identity(); ++ + public Builder(Enchantment.EnchantmentDefinition p_345317_) { + this.definition = p_345317_; + } +@@ -562,6 +_,16 @@ + return this; + } + ++ /** ++ * Allows specifying an operator that can customize the default {@link Component} created by {@link #build(ResourceLocation)}. ++ * ++ * @return this ++ */ ++ public Enchantment.Builder withCustomName(java.util.function.UnaryOperator nameFactory) { ++ this.nameFactory = nameFactory; ++ return this; ++ } ++ + private List getEffectsList(DataComponentType> p_344770_) { + return (List)this.effectLists.computeIfAbsent(p_344770_, p_346247_ -> { + ArrayList arraylist = new ArrayList<>(); +@@ -572,7 +_,9 @@ + + public Enchantment build(ResourceLocation p_344988_) { + return new Enchantment( +- Component.translatable(Util.makeDescriptionId("enchantment", p_344988_)), this.definition, this.exclusiveSet, this.effectMapBuilder.build() ++ // Neo: permit custom name components instead of a single hardcoded translatable component. ++ this.nameFactory.apply(Component.translatable(Util.makeDescriptionId("enchantment", p_344988_))), ++ this.definition, this.exclusiveSet, this.effectMapBuilder.build() + ); + } + } From b88c1e1e17414097012330222a2a83796a8a7ce3 Mon Sep 17 00:00:00 2001 From: Luke Bemish Date: Mon, 7 Oct 2024 16:10:14 -0500 Subject: [PATCH 085/125] [no ci] Add note in `CONTRIBUTING.md` about fetching tags when contributing (#1570) --- docs/CONTRIBUTING.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index d34d06f231..eea2cf6d4b 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -12,20 +12,21 @@ Contributing to NeoForge 1. Have preliminary discussions on Discord (`#neoforge-github`) 2. Fork the repository 3. Check out your fork -4. Make a branch -5. Run `gradlew setup` from the project root to decompile sources and apply current patches -6. Import project into your IDE (IntelliJ/Eclipse) or Reload Gradle Project -7. Modify the patched Minecraft sources in `projects/neoforge/src/main/java` as needed. The unmodified sources are available in `projects/base/src/main/java` for your reference. Do not modify these. -8. Test your changes +4. Fetch tags from the upstream repository by running `git remote add upstream https://github.com/neoforged/NeoForge.git` followed by `git fetch upstream --tags` +5. Make a branch +6. Run `gradlew setup` from the project root to decompile sources and apply current patches +7. Import project into your IDE (IntelliJ/Eclipse) or Reload Gradle Project +8. Modify the patched Minecraft sources in `projects/neoforge/src/main/java` as needed. The unmodified sources are available in `projects/base/src/main/java` for your reference. Do not modify these. +9. Test your changes - Run the game (Runs are available in the IDE) - Run `gradlew :tests:runGameTestServer` or `Tests: GameTestServer` from IDE - Run `gradlew :tests:runGameTestClient` or `Tests: GameTestClient` from IDE - If possible, write an automated test under the tests project. See [NEOGAMETESTS.md](NEOGAMETESTS.md) for more info. -9. Run `gradlew unpackSourcePatches` to generate patch-files from the patched sources -10. Run `gradlew applyAllFormatting` to automatically format sources -11. Check correct formatting with `gradlew spotlessCheck` -12. Commit & Push -13. Make PR +10. Run `gradlew unpackSourcePatches` to generate patch-files from the patched sources +11. Run `gradlew applyAllFormatting` to automatically format sources +12. Check correct formatting with `gradlew spotlessCheck` +13. Commit & Push +14. Make PR ## Porting From f869db584b46fd49066f266ee768fe51f071c836 Mon Sep 17 00:00:00 2001 From: ZestyBlaze <68081568+ZestyBlaze@users.noreply.github.com> Date: Fri, 11 Oct 2024 00:33:42 +0100 Subject: [PATCH 086/125] Add a few new `ItemModelProvider` methods! (#1542) --- .../model/generators/ItemModelProvider.java | 28 +++++++++++++++++++ .../minecraft/models/item/acacia_planks.json | 3 ++ .../models/item/sheep_spawn_egg.json | 3 ++ .../minecraft/models/item/wooden_sword.json | 6 ++++ .../model/CustomItemDisplayContextTest.java | 7 +++++ 5 files changed, 47 insertions(+) create mode 100644 tests/src/generated/resources/assets/minecraft/models/item/acacia_planks.json create mode 100644 tests/src/generated/resources/assets/minecraft/models/item/sheep_spawn_egg.json create mode 100644 tests/src/generated/resources/assets/minecraft/models/item/wooden_sword.json diff --git a/src/main/java/net/neoforged/neoforge/client/model/generators/ItemModelProvider.java b/src/main/java/net/neoforged/neoforge/client/model/generators/ItemModelProvider.java index f4af7fdeaf..046ef31566 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/generators/ItemModelProvider.java +++ b/src/main/java/net/neoforged/neoforge/client/model/generators/ItemModelProvider.java @@ -10,6 +10,7 @@ import net.minecraft.data.PackOutput; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; import net.neoforged.neoforge.common.data.ExistingFileHelper; /** @@ -31,6 +32,33 @@ public ItemModelBuilder basicItem(ResourceLocation item) { .texture("layer0", ResourceLocation.fromNamespaceAndPath(item.getNamespace(), "item/" + item.getPath())); } + public ItemModelBuilder handheldItem(Item item) { + return handheldItem(Objects.requireNonNull(BuiltInRegistries.ITEM.getKey(item))); + } + + public ItemModelBuilder handheldItem(ResourceLocation item) { + return getBuilder(item.toString()) + .parent(new ModelFile.UncheckedModelFile("item/handheld")) + .texture("layer0", ResourceLocation.fromNamespaceAndPath(item.getNamespace(), "item/" + item.getPath())); + } + + public ItemModelBuilder spawnEggItem(Item item) { + return spawnEggItem(Objects.requireNonNull(BuiltInRegistries.ITEM.getKey(item))); + } + + public ItemModelBuilder spawnEggItem(ResourceLocation item) { + return getBuilder(item.toString()) + .parent(new ModelFile.UncheckedModelFile("item/template_spawn_egg")); + } + + public ItemModelBuilder simpleBlockItem(Block block) { + return simpleBlockItem(Objects.requireNonNull(BuiltInRegistries.BLOCK.getKey(block))); + } + + public ItemModelBuilder simpleBlockItem(ResourceLocation block) { + return withExistingParent(block.toString(), ResourceLocation.fromNamespaceAndPath(block.getNamespace(), "block/" + block.getPath())); + } + @Override public String getName() { return "Item Models: " + modid; diff --git a/tests/src/generated/resources/assets/minecraft/models/item/acacia_planks.json b/tests/src/generated/resources/assets/minecraft/models/item/acacia_planks.json new file mode 100644 index 0000000000..3c90abef53 --- /dev/null +++ b/tests/src/generated/resources/assets/minecraft/models/item/acacia_planks.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:block/acacia_planks" +} \ No newline at end of file diff --git a/tests/src/generated/resources/assets/minecraft/models/item/sheep_spawn_egg.json b/tests/src/generated/resources/assets/minecraft/models/item/sheep_spawn_egg.json new file mode 100644 index 0000000000..d1aaa9d6ef --- /dev/null +++ b/tests/src/generated/resources/assets/minecraft/models/item/sheep_spawn_egg.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:item/template_spawn_egg" +} \ No newline at end of file diff --git a/tests/src/generated/resources/assets/minecraft/models/item/wooden_sword.json b/tests/src/generated/resources/assets/minecraft/models/item/wooden_sword.json new file mode 100644 index 0000000000..4024a58a08 --- /dev/null +++ b/tests/src/generated/resources/assets/minecraft/models/item/wooden_sword.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "minecraft:item/wooden_sword" + } +} \ No newline at end of file diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/CustomItemDisplayContextTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/CustomItemDisplayContextTest.java index 9c6ce94624..17f8a3cb3a 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/CustomItemDisplayContextTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/client/model/CustomItemDisplayContextTest.java @@ -34,6 +34,7 @@ import net.minecraft.world.item.Items; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.HorizontalDirectionalBlock; import net.minecraft.world.level.block.RenderShape; @@ -167,6 +168,12 @@ protected void registerModels() { .translation(-2.25f, 1.5f, -0.25f).scale(0.48f) .end() .end(); + + handheldItem(Items.WOODEN_SWORD); + + spawnEggItem(Items.SHEEP_SPAWN_EGG); + + simpleBlockItem(Blocks.ACACIA_PLANKS); } } From 22971888941fcdef33b63f957657ad2a111c5925 Mon Sep 17 00:00:00 2001 From: shartte Date: Sun, 13 Oct 2024 17:06:05 +0200 Subject: [PATCH 087/125] Disable JCC for Port Branches (#1434) --- .github/workflows/build-prs.yml | 2 ++ .github/workflows/publish-jcc.yml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-prs.yml b/.github/workflows/build-prs.yml index 9d70bf8a29..275a91f5d0 100644 --- a/.github/workflows/build-prs.yml +++ b/.github/workflows/build-prs.yml @@ -48,9 +48,11 @@ jobs: run: ./gradlew assemble checkFormatting - name: Run JCC + if: ${{ ! startsWith(github.event.pull_request.head.ref, 'refs/heads/port/') }} run: ./gradlew checkJarCompatibility - name: Upload JCC + if: ${{ ! startsWith(github.event.pull_request.head.ref, 'refs/heads/port/') }} uses: neoforged/action-jar-compatibility/upload@v1 - name: Publish artifacts diff --git a/.github/workflows/publish-jcc.yml b/.github/workflows/publish-jcc.yml index f4c78789bc..477bf720c7 100644 --- a/.github/workflows/publish-jcc.yml +++ b/.github/workflows/publish-jcc.yml @@ -11,7 +11,7 @@ on: jobs: publish-jcc: - if: true + if: ${{ ! startsWith(github.event.workflow_run.head_branch, 'port/') }} uses: neoforged/actions/.github/workflows/publish-jcc.yml@main with: beta_version_pattern: .*-beta.* From feb80270cf7f65fe969eefb38bb3b04e196a43be Mon Sep 17 00:00:00 2001 From: TelepathicGrunt <40846040+TelepathicGrunt@users.noreply.github.com> Date: Tue, 15 Oct 2024 11:58:15 -0400 Subject: [PATCH 088/125] Add `c:experience` fluid tag with javadoc for standard conversion rate (#1573) --- .../resources/assets/c/lang/en_us.json | 1 + .../data/c/tags/fluid/experience.json | 3 ++ .../common/TagConventionLogWarning.java | 2 ++ .../net/neoforged/neoforge/common/Tags.java | 30 +++++++++++++------ .../internal/NeoForgeFluidTagsProvider.java | 1 + .../internal/NeoForgeLanguageProvider.java | 1 + 6 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 src/generated/resources/data/c/tags/fluid/experience.json diff --git a/src/generated/resources/assets/c/lang/en_us.json b/src/generated/resources/assets/c/lang/en_us.json index 626b385a89..cf6783aeb8 100644 --- a/src/generated/resources/assets/c/lang/en_us.json +++ b/src/generated/resources/assets/c/lang/en_us.json @@ -128,6 +128,7 @@ "tag.entity_type.c.minecarts": "Minecarts", "tag.entity_type.c.teleporting_not_supported": "Teleporting Not Supported", "tag.fluid.c.beetroot_soup": "Beetroot Soup", + "tag.fluid.c.experience": "Experience", "tag.fluid.c.gaseous": "Gaseous", "tag.fluid.c.hidden_from_recipe_viewers": "Hidden From Recipe Viewers", "tag.fluid.c.honey": "Honey", diff --git a/src/generated/resources/data/c/tags/fluid/experience.json b/src/generated/resources/data/c/tags/fluid/experience.json new file mode 100644 index 0000000000..f72d209df7 --- /dev/null +++ b/src/generated/resources/data/c/tags/fluid/experience.json @@ -0,0 +1,3 @@ +{ + "values": [] +} \ No newline at end of file diff --git a/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java b/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java index 8802212cbf..854a826426 100644 --- a/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java +++ b/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java @@ -420,6 +420,8 @@ public enum LogWarningMode { createForgeMapEntry(Registries.FLUID, "milk", Tags.Fluids.MILK), createForgeMapEntry(Registries.FLUID, "gaseous", Tags.Fluids.GASEOUS), createForgeMapEntry(Registries.FLUID, "honey", Tags.Fluids.HONEY), + createForgeMapEntry(Registries.FLUID, "xp", Tags.Fluids.EXPERIENCE), + createForgeMapEntry(Registries.FLUID, "experience", Tags.Fluids.EXPERIENCE), createForgeMapEntry(Registries.FLUID, "potion", Tags.Fluids.POTION), createForgeMapEntry(Registries.FLUID, "plantoil", "plant_oil"), diff --git a/src/main/java/net/neoforged/neoforge/common/Tags.java b/src/main/java/net/neoforged/neoforge/common/Tags.java index c4dfe263b7..9a39ba84a9 100644 --- a/src/main/java/net/neoforged/neoforge/common/Tags.java +++ b/src/main/java/net/neoforged/neoforge/common/Tags.java @@ -768,12 +768,12 @@ private static TagKey neoforgeTag(String name) { */ public static class Fluids { /** - * Holds all fluids related to water. + * Holds all fluids related to water.

* This tag is done to help out multi-loader mods/datapacks where the vanilla water tag has attached behaviors outside Neo. */ public static final TagKey WATER = tag("water"); /** - * Holds all fluids related to lava. + * Holds all fluids related to lava.

* This tag is done to help out multi-loader mods/datapacks where the vanilla lava tag has attached behaviors outside Neo. */ public static final TagKey LAVA = tag("lava"); @@ -786,36 +786,48 @@ public static class Fluids { */ public static final TagKey GASEOUS = tag("gaseous"); /** - * Holds all fluids related to honey.

+ * Holds all fluids related to honey. + *

* (Standard unit for honey bottle is 250mb per bottle) */ public static final TagKey HONEY = tag("honey"); /** - * Holds all fluids related to potions. The effects of the potion fluid should be read from NBT. + * Holds all fluids related to experience. + *

+ * (Standard unit for experience is 20mb per 1 experience. However, extraction from Bottle o' Enchanting should yield 250mb while smashing yields less) + */ + public static final TagKey EXPERIENCE = tag("experience"); + /** + * Holds all fluids related to potions. The effects of the potion fluid should be read from DataComponents. * The effects and color of the potion fluid should be read from {@link net.minecraft.core.component.DataComponents#POTION_CONTENTS} - * component that people should be attaching to the fluidstack of this fluid.

+ * component that people should be attaching to the fluidstack of this fluid. + *

* (Standard unit for potions is 250mb per bottle) */ public static final TagKey POTION = tag("potion"); /** * Holds all fluids related to Suspicious Stew. * The effects of the suspicious stew fluid should be read from {@link net.minecraft.core.component.DataComponents#SUSPICIOUS_STEW_EFFECTS} - * component that people should be attaching to the fluidstack of this fluid.

+ * component that people should be attaching to the fluidstack of this fluid. + *

* (Standard unit for suspicious stew is 250mb per bowl) */ public static final TagKey SUSPICIOUS_STEW = tag("suspicious_stew"); /** - * Holds all fluids related to Mushroom Stew.

+ * Holds all fluids related to Mushroom Stew. + *

* (Standard unit for mushroom stew is 250mb per bowl) */ public static final TagKey MUSHROOM_STEW = tag("mushroom_stew"); /** - * Holds all fluids related to Rabbit Stew.

+ * Holds all fluids related to Rabbit Stew. + *

* (Standard unit for rabbit stew is 250mb per bowl) */ public static final TagKey RABBIT_STEW = tag("rabbit_stew"); /** - * Holds all fluids related to Beetroot Soup.

+ * Holds all fluids related to Beetroot Soup. + *

* (Standard unit for beetroot soup is 250mb per bowl) */ public static final TagKey BEETROOT_SOUP = tag("beetroot_soup"); diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeFluidTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeFluidTagsProvider.java index 880ebada1d..5d96ec98ba 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeFluidTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeFluidTagsProvider.java @@ -29,6 +29,7 @@ public void addTags(HolderLookup.Provider lookupProvider) { tag(Fluids.MILK).addOptional(NeoForgeMod.MILK.getId()).addOptional(NeoForgeMod.FLOWING_MILK.getId()); tag(Fluids.GASEOUS); tag(Fluids.HONEY); + tag(Fluids.EXPERIENCE); tag(Fluids.POTION); tag(Fluids.SUSPICIOUS_STEW); tag(Fluids.MUSHROOM_STEW); diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java index f8cb9f9f26..e63397cdcb 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java @@ -345,6 +345,7 @@ protected void addTranslations() { add(Tags.Fluids.MILK, "Milk"); add(Tags.Fluids.GASEOUS, "Gaseous"); add(Tags.Fluids.HONEY, "Honey"); + add(Tags.Fluids.EXPERIENCE, "Experience"); add(Tags.Fluids.POTION, "Potion"); add(Tags.Fluids.SUSPICIOUS_STEW, "Suspicious Stew"); add(Tags.Fluids.MUSHROOM_STEW, "Mushroom Stew"); From 8450a90c52f3bd8b5f4d48f159d34e359ab2af7f Mon Sep 17 00:00:00 2001 From: IThundxr Date: Tue, 15 Oct 2024 11:58:24 -0400 Subject: [PATCH 089/125] Add Stripped Logs and Stripped Woods Tags (#1584) --- src/generated/resources/assets/c/lang/en_us.json | 4 ++++ .../resources/data/c/tags/block/stripped_logs.json | 13 +++++++++++++ .../resources/data/c/tags/block/stripped_woods.json | 12 ++++++++++++ .../resources/data/c/tags/item/stripped_logs.json | 13 +++++++++++++ .../resources/data/c/tags/item/stripped_woods.json | 12 ++++++++++++ .../java/net/neoforged/neoforge/common/Tags.java | 4 ++++ .../data/internal/NeoForgeBlockTagsProvider.java | 8 ++++++++ .../data/internal/NeoForgeItemTagsProvider.java | 2 ++ .../data/internal/NeoForgeLanguageProvider.java | 4 ++++ 9 files changed, 72 insertions(+) create mode 100644 src/generated/resources/data/c/tags/block/stripped_logs.json create mode 100644 src/generated/resources/data/c/tags/block/stripped_woods.json create mode 100644 src/generated/resources/data/c/tags/item/stripped_logs.json create mode 100644 src/generated/resources/data/c/tags/item/stripped_woods.json diff --git a/src/generated/resources/assets/c/lang/en_us.json b/src/generated/resources/assets/c/lang/en_us.json index cf6783aeb8..3c27e29b49 100644 --- a/src/generated/resources/assets/c/lang/en_us.json +++ b/src/generated/resources/assets/c/lang/en_us.json @@ -110,6 +110,8 @@ "tag.block.c.storage_blocks.redstone": "Redstone Storage Blocks", "tag.block.c.storage_blocks.slime": "Slime Storage Blocks", "tag.block.c.storage_blocks.wheat": "Wheat Storage Blocks", + "tag.block.c.stripped_logs": "Stripped Logs", + "tag.block.c.stripped_woods": "Stripped Woods", "tag.block.c.villager_job_sites": "Villager Job Sites", "tag.block.neoforge.enderman_place_on_blacklist": "Enderman Place On Blacklist", "tag.block.neoforge.needs_gold_tool": "Needs Gold Tools", @@ -348,6 +350,8 @@ "tag.item.c.storage_blocks.slime": "Slime Storage Blocks", "tag.item.c.storage_blocks.wheat": "Wheat Storage Blocks", "tag.item.c.strings": "Strings", + "tag.item.c.stripped_logs": "Stripped Log Blocks", + "tag.item.c.stripped_woods": "Stripped Wood Blocks", "tag.item.c.tools": "Tools", "tag.item.c.tools.bow": "Bows", "tag.item.c.tools.brush": "Brushes", diff --git a/src/generated/resources/data/c/tags/block/stripped_logs.json b/src/generated/resources/data/c/tags/block/stripped_logs.json new file mode 100644 index 0000000000..ae69c996ad --- /dev/null +++ b/src/generated/resources/data/c/tags/block/stripped_logs.json @@ -0,0 +1,13 @@ +{ + "values": [ + "minecraft:stripped_acacia_log", + "minecraft:stripped_bamboo_block", + "minecraft:stripped_birch_log", + "minecraft:stripped_cherry_log", + "minecraft:stripped_dark_oak_log", + "minecraft:stripped_jungle_log", + "minecraft:stripped_mangrove_log", + "minecraft:stripped_oak_log", + "minecraft:stripped_spruce_log" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/stripped_woods.json b/src/generated/resources/data/c/tags/block/stripped_woods.json new file mode 100644 index 0000000000..197542891d --- /dev/null +++ b/src/generated/resources/data/c/tags/block/stripped_woods.json @@ -0,0 +1,12 @@ +{ + "values": [ + "minecraft:stripped_acacia_wood", + "minecraft:stripped_birch_wood", + "minecraft:stripped_cherry_wood", + "minecraft:stripped_dark_oak_wood", + "minecraft:stripped_jungle_wood", + "minecraft:stripped_mangrove_wood", + "minecraft:stripped_oak_wood", + "minecraft:stripped_spruce_wood" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/stripped_logs.json b/src/generated/resources/data/c/tags/item/stripped_logs.json new file mode 100644 index 0000000000..ae69c996ad --- /dev/null +++ b/src/generated/resources/data/c/tags/item/stripped_logs.json @@ -0,0 +1,13 @@ +{ + "values": [ + "minecraft:stripped_acacia_log", + "minecraft:stripped_bamboo_block", + "minecraft:stripped_birch_log", + "minecraft:stripped_cherry_log", + "minecraft:stripped_dark_oak_log", + "minecraft:stripped_jungle_log", + "minecraft:stripped_mangrove_log", + "minecraft:stripped_oak_log", + "minecraft:stripped_spruce_log" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/stripped_woods.json b/src/generated/resources/data/c/tags/item/stripped_woods.json new file mode 100644 index 0000000000..197542891d --- /dev/null +++ b/src/generated/resources/data/c/tags/item/stripped_woods.json @@ -0,0 +1,12 @@ +{ + "values": [ + "minecraft:stripped_acacia_wood", + "minecraft:stripped_birch_wood", + "minecraft:stripped_cherry_wood", + "minecraft:stripped_dark_oak_wood", + "minecraft:stripped_jungle_wood", + "minecraft:stripped_mangrove_wood", + "minecraft:stripped_oak_wood", + "minecraft:stripped_spruce_wood" + ] +} \ No newline at end of file diff --git a/src/main/java/net/neoforged/neoforge/common/Tags.java b/src/main/java/net/neoforged/neoforge/common/Tags.java index 9a39ba84a9..8a57785dc8 100644 --- a/src/main/java/net/neoforged/neoforge/common/Tags.java +++ b/src/main/java/net/neoforged/neoforge/common/Tags.java @@ -224,6 +224,8 @@ public static class Blocks { public static final TagKey STORAGE_BLOCKS_REDSTONE = tag("storage_blocks/redstone"); public static final TagKey STORAGE_BLOCKS_SLIME = tag("storage_blocks/slime"); public static final TagKey STORAGE_BLOCKS_WHEAT = tag("storage_blocks/wheat"); + public static final TagKey STRIPPED_LOGS = tag("stripped_logs"); + public static final TagKey STRIPPED_WOODS = tag("stripped_woods"); public static final TagKey VILLAGER_JOB_SITES = tag("villager_job_sites"); /** @@ -627,6 +629,8 @@ public static class Items { public static final TagKey STORAGE_BLOCKS_SLIME = tag("storage_blocks/slime"); public static final TagKey STORAGE_BLOCKS_WHEAT = tag("storage_blocks/wheat"); public static final TagKey STRINGS = tag("strings"); + public static final TagKey STRIPPED_LOGS = tag("stripped_logs"); + public static final TagKey STRIPPED_WOODS = tag("stripped_woods"); public static final TagKey VILLAGER_JOB_SITES = tag("villager_job_sites"); // Tools and Armors diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java index 8a689441d4..ca4fde00ba 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java @@ -144,6 +144,14 @@ public void addTags(HolderLookup.Provider p_256380_) { tag(Tags.Blocks.STORAGE_BLOCKS_REDSTONE).add(Blocks.REDSTONE_BLOCK); tag(Tags.Blocks.STORAGE_BLOCKS_SLIME).add(Blocks.SLIME_BLOCK); tag(Tags.Blocks.STORAGE_BLOCKS_WHEAT).add(Blocks.HAY_BLOCK); + tag(Tags.Blocks.STRIPPED_LOGS).add( + Blocks.STRIPPED_ACACIA_LOG, Blocks.STRIPPED_BAMBOO_BLOCK, Blocks.STRIPPED_BIRCH_LOG, + Blocks.STRIPPED_CHERRY_LOG, Blocks.STRIPPED_DARK_OAK_LOG, Blocks.STRIPPED_JUNGLE_LOG, + Blocks.STRIPPED_MANGROVE_LOG, Blocks.STRIPPED_OAK_LOG, Blocks.STRIPPED_SPRUCE_LOG); + tag(Tags.Blocks.STRIPPED_WOODS).add( + Blocks.STRIPPED_ACACIA_WOOD, Blocks.STRIPPED_BIRCH_WOOD, Blocks.STRIPPED_CHERRY_WOOD, + Blocks.STRIPPED_DARK_OAK_WOOD, Blocks.STRIPPED_JUNGLE_WOOD, Blocks.STRIPPED_MANGROVE_WOOD, + Blocks.STRIPPED_OAK_WOOD, Blocks.STRIPPED_SPRUCE_WOOD); tag(Tags.Blocks.VILLAGER_JOB_SITES).add( Blocks.BARREL, Blocks.BLAST_FURNACE, Blocks.BREWING_STAND, Blocks.CARTOGRAPHY_TABLE, Blocks.CAULDRON, Blocks.WATER_CAULDRON, Blocks.LAVA_CAULDRON, Blocks.POWDER_SNOW_CAULDRON, diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java index f683fa8a72..20e88b6501 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeItemTagsProvider.java @@ -250,6 +250,8 @@ public void addTags(HolderLookup.Provider lookupProvider) { copy(Tags.Blocks.STORAGE_BLOCKS_SLIME, Tags.Items.STORAGE_BLOCKS_SLIME); copy(Tags.Blocks.STORAGE_BLOCKS_WHEAT, Tags.Items.STORAGE_BLOCKS_WHEAT); tag(Tags.Items.STRINGS).add(Items.STRING); + copy(Tags.Blocks.STRIPPED_LOGS, Tags.Items.STRIPPED_LOGS); + copy(Tags.Blocks.STRIPPED_WOODS, Tags.Items.STRIPPED_WOODS); tag(Tags.Items.VILLAGER_JOB_SITES).add( Items.BARREL, Items.BLAST_FURNACE, Items.BREWING_STAND, Items.CARTOGRAPHY_TABLE, Items.CAULDRON, Items.COMPOSTER, Items.FLETCHING_TABLE, Items.GRINDSTONE, diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java index e63397cdcb..f764016f5c 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeLanguageProvider.java @@ -125,6 +125,8 @@ protected void addTranslations() { add(Tags.Blocks.STORAGE_BLOCKS_REDSTONE, "Redstone Storage Blocks"); add(Tags.Blocks.STORAGE_BLOCKS_SLIME, "Slime Storage Blocks"); add(Tags.Blocks.STORAGE_BLOCKS_WHEAT, "Wheat Storage Blocks"); + add(Tags.Blocks.STRIPPED_LOGS, "Stripped Logs"); + add(Tags.Blocks.STRIPPED_WOODS, "Stripped Woods"); add(Tags.Blocks.VILLAGER_JOB_SITES, "Villager Job Sites"); add(Tags.Blocks.VILLAGER_FARMLANDS, "Villager Farmlands"); @@ -322,6 +324,8 @@ protected void addTranslations() { add(Tags.Items.STORAGE_BLOCKS_SLIME, "Slime Storage Blocks"); add(Tags.Items.STORAGE_BLOCKS_WHEAT, "Wheat Storage Blocks"); add(Tags.Items.STRINGS, "Strings"); + add(Tags.Items.STRIPPED_LOGS, "Stripped Log Blocks"); + add(Tags.Items.STRIPPED_WOODS, "Stripped Wood Blocks"); add(Tags.Items.VILLAGER_JOB_SITES, "Villager Job Sites"); add(Tags.Items.TOOLS_SHEAR, "Shears"); add(Tags.Items.TOOLS_SHIELD, "Shields"); From 718fd71c745ed393c69aaa4bc313745394251f83 Mon Sep 17 00:00:00 2001 From: "neoforged-renovate[bot]" <174042230+neoforged-renovate[bot]@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:38:56 +0000 Subject: [PATCH 090/125] Update fancy_mod_loader_version to v4.0.29 (#1601) --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 270ebe4a68..d65d2d4d71 100644 --- a/gradle.properties +++ b/gradle.properties @@ -30,7 +30,7 @@ jetbrains_annotations_version=24.0.1 slf4j_api_version=2.0.7 apache_maven_artifact_version=3.8.5 jarjar_version=0.4.1 -fancy_mod_loader_version=4.0.24 +fancy_mod_loader_version=4.0.29 mojang_logging_version=1.1.1 log4j_version=2.22.1 guava_version=31.1.2-jre From e18c20024a7f81d3ab7a4f625d6bcfa13c217767 Mon Sep 17 00:00:00 2001 From: Technici4n <13494793+Technici4n@users.noreply.github.com> Date: Sat, 12 Oct 2024 20:10:47 +0200 Subject: [PATCH 091/125] Port to 1.21.2-rc1 Co-Authored-By: Apex Co-Authored-By: coehlrich Co-Authored-By: embeddedt <42941056+embeddedt@users.noreply.github.com> Co-Authored-By: Sebastian Hartte Co-Authored-By: Technici4n <13494793+Technici4n@users.noreply.github.com> Co-Authored-By: XFactHD --- .github/workflows/build-prs.yml | 15 +- .../neoforge/coremods/MethodRedirector.java | 4 +- docs/CONTRIBUTING.md | 2 +- gradle.properties | 6 +- .../blaze3d/pipeline/RenderTarget.java.patch | 57 -- .../platform/GlStateManager.java.patch | 2 +- .../mojang/blaze3d/platform/Window.java.patch | 6 +- .../blaze3d/systems/RenderSystem.java.patch | 2 +- .../blaze3d/vertex/PoseStack.java.patch | 2 +- .../blaze3d/vertex/VertexConsumer.java.patch | 14 +- .../blaze3d/vertex/VertexFormat.java.patch | 2 +- .../RealmsNotificationsScreen.java.patch | 2 +- .../net/minecraft/SharedConstants.java.patch | 4 +- patches/net/minecraft/Util.java.patch | 4 +- .../AdvancementRewards.java.patch | 2 +- .../net/minecraft/client/Camera.java.patch | 34 +- .../client/ClientRecipeBook.java.patch | 35 +- .../client/KeyboardHandler.java.patch | 92 ++-- .../net/minecraft/client/Minecraft.java.patch | 153 +++--- .../minecraft/client/MouseHandler.java.patch | 100 ++-- .../net/minecraft/client/Options.java.patch | 16 +- .../client/RecipeBookCategories.java.patch | 59 --- .../client/color/item/ItemColors.java.patch | 4 +- .../net/minecraft/client/gui/Font.java.patch | 4 +- .../net/minecraft/client/gui/Gui.java.patch | 122 +++-- .../client/gui/GuiGraphics.java.patch | 117 ++-- .../client/gui/MapRenderer.java.patch | 13 - .../gui/components/AbstractButton.java.patch | 8 +- .../gui/components/AbstractWidget.java.patch | 2 +- .../components/BossHealthOverlay.java.patch | 2 +- .../components/DebugScreenOverlay.java.patch | 37 +- .../toasts/ToastComponent.java.patch | 10 - .../components/toasts/ToastManager.java.patch | 10 + .../gui/screens/LoadingOverlay.java.patch | 4 +- .../client/gui/screens/PauseScreen.java.patch | 2 +- .../client/gui/screens/Screen.java.patch | 20 +- .../client/gui/screens/TitleScreen.java.patch | 12 +- .../advancements/AdvancementTab.java.patch | 6 +- .../AdvancementTabType.java.patch | 2 +- .../AdvancementsScreen.java.patch | 14 +- .../AbstractContainerScreen.java.patch | 82 +-- .../CreativeModeInventoryScreen.java.patch | 56 +- ...va.patch => EffectsInInventory.java.patch} | 43 +- .../inventory/EnchantmentScreen.java.patch | 14 +- .../HangingSignEditScreen.java.patch | 2 +- .../inventory/MerchantScreen.java.patch | 6 +- .../tooltip/ClientTooltipComponent.java.patch | 20 +- .../tooltip/TooltipRenderUtil.java.patch | 49 -- .../options/controls/KeyBindsList.java.patch | 4 +- .../controls/KeyBindsScreen.java.patch | 8 +- .../screens/recipebook/GhostSlots.java.patch | 11 + .../recipebook/RecipeBookComponent.java.patch | 28 +- .../CreateWorldScreen.java.patch | 26 +- .../WorldCreationContext.java.patch | 4 +- .../WorldCreationUiState.java.patch | 2 +- .../worldselection/WorldOpenFlows.java.patch | 6 +- .../WorldSelectionList.java.patch | 14 +- .../net/minecraft/client/main/Main.java.patch | 2 +- .../client/model/HumanoidModel.java.patch | 14 +- ...hicalModel.java.patch => Model.java.patch} | 41 +- .../model/geom/LayerDefinitions.java.patch | 17 +- .../client/model/geom/ModelLayers.java.patch | 36 +- .../multiplayer/ClientChunkCache.java.patch | 6 +- .../ClientCommonPacketListenerImpl.java.patch | 14 +- ...ConfigurationPacketListenerImpl.java.patch | 6 +- .../client/multiplayer/ClientLevel.java.patch | 40 +- .../ClientPacketListener.java.patch | 63 ++- .../CommonListenerCookie.java.patch | 9 +- .../MultiPlayerGameMode.java.patch | 43 +- .../client/multiplayer/PlayerInfo.java.patch | 2 +- .../multiplayer/SessionSearchTrees.java.patch | 10 +- .../multiplayer/TagCollector.java.patch | 9 - .../particle/BreakingItemParticle.java.patch | 5 +- .../particle/ItemPickupParticle.java.patch | 2 +- .../client/particle/ParticleEngine.java.patch | 23 +- .../particle/ParticleRenderType.java.patch | 8 +- .../player/AbstractClientPlayer.java.patch | 6 +- .../client/player/LocalPlayer.java.patch | 48 +- .../DimensionSpecialEffects.java.patch | 4 +- .../client/renderer/EffectInstance.java.patch | 22 - .../client/renderer/FogRenderer.java.patch | 30 +- .../client/renderer/GameRenderer.java.patch | 52 +- .../renderer/ItemBlockRenderTypes.java.patch | 38 +- .../renderer/ItemInHandRenderer.java.patch | 39 +- .../renderer/LevelEventHandler.java.patch | 13 + .../client/renderer/LevelRenderer.java.patch | 442 ++++++++------- .../client/renderer/LightTexture.java.patch | 13 +- .../client/renderer/MapRenderer.java.patch | 21 + .../renderer/PanoramaRenderer.java.patch | 11 - .../client/renderer/PostChain.java.patch | 20 - .../client/renderer/RenderBuffers.java.patch | 8 +- .../client/renderer/RenderType.java.patch | 8 +- .../renderer/ScreenEffectRenderer.java.patch | 2 +- .../client/renderer/ShaderInstance.java.patch | 57 -- .../client/renderer/ShaderManager.java.patch | 11 + .../client/renderer/Sheets.java.patch | 4 +- .../renderer/WeatherEffectRenderer.java.patch | 20 + .../block/BlockRenderDispatcher.java.patch | 4 +- .../block/LiquidBlockRenderer.java.patch | 14 +- .../block/ModelBlockRenderer.java.patch | 89 ++-- .../block/model/BakedOverrides.java.patch | 38 ++ .../renderer/block/model/BakedQuad.java.patch | 17 +- .../block/model/BlockElement.java.patch | 41 +- .../block/model/BlockModel.java.patch | 84 +-- .../block/model/FaceBakery.java.patch | 6 +- .../block/model/ItemOverrides.java.patch | 50 -- .../block/model/MultiVariant.java.patch | 14 +- .../blockentity/BannerRenderer.java.patch | 2 +- .../blockentity/ChestRenderer.java.patch | 10 +- .../EnchantTableRenderer.java.patch | 2 +- .../blockentity/ShulkerBoxRenderer.java.patch | 10 +- .../blockentity/SignRenderer.java.patch | 6 +- .../blockentity/SpawnerRenderer.java.patch | 2 +- .../chunk/SectionRenderDispatcher.java.patch | 51 +- .../renderer/culling/Frustum.java.patch | 6 +- .../renderer/entity/BoatRenderer.java.patch | 45 -- .../entity/EntityRenderDispatcher.java.patch | 10 +- .../renderer/entity/EntityRenderer.java.patch | 42 +- .../entity/FallingBlockRenderer.java.patch | 50 +- .../entity/FishingHookRenderer.java.patch | 2 +- .../entity/HumanoidMobRenderer.java.patch | 11 + .../entity/ItemEntityRenderer.java.patch | 22 +- .../entity/ItemFrameRenderer.java.patch | 57 +- .../renderer/entity/ItemRenderer.java.patch | 87 ++- .../entity/LivingEntityRenderer.java.patch | 56 +- .../entity/layers/ElytraLayer.java.patch | 55 -- .../layers/EquipmentLayerRenderer.java.patch | 45 ++ .../layers/HumanoidArmorLayer.java.patch | 105 ---- .../entity/player/PlayerRenderer.java.patch | 87 +-- .../entity/state/EntityRenderState.java.patch | 10 + .../entity/state/PlayerRenderState.java.patch | 10 + .../renderer/state/MapRenderState.java.patch | 10 + .../texture/AbstractTexture.java.patch | 28 +- .../texture/MipmapGenerator.java.patch | 4 +- .../renderer/texture/TextureAtlas.java.patch | 2 +- .../texture/TextureAtlasSprite.java.patch | 2 +- .../language/ClientLanguage.java.patch | 15 +- .../resources/model/BakedModel.java.patch | 4 +- .../model/DelegateBakedModel.java.patch | 75 +++ .../resources/model/ItemModel.java.patch | 16 + .../resources/model/ModelBaker.java.patch | 5 +- .../resources/model/ModelBakery.java.patch | 32 +- .../resources/model/ModelDiscovery.java.patch | 26 + .../resources/model/ModelManager.java.patch | 26 +- .../model/ModelResourceLocation.java.patch | 2 +- .../model/MultiPartBakedModel.java.patch | 90 +--- .../model/SimpleBakedModel.java.patch | 72 ++- .../model/WeightedBakedModel.java.patch | 71 +-- .../client/server/IntegratedServer.java.patch | 4 +- .../client/sounds/MusicManager.java.patch | 2 +- .../commands/CommandSourceStack.java.patch | 2 +- .../minecraft/commands/Commands.java.patch | 10 +- .../arguments/ResourceKeyArgument.java.patch | 31 ++ .../ResourceLocationArgument.java.patch | 20 - patches/net/minecraft/core/Holder.java.patch | 4 +- .../minecraft/core/HolderLookup.java.patch | 19 +- .../net/minecraft/core/HolderSet.java.patch | 4 +- .../minecraft/core/MappedRegistry.java.patch | 126 ++--- .../net/minecraft/core/Registry.java.patch | 8 +- .../core/RegistrySetBuilder.java.patch | 12 +- .../component/DataComponentHolder.java.patch | 4 +- .../PatchedDataComponentMap.java.patch | 2 +- .../BoatDispenseItemBehavior.java.patch | 39 +- .../dispenser/DispenseItemBehavior.java.patch | 22 +- .../EquipmentDispenseItemBehavior.java.patch | 11 + .../MinecartDispenseItemBehavior.java.patch | 31 ++ .../ShearsDispenseItemBehavior.java.patch | 15 +- .../particles/ItemParticleOption.java.patch | 2 +- .../registries/BuiltInRegistries.java.patch | 4 +- .../core/registries/Registries.java.patch | 2 +- .../minecraft/data/DataProvider.java.patch | 3 +- patches/net/minecraft/data/Main.java.patch | 6 +- .../data/loot/BlockLootSubProvider.java.patch | 8 +- .../loot/EntityLootSubProvider.java.patch | 17 +- .../data/loot/LootTableProvider.java.patch | 29 +- .../data/recipes/RecipeOutput.java.patch | 8 +- .../data/recipes/RecipeProvider.java.patch | 106 ++-- .../recipes/ShapedRecipeBuilder.java.patch | 27 +- .../recipes/ShapelessRecipeBuilder.java.patch | 46 -- .../SimpleCookingRecipeBuilder.java.patch | 12 +- .../RegistriesDatapackGenerator.java.patch | 4 +- .../RegistryPatchGenerator.java.patch | 2 +- .../registries/VanillaRegistries.java.patch | 6 +- .../framework/GameTestInfo.java.patch | 2 +- .../framework/GameTestServer.java.patch | 4 +- .../gametest/framework/TestCommand.java.patch | 2 +- .../net/minecraft/locale/Language.java.patch | 19 +- .../network/FriendlyByteBuf.java.patch | 2 +- .../network/codec/ByteBufCodecs.java.patch | 36 +- .../ClientCommonPacketListener.java.patch | 8 +- .../ClientboundCustomPayloadPacket.java.patch | 2 +- .../ServerCommonPacketListener.java.patch | 8 +- .../game/ServerGamePacketListener.java.patch | 4 +- .../resources/RegistryDataLoader.java.patch | 20 +- .../net/minecraft/server/Bootstrap.java.patch | 4 +- patches/net/minecraft/server/Main.java.patch | 6 +- .../server/MinecraftServer.java.patch | 97 ++-- .../server/PlayerAdvancements.java.patch | 6 +- .../ReloadableServerRegistries.java.patch | 20 + .../ReloadableServerResources.java.patch | 44 +- .../ServerAdvancementManager.java.patch | 20 - .../minecraft/server/WorldLoader.java.patch | 16 +- .../commands/SpreadPlayersCommand.java.patch | 8 +- .../commands/TeleportCommand.java.patch | 4 +- .../dedicated/DedicatedServer.java.patch | 12 +- .../DedicatedServerProperties.java.patch | 2 +- .../dedicated/ServerWatchdog.java.patch | 50 +- .../server/level/ChunkMap.java.patch | 40 +- .../server/level/DistanceManager.java.patch | 19 +- .../level/GenerationChunkHolder.java.patch | 4 +- .../server/level/ServerChunkCache.java.patch | 30 +- .../server/level/ServerEntity.java.patch | 4 +- .../server/level/ServerLevel.java.patch | 93 ++-- .../server/level/ServerPlayer.java.patch | 75 ++- .../level/ServerPlayerGameMode.java.patch | 34 +- .../ServerCommonPacketListenerImpl.java.patch | 10 +- .../ServerGamePacketListenerImpl.java.patch | 22 +- .../repository/PackRepository.java.patch | 8 +- ...impleJsonResourceReloadListener.java.patch | 37 +- .../SimplePreparableReloadListener.java.patch | 6 +- .../server/players/PlayerList.java.patch | 64 +-- .../stats/RecipeBookSettings.java.patch | 18 +- .../net/minecraft/tags/BlockTags.java.patch | 2 +- .../net/minecraft/tags/ItemTags.java.patch | 2 +- .../net/minecraft/tags/TagEntry.java.patch | 2 +- .../net/minecraft/tags/TagLoader.java.patch | 40 +- .../net/minecraft/util/SpawnUtil.java.patch | 8 +- .../util/context/ContextMap.java.patch | 11 + .../util/datafix/DataFixers.java.patch | 12 +- .../util/thread/BlockableEventLoop.java.patch | 2 +- .../world/effect/MobEffect.java.patch | 14 +- .../world/effect/MobEffectInstance.java.patch | 100 +--- .../world/effect/PoisonMobEffect.java.patch | 10 +- .../minecraft/world/entity/Entity.java.patch | 126 ++--- .../world/entity/EntityType.java.patch | 60 ++- .../world/entity/ExperienceOrb.java.patch | 10 +- .../world/entity/LightningBolt.java.patch | 2 +- .../world/entity/LivingEntity.java.patch | 455 ++++++++-------- .../net/minecraft/world/entity/Mob.java.patch | 76 +-- .../world/entity/Shearable.java.patch | 10 +- .../world/entity/SpawnPlacements.java.patch | 16 +- .../world/entity/TamableAnimal.java.patch | 14 +- .../ai/attributes/Attributes.java.patch | 23 +- .../attributes/DefaultAttributes.java.patch | 2 +- .../ai/behavior/GiveGiftToHero.java.patch | 29 +- .../ai/behavior/StartAttacking.java.patch | 6 +- .../world/entity/ai/behavior/Swim.java.patch | 2 +- .../entity/ai/goal/BreakDoorGoal.java.patch | 4 +- .../entity/ai/goal/EatBlockGoal.java.patch | 8 +- .../entity/ai/goal/RemoveBlockGoal.java.patch | 4 +- .../ai/navigation/PathNavigation.java.patch | 2 +- .../entity/ai/village/VillageSiege.java.patch | 4 +- .../world/entity/animal/Animal.java.patch | 2 +- .../world/entity/animal/Bee.java.patch | 12 +- .../world/entity/animal/Cat.java.patch | 9 +- .../world/entity/animal/Fox.java.patch | 22 +- .../entity/animal/MushroomCow.java.patch | 45 +- .../world/entity/animal/Ocelot.java.patch | 2 +- .../world/entity/animal/Parrot.java.patch | 16 +- .../world/entity/animal/Pig.java.patch | 19 +- .../world/entity/animal/Rabbit.java.patch | 8 +- .../world/entity/animal/Sheep.java.patch | 6 +- .../world/entity/animal/SnowGolem.java.patch | 16 +- .../world/entity/animal/Wolf.java.patch | 38 +- .../entity/animal/allay/Allay.java.patch | 8 +- .../animal/armadillo/Armadillo.java.patch | 4 +- .../entity/animal/camel/Camel.java.patch | 2 +- .../entity/animal/frog/Tadpole.java.patch | 16 +- .../animal/horse/AbstractHorse.java.patch | 8 +- .../animal/horse/SkeletonTrapGoal.java.patch | 2 +- .../entity/animal/sniffer/Sniffer.java.patch | 2 +- .../entity/boss/EnderDragonPart.java.patch | 2 +- .../boss/enderdragon/EnderDragon.java.patch | 41 +- .../entity/boss/wither/WitherBoss.java.patch | 16 +- .../entity/decoration/ArmorStand.java.patch | 11 - .../decoration/HangingEntity.java.patch | 10 +- .../entity/decoration/ItemFrame.java.patch | 4 +- .../entity/item/FallingBlockEntity.java.patch | 6 +- .../world/entity/item/ItemEntity.java.patch | 26 +- .../monster/AbstractSkeleton.java.patch | 4 +- .../world/entity/monster/Bogged.java.patch | 8 +- .../world/entity/monster/EnderMan.java.patch | 35 +- .../world/entity/monster/Evoker.java.patch | 14 +- .../world/entity/monster/Husk.java.patch | 2 +- .../world/entity/monster/Monster.java.patch | 2 +- .../world/entity/monster/Pillager.java.patch | 2 +- .../world/entity/monster/Ravager.java.patch | 19 +- .../world/entity/monster/Shulker.java.patch | 2 +- .../entity/monster/Silverfish.java.patch | 12 +- .../world/entity/monster/Skeleton.java.patch | 13 +- .../world/entity/monster/Slime.java.patch | 28 +- .../world/entity/monster/Zombie.java.patch | 36 +- .../entity/monster/ZombieVillager.java.patch | 15 +- .../monster/creaking/Creaking.java.patch | 12 + .../entity/monster/hoglin/Hoglin.java.patch | 24 +- .../monster/piglin/AbstractPiglin.java.patch | 20 +- .../entity/monster/piglin/Piglin.java.patch | 14 +- .../entity/monster/piglin/PiglinAi.java.patch | 22 +- ...opHoldingItemIfNoLongerAdmiring.java.patch | 8 +- .../entity/npc/AbstractVillager.java.patch | 8 +- .../world/entity/npc/CatSpawner.java.patch | 2 +- .../world/entity/npc/Villager.java.patch | 32 +- .../world/entity/player/Inventory.java.patch | 6 +- .../world/entity/player/Player.java.patch | 161 +++--- .../projectile/AbstractArrow.java.patch | 24 +- .../AbstractHurtingProjectile.java.patch | 18 +- .../FireworkRocketEntity.java.patch | 6 +- .../entity/projectile/FishingHook.java.patch | 10 +- .../projectile/LargeFireball.java.patch | 6 +- .../entity/projectile/Projectile.java.patch | 10 +- .../projectile/ProjectileUtil.java.patch | 2 +- .../projectile/ShulkerBullet.java.patch | 14 +- .../projectile/SmallFireball.java.patch | 6 +- .../projectile/ThrowableProjectile.java.patch | 12 +- .../projectile/ThrownEnderpearl.java.patch | 31 +- .../world/entity/raid/Raid.java.patch | 14 +- .../entity/vehicle/AbstractBoat.java.patch | 65 +++ .../vehicle/AbstractMinecart.java.patch | 377 +++---------- .../AbstractMinecartContainer.java.patch | 2 +- .../world/entity/vehicle/Boat.java.patch | 193 ------- .../world/entity/vehicle/ChestBoat.java.patch | 12 - .../entity/vehicle/ContainerEntity.java.patch | 4 +- .../world/entity/vehicle/Minecart.java.patch | 8 +- .../vehicle/MinecartCommandBlock.java.patch | 2 +- .../entity/vehicle/MinecartFurnace.java.patch | 16 +- .../entity/vehicle/MinecartSpawner.java.patch | 2 +- .../vehicle/NewMinecartBehavior.java.patch | 57 ++ .../vehicle/OldMinecartBehavior.java.patch | 55 ++ .../world/food/FoodProperties.java.patch | 67 --- .../AbstractContainerMenu.java.patch | 2 +- .../inventory/AbstractFurnaceMenu.java.patch | 6 +- .../world/inventory/AnvilMenu.java.patch | 16 +- .../world/inventory/BeaconMenu.java.patch | 2 +- .../inventory/BrewingStandMenu.java.patch | 8 +- .../inventory/EnchantmentMenu.java.patch | 8 +- .../world/inventory/GrindstoneMenu.java.patch | 12 +- .../world/inventory/RecipeBookMenu.java.patch | 13 - .../world/inventory/ResultSlot.java.patch | 6 +- .../minecraft/world/item/ArmorItem.java.patch | 11 - .../minecraft/world/item/AxeItem.java.patch | 8 +- .../minecraft/world/item/BlockItem.java.patch | 25 +- .../minecraft/world/item/BowItem.java.patch | 20 +- .../minecraft/world/item/BrushItem.java.patch | 2 +- .../world/item/BucketItem.java.patch | 2 +- .../world/item/BundleItem.java.patch | 18 +- .../world/item/ChorusFruitItem.java.patch | 13 - .../world/item/CrossbowItem.java.patch | 2 +- .../minecraft/world/item/DyeColor.java.patch | 2 +- .../world/item/ElytraItem.java.patch | 28 - .../world/item/FishingRodItem.java.patch | 10 +- .../world/item/FlintAndSteelItem.java.patch | 2 +- .../world/item/HoneyBottleItem.java.patch | 11 - .../net/minecraft/world/item/Item.java.patch | 150 ++---- .../minecraft/world/item/ItemStack.java.patch | 141 ++--- .../world/item/ItemUseAnimation.java.patch | 24 + .../net/minecraft/world/item/Items.java.patch | 41 +- .../minecraft/world/item/MapItem.java.patch | 2 +- .../world/item/MilkBucketItem.java.patch | 11 - .../world/item/MinecartItem.java.patch | 30 +- .../world/item/PickaxeItem.java.patch | 4 +- .../item/ProjectileWeaponItem.java.patch | 6 +- .../world/item/ShearsItem.java.patch | 8 +- .../world/item/ShieldItem.java.patch | 6 +- .../world/item/SpawnEggItem.java.patch | 8 +- .../item/StandingAndWallBlockItem.java.patch | 14 - .../minecraft/world/item/SwordItem.java.patch | 30 +- .../net/minecraft/world/item/Tiers.java.patch | 9 - .../world/item/TridentItem.java.patch | 2 +- .../minecraft/world/item/UseAnim.java.patch | 14 - .../item/alchemy/PotionContents.java.patch | 2 +- .../TeleportRandomlyConsumeEffect.java.patch | 13 + .../crafting/AbstractCookingRecipe.java.patch | 11 + .../crafting/BannerDuplicateRecipe.java.patch | 12 +- .../crafting/BookCloningRecipe.java.patch | 12 +- .../item/crafting/CraftingRecipe.java.patch | 11 + .../world/item/crafting/Ingredient.java.patch | 249 +++------ .../world/item/crafting/Recipe.java.patch | 22 +- .../item/crafting/RecipeManager.java.patch | 27 - .../item/crafting/RepairItemRecipe.java.patch | 2 +- .../item/crafting/ShapedRecipe.java.patch | 11 - .../crafting/ShapedRecipePattern.java.patch | 5 +- .../item/crafting/ShapelessRecipe.java.patch | 41 +- .../crafting/ShulkerBoxColoring.java.patch | 38 -- .../SimpleCookingSerializer.java.patch | 11 - .../SmithingTransformRecipe.java.patch | 11 - .../crafting/SmithingTrimRecipe.java.patch | 11 - .../item/enchantment/Enchantment.java.patch | 6 +- .../enchantment/EnchantmentHelper.java.patch | 26 +- .../world/level/BaseSpawner.java.patch | 13 +- .../world/level/BlockGetter.java.patch | 10 +- .../world/level/Explosion.java.patch | 18 - .../minecraft/world/level/Level.java.patch | 59 +-- .../world/level/LevelSettings.java.patch | 17 +- .../world/level/NaturalSpawner.java.patch | 24 +- .../world/level/ServerExplosion.java.patch | 21 + .../world/level/biome/Biome.java.patch | 4 +- .../biome/BiomeGenerationSettings.java.patch | 26 - .../level/block/AttachedStemBlock.java.patch | 2 +- .../level/block/BambooSaplingBlock.java.patch | 2 +- .../level/block/BambooStalkBlock.java.patch | 2 +- .../level/block/BaseFireBlock.java.patch | 6 +- .../level/block/BaseRailBlock.java.patch | 36 +- .../world/level/block/BeehiveBlock.java.patch | 2 +- .../level/block/BigDripleafBlock.java.patch | 2 +- .../world/level/block/Block.java.patch | 57 +- .../world/level/block/Blocks.java.patch | 16 +- .../level/block/BubbleColumnBlock.java.patch | 4 +- .../world/level/block/BushBlock.java.patch | 4 +- .../world/level/block/CactusBlock.java.patch | 2 +- .../level/block/CampfireBlock.java.patch | 2 +- .../world/level/block/ChestBlock.java.patch | 2 +- .../level/block/ChorusFlowerBlock.java.patch | 10 +- .../level/block/ChorusPlantBlock.java.patch | 8 +- .../level/block/ComparatorBlock.java.patch | 9 +- .../level/block/ComposterBlock.java.patch | 14 +- .../block/ConcretePowderBlock.java.patch | 18 +- .../world/level/block/CoralBlock.java.patch | 2 +- .../world/level/block/CrafterBlock.java.patch | 2 +- .../world/level/block/CropBlock.java.patch | 6 +- .../level/block/DetectorRailBlock.java.patch | 12 +- .../world/level/block/DiodeBlock.java.patch | 8 +- .../world/level/block/DoorBlock.java.patch | 2 +- .../level/block/DoublePlantBlock.java.patch | 2 +- .../world/level/block/FarmBlock.java.patch | 10 +- .../level/block/FenceGateBlock.java.patch | 22 +- .../world/level/block/FireBlock.java.patch | 18 +- .../level/block/FlowerPotBlock.java.patch | 4 +- .../world/level/block/LeavesBlock.java.patch | 2 +- .../world/level/block/LiquidBlock.java.patch | 6 +- .../level/block/MushroomBlock.java.patch | 4 +- .../world/level/block/NoteBlock.java.patch | 11 +- .../level/block/PitcherCropBlock.java.patch | 4 +- .../block/PointedDripstoneBlock.java.patch | 8 +- .../level/block/PowderSnowBlock.java.patch | 2 +- .../level/block/PoweredRailBlock.java.patch | 6 +- .../world/level/block/PumpkinBlock.java.patch | 4 +- .../level/block/RedStoneWireBlock.java.patch | 4 +- .../level/block/SculkSensorBlock.java.patch | 2 +- .../level/block/SculkShriekerBlock.java.patch | 2 +- .../level/block/SeagrassBlock.java.patch | 2 +- .../world/level/block/SoundType.java.patch | 2 +- .../world/level/block/SpongeBlock.java.patch | 4 +- .../block/SpreadingSnowyDirtBlock.java.patch | 2 +- .../world/level/block/StemBlock.java.patch | 2 +- .../level/block/SugarCaneBlock.java.patch | 2 +- .../block/SweetBerryBushBlock.java.patch | 2 +- .../world/level/block/TntBlock.java.patch | 12 +- .../level/block/TrapDoorBlock.java.patch | 4 +- .../level/block/TripWireBlock.java.patch | 2 +- .../level/block/TripWireHookBlock.java.patch | 12 - .../level/block/TurtleEggBlock.java.patch | 6 +- .../world/level/block/VineBlock.java.patch | 2 +- .../AbstractFurnaceBlockEntity.java.patch | 146 +---- .../level/block/entity/BlockEntity.java.patch | 6 +- .../block/entity/BlockEntityType.java.patch | 21 +- .../entity/BrewingStandBlockEntity.java.patch | 26 +- .../level/block/entity/FuelValues.java.patch | 26 + .../TheEndGatewayBlockEntity.java.patch | 11 + .../trialspawner/TrialSpawner.java.patch | 10 +- .../level/block/grower/TreeGrower.java.patch | 16 +- .../block/piston/PistonBaseBlock.java.patch | 10 +- .../piston/PistonMovingBlockEntity.java.patch | 2 +- .../block/state/BlockBehaviour.java.patch | 111 +--- .../world/level/chunk/ChunkAccess.java.patch | 26 +- .../level/chunk/ImposterProtoChunk.java.patch | 4 +- .../world/level/chunk/LevelChunk.java.patch | 41 +- .../level/chunk/LevelChunkSection.java.patch | 6 +- .../world/level/chunk/ProtoChunk.java.patch | 11 + .../chunk/status/ChunkStatusTasks.java.patch | 43 +- .../chunk/storage/ChunkSerializer.java.patch | 61 --- .../chunk/storage/EntityStorage.java.patch | 2 +- .../chunk/storage/SectionStorage.java.patch | 19 +- .../storage/SerializableChunkData.java.patch | 139 +++++ .../vibrations/VibrationSystem.java.patch | 2 +- .../level/levelgen/PhantomSpawner.java.patch | 2 +- .../level/levelgen/WorldDimensions.java.patch | 2 +- .../structure/StructurePiece.java.patch | 2 +- .../structure/StructureStart.java.patch | 4 +- .../StructureTemplate.java.patch | 46 +- .../lighting/BlockLightEngine.java.patch | 8 +- .../level/lighting/LightEngine.java.patch | 18 +- .../level/material/FlowingFluid.java.patch | 22 +- .../world/level/material/Fluid.java.patch | 4 +- .../level/material/FluidState.java.patch | 4 +- .../world/level/material/LavaFluid.java.patch | 32 +- .../world/level/portal/PortalShape.java.patch | 4 +- .../level/saveddata/SavedData.java.patch | 11 +- .../storage/DimensionDataStorage.java.patch | 31 +- .../level/storage/ServerLevelData.java.patch | 6 +- .../level/storage/loot/LootContext.java.patch | 2 +- .../storage/loot/LootDataType.java.patch | 37 +- .../level/storage/loot/LootParams.java.patch | 11 - .../level/storage/loot/LootTable.java.patch | 10 +- .../EnchantRandomlyFunction.java.patch | 2 +- .../functions/SmeltItemFunction.java.patch | 4 +- .../LootContextParamSets.java.patch | 22 +- .../nbt/ContextNbtProvider.java.patch | 2 +- .../net/minecraft/world/phys/AABB.java.patch | 4 +- .../MinecartCollisionContext.java.patch | 11 + projects/neoforge/build.gradle | 18 +- .../data/c/tags/entity_type/boats.json | 12 +- .../minecraft/recipe/acacia_chest_boat.json | 14 +- .../data/minecraft/recipe/acacia_fence.json | 8 +- .../minecraft/recipe/acacia_fence_gate.json | 8 +- .../data/minecraft/recipe/acacia_sign.json | 8 +- .../data/minecraft/recipe/activator_rail.json | 12 +- .../data/minecraft/recipe/andesite.json | 8 +- .../data/minecraft/recipe/anvil.json | 8 +- .../data/minecraft/recipe/armor_stand.json | 8 +- .../data/minecraft/recipe/arrow.json | 12 +- .../minecraft/recipe/bamboo_chest_raft.json | 14 +- .../data/minecraft/recipe/bamboo_fence.json | 8 +- .../minecraft/recipe/bamboo_fence_gate.json | 8 +- .../data/minecraft/recipe/bamboo_sign.json | 8 +- .../minecraft/recipe/birch_chest_boat.json | 14 +- .../data/minecraft/recipe/birch_fence.json | 8 +- .../minecraft/recipe/birch_fence_gate.json | 8 +- .../data/minecraft/recipe/birch_sign.json | 8 +- .../data/minecraft/recipe/black_banner.json | 8 +- .../data/minecraft/recipe/black_candle.json | 13 + .../recipe/black_concrete_powder.json | 20 + .../minecraft/recipe/black_stained_glass.json | 18 + ...ck_stained_glass_pane_from_glass_pane.json | 18 + .../minecraft/recipe/black_terracotta.json | 18 + .../data/minecraft/recipe/blast_furnace.json | 12 +- .../data/minecraft/recipe/blue_banner.json | 8 +- .../data/minecraft/recipe/blue_candle.json | 13 + .../recipe/blue_concrete_powder.json | 20 + .../minecraft/recipe/blue_stained_glass.json | 18 + ...ue_stained_glass_pane_from_glass_pane.json | 18 + .../minecraft/recipe/blue_terracotta.json | 18 + .../bolt_armor_trim_smithing_template.json | 16 +- .../resources/data/minecraft/recipe/bow.json | 8 +- .../data/minecraft/recipe/brown_banner.json | 8 +- .../data/minecraft/recipe/brown_candle.json | 13 + .../recipe/brown_concrete_powder.json | 20 + .../minecraft/recipe/brown_stained_glass.json | 18 + ...wn_stained_glass_pane_from_glass_pane.json | 18 + .../minecraft/recipe/brown_terracotta.json | 18 + .../data/minecraft/recipe/brush.json | 12 +- .../data/minecraft/recipe/bucket.json | 4 +- .../data/minecraft/recipe/bundle.json | 16 + .../recipe/calibrated_sculk_sensor.json | 8 +- .../data/minecraft/recipe/campfire.json | 12 +- .../data/minecraft/recipe/candle.json | 8 +- .../data/minecraft/recipe/cauldron.json | 4 +- .../data/minecraft/recipe/chain.json | 8 +- .../minecraft/recipe/cherry_chest_boat.json | 14 +- .../data/minecraft/recipe/cherry_fence.json | 8 +- .../minecraft/recipe/cherry_fence_gate.json | 8 +- .../data/minecraft/recipe/cherry_sign.json | 8 +- .../data/minecraft/recipe/chest_minecart.json | 14 +- .../data/minecraft/recipe/clock.json | 8 +- .../coast_armor_trim_smithing_template.json | 12 +- .../data/minecraft/recipe/compass.json | 8 +- .../data/minecraft/recipe/copper_door.json | 4 +- .../minecraft/recipe/copper_trapdoor.json | 4 +- .../data/minecraft/recipe/crafter.json | 16 +- .../data/minecraft/recipe/crimson_fence.json | 8 +- .../minecraft/recipe/crimson_fence_gate.json | 8 +- .../data/minecraft/recipe/crimson_sign.json | 8 +- .../data/minecraft/recipe/crossbow.json | 16 +- .../data/minecraft/recipe/cyan_banner.json | 8 +- .../data/minecraft/recipe/cyan_candle.json | 13 + .../recipe/cyan_concrete_powder.json | 20 + .../data/minecraft/recipe/cyan_dye.json | 13 + .../minecraft/recipe/cyan_stained_glass.json | 18 + ...an_stained_glass_pane_from_glass_pane.json | 18 + .../minecraft/recipe/cyan_terracotta.json | 18 + .../minecraft/recipe/dark_oak_chest_boat.json | 14 +- .../data/minecraft/recipe/dark_oak_fence.json | 8 +- .../minecraft/recipe/dark_oak_fence_gate.json | 8 +- .../data/minecraft/recipe/dark_oak_sign.json | 8 +- .../minecraft/recipe/dark_prismarine.json | 17 + .../data/minecraft/recipe/detector_rail.json | 12 +- .../data/minecraft/recipe/diamond_axe.json | 8 +- .../data/minecraft/recipe/diamond_boots.json | 4 +- .../minecraft/recipe/diamond_chestplate.json | 4 +- .../data/minecraft/recipe/diamond_helmet.json | 4 +- .../data/minecraft/recipe/diamond_hoe.json | 8 +- .../minecraft/recipe/diamond_leggings.json | 4 +- .../minecraft/recipe/diamond_pickaxe.json | 8 +- .../data/minecraft/recipe/diamond_shovel.json | 8 +- .../data/minecraft/recipe/diamond_sword.json | 8 +- .../data/minecraft/recipe/diorite.json | 8 +- .../data/minecraft/recipe/dispenser.json | 12 +- .../data/minecraft/recipe/dropper.json | 8 +- .../dune_armor_trim_smithing_template.json | 12 +- .../data/minecraft/recipe/dye_black_bed.json | 29 + .../minecraft/recipe/dye_black_carpet.json | 29 + .../data/minecraft/recipe/dye_black_wool.json | 29 + .../data/minecraft/recipe/dye_blue_bed.json | 29 + .../minecraft/recipe/dye_blue_carpet.json | 29 + .../data/minecraft/recipe/dye_blue_wool.json | 29 + .../data/minecraft/recipe/dye_brown_bed.json | 29 + .../minecraft/recipe/dye_brown_carpet.json | 29 + .../data/minecraft/recipe/dye_brown_wool.json | 29 + .../data/minecraft/recipe/dye_cyan_bed.json | 29 + .../minecraft/recipe/dye_cyan_carpet.json | 29 + .../data/minecraft/recipe/dye_cyan_wool.json | 29 + .../data/minecraft/recipe/dye_gray_bed.json | 29 + .../minecraft/recipe/dye_gray_carpet.json | 29 + .../data/minecraft/recipe/dye_gray_wool.json | 29 + .../data/minecraft/recipe/dye_green_bed.json | 29 + .../minecraft/recipe/dye_green_carpet.json | 29 + .../data/minecraft/recipe/dye_green_wool.json | 29 + .../minecraft/recipe/dye_light_blue_bed.json | 29 + .../recipe/dye_light_blue_carpet.json | 29 + .../minecraft/recipe/dye_light_blue_wool.json | 29 + .../minecraft/recipe/dye_light_gray_bed.json | 29 + .../recipe/dye_light_gray_carpet.json | 29 + .../minecraft/recipe/dye_light_gray_wool.json | 29 + .../data/minecraft/recipe/dye_lime_bed.json | 29 + .../minecraft/recipe/dye_lime_carpet.json | 29 + .../data/minecraft/recipe/dye_lime_wool.json | 29 + .../minecraft/recipe/dye_magenta_bed.json | 29 + .../minecraft/recipe/dye_magenta_carpet.json | 29 + .../minecraft/recipe/dye_magenta_wool.json | 29 + .../data/minecraft/recipe/dye_orange_bed.json | 29 + .../minecraft/recipe/dye_orange_carpet.json | 29 + .../minecraft/recipe/dye_orange_wool.json | 29 + .../data/minecraft/recipe/dye_pink_bed.json | 29 + .../minecraft/recipe/dye_pink_carpet.json | 29 + .../data/minecraft/recipe/dye_pink_wool.json | 29 + .../data/minecraft/recipe/dye_purple_bed.json | 29 + .../minecraft/recipe/dye_purple_carpet.json | 29 + .../minecraft/recipe/dye_purple_wool.json | 29 + .../data/minecraft/recipe/dye_red_bed.json | 29 + .../data/minecraft/recipe/dye_red_carpet.json | 29 + .../data/minecraft/recipe/dye_red_wool.json | 29 + .../data/minecraft/recipe/dye_white_bed.json | 29 + .../minecraft/recipe/dye_white_carpet.json | 29 + .../data/minecraft/recipe/dye_white_wool.json | 29 + .../data/minecraft/recipe/dye_yellow_bed.json | 29 + .../minecraft/recipe/dye_yellow_carpet.json | 29 + .../minecraft/recipe/dye_yellow_wool.json | 29 + .../minecraft/recipe/enchanting_table.json | 12 +- .../eye_armor_trim_smithing_template.json | 12 +- .../data/minecraft/recipe/fishing_rod.json | 8 +- .../minecraft/recipe/flint_and_steel.json | 8 +- .../flow_armor_trim_smithing_template.json | 12 +- .../recipe/glistering_melon_slice.json | 8 +- .../recipe/gold_ingot_from_nuggets.json | 4 +- .../data/minecraft/recipe/golden_apple.json | 8 +- .../data/minecraft/recipe/golden_axe.json | 8 +- .../data/minecraft/recipe/golden_boots.json | 4 +- .../data/minecraft/recipe/golden_carrot.json | 8 +- .../minecraft/recipe/golden_chestplate.json | 4 +- .../data/minecraft/recipe/golden_helmet.json | 4 +- .../data/minecraft/recipe/golden_hoe.json | 8 +- .../minecraft/recipe/golden_leggings.json | 4 +- .../data/minecraft/recipe/golden_pickaxe.json | 8 +- .../data/minecraft/recipe/golden_shovel.json | 8 +- .../data/minecraft/recipe/golden_sword.json | 8 +- .../data/minecraft/recipe/gray_banner.json | 8 +- .../data/minecraft/recipe/gray_candle.json | 13 + .../recipe/gray_concrete_powder.json | 20 + .../data/minecraft/recipe/gray_dye.json | 12 + .../minecraft/recipe/gray_stained_glass.json | 18 + ...ay_stained_glass_pane_from_glass_pane.json | 18 + .../minecraft/recipe/gray_terracotta.json | 18 + .../data/minecraft/recipe/green_banner.json | 8 +- .../data/minecraft/recipe/green_candle.json | 13 + .../recipe/green_concrete_powder.json | 20 + .../minecraft/recipe/green_stained_glass.json | 18 + ...en_stained_glass_pane_from_glass_pane.json | 18 + .../minecraft/recipe/green_terracotta.json | 18 + .../data/minecraft/recipe/grindstone.json | 12 +- .../recipe/heavy_weighted_pressure_plate.json | 4 +- .../data/minecraft/recipe/hopper.json | 14 +- .../host_armor_trim_smithing_template.json | 12 +- .../data/minecraft/recipe/iron_axe.json | 8 +- .../data/minecraft/recipe/iron_bars.json | 4 +- .../data/minecraft/recipe/iron_boots.json | 4 +- .../minecraft/recipe/iron_chestplate.json | 4 +- .../data/minecraft/recipe/iron_door.json | 4 +- .../data/minecraft/recipe/iron_helmet.json | 4 +- .../data/minecraft/recipe/iron_hoe.json | 8 +- .../recipe/iron_ingot_from_nuggets.json | 4 +- .../data/minecraft/recipe/iron_leggings.json | 4 +- .../data/minecraft/recipe/iron_pickaxe.json | 8 +- .../data/minecraft/recipe/iron_shovel.json | 8 +- .../data/minecraft/recipe/iron_sword.json | 8 +- .../data/minecraft/recipe/iron_trapdoor.json | 4 +- .../data/minecraft/recipe/item_frame.json | 8 +- .../data/minecraft/recipe/jukebox.json | 8 +- .../minecraft/recipe/jungle_chest_boat.json | 14 +- .../data/minecraft/recipe/jungle_fence.json | 8 +- .../minecraft/recipe/jungle_fence_gate.json | 8 +- .../data/minecraft/recipe/jungle_sign.json | 8 +- .../data/minecraft/recipe/ladder.json | 4 +- .../data/minecraft/recipe/lantern.json | 8 +- .../resources/data/minecraft/recipe/lead.json | 8 +- .../data/minecraft/recipe/lever.json | 8 +- .../minecraft/recipe/light_blue_banner.json | 8 +- .../minecraft/recipe/light_blue_candle.json | 13 + .../recipe/light_blue_concrete_powder.json | 20 + .../light_blue_dye_from_blue_white_dye.json | 13 + .../recipe/light_blue_stained_glass.json | 18 + ...ue_stained_glass_pane_from_glass_pane.json | 18 + .../recipe/light_blue_terracotta.json | 18 + .../minecraft/recipe/light_gray_banner.json | 8 +- .../minecraft/recipe/light_gray_candle.json | 13 + .../recipe/light_gray_concrete_powder.json | 20 + .../light_gray_dye_from_black_white_dye.json | 14 + .../light_gray_dye_from_gray_white_dye.json | 13 + .../recipe/light_gray_stained_glass.json | 18 + ...ay_stained_glass_pane_from_glass_pane.json | 18 + .../recipe/light_gray_terracotta.json | 18 + .../recipe/light_weighted_pressure_plate.json | 4 +- .../data/minecraft/recipe/lightning_rod.json | 4 +- .../data/minecraft/recipe/lime_banner.json | 8 +- .../data/minecraft/recipe/lime_candle.json | 13 + .../recipe/lime_concrete_powder.json | 20 + .../data/minecraft/recipe/lime_dye.json | 12 + .../minecraft/recipe/lime_stained_glass.json | 18 + ...me_stained_glass_pane_from_glass_pane.json | 18 + .../minecraft/recipe/lime_terracotta.json | 18 + .../data/minecraft/recipe/lodestone.json | 8 +- .../resources/data/minecraft/recipe/loom.json | 8 +- .../data/minecraft/recipe/magenta_banner.json | 8 +- .../data/minecraft/recipe/magenta_candle.json | 13 + .../recipe/magenta_concrete_powder.json | 20 + .../magenta_dye_from_blue_red_pink.json | 14 + .../magenta_dye_from_blue_red_white_dye.json | 15 + .../magenta_dye_from_purple_and_pink.json | 13 + .../recipe/magenta_stained_glass.json | 18 + ...ta_stained_glass_pane_from_glass_pane.json | 18 + .../minecraft/recipe/magenta_terracotta.json | 18 + .../minecraft/recipe/mangrove_chest_boat.json | 14 +- .../data/minecraft/recipe/mangrove_fence.json | 8 +- .../minecraft/recipe/mangrove_fence_gate.json | 8 +- .../data/minecraft/recipe/mangrove_sign.json | 8 +- .../data/minecraft/recipe/minecart.json | 4 +- .../mossy_cobblestone_from_moss_block.json | 8 +- .../recipe/mossy_cobblestone_from_vine.json | 8 +- .../minecraft/recipe/netherite_ingot.json | 32 +- .../netherite_upgrade_smithing_template.json | 12 +- .../data/minecraft/recipe/oak_chest_boat.json | 14 +- .../data/minecraft/recipe/oak_fence.json | 8 +- .../data/minecraft/recipe/oak_fence_gate.json | 8 +- .../data/minecraft/recipe/oak_sign.json | 8 +- .../data/minecraft/recipe/observer.json | 12 +- .../data/minecraft/recipe/orange_banner.json | 8 +- .../data/minecraft/recipe/orange_candle.json | 13 + .../recipe/orange_concrete_powder.json | 20 + .../recipe/orange_dye_from_red_yellow.json | 13 + .../recipe/orange_stained_glass.json | 18 + ...ge_stained_glass_pane_from_glass_pane.json | 18 + .../minecraft/recipe/orange_terracotta.json | 18 + .../data/minecraft/recipe/painting.json | 8 +- .../data/minecraft/recipe/pink_banner.json | 8 +- .../data/minecraft/recipe/pink_candle.json | 13 + .../recipe/pink_concrete_powder.json | 20 + .../recipe/pink_dye_from_red_white_dye.json | 13 + .../minecraft/recipe/pink_stained_glass.json | 18 + ...nk_stained_glass_pane_from_glass_pane.json | 18 + .../minecraft/recipe/pink_terracotta.json | 18 + .../data/minecraft/recipe/piston.json | 16 +- .../minecraft/recipe/polished_deepslate.json | 4 +- .../data/minecraft/recipe/powered_rail.json | 12 +- .../data/minecraft/recipe/purple_banner.json | 8 +- .../data/minecraft/recipe/purple_candle.json | 13 + .../recipe/purple_concrete_powder.json | 20 + .../data/minecraft/recipe/purple_dye.json | 12 + .../recipe/purple_stained_glass.json | 18 + ...le_stained_glass_pane_from_glass_pane.json | 18 + .../minecraft/recipe/purple_terracotta.json | 18 + .../resources/data/minecraft/recipe/rail.json | 8 +- .../raiser_armor_trim_smithing_template.json | 12 +- .../data/minecraft/recipe/red_banner.json | 8 +- .../data/minecraft/recipe/red_candle.json | 13 + .../minecraft/recipe/red_concrete_powder.json | 20 + .../minecraft/recipe/red_stained_glass.json | 18 + ...ed_stained_glass_pane_from_glass_pane.json | 18 + .../data/minecraft/recipe/red_terracotta.json | 18 + .../data/minecraft/recipe/redstone_torch.json | 8 +- .../rib_armor_trim_smithing_template.json | 12 +- .../data/minecraft/recipe/scaffolding.json | 8 +- .../sentry_armor_trim_smithing_template.json | 12 +- .../shaper_armor_trim_smithing_template.json | 12 +- .../data/minecraft/recipe/shears.json | 4 +- .../data/minecraft/recipe/shield.json | 8 +- .../data/minecraft/recipe/shulker_box.json | 14 +- .../silence_armor_trim_smithing_template.json | 12 +- .../data/minecraft/recipe/smithing_table.json | 8 +- .../snout_armor_trim_smithing_template.json | 12 +- .../data/minecraft/recipe/soul_campfire.json | 12 +- .../data/minecraft/recipe/soul_lantern.json | 8 +- .../data/minecraft/recipe/soul_torch.json | 16 +- .../spire_armor_trim_smithing_template.json | 12 +- .../minecraft/recipe/spruce_chest_boat.json | 14 +- .../data/minecraft/recipe/spruce_fence.json | 8 +- .../minecraft/recipe/spruce_fence_gate.json | 8 +- .../data/minecraft/recipe/spruce_sign.json | 8 +- .../data/minecraft/recipe/spyglass.json | 8 +- .../data/minecraft/recipe/stone_axe.json | 8 +- .../data/minecraft/recipe/stone_hoe.json | 8 +- .../data/minecraft/recipe/stone_pickaxe.json | 8 +- .../data/minecraft/recipe/stone_shovel.json | 8 +- .../data/minecraft/recipe/stone_sword.json | 8 +- .../data/minecraft/recipe/stonecutter.json | 8 +- .../tide_armor_trim_smithing_template.json | 12 +- .../data/minecraft/recipe/tinted_glass.json | 8 +- .../data/minecraft/recipe/torch.json | 12 +- .../data/minecraft/recipe/trapped_chest.json | 14 +- .../data/minecraft/recipe/tripwire_hook.json | 12 +- .../vex_armor_trim_smithing_template.json | 12 +- .../ward_armor_trim_smithing_template.json | 12 +- .../data/minecraft/recipe/warped_fence.json | 8 +- .../minecraft/recipe/warped_fence_gate.json | 8 +- .../data/minecraft/recipe/warped_sign.json | 8 +- ...ayfinder_armor_trim_smithing_template.json | 12 +- .../data/minecraft/recipe/white_banner.json | 8 +- .../data/minecraft/recipe/white_candle.json | 13 + .../recipe/white_concrete_powder.json | 20 + .../minecraft/recipe/white_stained_glass.json | 18 + ...te_stained_glass_pane_from_glass_pane.json | 18 + .../minecraft/recipe/white_terracotta.json | 18 + .../wild_armor_trim_smithing_template.json | 12 +- .../data/minecraft/recipe/wooden_axe.json | 8 +- .../data/minecraft/recipe/wooden_hoe.json | 8 +- .../data/minecraft/recipe/wooden_pickaxe.json | 8 +- .../data/minecraft/recipe/wooden_shovel.json | 8 +- .../data/minecraft/recipe/wooden_sword.json | 8 +- .../data/minecraft/recipe/yellow_banner.json | 8 +- .../data/minecraft/recipe/yellow_candle.json | 13 + .../recipe/yellow_concrete_powder.json | 20 + .../recipe/yellow_stained_glass.json | 18 + ...ow_stained_glass_pane_from_glass_pane.json | 18 + .../minecraft/recipe/yellow_terracotta.json | 18 + .../entity_type/parrot_imitations.json | 6 + .../neoforge/data_maps/item/compostables.json | 15 + src/generated/resources/pack.mcmeta | 2 +- .../resources/reports/registry_order.json | 6 +- .../neoforge/attachment/AttachmentHolder.java | 2 +- .../capabilities/CapabilityHooks.java | 10 +- .../BlockEntityRenderBoundsDebugRenderer.java | 3 +- .../neoforge/client/ClientCommandHandler.java | 30 +- .../client/ClientCommandSourceStack.java | 36 +- .../neoforge/client/ClientHooks.java | 148 ++---- .../neoforge/client/ClientNeoForgeMod.java | 2 - .../neoforge/client/CoreShaderManager.java | 32 ++ .../neoforge/client/IArmPoseTransformer.java | 3 +- .../neoforge/client/NeoForgeRenderTypes.java | 21 +- .../client/ParticleBoundsDebugRenderer.java | 4 +- .../neoforge/client/RecipeBookManager.java | 62 +-- .../neoforge/client/RenderTypeGroup.java | 14 +- .../neoforge/client/RenderTypeHelper.java | 15 +- .../client/TagConventionLogWarningClient.java | 5 +- .../animation/json/AnimationLoader.java | 24 +- .../client/event/ComputeFovModifierEvent.java | 14 +- .../client/event/EntityRenderersEvent.java | 10 +- .../GatherEffectScreenTooltipsEvent.java | 11 +- .../event/MovementInputUpdateEvent.java | 8 +- .../client/event/RecipesUpdatedEvent.java | 36 -- .../event/RegisterNamedRenderTypesEvent.java | 16 +- .../RegisterRecipeBookCategoriesEvent.java | 64 --- ...gisterRecipeBookSearchCategoriesEvent.java | 41 ++ .../client/event/RegisterShadersEvent.java | 37 +- .../client/event/RenderHighlightEvent.java | 13 +- .../client/event/RenderItemInFrameEvent.java | 16 +- .../client/event/RenderLivingEvent.java | 31 +- .../client/event/RenderNameTagEvent.java | 193 ++++--- .../client/event/RenderPlayerEvent.java | 68 +-- .../neoforge/client/event/ScreenEvent.java | 5 +- .../neoforge/client/event/ViewportEvent.java | 17 +- .../extensions/IBakedModelExtension.java | 14 +- .../IDimensionSpecialEffectsExtension.java | 22 +- .../extensions/IGuiGraphicsExtension.java | 20 +- .../extensions/IModelBakerExtension.java | 2 - .../common/ClientExtensionsManager.java | 19 - .../common/IClientFluidTypeExtensions.java | 17 +- .../common/IClientItemExtensions.java | 50 +- .../common/IClientMobEffectExtensions.java | 9 +- .../neoforge/client/gui/ScreenUtils.java | 24 +- .../gui/map/IMapDecorationRenderer.java | 22 +- .../gui/map/MapDecorationRendererManager.java | 11 +- .../client/gui/widget/ExtendedButton.java | 3 +- .../client/gui/widget/ExtendedSlider.java | 12 +- .../client/gui/widget/ModListWidget.java | 3 +- .../client/gui/widget/ModsButton.java | 2 + .../client/gui/widget/ScrollPanel.java | 4 +- .../client/gui/widget/UnicodeGlyphButton.java | 3 +- .../client/loading/ClientModLoader.java | 3 +- .../loading/NeoForgeLoadingOverlay.java | 14 +- .../client/model/BakedModelWrapper.java | 14 +- .../neoforge/client/model/CompositeModel.java | 52 +- .../model/DynamicFluidContainerModel.java | 35 +- .../neoforge/client/model/ElementsModel.java | 81 --- .../neoforge/client/model/EmptyModel.java | 6 +- .../neoforge/client/model/IModelBuilder.java | 11 +- .../client/model/IQuadTransformer.java | 2 +- .../neoforge/client/model/ItemLayerModel.java | 16 +- .../model/RegistryAwareItemModelShaper.java | 56 -- .../client/model/SeparateTransformsModel.java | 36 +- .../client/model/data/ModelDataManager.java | 4 +- .../client/model/data/MultipartModelData.java | 7 +- .../model/generators/ItemModelBuilder.java | 4 +- .../client/model/generators/ModelBuilder.java | 16 +- .../geometry/BlockGeometryBakingContext.java | 5 +- .../model/geometry/IUnbakedGeometry.java | 12 +- .../model/geometry/SimpleUnbakedGeometry.java | 7 +- .../model/geometry/UnbakedGeometryHelper.java | 58 +- .../LightPipelineAwareModelBlockRenderer.java | 2 +- .../model/lighting/SmoothQuadLighter.java | 4 +- .../neoforge/client/model/obj/ObjModel.java | 2 +- .../pipeline/QuadBakingVertexConsumer.java | 7 +- .../neoforge/common/CommonHooks.java | 51 +- .../common/CreativeModeTabRegistry.java | 12 +- .../neoforge/common/DataMapHooks.java | 17 +- .../neoforge/common/DeferredSpawnEggItem.java | 8 +- .../neoforged/neoforge/common/EffectCure.java | 69 --- .../neoforge/common/EffectCures.java | 25 - .../neoforged/neoforge/common/IShearable.java | 15 +- .../neoforge/common/MonsterRoomHooks.java | 2 +- .../neoforge/common/NeoForgeConfig.java | 7 - .../neoforge/common/NeoForgeEventHandler.java | 4 +- .../neoforge/common/NeoForgeMod.java | 21 +- .../neoforged/neoforge/common/SimpleTier.java | 18 +- .../common/TagConventionLogWarning.java | 3 +- .../common/VillagerTradingManager.java | 14 +- .../common/conditions/ConditionContext.java | 42 +- .../common/conditions/ICondition.java | 28 +- .../common/conditions/TagEmptyCondition.java | 2 +- .../common/crafting/BlockTagIngredient.java | 53 +- .../common/crafting/CompoundIngredient.java | 19 +- .../crafting/ConditionalRecipeOutput.java | 9 +- .../common/crafting/CraftingHelper.java | 66 --- .../crafting/CustomDisplayIngredient.java | 52 ++ .../crafting/DataComponentIngredient.java | 25 +- .../common/crafting/DifferenceIngredient.java | 6 +- .../common/crafting/ICustomIngredient.java | 32 +- .../common/crafting/IngredientCodecs.java | 90 ++++ .../crafting/IntersectionIngredient.java | 14 +- .../common/crafting/SizedIngredient.java | 65 +-- .../neoforge/common/data/DataMapProvider.java | 6 +- .../common/data/LanguageProvider.java | 2 +- .../common/data/SoundDefinitionsProvider.java | 2 +- .../internal/NeoForgeAdvancementProvider.java | 72 ++- .../internal/NeoForgeBlockTagsProvider.java | 2 +- .../internal/NeoForgeDataMapsProvider.java | 39 +- .../NeoForgeEntityTypeTagsProvider.java | 13 +- .../internal/NeoForgeItemTagsProvider.java | 2 +- .../data/internal/NeoForgeRecipeProvider.java | 222 ++++---- ...nsion.java => IAbstractBoatExtension.java} | 8 +- .../IAbstractMinecartExtension.java | 130 ----- .../IBlockAndTintGetterExtension.java | 2 +- .../extensions/IBlockEntityExtension.java | 11 - .../common/extensions/IBlockExtension.java | 2 +- .../extensions/IBlockStateExtension.java | 2 +- .../ICommandSourceStackExtension.java | 10 +- .../common/extensions/IEntityExtension.java | 3 +- .../common/extensions/IFluidExtension.java | 8 +- .../extensions/IFluidStateExtension.java | 8 +- .../IHolderLookupProviderExtension.java | 2 +- .../common/extensions/IItemExtension.java | 131 +---- .../extensions/IItemStackExtension.java | 86 +-- .../extensions/IMobEffectExtension.java | 14 - .../extensions/IRecipeOutputExtension.java | 4 +- .../common/loot/AddTableLootModifier.java | 2 +- .../common/loot/CanItemPerformAbility.java | 6 +- .../common/loot/LootModifierManager.java | 5 +- .../neoforge/common/util/DummySavedData.java | 37 -- .../neoforge/common/util/FakePlayer.java | 11 +- .../common/util/NeoForgeExtraCodecs.java | 1 + .../world/BiomeGenerationSettingsBuilder.java | 9 +- .../neoforge/common/world/BiomeModifiers.java | 25 +- .../LevelChunkAuxiliaryLightManager.java | 2 +- .../common/world/StructureModifiers.java | 2 +- .../event/AddReloadListenerEvent.java | 5 +- .../neoforged/neoforge/event/EventHooks.java | 59 +-- .../neoforge/event/TagsUpdatedEvent.java | 12 +- .../event/entity/EntityMobGriefingEvent.java | 4 +- .../event/entity/EntityTeleportEvent.java | 11 +- .../entity/EntityTravelToDimensionEvent.java | 2 +- .../entity/living/EnderManAngerEvent.java | 4 +- .../entity/living/FinalizeSpawnEvent.java | 10 +- .../event/entity/living/MobEffectEvent.java | 17 +- .../event/entity/living/MobSpawnEvent.java | 26 +- .../event/entity/player/ArrowNockEvent.java | 8 +- .../entity/player/PlayerDestroyItemEvent.java | 2 +- .../player/PlayerRespawnPositionEvent.java | 42 +- .../entity/player/UseItemOnBlockEvent.java | 25 +- .../furnace/FurnaceFuelBurnTimeEvent.java | 22 +- .../event/level/BlockGrowFeatureEvent.java | 2 +- .../neoforge/event/level/ChunkDataEvent.java | 78 +-- .../neoforge/event/level/ExplosionEvent.java | 18 +- .../event/level/ExplosionKnockbackEvent.java | 11 +- .../level/block/CreateFluidSourceEvent.java | 10 +- .../event/village/VillagerTradesEvent.java | 20 +- .../event/village/WandererTradesEvent.java | 20 +- .../neoforge/fluids/BaseFlowingFluid.java | 6 +- .../neoforged/neoforge/fluids/FluidType.java | 14 +- .../wrappers/FluidBucketWrapper.java | 5 +- .../fluids/crafting/FluidIngredient.java | 2 +- .../fluids/crafting/TagFluidIngredient.java | 2 +- .../network/codec/NeoForgeStreamCodecs.java | 44 -- .../handlers/ClientPayloadHandler.java | 8 +- .../registries/BaseMappedRegistry.java | 6 +- .../registries/ClientRegistryManager.java | 2 +- .../neoforge/registries/DataMapLoader.java | 9 +- .../neoforge/registries/DeferredHolder.java | 4 +- .../neoforge/registries/DeferredRegister.java | 11 +- .../neoforge/registries/GameData.java | 10 +- .../registries/IRegistryExtension.java | 11 - .../registries/ModifyRegistriesEvent.java | 2 +- .../registries/NeoForgeRegistriesSetup.java | 7 +- .../registries/NeoForgeRegistryCallbacks.java | 2 +- .../neoforge/registries/NewRegistryEvent.java | 2 +- .../neoforge/registries/RegistryManager.java | 4 +- .../registries/holdersets/AnyHolderSet.java | 5 + .../holdersets/CompositeHolderSet.java | 5 + .../registries/holdersets/NotHolderSet.java | 5 + .../neoforge/server/ServerLifecycleHooks.java | 16 +- .../neoforge/server/command/CommandUtils.java | 4 +- .../server/command/DimensionsCommand.java | 2 +- .../neoforge/server/command/DumpCommand.java | 2 +- .../neoforge/server/command/TagsCommand.java | 17 +- .../command/generation/GenerationTask.java | 3 +- .../resources/META-INF/accesstransformer.cfg | 44 +- .../resources/assets/neoforge/lang/en_us.json | 2 + .../rendertype_entity_unlit_translucent.json | 17 +- .../testframework/client/ClientUtils.java | 5 +- .../testframework/client/TestsOverlay.java | 6 +- .../condition/TestEnabledIngredient.java | 14 +- .../gametest/ExtendedGameTestHelper.java | 15 +- .../testframework/impl/PlayerTestStore.java | 9 - .../testframework/impl/TestFrameworkImpl.java | 3 +- .../testframework/impl/test/AbstractTest.java | 5 +- .../junit/EphemeralTestServerProvider.java | 6 +- .../registration/DeferredBlocks.java | 6 +- .../DeferredEntityTypeBuilder.java | 2 +- .../registration/DeferredEntityTypes.java | 2 +- .../neotests_custom_boat_type/lang/en_us.json | 4 +- .../compound_ingredient_custom_types.json | 115 ++-- .../compound_ingredient_only_vanilla.json | 19 +- .../data_gen_test/recipe/conditional.json | 4 +- .../data_gen_test/recipe/conditional2.json | 4 +- .../data_gen_test/recipe/conditional3.json | 4 +- .../data_gen_test/recipe/conditional4.json | 4 +- .../recipe/difference_ingredient.json | 10 +- .../recipe/intersection_ingredient.json | 10 +- .../minecraft/advancement/good_parent.json | 34 ++ .../loot_modifiers/global_loot_modifiers.json | 3 +- .../recipe/block_tag.json | 8 +- .../recipe/partial_nbt.json | 12 +- .../recipe/strict_nbt.json | 8 +- .../recipe/sized_ingredient_1.json | 27 +- .../loot_modifiers/global_loot_modifiers.json | 6 + .../loot_modifiers/wheat_harvest.json | 0 tests/src/generated/resources/pack.mcmeta | 2 +- .../BlockEntityTypeValidBlocksEventTests.java | 2 +- .../unittest/CreativeTabOrderTest.java | 6 +- .../neoforge/unittest/IngredientTests.java | 24 +- .../debug/attachment/AttachmentTests.java | 4 +- .../neoforge/debug/block/BlockEventTests.java | 22 +- .../debug/block/BlockPropertyTests.java | 10 +- .../neoforge/debug/block/BlockTests.java | 21 +- .../debug/block/CanSustainPlantTests.java | 2 +- .../block/OnDestroyedByPushReactionTests.java | 76 +-- .../neoforge/debug/block/PistonTests.java | 36 +- .../debug/capabilities/ItemEnergyTests.java | 2 +- .../capabilities/ItemInventoryTests.java | 2 +- .../neoforge/debug/chat/CommandTests.java | 5 +- .../debug/client/ClientEventTests.java | 4 +- .../neoforge/debug/client/ClientTests.java | 4 +- .../DimensionTransitionScreenTests.java | 3 +- .../client/MapDecorationRenderTests.java | 12 +- .../debug/crafting/IngredientTests.java | 501 ++++++------------ .../debug/damagesource/DamageTypeTests.java | 4 +- .../neoforge/debug/data/DataMapTests.java | 29 +- .../data/registries/DatapackEntryTests.java | 2 +- .../neoforge/debug/effect/MobEffectTests.java | 21 +- .../enchantment/EnchantmentLevelTests.java | 12 +- .../entity/EntityDataSerializerTest.java | 15 +- .../debug/entity/EntityEventTests.java | 22 +- .../neoforge/debug/entity/EntityTests.java | 17 + .../entity/living/LivingEntityEventTests.java | 4 +- .../debug/entity/player/PlayerEventTests.java | 20 +- .../debug/entity/vehicle/CustomBoatTest.java | 51 +- .../neoforge/debug/fluid/FluidEventTests.java | 20 +- .../neoforge/debug/item/ItemTests.java | 22 +- .../neoforge/debug/level/LevelEventTests.java | 2 +- .../neoforge/debug/level/LevelTests.java | 8 +- .../debug/loot/GlobalLootModifiersTest.java | 56 +- .../debug/registries/HolderSetTests.java | 4 +- .../debug/registry/BiomeModifierSyncTest.java | 4 +- .../debug/resources/BulkKnownPackTest.java | 6 +- .../debug/resources/ModDatapackTest.java | 6 +- .../neoforge/oldtest/DataGeneratorTest.java | 100 ++-- .../oldtest/DeferredRegistryTest.java | 2 +- .../oldtest/DuplicateOptionalTagTest.java | 4 +- .../neoforge/oldtest/ManyMobEffectsTest.java | 9 +- .../oldtest/block/CustomHeadTest.java | 8 +- .../oldtest/block/CustomPlantTypeTest.java | 18 +- .../oldtest/block/CustomSignsTest.java | 6 +- .../neoforge/oldtest/block/FlowerPotTest.java | 7 +- .../oldtest/block/FullPotsAccessorDemo.java | 27 +- .../oldtest/block/HideNeighborFaceTest.java | 7 +- .../oldtest/block/OnTreeGrowBlockTest.java | 8 +- .../block/RedstoneSidedConnectivityTest.java | 18 +- .../oldtest/block/ScaffoldingTest.java | 2 +- .../oldtest/block/SlipperinessTest.java | 5 +- .../oldtest/block/ValidRailShapeTest.java | 4 +- .../oldtest/chat/ClientCommandTest.java | 40 +- .../oldtest/client/CustomArmorModelTest.java | 66 +-- .../client/CustomColorResolverTest.java | 5 +- .../client/CustomPresetEditorTest.java | 6 +- .../oldtest/client/CustomTooltipTest.java | 12 +- .../oldtest/client/EmissiveElementsTest.java | 2 +- .../client/model/CompositeModelTest.java | 6 +- .../model/CustomItemDisplayContextTest.java | 4 +- .../oldtest/client/model/MegaModelTest.java | 15 +- .../client/model/MultiLayerModelTest.java | 2 +- .../client/model/NewModelLoaderTest.java | 6 +- .../client/model/TRSRTransformerTest.java | 11 +- .../rendering/CustomItemDecorationsTest.java | 2 +- .../rendering/EntityRendererEventsTest.java | 40 +- .../NameplateRenderingEventTest.java | 6 +- .../client/rendering/RenderableTest.java | 3 +- .../client/rendering/ShaderResourcesTest.java | 42 +- .../client/rendering/StencilEnableTest.java | 5 +- .../oldtest/entity/PartEntityTest.java | 10 +- .../entity/player/ItemUseAnimationTest.java | 10 +- .../neoforge/oldtest/fluid/FluidTypeTest.java | 23 +- .../oldtest/item/CustomElytraTest.java | 93 +--- .../item/CustomFluidContainerTest.java | 8 +- .../oldtest/item/CustomShieldTest.java | 17 +- .../neoforge/oldtest/item/EnderMaskTest.java | 11 +- .../oldtest/item/MayFlyAttributeTest.java | 2 +- .../neoforge/oldtest/item/MusicDiscTest.java | 4 +- .../item/RangedMobsUseModdedWeaponsTest.java | 4 +- .../oldtest/item/StopUsingItemTest.java | 19 +- .../oldtest/misc/DataPackRegistriesTest.java | 16 +- .../neoforge/oldtest/misc/GameTestTest.java | 7 +- .../RecipeBookExtensionClientHelper.java | 46 -- .../recipebook/RecipeBookExtensionTest.java | 22 +- .../recipebook/RecipeBookTestComponent.java | 77 +++ .../recipebook/RecipeBookTestMenu.java | 198 ++++--- .../recipebook/RecipeBookTestRecipe.java | 86 +-- .../recipebook/RecipeBookTestScreen.java | 89 +--- .../oldtest/world/ForgeChunkManagerTest.java | 3 +- .../oldtest/world/LoginPacketSplitTest.java | 4 +- .../resources/META-INF/enumextensions.json | 51 +- .../models/equipment/test_elytra.json | 10 + .../{ => equipment/wings}/custom_elytra.png | Bin .../gui/container/recipe_book_test.png | Bin 0 -> 1478 bytes .../worldgen/biome/desert.json | 177 ------- .../dummy_parent.json | 0 .../recipe_book_extension_advancment.json | 5 - .../recipe_book_extension_recipe_1.json | 16 + .../recipe_book_extension_recipe_2.json | 18 + .../recipe_book_extension_recipe_3.json | 15 + .../recipe_book_extension_recipe_4.json | 16 + .../recipe_book_extension_recipe_5.json | 14 + .../recipe_book_extension_recipe_1.json | 26 - .../recipe_book_extension_recipe_2.json | 30 -- .../recipe_book_extension_recipe_3.json | 25 - .../recipe_book_extension_recipe_4.json | 26 - .../recipe_book_extension_recipe_5.json | 22 - 1161 files changed, 11597 insertions(+), 11739 deletions(-) delete mode 100644 patches/com/mojang/blaze3d/pipeline/RenderTarget.java.patch delete mode 100644 patches/net/minecraft/client/RecipeBookCategories.java.patch delete mode 100644 patches/net/minecraft/client/gui/MapRenderer.java.patch delete mode 100644 patches/net/minecraft/client/gui/components/toasts/ToastComponent.java.patch create mode 100644 patches/net/minecraft/client/gui/components/toasts/ToastManager.java.patch rename patches/net/minecraft/client/gui/screens/inventory/{EffectRenderingInventoryScreen.java.patch => EffectsInInventory.java.patch} (64%) delete mode 100644 patches/net/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil.java.patch create mode 100644 patches/net/minecraft/client/gui/screens/recipebook/GhostSlots.java.patch rename patches/net/minecraft/client/model/{HierarchicalModel.java.patch => Model.java.patch} (52%) delete mode 100644 patches/net/minecraft/client/multiplayer/TagCollector.java.patch delete mode 100644 patches/net/minecraft/client/renderer/EffectInstance.java.patch create mode 100644 patches/net/minecraft/client/renderer/LevelEventHandler.java.patch create mode 100644 patches/net/minecraft/client/renderer/MapRenderer.java.patch delete mode 100644 patches/net/minecraft/client/renderer/PanoramaRenderer.java.patch delete mode 100644 patches/net/minecraft/client/renderer/PostChain.java.patch delete mode 100644 patches/net/minecraft/client/renderer/ShaderInstance.java.patch create mode 100644 patches/net/minecraft/client/renderer/ShaderManager.java.patch create mode 100644 patches/net/minecraft/client/renderer/WeatherEffectRenderer.java.patch create mode 100644 patches/net/minecraft/client/renderer/block/model/BakedOverrides.java.patch delete mode 100644 patches/net/minecraft/client/renderer/block/model/ItemOverrides.java.patch delete mode 100644 patches/net/minecraft/client/renderer/entity/BoatRenderer.java.patch create mode 100644 patches/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java.patch delete mode 100644 patches/net/minecraft/client/renderer/entity/layers/ElytraLayer.java.patch create mode 100644 patches/net/minecraft/client/renderer/entity/layers/EquipmentLayerRenderer.java.patch delete mode 100644 patches/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java.patch create mode 100644 patches/net/minecraft/client/renderer/entity/state/EntityRenderState.java.patch create mode 100644 patches/net/minecraft/client/renderer/entity/state/PlayerRenderState.java.patch create mode 100644 patches/net/minecraft/client/renderer/state/MapRenderState.java.patch create mode 100644 patches/net/minecraft/client/resources/model/DelegateBakedModel.java.patch create mode 100644 patches/net/minecraft/client/resources/model/ItemModel.java.patch create mode 100644 patches/net/minecraft/client/resources/model/ModelDiscovery.java.patch create mode 100644 patches/net/minecraft/commands/arguments/ResourceKeyArgument.java.patch delete mode 100644 patches/net/minecraft/commands/arguments/ResourceLocationArgument.java.patch create mode 100644 patches/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java.patch create mode 100644 patches/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java.patch delete mode 100644 patches/net/minecraft/data/recipes/ShapelessRecipeBuilder.java.patch create mode 100644 patches/net/minecraft/server/ReloadableServerRegistries.java.patch delete mode 100644 patches/net/minecraft/server/ServerAdvancementManager.java.patch create mode 100644 patches/net/minecraft/util/context/ContextMap.java.patch delete mode 100644 patches/net/minecraft/world/entity/decoration/ArmorStand.java.patch create mode 100644 patches/net/minecraft/world/entity/monster/creaking/Creaking.java.patch create mode 100644 patches/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch delete mode 100644 patches/net/minecraft/world/entity/vehicle/Boat.java.patch delete mode 100644 patches/net/minecraft/world/entity/vehicle/ChestBoat.java.patch create mode 100644 patches/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java.patch create mode 100644 patches/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java.patch delete mode 100644 patches/net/minecraft/world/food/FoodProperties.java.patch delete mode 100644 patches/net/minecraft/world/inventory/RecipeBookMenu.java.patch delete mode 100644 patches/net/minecraft/world/item/ArmorItem.java.patch delete mode 100644 patches/net/minecraft/world/item/ChorusFruitItem.java.patch delete mode 100644 patches/net/minecraft/world/item/ElytraItem.java.patch delete mode 100644 patches/net/minecraft/world/item/HoneyBottleItem.java.patch create mode 100644 patches/net/minecraft/world/item/ItemUseAnimation.java.patch delete mode 100644 patches/net/minecraft/world/item/MilkBucketItem.java.patch delete mode 100644 patches/net/minecraft/world/item/StandingAndWallBlockItem.java.patch delete mode 100644 patches/net/minecraft/world/item/Tiers.java.patch delete mode 100644 patches/net/minecraft/world/item/UseAnim.java.patch create mode 100644 patches/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java.patch create mode 100644 patches/net/minecraft/world/item/crafting/AbstractCookingRecipe.java.patch create mode 100644 patches/net/minecraft/world/item/crafting/CraftingRecipe.java.patch delete mode 100644 patches/net/minecraft/world/item/crafting/RecipeManager.java.patch delete mode 100644 patches/net/minecraft/world/item/crafting/ShapedRecipe.java.patch delete mode 100644 patches/net/minecraft/world/item/crafting/ShulkerBoxColoring.java.patch delete mode 100644 patches/net/minecraft/world/item/crafting/SimpleCookingSerializer.java.patch delete mode 100644 patches/net/minecraft/world/item/crafting/SmithingTransformRecipe.java.patch delete mode 100644 patches/net/minecraft/world/item/crafting/SmithingTrimRecipe.java.patch delete mode 100644 patches/net/minecraft/world/level/Explosion.java.patch create mode 100644 patches/net/minecraft/world/level/ServerExplosion.java.patch delete mode 100644 patches/net/minecraft/world/level/biome/BiomeGenerationSettings.java.patch delete mode 100644 patches/net/minecraft/world/level/block/TripWireHookBlock.java.patch create mode 100644 patches/net/minecraft/world/level/block/entity/FuelValues.java.patch create mode 100644 patches/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java.patch create mode 100644 patches/net/minecraft/world/level/chunk/ProtoChunk.java.patch delete mode 100644 patches/net/minecraft/world/level/chunk/storage/ChunkSerializer.java.patch create mode 100644 patches/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch delete mode 100644 patches/net/minecraft/world/level/storage/loot/LootParams.java.patch create mode 100644 patches/net/minecraft/world/phys/shapes/MinecartCollisionContext.java.patch create mode 100644 src/generated/resources/data/minecraft/recipe/black_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/black_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/black_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/black_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/black_terracotta.json create mode 100644 src/generated/resources/data/minecraft/recipe/blue_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/blue_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/blue_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/blue_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/blue_terracotta.json create mode 100644 src/generated/resources/data/minecraft/recipe/brown_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/brown_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/brown_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/brown_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/brown_terracotta.json create mode 100644 src/generated/resources/data/minecraft/recipe/bundle.json create mode 100644 src/generated/resources/data/minecraft/recipe/cyan_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/cyan_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/cyan_dye.json create mode 100644 src/generated/resources/data/minecraft/recipe/cyan_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/cyan_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/cyan_terracotta.json create mode 100644 src/generated/resources/data/minecraft/recipe/dark_prismarine.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_black_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_black_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_black_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_blue_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_blue_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_blue_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_brown_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_brown_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_brown_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_cyan_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_cyan_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_cyan_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_gray_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_gray_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_gray_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_green_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_green_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_green_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_light_blue_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_light_blue_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_light_blue_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_light_gray_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_light_gray_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_light_gray_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_lime_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_lime_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_lime_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_magenta_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_magenta_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_magenta_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_orange_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_orange_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_orange_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_pink_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_pink_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_pink_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_purple_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_purple_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_purple_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_red_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_red_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_red_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_white_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_white_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_white_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_yellow_bed.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_yellow_carpet.json create mode 100644 src/generated/resources/data/minecraft/recipe/dye_yellow_wool.json create mode 100644 src/generated/resources/data/minecraft/recipe/gray_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/gray_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/gray_dye.json create mode 100644 src/generated/resources/data/minecraft/recipe/gray_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/gray_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/gray_terracotta.json create mode 100644 src/generated/resources/data/minecraft/recipe/green_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/green_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/green_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/green_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/green_terracotta.json create mode 100644 src/generated/resources/data/minecraft/recipe/light_blue_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/light_blue_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/light_blue_dye_from_blue_white_dye.json create mode 100644 src/generated/resources/data/minecraft/recipe/light_blue_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/light_blue_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/light_blue_terracotta.json create mode 100644 src/generated/resources/data/minecraft/recipe/light_gray_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/light_gray_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/light_gray_dye_from_black_white_dye.json create mode 100644 src/generated/resources/data/minecraft/recipe/light_gray_dye_from_gray_white_dye.json create mode 100644 src/generated/resources/data/minecraft/recipe/light_gray_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/light_gray_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/light_gray_terracotta.json create mode 100644 src/generated/resources/data/minecraft/recipe/lime_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/lime_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/lime_dye.json create mode 100644 src/generated/resources/data/minecraft/recipe/lime_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/lime_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/lime_terracotta.json create mode 100644 src/generated/resources/data/minecraft/recipe/magenta_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/magenta_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/magenta_dye_from_blue_red_pink.json create mode 100644 src/generated/resources/data/minecraft/recipe/magenta_dye_from_blue_red_white_dye.json create mode 100644 src/generated/resources/data/minecraft/recipe/magenta_dye_from_purple_and_pink.json create mode 100644 src/generated/resources/data/minecraft/recipe/magenta_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/magenta_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/magenta_terracotta.json create mode 100644 src/generated/resources/data/minecraft/recipe/orange_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/orange_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/orange_dye_from_red_yellow.json create mode 100644 src/generated/resources/data/minecraft/recipe/orange_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/orange_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/orange_terracotta.json create mode 100644 src/generated/resources/data/minecraft/recipe/pink_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/pink_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/pink_dye_from_red_white_dye.json create mode 100644 src/generated/resources/data/minecraft/recipe/pink_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/pink_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/pink_terracotta.json create mode 100644 src/generated/resources/data/minecraft/recipe/purple_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/purple_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/purple_dye.json create mode 100644 src/generated/resources/data/minecraft/recipe/purple_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/purple_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/purple_terracotta.json create mode 100644 src/generated/resources/data/minecraft/recipe/red_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/red_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/red_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/red_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/red_terracotta.json create mode 100644 src/generated/resources/data/minecraft/recipe/white_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/white_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/white_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/white_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/white_terracotta.json create mode 100644 src/generated/resources/data/minecraft/recipe/yellow_candle.json create mode 100644 src/generated/resources/data/minecraft/recipe/yellow_concrete_powder.json create mode 100644 src/generated/resources/data/minecraft/recipe/yellow_stained_glass.json create mode 100644 src/generated/resources/data/minecraft/recipe/yellow_stained_glass_pane_from_glass_pane.json create mode 100644 src/generated/resources/data/minecraft/recipe/yellow_terracotta.json create mode 100644 src/main/java/net/neoforged/neoforge/client/CoreShaderManager.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/event/RecipesUpdatedEvent.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/event/RegisterRecipeBookCategoriesEvent.java create mode 100644 src/main/java/net/neoforged/neoforge/client/event/RegisterRecipeBookSearchCategoriesEvent.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/ElementsModel.java delete mode 100644 src/main/java/net/neoforged/neoforge/client/model/RegistryAwareItemModelShaper.java delete mode 100644 src/main/java/net/neoforged/neoforge/common/EffectCure.java delete mode 100644 src/main/java/net/neoforged/neoforge/common/EffectCures.java delete mode 100644 src/main/java/net/neoforged/neoforge/common/crafting/CraftingHelper.java create mode 100644 src/main/java/net/neoforged/neoforge/common/crafting/CustomDisplayIngredient.java create mode 100644 src/main/java/net/neoforged/neoforge/common/crafting/IngredientCodecs.java rename src/main/java/net/neoforged/neoforge/common/extensions/{IBoatExtension.java => IAbstractBoatExtension.java} (83%) delete mode 100644 src/main/java/net/neoforged/neoforge/common/extensions/IAbstractMinecartExtension.java delete mode 100644 src/main/java/net/neoforged/neoforge/common/util/DummySavedData.java create mode 100644 tests/src/generated/resources/data/minecraft/advancement/good_parent.json create mode 100644 tests/src/generated/resources/neotests_glm_test_wheat_seed_glms/data/neoforge/loot_modifiers/global_loot_modifiers.json rename tests/src/generated/resources/{ => neotests_glm_test_wheat_seed_glms}/data/neotests_glm_test/loot_modifiers/wheat_harvest.json (100%) delete mode 100644 tests/src/main/java/net/neoforged/neoforge/oldtest/recipebook/RecipeBookExtensionClientHelper.java create mode 100644 tests/src/main/java/net/neoforged/neoforge/oldtest/recipebook/RecipeBookTestComponent.java create mode 100644 tests/src/main/resources/assets/custom_elytra_test/models/equipment/test_elytra.json rename tests/src/main/resources/assets/custom_elytra_test/textures/entity/{ => equipment/wings}/custom_elytra.png (100%) create mode 100644 tests/src/main/resources/assets/recipe_book_extension_test/textures/gui/container/recipe_book_test.png delete mode 100644 tests/src/main/resources/data/biome_loading_event_test/worldgen/biome/desert.json rename tests/src/main/resources/data/neoforge/{advancements => advancement}/dummy_parent.json (100%) rename tests/src/main/resources/data/recipe_book_extension_test/{advancements => advancement}/recipes/recipe_book_extension_advancment.json (89%) create mode 100644 tests/src/main/resources/data/recipe_book_extension_test/recipe/recipe_book_extension_recipe_1.json create mode 100644 tests/src/main/resources/data/recipe_book_extension_test/recipe/recipe_book_extension_recipe_2.json create mode 100644 tests/src/main/resources/data/recipe_book_extension_test/recipe/recipe_book_extension_recipe_3.json create mode 100644 tests/src/main/resources/data/recipe_book_extension_test/recipe/recipe_book_extension_recipe_4.json create mode 100644 tests/src/main/resources/data/recipe_book_extension_test/recipe/recipe_book_extension_recipe_5.json delete mode 100644 tests/src/main/resources/data/recipe_book_extension_test/recipes/recipe_book_extension_recipe_1.json delete mode 100644 tests/src/main/resources/data/recipe_book_extension_test/recipes/recipe_book_extension_recipe_2.json delete mode 100644 tests/src/main/resources/data/recipe_book_extension_test/recipes/recipe_book_extension_recipe_3.json delete mode 100644 tests/src/main/resources/data/recipe_book_extension_test/recipes/recipe_book_extension_recipe_4.json delete mode 100644 tests/src/main/resources/data/recipe_book_extension_test/recipes/recipe_book_extension_recipe_5.json diff --git a/.github/workflows/build-prs.yml b/.github/workflows/build-prs.yml index 275a91f5d0..24300a0ed5 100644 --- a/.github/workflows/build-prs.yml +++ b/.github/workflows/build-prs.yml @@ -27,10 +27,16 @@ jobs: # GradleUtils will append the branch name to the version, # but for that we need a properly checked out branch - - name: Create branch for commit + - name: Create branch for commit (PR) + if: ${{ github.event_name == 'pull_request' }} run: git switch -C pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.ref }} + - name: Create branch for commit + if: ${{ github.event_name != 'pull_request' }} + run: + git switch -C ${{ github.ref_name }} + - name: Setup JDK 21 uses: neoforged/actions/setup-java@main with: @@ -48,12 +54,13 @@ jobs: run: ./gradlew assemble checkFormatting - name: Run JCC - if: ${{ ! startsWith(github.event.pull_request.head.ref, 'refs/heads/port/') }} + if: ${{ ! startsWith(github.event.pull_request.head.ref, 'port/') && ! startsWith(github.ref_name, 'port/') }} run: ./gradlew checkJarCompatibility - name: Upload JCC - if: ${{ ! startsWith(github.event.pull_request.head.ref, 'refs/heads/port/') }} + if: ${{ ! startsWith(github.event.pull_request.head.ref, 'port/') && ! startsWith(github.ref_name, 'port/') }} uses: neoforged/action-jar-compatibility/upload@v1 - name: Publish artifacts - uses: neoforged/action-pr-publishing/upload@v1 \ No newline at end of file + if: ${{ github.event_name == 'pull_request' }} + uses: neoforged/action-pr-publishing/upload@v1 diff --git a/coremods/src/main/java/net/neoforged/neoforge/coremods/MethodRedirector.java b/coremods/src/main/java/net/neoforged/neoforge/coremods/MethodRedirector.java index 8db3d7486d..d3bb0616c8 100644 --- a/coremods/src/main/java/net/neoforged/neoforge/coremods/MethodRedirector.java +++ b/coremods/src/main/java/net/neoforged/neoforge/coremods/MethodRedirector.java @@ -32,13 +32,13 @@ public class MethodRedirector implements ITransformer { new MethodRedirection( Opcodes.INVOKEVIRTUAL, "finalizeSpawn", - "(Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/world/DifficultyInstance;Lnet/minecraft/world/entity/MobSpawnType;Lnet/minecraft/world/entity/SpawnGroupData;)Lnet/minecraft/world/entity/SpawnGroupData;", + "(Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/world/DifficultyInstance;Lnet/minecraft/world/entity/EntitySpawnReason;Lnet/minecraft/world/entity/SpawnGroupData;)Lnet/minecraft/world/entity/SpawnGroupData;", "finalize_spawn_targets.json", methodInsnNode -> new MethodInsnNode( Opcodes.INVOKESTATIC, "net/neoforged/neoforge/event/EventHooks", "finalizeMobSpawn", - "(Lnet/minecraft/world/entity/Mob;Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/world/DifficultyInstance;Lnet/minecraft/world/entity/MobSpawnType;Lnet/minecraft/world/entity/SpawnGroupData;)Lnet/minecraft/world/entity/SpawnGroupData;", + "(Lnet/minecraft/world/entity/Mob;Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/world/DifficultyInstance;Lnet/minecraft/world/entity/EntitySpawnReason;Lnet/minecraft/world/entity/SpawnGroupData;)Lnet/minecraft/world/entity/SpawnGroupData;", false))); public MethodRedirector() { diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index eea2cf6d4b..80f55cebf7 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -22,7 +22,7 @@ Contributing to NeoForge - Run `gradlew :tests:runGameTestServer` or `Tests: GameTestServer` from IDE - Run `gradlew :tests:runGameTestClient` or `Tests: GameTestClient` from IDE - If possible, write an automated test under the tests project. See [NEOGAMETESTS.md](NEOGAMETESTS.md) for more info. -10. Run `gradlew unpackSourcePatches` to generate patch-files from the patched sources +10. Run `gradlew genPatches` to generate patch-files from the patched sources 11. Run `gradlew applyAllFormatting` to automatically format sources 12. Check correct formatting with `gradlew spotlessCheck` 13. Commit & Push diff --git a/gradle.properties b/gradle.properties index d65d2d4d71..d524c7c996 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,10 +9,10 @@ org.gradle.debug=false java_version=21 -minecraft_version=1.21.1 -neoform_version=20240808.144430 +minecraft_version=1.21.2-rc1 +neoform_version=20241017.134216 # on snapshot versions, used to prefix the version -neoforge_snapshot_next_stable=22.0 +neoforge_snapshot_next_stable=21.2 mergetool_version=2.0.0 accesstransformers_version=10.0.1 diff --git a/patches/com/mojang/blaze3d/pipeline/RenderTarget.java.patch b/patches/com/mojang/blaze3d/pipeline/RenderTarget.java.patch deleted file mode 100644 index da006f8e16..0000000000 --- a/patches/com/mojang/blaze3d/pipeline/RenderTarget.java.patch +++ /dev/null @@ -1,57 +0,0 @@ ---- a/com/mojang/blaze3d/pipeline/RenderTarget.java -+++ b/com/mojang/blaze3d/pipeline/RenderTarget.java -@@ -104,7 +_,10 @@ - GlStateManager._texParameter(3553, 34892, 0); - GlStateManager._texParameter(3553, 10242, 33071); - GlStateManager._texParameter(3553, 10243, 33071); -+ if (!stencilEnabled) - GlStateManager._texImage2D(3553, 0, 6402, this.width, this.height, 0, 6402, 5126, null); -+ else -+ GlStateManager._texImage2D(3553, 0, org.lwjgl.opengl.GL30.GL_DEPTH32F_STENCIL8, this.width, this.height, 0, org.lwjgl.opengl.GL30.GL_DEPTH_STENCIL, org.lwjgl.opengl.GL30.GL_FLOAT_32_UNSIGNED_INT_24_8_REV, null); - } - - this.setFilterMode(9728, true); -@@ -115,7 +_,14 @@ - GlStateManager._glBindFramebuffer(36160, this.frameBufferId); - GlStateManager._glFramebufferTexture2D(36160, 36064, 3553, this.colorTextureId, 0); - if (this.useDepth) { -+ if(!stencilEnabled) - GlStateManager._glFramebufferTexture2D(36160, 36096, 3553, this.depthBufferId, 0); -+ else if(net.neoforged.neoforge.common.NeoForgeConfig.CLIENT.useCombinedDepthStencilAttachment.get()) { -+ GlStateManager._glFramebufferTexture2D(org.lwjgl.opengl.GL30.GL_FRAMEBUFFER, org.lwjgl.opengl.GL30.GL_DEPTH_STENCIL_ATTACHMENT, 3553, this.depthBufferId, 0); -+ } else { -+ GlStateManager._glFramebufferTexture2D(org.lwjgl.opengl.GL30.GL_FRAMEBUFFER, org.lwjgl.opengl.GL30.GL_DEPTH_ATTACHMENT, 3553, this.depthBufferId, 0); -+ GlStateManager._glFramebufferTexture2D(org.lwjgl.opengl.GL30.GL_FRAMEBUFFER, org.lwjgl.opengl.GL30.GL_STENCIL_ATTACHMENT, 3553, this.depthBufferId, 0); -+ } - } - - this.checkStatus(); -@@ -257,5 +_,28 @@ - - public int getDepthTextureId() { - return this.depthBufferId; -+ } -+ -+ // Neo: Injected stencil control -+ private boolean stencilEnabled = false; -+ -+ /** -+ * Attempts to enable 8 bits of stencil buffer on this FrameBuffer. -+ * Modders must call this directly to set things up. -+ * This is to prevent the default cause where graphics cards do not support stencil bits. -+ * Make sure to call this on the main render thread! -+ */ -+ public void enableStencil() { -+ if(stencilEnabled) return; -+ stencilEnabled = true; -+ this.resize(viewWidth, viewHeight, net.minecraft.client.Minecraft.ON_OSX); -+ } -+ -+ /** -+ * Returns whether this FBO has been successfully initialized with stencil bits. -+ * If not, and a modder wishes it to be, they must call enableStencil. -+ */ -+ public boolean isStencilEnabled() { -+ return this.stencilEnabled; - } - } diff --git a/patches/com/mojang/blaze3d/platform/GlStateManager.java.patch b/patches/com/mojang/blaze3d/platform/GlStateManager.java.patch index 4eb7c902e9..88bb511647 100644 --- a/patches/com/mojang/blaze3d/platform/GlStateManager.java.patch +++ b/patches/com/mojang/blaze3d/platform/GlStateManager.java.patch @@ -1,6 +1,6 @@ --- a/com/mojang/blaze3d/platform/GlStateManager.java +++ b/com/mojang/blaze3d/platform/GlStateManager.java -@@ -945,4 +_,53 @@ +@@ -1009,4 +_,53 @@ return INSTANCE.height; } } diff --git a/patches/com/mojang/blaze3d/platform/Window.java.patch b/patches/com/mojang/blaze3d/platform/Window.java.patch index edf8e76920..f211b35fad 100644 --- a/patches/com/mojang/blaze3d/platform/Window.java.patch +++ b/patches/com/mojang/blaze3d/platform/Window.java.patch @@ -1,6 +1,6 @@ --- a/com/mojang/blaze3d/platform/Window.java +++ b/com/mojang/blaze3d/platform/Window.java -@@ -86,7 +_,8 @@ +@@ -90,7 +_,8 @@ GLFW.glfwWindowHint(139267, 2); GLFW.glfwWindowHint(139272, 204801); GLFW.glfwWindowHint(139270, 1); @@ -10,7 +10,7 @@ if (monitor != null) { VideoMode videomode = monitor.getPreferredVidMode(this.fullscreen ? this.preferredFullscreenVideoMode : Optional.empty()); this.windowedX = this.x = monitor.getX() + videomode.getWidth() / 2 - this.width / 2; -@@ -98,6 +_,7 @@ +@@ -102,6 +_,7 @@ this.windowedX = this.x = aint1[0]; this.windowedY = this.y = aint[0]; } @@ -18,7 +18,7 @@ GLFW.glfwMakeContextCurrent(this.window); GL.createCapabilities(); -@@ -256,6 +_,7 @@ +@@ -269,6 +_,7 @@ GLFW.glfwGetFramebufferSize(this.window, aint, aint1); this.framebufferWidth = aint[0] > 0 ? aint[0] : 1; this.framebufferHeight = aint1[0] > 0 ? aint1[0] : 1; diff --git a/patches/com/mojang/blaze3d/systems/RenderSystem.java.patch b/patches/com/mojang/blaze3d/systems/RenderSystem.java.patch index 3a0ac77ee0..756e40c7c9 100644 --- a/patches/com/mojang/blaze3d/systems/RenderSystem.java.patch +++ b/patches/com/mojang/blaze3d/systems/RenderSystem.java.patch @@ -1,6 +1,6 @@ --- a/com/mojang/blaze3d/systems/RenderSystem.java +++ b/com/mojang/blaze3d/systems/RenderSystem.java -@@ -932,4 +_,14 @@ +@@ -822,4 +_,14 @@ void accept(it.unimi.dsi.fastutil.ints.IntConsumer p_157488_, int p_157489_); } } diff --git a/patches/com/mojang/blaze3d/vertex/PoseStack.java.patch b/patches/com/mojang/blaze3d/vertex/PoseStack.java.patch index a21f52da74..c3b47049f8 100644 --- a/patches/com/mojang/blaze3d/vertex/PoseStack.java.patch +++ b/patches/com/mojang/blaze3d/vertex/PoseStack.java.patch @@ -1,6 +1,6 @@ --- a/com/mojang/blaze3d/vertex/PoseStack.java +++ b/com/mojang/blaze3d/vertex/PoseStack.java -@@ -13,7 +_,7 @@ +@@ -14,7 +_,7 @@ import org.joml.Vector3f; @OnlyIn(Dist.CLIENT) diff --git a/patches/com/mojang/blaze3d/vertex/VertexConsumer.java.patch b/patches/com/mojang/blaze3d/vertex/VertexConsumer.java.patch index 7648e30906..30c19c43bf 100644 --- a/patches/com/mojang/blaze3d/vertex/VertexConsumer.java.patch +++ b/patches/com/mojang/blaze3d/vertex/VertexConsumer.java.patch @@ -1,6 +1,6 @@ --- a/com/mojang/blaze3d/vertex/VertexConsumer.java +++ b/com/mojang/blaze3d/vertex/VertexConsumer.java -@@ -12,7 +_,7 @@ +@@ -13,7 +_,7 @@ import org.lwjgl.system.MemoryStack; @OnlyIn(Dist.CLIENT) @@ -10,19 +10,19 @@ VertexConsumer setColor(int p_350535_, int p_350875_, int p_350886_, int p_350775_); @@ -131,11 +_,14 @@ - f5 = p_331397_[l] * p_85992_ * 255.0F; + f5 = p_331397_[i1] * p_85992_ * 255.0F; } -- int i1 = FastColor.ARGB32.color(k, (int)f3, (int)f4, (int)f5); -- int j1 = p_331378_[l]; +- int j1 = ARGB.color(k, (int)f3, (int)f4, (int)f5); +- int k1 = LightTexture.lightCoordsWithEmission(p_331378_[i1], l); + // Neo: also apply alpha that's coming from the baked quad + int vertexAlpha = p_331268_ ? (int)((p_331416_ * (float) (bytebuffer.get(15) & 255) / 255.0F) * 255) : k; -+ int i1 = FastColor.ARGB32.color(vertexAlpha, (int)f3, (int)f4, (int)f5); -+ int j1 = applyBakedLighting(p_331378_[l], bytebuffer); ++ int j1 = ARGB.color(vertexAlpha, (int)f3, (int)f4, (int)f5); ++ int k1 = applyBakedLighting(LightTexture.lightCoordsWithEmission(p_331378_[i1], l), bytebuffer); float f10 = bytebuffer.getFloat(16); float f9 = bytebuffer.getFloat(20); Vector3f vector3f1 = matrix4f.transformPosition(f, f1, f2, new Vector3f()); + applyBakedNormals(vector3f, bytebuffer, p_85988_.normal()); - this.addVertex(vector3f1.x(), vector3f1.y(), vector3f1.z(), i1, f10, f9, p_85993_, j1, vector3f.x(), vector3f.y(), vector3f.z()); + this.addVertex(vector3f1.x(), vector3f1.y(), vector3f1.z(), j1, f10, f9, p_85993_, k1, vector3f.x(), vector3f.y(), vector3f.z()); } } diff --git a/patches/com/mojang/blaze3d/vertex/VertexFormat.java.patch b/patches/com/mojang/blaze3d/vertex/VertexFormat.java.patch index a6debaffd6..792970ee3a 100644 --- a/patches/com/mojang/blaze3d/vertex/VertexFormat.java.patch +++ b/patches/com/mojang/blaze3d/vertex/VertexFormat.java.patch @@ -1,6 +1,6 @@ --- a/com/mojang/blaze3d/vertex/VertexFormat.java +++ b/com/mojang/blaze3d/vertex/VertexFormat.java -@@ -237,4 +_,28 @@ +@@ -220,4 +_,28 @@ }; } } diff --git a/patches/com/mojang/realmsclient/gui/screens/RealmsNotificationsScreen.java.patch b/patches/com/mojang/realmsclient/gui/screens/RealmsNotificationsScreen.java.patch index 0757213ad6..b9cb377a05 100644 --- a/patches/com/mojang/realmsclient/gui/screens/RealmsNotificationsScreen.java.patch +++ b/patches/com/mojang/realmsclient/gui/screens/RealmsNotificationsScreen.java.patch @@ -1,6 +1,6 @@ --- a/com/mojang/realmsclient/gui/screens/RealmsNotificationsScreen.java +++ b/com/mojang/realmsclient/gui/screens/RealmsNotificationsScreen.java -@@ -127,7 +_,7 @@ +@@ -128,7 +_,7 @@ private void drawIcons(GuiGraphics p_282966_) { int i = this.numberOfPendingInvites; int j = 24; diff --git a/patches/net/minecraft/SharedConstants.java.patch b/patches/net/minecraft/SharedConstants.java.patch index c0e578e4f8..d36ef831de 100644 --- a/patches/net/minecraft/SharedConstants.java.patch +++ b/patches/net/minecraft/SharedConstants.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/SharedConstants.java +++ b/net/minecraft/SharedConstants.java -@@ -118,7 +_,8 @@ +@@ -117,7 +_,8 @@ public static final boolean USE_WORKFLOWS_HOOKS = false; public static final boolean USE_DEVONLY = false; public static boolean CHECK_DATA_FIXER_SCHEMA = true; @@ -10,7 +10,7 @@ public static final int WORLD_RESOLUTION = 16; public static final int MAX_CHAT_LENGTH = 256; public static final int MAX_USER_INPUT_COMMAND_LENGTH = 32500; -@@ -171,6 +_,7 @@ +@@ -170,6 +_,7 @@ } static { diff --git a/patches/net/minecraft/Util.java.patch b/patches/net/minecraft/Util.java.patch index e74d02220d..06262a76e0 100644 --- a/patches/net/minecraft/Util.java.patch +++ b/patches/net/minecraft/Util.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/Util.java +++ b/net/minecraft/Util.java -@@ -267,8 +_,8 @@ +@@ -264,8 +_,8 @@ .getSchema(DataFixUtils.makeKey(SharedConstants.getCurrentVersion().getDataVersion().getVersion())) .getChoiceType(p_137552_, p_137553_); } catch (IllegalArgumentException illegalargumentexception) { @@ -11,7 +11,7 @@ throw illegalargumentexception; } } -@@ -526,20 +_,20 @@ +@@ -630,20 +_,20 @@ public static void logAndPauseIfInIde(String p_143786_) { LOGGER.error(p_143786_); diff --git a/patches/net/minecraft/advancements/AdvancementRewards.java.patch b/patches/net/minecraft/advancements/AdvancementRewards.java.patch index 2b4fd0ad19..34bfaa4c01 100644 --- a/patches/net/minecraft/advancements/AdvancementRewards.java.patch +++ b/patches/net/minecraft/advancements/AdvancementRewards.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/advancements/AdvancementRewards.java +++ b/net/minecraft/advancements/AdvancementRewards.java -@@ -40,6 +_,7 @@ +@@ -41,6 +_,7 @@ LootParams lootparams = new LootParams.Builder(p_9990_.serverLevel()) .withParameter(LootContextParams.THIS_ENTITY, p_9990_) .withParameter(LootContextParams.ORIGIN, p_9990_.position()) diff --git a/patches/net/minecraft/client/Camera.java.patch b/patches/net/minecraft/client/Camera.java.patch index 5af6f8da3e..df73884274 100644 --- a/patches/net/minecraft/client/Camera.java.patch +++ b/patches/net/minecraft/client/Camera.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/Camera.java +++ b/net/minecraft/client/Camera.java -@@ -42,6 +_,7 @@ +@@ -44,6 +_,7 @@ private float eyeHeightOld; private float partialTickTime; public static final float FOG_DISTANCE_SCALE = 0.083333336F; @@ -8,20 +8,20 @@ public void setup(BlockGetter p_90576_, Entity p_90577_, boolean p_90578_, boolean p_90579_, float p_90580_) { this.initialized = true; -@@ -49,7 +_,10 @@ - this.entity = p_90577_; - this.detached = p_90578_; - this.partialTickTime = p_90580_; -- this.setRotation(p_90577_.getViewYRot(p_90580_), p_90577_.getViewXRot(p_90580_)); -+ var cameraSetup = net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.ViewportEvent.ComputeCameraAngles( -+ this, p_90580_, p_90577_.getViewYRot(p_90580_), p_90577_.getViewXRot(p_90580_), 0) -+ ); -+ this.setRotation(cameraSetup.getYaw(), cameraSetup.getPitch(), cameraSetup.getRoll()); - this.setPosition( - Mth.lerp((double)p_90580_, p_90577_.xo, p_90577_.getX()), - Mth.lerp((double)p_90580_, p_90577_.yo, p_90577_.getY()) + (double)Mth.lerp(p_90580_, this.eyeHeightOld, this.eyeHeight), -@@ -57,11 +_,11 @@ - ); +@@ -62,7 +_,10 @@ + this.setRotation(p_90577_.getViewYRot(p_90580_), p_90577_.getViewXRot(p_90580_)); + this.setPosition(newminecartbehavior.getCartLerpPosition(p_90580_).add(vec3)); + } else { +- this.setRotation(p_90577_.getViewYRot(p_90580_), p_90577_.getViewXRot(p_90580_)); ++ var cameraSetup = net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.ViewportEvent.ComputeCameraAngles( ++ this, p_90580_, p_90577_.getViewYRot(p_90580_), p_90577_.getViewXRot(p_90580_), 0) ++ ); ++ this.setRotation(cameraSetup.getYaw(), cameraSetup.getPitch(), cameraSetup.getRoll()); + this.setPosition( + Mth.lerp((double)p_90580_, p_90577_.xo, p_90577_.getX()), + Mth.lerp((double)p_90580_, p_90577_.yo, p_90577_.getY()) + (double)Mth.lerp(p_90580_, this.eyeHeightOld, this.eyeHeight), +@@ -72,11 +_,11 @@ + if (p_90578_) { if (p_90579_) { - this.setRotation(this.yRot + 180.0F, -this.xRot); @@ -34,7 +34,7 @@ } else if (p_90577_ instanceof LivingEntity && ((LivingEntity)p_90577_).isSleeping()) { Direction direction = ((LivingEntity)p_90577_).getBedOrientation(); this.setRotation(direction != null ? direction.toYRot() - 180.0F : 0.0F, 0.0F); -@@ -102,10 +_,17 @@ +@@ -117,10 +_,17 @@ this.setPosition(new Vec3(this.position.x + (double)vector3f.x, this.position.y + (double)vector3f.y, this.position.z + (double)vector3f.z)); } @@ -53,7 +53,7 @@ FORWARDS.rotate(this.rotation, this.forwards); UP.rotate(this.rotation, this.up); LEFT.rotate(this.rotation, this.left); -@@ -221,6 +_,17 @@ +@@ -236,6 +_,17 @@ public float getPartialTickTime() { return this.partialTickTime; diff --git a/patches/net/minecraft/client/ClientRecipeBook.java.patch b/patches/net/minecraft/client/ClientRecipeBook.java.patch index 774d2198da..8d6b3ae4cf 100644 --- a/patches/net/minecraft/client/ClientRecipeBook.java.patch +++ b/patches/net/minecraft/client/ClientRecipeBook.java.patch @@ -1,20 +1,19 @@ --- a/net/minecraft/client/ClientRecipeBook.java +++ b/net/minecraft/client/ClientRecipeBook.java -@@ -65,7 +_,7 @@ - Recipe recipe = recipeholder.value(); - if (!recipe.isSpecial() && !recipe.isIncomplete()) { - RecipeBookCategories recipebookcategories = getCategory(recipeholder); -- String s = recipe.getGroup(); -+ String s = recipe.getGroup().isEmpty() ? recipeholder.id().toString() : recipe.getGroup(); // FORGE: Group value defaults to the recipe's ID if the recipe's explicit group is empty. - if (s.isEmpty()) { - map.computeIfAbsent(recipebookcategories, p_90645_ -> Lists.newArrayList()).add(ImmutableList.of(recipeholder)); - } else { -@@ -125,6 +_,8 @@ - } else if (recipetype == RecipeType.SMITHING) { - return RecipeBookCategories.SMITHING; - } else { -+ RecipeBookCategories categories = net.neoforged.neoforge.client.RecipeBookManager.findCategories((RecipeType) recipetype, p_301136_); -+ if (categories != null) return categories; - LOGGER.warn( - "Unknown recipe category: {}/{}", - LogUtils.defer(() -> BuiltInRegistries.RECIPE_TYPE.getKey(recipe.getType())), +@@ -74,6 +_,16 @@ + .collect(ImmutableList.toImmutableList()) + ); + } ++ // Neo: Do the same for modded search categories. ++ for (var entry : net.neoforged.neoforge.client.RecipeBookManager.getSearchCategories().entrySet()) { ++ map1.put( ++ entry.getKey(), ++ entry.getValue() ++ .stream() ++ .flatMap(category -> map1.getOrDefault(category, List.of()).stream()) ++ .collect(ImmutableList.toImmutableList()) ++ ); ++ } + + this.collectionsByTab = Map.copyOf(map1); + this.allCollections = builder.build(); diff --git a/patches/net/minecraft/client/KeyboardHandler.java.patch b/patches/net/minecraft/client/KeyboardHandler.java.patch index 2c5ce4a44e..2470d92b3a 100644 --- a/patches/net/minecraft/client/KeyboardHandler.java.patch +++ b/patches/net/minecraft/client/KeyboardHandler.java.patch @@ -1,53 +1,49 @@ --- a/net/minecraft/client/KeyboardHandler.java +++ b/net/minecraft/client/KeyboardHandler.java -@@ -407,9 +_,13 @@ - Screen.wrapScreenError(() -> { - if (p_90897_ == 1 || p_90897_ == 2) { +@@ -426,12 +_,20 @@ + if (screen != null) { + try { + if (p_90897_ != 1 && p_90897_ != 2) { +- if (p_90897_ == 0 && screen.keyReleased(p_90895_, p_90896_, p_90898_)) { ++ if (p_90897_ == 0 && ( ++ net.neoforged.neoforge.client.ClientHooks.onScreenKeyReleasedPre(screen, p_90895_, p_90896_, p_90898_) || ++ screen.keyReleased(p_90895_, p_90896_, p_90898_) || ++ net.neoforged.neoforge.client.ClientHooks.onScreenKeyReleasedPost(screen, p_90895_, p_90896_, p_90898_)) ++ ) { + return; + } + } else { screen.afterKeyboardAction(); -- aboolean[0] = screen.keyPressed(p_90895_, p_90896_, p_90898_); -+ aboolean[0] = net.neoforged.neoforge.client.ClientHooks.onScreenKeyPressedPre(screen, p_90895_, p_90896_, p_90898_); -+ if (!aboolean[0]) aboolean[0] = screen.keyPressed(p_90895_, p_90896_, p_90898_); -+ if (!aboolean[0]) aboolean[0] = net.neoforged.neoforge.client.ClientHooks.onScreenKeyPressedPost(screen, p_90895_, p_90896_, p_90898_); - } else if (p_90897_ == 0) { -- aboolean[0] = screen.keyReleased(p_90895_, p_90896_, p_90898_); -+ aboolean[0] = net.neoforged.neoforge.client.ClientHooks.onScreenKeyReleasedPre(screen, p_90895_, p_90896_, p_90898_); -+ if (!aboolean[0]) aboolean[0] = screen.keyReleased(p_90895_, p_90896_, p_90898_); -+ if (!aboolean[0]) aboolean[0] = net.neoforged.neoforge.client.ClientHooks.onScreenKeyReleasedPost(screen, p_90895_, p_90896_, p_90898_); +- if (screen.keyPressed(p_90895_, p_90896_, p_90898_)) { ++ if ( ++ net.neoforged.neoforge.client.ClientHooks.onScreenKeyPressedPre(screen, p_90895_, p_90896_, p_90898_) || ++ screen.keyPressed(p_90895_, p_90896_, p_90898_) || ++ net.neoforged.neoforge.client.ClientHooks.onScreenKeyPressedPost(screen, p_90895_, p_90896_, p_90898_) ++ ) { + return; + } } - }, "keyPressed event handler", screen.getClass().getCanonicalName()); - if (aboolean[0]) { -@@ -478,22 +_,27 @@ +@@ -516,10 +_,20 @@ + if (screen != null && this.minecraft.getOverlay() == null) { + try { + if (Character.isBmpCodePoint(p_90891_)) { +- screen.charTyped((char)p_90891_, p_90892_); ++ if (net.neoforged.neoforge.client.ClientHooks.onScreenCharTypedPre(screen, (char)p_90891_, p_90892_)) return; ++ if (screen.charTyped((char)p_90891_, p_90892_)) return; ++ net.neoforged.neoforge.client.ClientHooks.onScreenCharTypedPost(screen, (char)p_90891_, p_90892_); + } else if (Character.isValidCodePoint(p_90891_)) { +- screen.charTyped(Character.highSurrogate(p_90891_), p_90892_); +- screen.charTyped(Character.lowSurrogate(p_90891_), p_90892_); ++ if (!net.neoforged.neoforge.client.ClientHooks.onScreenCharTypedPre(screen, Character.highSurrogate(p_90891_), p_90892_)) { ++ if (!screen.charTyped(Character.highSurrogate(p_90891_), p_90892_)) { ++ net.neoforged.neoforge.client.ClientHooks.onScreenCharTypedPost(screen, Character.highSurrogate(p_90891_), p_90892_); ++ } ++ } ++ if (!net.neoforged.neoforge.client.ClientHooks.onScreenCharTypedPre(screen, Character.lowSurrogate(p_90891_), p_90892_)) { ++ if (!screen.charTyped(Character.lowSurrogate(p_90891_), p_90892_)) { ++ net.neoforged.neoforge.client.ClientHooks.onScreenCharTypedPost(screen, Character.lowSurrogate(p_90891_), p_90892_); ++ } ++ } } - } - } -+ net.neoforged.neoforge.client.ClientHooks.onKeyInput(p_90895_, p_90896_, p_90897_, p_90898_); - } - } - - private void charTyped(long p_90890_, int p_90891_, int p_90892_) { - if (p_90890_ == this.minecraft.getWindow().getWindow()) { -- GuiEventListener guieventlistener = this.minecraft.screen; -+ Screen guieventlistener = this.minecraft.screen; - if (guieventlistener != null && this.minecraft.getOverlay() == null) { - if (Character.charCount(p_90891_) == 1) { -- Screen.wrapScreenError( -- () -> guieventlistener.charTyped((char)p_90891_, p_90892_), "charTyped event handler", guieventlistener.getClass().getCanonicalName() -- ); -+ Screen.wrapScreenError(() -> { -+ if (net.neoforged.neoforge.client.ClientHooks.onScreenCharTypedPre(guieventlistener, (char)p_90891_, p_90892_)) return; -+ if (guieventlistener.charTyped((char)p_90891_, p_90892_)) return; -+ net.neoforged.neoforge.client.ClientHooks.onScreenCharTypedPost(guieventlistener, (char)p_90891_, p_90892_); -+ }, "charTyped event handler", guieventlistener.getClass().getCanonicalName()); - } else { - for (char c0 : Character.toChars(p_90891_)) { -- Screen.wrapScreenError( -- () -> guieventlistener.charTyped(c0, p_90892_), "charTyped event handler", guieventlistener.getClass().getCanonicalName() -- ); -+ Screen.wrapScreenError(() -> { -+ if (net.neoforged.neoforge.client.ClientHooks.onScreenCharTypedPre(guieventlistener, c0, p_90892_)) return; -+ if (guieventlistener.charTyped(c0, p_90892_)) return; -+ net.neoforged.neoforge.client.ClientHooks.onScreenCharTypedPost(guieventlistener, c0, p_90892_); -+ }, "charTyped event handler", guieventlistener.getClass().getCanonicalName()); - } - } - } + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.forThrowable(throwable, "charTyped event handler"); diff --git a/patches/net/minecraft/client/Minecraft.java.patch b/patches/net/minecraft/client/Minecraft.java.patch index 13ff259e92..d73618ac55 100644 --- a/patches/net/minecraft/client/Minecraft.java.patch +++ b/patches/net/minecraft/client/Minecraft.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/Minecraft.java +++ b/net/minecraft/client/Minecraft.java -@@ -254,7 +_,7 @@ +@@ -253,7 +_,7 @@ import org.slf4j.Logger; @OnlyIn(Dist.CLIENT) @@ -9,7 +9,7 @@ static Minecraft instance; private static final Logger LOGGER = LogUtils.getLogger(); public static final boolean ON_OSX = Util.getPlatform() == Util.OS.OSX; -@@ -435,7 +_,6 @@ +@@ -437,7 +_,6 @@ } }, Util.nonCriticalIoPool()); LOGGER.info("Setting user: {}", this.user.getName()); @@ -17,10 +17,10 @@ this.demo = p_91084_.game.demo; this.allowsMultiplayer = !p_91084_.game.disableMultiplayer; this.allowsChat = !p_91084_.game.disableChat; -@@ -476,15 +_,15 @@ +@@ -488,15 +_,15 @@ + LOGGER.error("Couldn't set icon", (Throwable)ioexception); } - this.window.setFramerateLimit(this.options.framerateLimit().get()); + // FORGE: Move mouse and keyboard handler setup further below this.mouseHandler = new MouseHandler(this); - this.mouseHandler.setup(this.window.getWindow()); @@ -29,13 +29,13 @@ RenderSystem.initRenderer(this.options.glDebugVerbosity, false); this.mainRenderTarget = new MainTarget(this.window.getWidth(), this.window.getHeight()); this.mainRenderTarget.setClearColor(0.0F, 0.0F, 0.0F, 0.0F); - this.mainRenderTarget.clear(ON_OSX); + this.mainRenderTarget.clear(); this.resourceManager = new ReloadableResourceManager(PackType.CLIENT_RESOURCES); + net.neoforged.neoforge.client.loading.ClientModLoader.begin(this, this.resourcePackRepository, this.resourceManager); this.resourcePackRepository.reload(); this.options.loadSelectedResourcePacks(this.resourcePackRepository); this.languageManager = new LanguageManager(this.options.languageCode, p_344151_ -> { -@@ -554,6 +_,7 @@ +@@ -582,6 +_,7 @@ ); this.resourceManager.registerReloadListener(this.entityRenderDispatcher); this.particleEngine = new ParticleEngine(this.level, this.textureManager); @@ -43,12 +43,13 @@ this.resourceManager.registerReloadListener(this.particleEngine); this.paintingTextures = new PaintingTextureManager(this.textureManager); this.resourceManager.registerReloadListener(this.paintingTextures); -@@ -566,10 +_,14 @@ +@@ -591,11 +_,15 @@ + this.resourceManager.registerReloadListener(this.guiSprites); this.gameRenderer = new GameRenderer(this, this.entityRenderDispatcher.getItemInHandRenderer(), this.resourceManager, this.renderBuffers); - this.resourceManager.registerReloadListener(this.gameRenderer.createReloadListener()); this.levelRenderer = new LevelRenderer(this, this.entityRenderDispatcher, this.blockEntityRenderDispatcher, this.renderBuffers); + net.neoforged.fml.ModLoader.postEvent(new net.neoforged.neoforge.client.event.RenderLevelStageEvent.RegisterStageEvent()); this.resourceManager.registerReloadListener(this.levelRenderer); + this.resourceManager.registerReloadListener(this.levelRenderer.getCloudRenderer()); this.gpuWarnlistManager = new GpuWarnlistManager(); this.resourceManager.registerReloadListener(this.gpuWarnlistManager); this.resourceManager.registerReloadListener(this.regionalCompliancies); @@ -58,7 +59,7 @@ this.gui = new Gui(this); this.debugRenderer = new DebugRenderer(this); RealmsClient realmsclient = RealmsClient.create(this); -@@ -594,6 +_,7 @@ +@@ -620,6 +_,7 @@ this.options.fullscreen().set(this.window.isFullscreen()); } @@ -66,7 +67,7 @@ this.window.updateVsync(this.options.enableVsync().get()); this.window.updateRawMouseInput(this.options.rawMouseInput().get()); this.window.setDefaultErrorCallback(); -@@ -614,16 +_,18 @@ +@@ -641,16 +_,18 @@ GameLoadTimesEvent.INSTANCE.beginStep(TelemetryProperty.LOAD_TIME_LOADING_OVERLAY_MS); Minecraft.GameLoadCookie minecraft$gameloadcookie = new Minecraft.GameLoadCookie(realmsclient, p_91084_.quickPlay); this.setOverlay( @@ -88,8 +89,8 @@ + ).get() ); this.quickPlayLog = QuickPlayLog.of(p_91084_.quickPlay.path()); - } -@@ -663,6 +_,8 @@ + this.framerateLimitTracker = new FramerateLimitTracker(this.options, this); +@@ -696,6 +_,8 @@ runnable = () -> this.setScreen(screen); } @@ -98,7 +99,7 @@ return runnable; } -@@ -711,7 +_,7 @@ +@@ -744,7 +_,7 @@ private String createTitle() { StringBuilder stringbuilder = new StringBuilder("Minecraft"); if (checkModStatus().shouldReportAsModified()) { @@ -107,7 +108,7 @@ } stringbuilder.append(" "); -@@ -743,7 +_,7 @@ +@@ -776,7 +_,7 @@ } private void rollbackResourcePacks(Throwable p_91240_, @Nullable Minecraft.GameLoadCookie p_299846_) { @@ -116,24 +117,16 @@ this.clearResourcePacksOnError(p_91240_, null, p_299846_); } else { Util.throwAsRuntime(p_91240_); -@@ -871,13 +_,13 @@ - - if (p_91333_.getSaveFile() != null) { - Bootstrap.realStdoutPrintln("#@!@# Game crashed! Crash report saved to: #@!@# " + p_91333_.getSaveFile().toAbsolutePath()); -- System.exit(-1); -+ net.neoforged.neoforge.server.ServerLifecycleHooks.handleExit(-1); - } else if (p_91333_.saveToFile(path1, ReportType.CRASH)) { - Bootstrap.realStdoutPrintln("#@!@# Game crashed! Crash report saved to: #@!@# " + path1.toAbsolutePath()); -- System.exit(-1); -+ net.neoforged.neoforge.server.ServerLifecycleHooks.handleExit(-1); - } else { - Bootstrap.realStdoutPrintln("#@?@# Game crashed! Crash report could not be saved. #@?@#"); -- System.exit(-2); -+ net.neoforged.neoforge.server.ServerLifecycleHooks.handleExit(-2); +@@ -935,7 +_,7 @@ + p_307414_.soundManager.emergencyShutdown(); } + +- System.exit(i); ++ net.neoforged.neoforge.server.ServerLifecycleHooks.handleExit(i); } -@@ -1006,9 +_,7 @@ + public boolean isEnforceUnicode() { +@@ -1062,9 +_,7 @@ LOGGER.error("setScreen called from non-game thread"); } @@ -144,7 +137,7 @@ this.setLastInputType(InputType.NONE); } -@@ -1025,6 +_,19 @@ +@@ -1081,6 +_,19 @@ } } @@ -164,20 +157,20 @@ this.screen = p_91153_; if (this.screen != null) { this.screen.added(); -@@ -1170,9 +_,11 @@ +@@ -1234,9 +_,11 @@ this.mouseHandler.handleAccumulatedMovement(); - this.profiler.pop(); + profilerfiller.pop(); if (!this.noRender) { -+ net.neoforged.neoforge.client.ClientHooks.fireRenderFramePre(this.timer); - this.profiler.popPush("gameRenderer"); - this.gameRenderer.render(this.timer, p_91384_); - this.profiler.pop(); -+ net.neoforged.neoforge.client.ClientHooks.fireRenderFramePost(this.timer); ++ net.neoforged.neoforge.client.ClientHooks.fireRenderFramePre(this.deltaTracker); + profilerfiller.popPush("gameRenderer"); + this.gameRenderer.render(this.deltaTracker, p_91384_); + profilerfiller.pop(); ++ net.neoforged.neoforge.client.ClientHooks.fireRenderFramePost(this.deltaTracker); } - if (this.fpsPieResults != null) { -@@ -1203,9 +_,13 @@ - this.profiler.pop(); + profilerfiller.push("blit"); +@@ -1264,9 +_,13 @@ + profilerfiller.pop(); this.window.setErrorSection("Post render"); this.frames++; - this.pause = this.hasSingleplayerServer() @@ -188,10 +181,10 @@ + this.pause = pause; + net.neoforged.neoforge.client.ClientHooks.onClientPauseChangePost(pause); + } - this.timer.updatePauseState(this.pause); - this.timer.updateFrozenState(!this.isLevelRunningNormally()); - long k = Util.getNanos(); -@@ -1298,10 +_,12 @@ + this.deltaTracker.updatePauseState(this.pause); + this.deltaTracker.updateFrozenState(!this.isLevelRunningNormally()); + long l = Util.getNanos(); +@@ -1358,10 +_,12 @@ this.window.setGuiScale((double)i); if (this.screen != null) { this.screen.resize(this, this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight()); @@ -199,12 +192,12 @@ } RenderTarget rendertarget = this.getMainRenderTarget(); - rendertarget.resize(this.window.getWidth(), this.window.getHeight(), ON_OSX); + rendertarget.resize(this.window.getWidth(), this.window.getHeight()); + if (this.gameRenderer != null) this.gameRenderer.resize(this.window.getWidth(), this.window.getHeight()); this.mouseHandler.setIgnoreFirstMove(); } -@@ -1569,6 +_,7 @@ +@@ -1502,6 +_,7 @@ } public void stop() { @@ -212,7 +205,7 @@ this.running = false; } -@@ -1598,9 +_,17 @@ +@@ -1531,9 +_,17 @@ BlockHitResult blockhitresult = (BlockHitResult)this.hitResult; BlockPos blockpos = blockhitresult.getBlockPos(); if (!this.level.getBlockState(blockpos).isAir()) { @@ -232,7 +225,7 @@ this.player.swing(InteractionHand.MAIN_HAND); } } -@@ -1628,6 +_,8 @@ +@@ -1561,6 +_,8 @@ return false; } else { boolean flag = false; @@ -241,7 +234,7 @@ switch (this.hitResult.getType()) { case ENTITY: this.gameMode.attack(this.player, ((EntityHitResult)this.hitResult).getEntity()); -@@ -1648,8 +_,10 @@ +@@ -1581,8 +_,10 @@ } this.player.resetAttackStrengthTicker(); @@ -252,7 +245,7 @@ this.player.swing(InteractionHand.MAIN_HAND); return flag; } -@@ -1665,6 +_,11 @@ +@@ -1598,6 +_,11 @@ } for (InteractionHand interactionhand : InteractionHand.values()) { @@ -264,35 +257,35 @@ ItemStack itemstack = this.player.getItemInHand(interactionhand); if (!itemstack.isItemEnabled(this.level.enabledFeatures())) { return; -@@ -1685,7 +_,7 @@ +@@ -1618,7 +_,7 @@ } - if (interactionresult.consumesAction()) { -- if (interactionresult.shouldSwing()) { -+ if (interactionresult.shouldSwing() && inputEvent.shouldSwingHand()) { + if (interactionresult instanceof InteractionResult.Success interactionresult$success2) { +- if (interactionresult$success2.swingSource() == InteractionResult.SwingSource.CLIENT) { ++ if (interactionresult$success2.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) { this.player.swing(interactionhand); } -@@ -1697,7 +_,7 @@ +@@ -1630,7 +_,7 @@ int i = itemstack.getCount(); InteractionResult interactionresult1 = this.gameMode.useItemOn(this.player, interactionhand, blockhitresult); - if (interactionresult1.consumesAction()) { -- if (interactionresult1.shouldSwing()) { -+ if (interactionresult1.shouldSwing() && inputEvent.shouldSwingHand()) { + if (interactionresult1 instanceof InteractionResult.Success interactionresult$success) { +- if (interactionresult$success.swingSource() == InteractionResult.SwingSource.CLIENT) { ++ if (interactionresult$success.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) { this.player.swing(interactionhand); if (!itemstack.isEmpty() && (itemstack.getCount() != i || this.gameMode.hasInfiniteItems())) { this.gameRenderer.itemInHandRenderer.itemUsed(interactionhand); -@@ -1713,6 +_,9 @@ +@@ -1646,6 +_,9 @@ } } + if (itemstack.isEmpty() && (this.hitResult == null || this.hitResult.getType() == HitResult.Type.MISS)) + net.neoforged.neoforge.common.CommonHooks.onEmptyClick(this.player, interactionhand); + - if (!itemstack.isEmpty()) { - InteractionResult interactionresult2 = this.gameMode.useItem(this.player, interactionhand); - if (interactionresult2.consumesAction()) { -@@ -1735,6 +_,8 @@ + if (!itemstack.isEmpty() + && this.gameMode.useItem(this.player, interactionhand) instanceof InteractionResult.Success interactionresult$success1) { + if (interactionresult$success1.swingSource() == InteractionResult.SwingSource.CLIENT) { +@@ -1666,6 +_,8 @@ public void tick() { this.clientTickCount++; @@ -301,32 +294,32 @@ if (this.level != null && !this.pause) { this.level.tickRateManager().tick(); } -@@ -1826,6 +_,7 @@ +@@ -1764,6 +_,7 @@ this.tutorial.tick(); + net.neoforged.neoforge.event.EventHooks.fireLevelTickPre(this.level, () -> true); try { this.level.tick(() -> true); - } catch (Throwable throwable) { -@@ -1839,6 +_,7 @@ + } catch (Throwable throwable1) { +@@ -1777,6 +_,7 @@ - throw new ReportedException(crashreport); + throw new ReportedException(crashreport1); } + net.neoforged.neoforge.event.EventHooks.fireLevelTickPost(this.level, () -> true); } - this.profiler.popPush("animateTick"); -@@ -1858,6 +_,8 @@ - this.profiler.popPush("keyboard"); + profilerfiller.popPush("animateTick"); +@@ -1801,6 +_,8 @@ + profilerfiller.popPush("keyboard"); this.keyboardHandler.tick(); - this.profiler.pop(); + profilerfiller.pop(); + + net.neoforged.neoforge.client.ClientHooks.fireClientTickPost(); } private boolean isLevelRunningNormally() { -@@ -2056,7 +_,8 @@ +@@ -2000,7 +_,8 @@ } public void setLevel(ClientLevel p_91157_, ReceivingLevelScreen.Reason p_341652_) { @@ -336,7 +329,7 @@ this.level = p_91157_; this.updateLevelInEngines(p_91157_); if (!this.isLocalServer) { -@@ -2093,6 +_,7 @@ +@@ -2037,6 +_,7 @@ IntegratedServer integratedserver = this.singleplayerServer; this.singleplayerServer = null; this.gameRenderer.resetData(); @@ -344,15 +337,15 @@ this.gameMode = null; this.narrator.clear(); this.clientLevelTeardownInProgress = true; -@@ -2100,6 +_,7 @@ +@@ -2044,6 +_,7 @@ try { this.updateScreenAndTick(p_320248_); if (this.level != null) { + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.LevelEvent.Unload(this.level)); if (integratedserver != null) { - this.profiler.push("waitForServer"); - -@@ -2258,6 +_,7 @@ + ProfilerFiller profilerfiller = Profiler.get(); + profilerfiller.push("waitForServer"); +@@ -2204,6 +_,7 @@ private void pickBlock() { if (this.hitResult != null && this.hitResult.getType() != HitResult.Type.MISS) { @@ -360,7 +353,7 @@ boolean flag = this.player.getAbilities().instabuild; BlockEntity blockentity = null; HitResult.Type hitresult$type = this.hitResult.getType(); -@@ -2270,7 +_,7 @@ +@@ -2216,7 +_,7 @@ } Block block = blockstate.getBlock(); @@ -369,7 +362,7 @@ if (itemstack.isEmpty()) { return; } -@@ -2284,7 +_,7 @@ +@@ -2230,7 +_,7 @@ } Entity entity = ((EntityHitResult)this.hitResult).getEntity(); @@ -378,7 +371,7 @@ if (itemstack == null) { return; } -@@ -2794,6 +_,10 @@ +@@ -2757,6 +_,10 @@ public void updateMaxMipLevel(int p_91313_) { this.modelManager.updateMaxMipLevel(p_91313_); diff --git a/patches/net/minecraft/client/MouseHandler.java.patch b/patches/net/minecraft/client/MouseHandler.java.patch index 01b53bd435..48d9f7cb68 100644 --- a/patches/net/minecraft/client/MouseHandler.java.patch +++ b/patches/net/minecraft/client/MouseHandler.java.patch @@ -1,42 +1,42 @@ --- a/net/minecraft/client/MouseHandler.java +++ b/net/minecraft/client/MouseHandler.java -@@ -79,6 +_,7 @@ +@@ -85,6 +_,7 @@ this.activeButton = -1; } + if (net.neoforged.neoforge.client.ClientHooks.onMouseButtonPre(p_91532_, p_91533_, p_91534_)) return; - boolean[] aboolean = new boolean[]{false}; if (this.minecraft.getOverlay() == null) { if (this.minecraft.screen == null) { -@@ -91,13 +_,21 @@ - Screen screen = this.minecraft.screen; - if (flag) { + if (!this.mouseGrabbed && flag) { +@@ -98,7 +_,12 @@ screen.afterMouseAction(); -- Screen.wrapScreenError( -- () -> aboolean[0] = screen.mouseClicked(d0, d1, i), "mouseClicked event handler", screen.getClass().getCanonicalName() -- ); -+ Screen.wrapScreenError(() -> { -+ aboolean[0] = net.neoforged.neoforge.client.ClientHooks.onScreenMouseClickedPre(screen, d0, d1, i); -+ if (!aboolean[0]) { -+ aboolean[0] = screen.mouseClicked(d0, d1, i); -+ aboolean[0] = net.neoforged.neoforge.client.ClientHooks.onScreenMouseClickedPost(screen, d0, d1, i, aboolean[0]); -+ } -+ }, "mouseClicked event handler", screen.getClass().getCanonicalName()); + + try { +- if (screen.mouseClicked(d0, d1, i)) { ++ boolean flag2; ++ if ( ++ net.neoforged.neoforge.client.ClientHooks.onScreenMouseClickedPre(screen, d0, d1, i) || ++ (flag2 = screen.mouseClicked(d0, d1, i)) | ++ net.neoforged.neoforge.client.ClientHooks.onScreenMouseClickedPost(screen, d0, d1, i, flag2) ++ ) { + return; + } + } catch (Throwable throwable1) { +@@ -112,7 +_,12 @@ + } } else { -- Screen.wrapScreenError( -- () -> aboolean[0] = screen.mouseReleased(d0, d1, i), "mouseReleased event handler", screen.getClass().getCanonicalName() -- ); -+ Screen.wrapScreenError(() -> { -+ aboolean[0] = net.neoforged.neoforge.client.ClientHooks.onScreenMouseReleasedPre(screen, d0, d1, i); -+ if (!aboolean[0]) { -+ aboolean[0] = screen.mouseReleased(d0, d1, i); -+ aboolean[0] = net.neoforged.neoforge.client.ClientHooks.onScreenMouseReleasedPost(screen, d0, d1, i, aboolean[0]); -+ } -+ }, "mouseReleased event handler", screen.getClass().getCanonicalName()); - } - } - } -@@ -120,6 +_,7 @@ + try { +- if (screen.mouseReleased(d0, d1, i)) { ++ boolean flag2; ++ if ( ++ net.neoforged.neoforge.client.ClientHooks.onScreenMouseReleasedPre(screen, d0, d1, i) || ++ (flag2 = screen.mouseReleased(d0, d1, i)) | ++ net.neoforged.neoforge.client.ClientHooks.onScreenMouseReleasedPost(screen, d0, d1, i, flag2) ++ ) { + return; + } + } catch (Throwable throwable) { +@@ -146,6 +_,7 @@ } } } @@ -44,7 +44,7 @@ } } -@@ -133,7 +_,11 @@ +@@ -160,7 +_,11 @@ if (this.minecraft.screen != null) { double d3 = this.xpos * (double)this.minecraft.getWindow().getGuiScaledWidth() / (double)this.minecraft.getWindow().getScreenWidth(); double d4 = this.ypos * (double)this.minecraft.getWindow().getGuiScaledHeight() / (double)this.minecraft.getWindow().getScreenHeight(); @@ -56,31 +56,29 @@ + } this.minecraft.screen.afterMouseAction(); } else if (this.minecraft.player != null) { - if (this.accumulatedScrollX != 0.0 && Math.signum(d1) != Math.signum(this.accumulatedScrollX)) { -@@ -155,6 +_,7 @@ - this.accumulatedScrollX -= (double)j; - this.accumulatedScrollY -= (double)i; - int k = i == 0 ? -j : i; + Vector2i vector2i = this.scrollWheelHandler.onMouseScroll(d1, d2); +@@ -169,6 +_,7 @@ + } + + int i = vector2i.y == 0 ? -vector2i.x : vector2i.y; + if (net.neoforged.neoforge.client.ClientHooks.onMouseScroll(this, d1, d2)) return; if (this.minecraft.player.isSpectator()) { if (this.minecraft.gui.getSpectatorGui().isMenuActive()) { - this.minecraft.gui.getSpectatorGui().onMouseScrolled(-k); -@@ -244,9 +_,11 @@ - double d5 = this.accumulatedDY - * (double)this.minecraft.getWindow().getGuiScaledHeight() + this.minecraft.gui.getSpectatorGui().onMouseScrolled(-i); +@@ -280,7 +_,11 @@ / (double)this.minecraft.getWindow().getScreenHeight(); -- Screen.wrapScreenError( -- () -> screen.mouseDragged(d2, d3, this.activeButton, d4, d5), "mouseDragged event handler", screen.getClass().getCanonicalName() -- ); -+ Screen.wrapScreenError(() -> { -+ if (net.neoforged.neoforge.client.ClientHooks.onScreenMouseDragPre(screen, d2, d3, this.activeButton, d4, d5)) return; -+ if (screen.mouseDragged(d2, d3, this.activeButton, d4, d5)) return; -+ net.neoforged.neoforge.client.ClientHooks.onScreenMouseDragPost(screen, d2, d3, this.activeButton, d4, d5); -+ }, "mouseDragged event handler", screen.getClass().getCanonicalName()); - } - screen.afterMouseMove(); -@@ -262,12 +_,13 @@ + try { +- screen.mouseDragged(d2, d3, this.activeButton, d4, d5); ++ if (!net.neoforged.neoforge.client.ClientHooks.onScreenMouseDragPre(screen, d2, d3, this.activeButton, d4, d5)) { ++ if (!screen.mouseDragged(d2, d3, this.activeButton, d4, d5)) { ++ net.neoforged.neoforge.client.ClientHooks.onScreenMouseDragPost(screen, d2, d3, this.activeButton, d4, d5); ++ } ++ } + } catch (Throwable throwable) { + CrashReport crashreport1 = CrashReport.forThrowable(throwable, "mouseDragged event handler"); + screen.fillCrashDetails(crashreport1); +@@ -304,12 +_,13 @@ } private void turnPlayer(double p_316356_) { @@ -96,7 +94,7 @@ double d5 = this.smoothTurnX.getNewDeltaValue(this.accumulatedDX * d4, p_316356_ * d4); double d6 = this.smoothTurnY.getNewDeltaValue(this.accumulatedDY * d4, p_316356_ * d4); d0 = d5; -@@ -313,6 +_,14 @@ +@@ -355,6 +_,14 @@ public double ypos() { return this.ypos; diff --git a/patches/net/minecraft/client/Options.java.patch b/patches/net/minecraft/client/Options.java.patch index 63cda73a1e..ba0680da72 100644 --- a/patches/net/minecraft/client/Options.java.patch +++ b/patches/net/minecraft/client/Options.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/Options.java +++ b/net/minecraft/client/Options.java -@@ -727,9 +_,10 @@ +@@ -746,9 +_,10 @@ } }, new OptionInstance.LazyEnum<>( @@ -12,7 +12,7 @@ && !Minecraft.getInstance().getSoundManager().getAvailableSoundDevices().contains(p_232011_) ? Optional.empty() : Optional.of(p_232011_), -@@ -799,7 +_,7 @@ +@@ -822,7 +_,7 @@ this.incompatibleResourcePacks.clear(); for (Pack pack : p_275268_.getSelectedPacks()) { @@ -21,7 +21,7 @@ this.resourcePacks.add(pack.getId()); if (!pack.getCompatibility().isCompatible()) { this.incompatibleResourcePacks.add(pack.getId()); -@@ -1099,6 +_,7 @@ +@@ -1130,6 +_,7 @@ } public Options(Minecraft p_92138_, File p_92139_) { @@ -29,7 +29,7 @@ this.minecraft = p_92138_; this.optionsFile = new File(p_92139_, "options.txt"); boolean flag = Runtime.getRuntime().maxMemory() >= 1000000000L; -@@ -1236,11 +_,21 @@ +@@ -1264,11 +_,21 @@ this.onboardAccessibility = p_168428_.process("onboardAccessibility", this.onboardAccessibility); p_168428_.process("menuBackgroundBlurriness", this.menuBackgroundBlurriness); @@ -53,7 +53,7 @@ } } -@@ -1258,6 +_,9 @@ +@@ -1286,6 +_,9 @@ } public void load() { @@ -63,7 +63,7 @@ try { if (!this.optionsFile.exists()) { return; -@@ -1285,7 +_,8 @@ +@@ -1313,7 +_,8 @@ } } @@ -73,7 +73,7 @@ new Options.FieldAccess() { @Nullable private String getValueOrNull(String p_168459_) { -@@ -1460,6 +_,7 @@ +@@ -1484,6 +_,7 @@ } public ClientInformation buildPlayerInformation() { @@ -81,7 +81,7 @@ int i = 0; for (PlayerModelPart playermodelpart : this.modelParts) { -@@ -1535,6 +_,23 @@ +@@ -1555,6 +_,23 @@ } p_92146_.setSelected(set); diff --git a/patches/net/minecraft/client/RecipeBookCategories.java.patch b/patches/net/minecraft/client/RecipeBookCategories.java.patch deleted file mode 100644 index 71ddc27bf7..0000000000 --- a/patches/net/minecraft/client/RecipeBookCategories.java.patch +++ /dev/null @@ -1,59 +0,0 @@ ---- a/net/minecraft/client/RecipeBookCategories.java -+++ b/net/minecraft/client/RecipeBookCategories.java -@@ -12,7 +_,7 @@ - import net.neoforged.api.distmarker.OnlyIn; - - @OnlyIn(Dist.CLIENT) --public enum RecipeBookCategories { -+public enum RecipeBookCategories implements net.neoforged.fml.common.asm.enumextension.IExtensibleEnum { - CRAFTING_SEARCH(new ItemStack(Items.COMPASS)), - CRAFTING_BUILDING_BLOCKS(new ItemStack(Blocks.BRICKS)), - CRAFTING_REDSTONE(new ItemStack(Items.REDSTONE)), -@@ -38,20 +_,20 @@ - public static final List CRAFTING_CATEGORIES = ImmutableList.of( - CRAFTING_SEARCH, CRAFTING_EQUIPMENT, CRAFTING_BUILDING_BLOCKS, CRAFTING_MISC, CRAFTING_REDSTONE - ); -- public static final Map> AGGREGATE_CATEGORIES = ImmutableMap.of( -- CRAFTING_SEARCH, -- ImmutableList.of(CRAFTING_EQUIPMENT, CRAFTING_BUILDING_BLOCKS, CRAFTING_MISC, CRAFTING_REDSTONE), -- FURNACE_SEARCH, -- ImmutableList.of(FURNACE_FOOD, FURNACE_BLOCKS, FURNACE_MISC), -- BLAST_FURNACE_SEARCH, -- ImmutableList.of(BLAST_FURNACE_BLOCKS, BLAST_FURNACE_MISC), -- SMOKER_SEARCH, -- ImmutableList.of(SMOKER_FOOD) -- ); -+ public static final Map> AGGREGATE_CATEGORIES = net.neoforged.neoforge.client.RecipeBookManager.getAggregateCategories(); -+ @Deprecated // Neo: Empty for custom categories. Use the getter. - private final List itemIcons; -+ private final java.util.function.Supplier> itemIconsSupplier; - -+ @net.neoforged.fml.common.asm.enumextension.ReservedConstructor - private RecipeBookCategories(ItemStack... p_92267_) { - this.itemIcons = ImmutableList.copyOf(p_92267_); -+ this.itemIconsSupplier = () -> this.itemIcons; -+ } -+ -+ private RecipeBookCategories(java.util.function.Supplier> itemIconsSupplier) { -+ this.itemIcons = List.of(); -+ this.itemIconsSupplier = net.neoforged.neoforge.common.util.Lazy.of(itemIconsSupplier); - } - - public static List getCategories(RecipeBookType p_92270_) { -@@ -60,10 +_,15 @@ - case FURNACE -> FURNACE_CATEGORIES; - case BLAST_FURNACE -> BLAST_FURNACE_CATEGORIES; - case SMOKER -> SMOKER_CATEGORIES; -+ default -> net.neoforged.neoforge.client.RecipeBookManager.getCustomCategoriesOrEmpty(p_92270_); - }; - } - - public List getIconItems() { -- return this.itemIcons; -+ return this.itemIconsSupplier.get(); -+ } -+ -+ public static net.neoforged.fml.common.asm.enumextension.ExtensionInfo getExtensionInfo() { -+ return net.neoforged.fml.common.asm.enumextension.ExtensionInfo.nonExtended(RecipeBookCategories.class); - } - } diff --git a/patches/net/minecraft/client/color/item/ItemColors.java.patch b/patches/net/minecraft/client/color/item/ItemColors.java.patch index 491886484d..afe4aac398 100644 --- a/patches/net/minecraft/client/color/item/ItemColors.java.patch +++ b/patches/net/minecraft/client/color/item/ItemColors.java.patch @@ -10,8 +10,8 @@ public static ItemColors createDefault(BlockColors p_92684_) { ItemColors itemcolors = new ItemColors(); -@@ -105,17 +_,20 @@ - : FastColor.ARGB32.opaque(p_329710_.getOrDefault(DataComponents.MAP_COLOR, MapItemColor.DEFAULT).rgb()), +@@ -101,17 +_,20 @@ + (p_359075_, p_359076_) -> p_359076_ == 0 ? -1 : ARGB.opaque(p_359075_.getOrDefault(DataComponents.MAP_COLOR, MapItemColor.DEFAULT).rgb()), Items.FILLED_MAP ); + net.neoforged.neoforge.client.ClientHooks.onItemColorsInit(itemcolors, p_92684_); diff --git a/patches/net/minecraft/client/gui/Font.java.patch b/patches/net/minecraft/client/gui/Font.java.patch index 57718aa4e8..92bc34f85a 100644 --- a/patches/net/minecraft/client/gui/Font.java.patch +++ b/patches/net/minecraft/client/gui/Font.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/Font.java +++ b/net/minecraft/client/gui/Font.java -@@ -31,7 +_,7 @@ +@@ -33,7 +_,7 @@ import org.joml.Vector3f; @OnlyIn(Dist.CLIENT) @@ -9,7 +9,7 @@ private static final float EFFECT_DEPTH = 0.01F; private static final Vector3f SHADOW_OFFSET = new Vector3f(0.0F, 0.0F, 0.03F); public static final int ALPHA_CUTOFF = 8; -@@ -326,6 +_,8 @@ +@@ -309,6 +_,8 @@ public StringSplitter getSplitter() { return this.splitter; } diff --git a/patches/net/minecraft/client/gui/Gui.java.patch b/patches/net/minecraft/client/gui/Gui.java.patch index dc1055a582..57ea34601f 100644 --- a/patches/net/minecraft/client/gui/Gui.java.patch +++ b/patches/net/minecraft/client/gui/Gui.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/Gui.java +++ b/net/minecraft/client/gui/Gui.java -@@ -69,6 +_,9 @@ +@@ -71,6 +_,9 @@ import net.neoforged.api.distmarker.OnlyIn; import org.joml.Matrix4fStack; @@ -10,8 +10,8 @@ @OnlyIn(Dist.CLIENT) public class Gui { private static final ResourceLocation CROSSHAIR_SPRITE = ResourceLocation.withDefaultNamespace("hud/crosshair"); -@@ -158,9 +_,21 @@ - private long healthBlinkTime; +@@ -175,9 +_,21 @@ + private int lastBubblePopSoundPlayed; private float autosaveIndicatorValue; private float lastAutosaveIndicatorValue; + /** Neo: This is empty and unused, rendering goes through {@link #layerManager} instead. */ @@ -32,7 +32,7 @@ public Gui(Minecraft p_232355_) { this.minecraft = p_232355_; this.debugOverlay = new DebugScreenOverlay(p_232355_); -@@ -170,27 +_,40 @@ +@@ -187,27 +_,40 @@ this.bossOverlay = new BossHealthOverlay(p_232355_); this.subtitleOverlay = new SubtitleOverlay(p_232355_); this.resetTitleTimes(); @@ -90,18 +90,18 @@ } public void resetTitleTimes() { -@@ -201,7 +_,9 @@ +@@ -217,7 +_,9 @@ + } public void render(GuiGraphics p_282884_, DeltaTracker p_348630_) { - RenderSystem.enableDepthTest(); - this.layers.render(p_282884_, p_348630_); + leftHeight = 39; + rightHeight = 39; + this.layerManager.render(p_282884_, p_348630_); - RenderSystem.disableDepthTest(); } -@@ -262,8 +_,12 @@ + private void renderCameraOverlays(GuiGraphics p_316735_, DeltaTracker p_348538_) { +@@ -289,8 +_,12 @@ } if (i > 8) { @@ -115,7 +115,7 @@ int j; if (this.animateOverlayMessageColor) { j = Mth.hsvToArgb(f / 50.0F, 0.7F, 0.6F, i); -@@ -323,9 +_,19 @@ +@@ -350,9 +_,19 @@ private void renderChat(GuiGraphics p_316307_, DeltaTracker p_348631_) { if (!this.chat.isChatFocused()) { Window window = this.minecraft.getWindow(); @@ -135,7 +135,7 @@ } } -@@ -441,6 +_,8 @@ +@@ -449,6 +_,8 @@ List list = Lists.newArrayListWithExpectedSize(collection.size()); for (MobEffectInstance mobeffectinstance : Ordering.natural().reverse().sortedCopy(collection)) { @@ -143,16 +143,16 @@ + if (!renderer.isVisibleInGui(mobeffectinstance)) continue; Holder holder = mobeffectinstance.getEffect(); if (mobeffectinstance.showIcon()) { - int i = p_282812_.guiWidth(); -@@ -471,6 +_,7 @@ + int k = p_282812_.guiWidth(); +@@ -480,6 +_,7 @@ } } -+ if (renderer.renderGuiIcon(mobeffectinstance, this, p_282812_, i, j, 0, f)) continue; ++ if (renderer.renderGuiIcon(mobeffectinstance, this, p_282812_, k, l, 0, f)) continue; TextureAtlasSprite textureatlassprite = mobeffecttexturemanager.get(holder); - int l1 = i; - int i1 = j; -@@ -488,29 +_,59 @@ + int l1 = k; + int k1 = l; +@@ -495,29 +_,59 @@ } } @@ -215,7 +215,7 @@ this.spectatorGui.renderTooltip(p_316628_); } } -@@ -633,18 +_,23 @@ +@@ -632,18 +_,23 @@ } private void renderSelectedItemName(GuiGraphics p_283501_) { @@ -223,7 +223,7 @@ + } + + public void renderSelectedItemName(GuiGraphics p_283501_, int yShift) { - this.minecraft.getProfiler().push("selectedItemName"); + Profiler.get().push("selectedItemName"); if (this.toolHighlightTimer > 0 && !this.lastToolHighlight.isEmpty()) { MutableComponent mutablecomponent = Component.empty() .append(this.lastToolHighlight.getHoverName()) @@ -242,31 +242,31 @@ if (!this.minecraft.gameMode.canHurtPlayer()) { k += 14; } -@@ -655,7 +_,13 @@ +@@ -654,7 +_,13 @@ } if (l > 0) { -- p_283501_.drawStringWithBackdrop(this.getFont(), mutablecomponent, j, k, i, FastColor.ARGB32.color(l, -1)); +- p_283501_.drawStringWithBackdrop(this.getFont(), mutablecomponent, j, k, i, ARGB.color(l, -1)); + Font font = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(lastToolHighlight).getFont(lastToolHighlight, net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.FontContext.SELECTED_ITEM_NAME); + if (font == null) { -+ p_283501_.drawStringWithBackdrop(this.getFont(), highlightTip, j, k, i, FastColor.ARGB32.color(l, -1)); ++ p_283501_.drawStringWithBackdrop(this.getFont(), highlightTip, j, k, i, ARGB.color(l, -1)); + } else { + j = (p_283501_.guiWidth() - font.width(highlightTip)) / 2; -+ p_283501_.drawStringWithBackdrop(font, highlightTip, j, k, i, FastColor.ARGB32.color(l, -1)); ++ p_283501_.drawStringWithBackdrop(font, highlightTip, j, k, i, ARGB.color(l, -1)); + } } } -@@ -663,7 +_,7 @@ +@@ -662,7 +_,7 @@ } private void renderDemoOverlay(GuiGraphics p_281825_, DeltaTracker p_348679_) { - if (this.minecraft.isDemo()) { + if (this.minecraft.isDemo() && !this.getDebugOverlay().showDebugScreen()) { // Neo: Hide demo timer when F3 debug overlay is open; fixes MC-271166 - this.minecraft.getProfiler().push("demo"); + Profiler.get().push("demo"); Component component; if (this.minecraft.level.getGameTime() >= 120500L) { -@@ -778,7 +_,15 @@ +@@ -774,7 +_,15 @@ return (int)Math.ceil((double)p_93013_ / 10.0); } @@ -282,7 +282,7 @@ Player player = this.getCameraPlayer(); if (player != null) { int i = Mth.ceil(player.getHealth()); -@@ -803,35 +_,62 @@ +@@ -798,31 +_,59 @@ this.random.setSeed((long)(this.tickCount * 312871)); int l = p_283143_.guiWidth() / 2 - 91; int i1 = p_283143_.guiWidth() / 2 + 91; @@ -299,12 +299,12 @@ k2 = this.tickCount % Mth.ceil(f + 5.0F); } - -- this.minecraft.getProfiler().push("armor"); +- Profiler.get().push("armor"); - renderArmor(p_283143_, player, j1, l1, i2, l); -- this.minecraft.getProfiler().popPush("health"); -+ this.minecraft.getProfiler().push("health"); +- Profiler.get().popPush("health"); ++ Profiler.get().push("health"); this.renderHearts(p_283143_, player, l, j1, i2, k2, f, i, k, k1, flag); -+ this.minecraft.getProfiler().pop(); ++ Profiler.get().pop(); + } + } + @@ -312,9 +312,9 @@ + Player player = this.getCameraPlayer(); + if (player != null) { + int l = p_283143_.guiWidth() / 2 - 91; -+ this.minecraft.getProfiler().push("armor"); ++ Profiler.get().push("armor"); + renderArmor(p_283143_, player, p_283143_.guiHeight() - leftHeight + 10, 1, 0, l); -+ this.minecraft.getProfiler().pop(); ++ Profiler.get().pop(); + if (player.getArmorValue() > 0) { + leftHeight += 10; + } @@ -327,61 +327,57 @@ LivingEntity livingentity = this.getPlayerVehicleWithHealth(); int l2 = this.getVehicleMaxHearts(livingentity); if (l2 == 0) { -- this.minecraft.getProfiler().popPush("food"); -+ this.minecraft.getProfiler().push("food"); +- Profiler.get().popPush("food"); ++ Profiler.get().push("food"); + int i1 = p_283143_.guiWidth() / 2 + 91; + int j1 = p_283143_.guiHeight() - rightHeight; this.renderFood(p_283143_, player, j1, i1); - j2 -= 10; + rightHeight += 10; -+ this.minecraft.getProfiler().pop(); ++ Profiler.get().pop(); } -- -- this.minecraft.getProfiler().popPush("air"); + } + } -+ + +- Profiler.get().popPush("air"); +- this.renderAirBubbles(p_283143_, player, l2, j2, i1); + private void renderAirLevel(GuiGraphics p_283143_) { + Player player = this.getCameraPlayer(); + if (player != null) { + int i1 = p_283143_.guiWidth() / 2 + 91; -+ -+ this.minecraft.getProfiler().push("air"); - int i3 = player.getMaxAirSupply(); - int j3 = Math.min(player.getAirSupply(), i3); - if (player.isEyeInFluid(FluidTags.WATER) || j3 < i3) { -- int k3 = this.getVisibleVehicleHeartRows(l2) - 1; -- j2 -= k3 * 10; -+ int j2 = p_283143_.guiHeight() - rightHeight; - int l3 = Mth.ceil((double)(j3 - 2) * 10.0 / (double)i3); - int i4 = Mth.ceil((double)j3 * 10.0 / (double)i3) - l3; - RenderSystem.enableBlend(); -@@ -845,6 +_,7 @@ ++ int j2 = p_283143_.guiHeight() - rightHeight; ++ Profiler.get().push("air"); ++ this.renderAirBubbles(p_283143_, player, 10, j2, i1); + Profiler.get().pop(); + } + } +@@ -936,6 +_,8 @@ + p_381066_.blitSprite(RenderType::guiTextured, AIR_EMPTY_SPRITE, k1, p_381100_ + l1, 9, 9); } - - RenderSystem.disableBlend(); -+ rightHeight += 10; } ++ ++ rightHeight += 10; + } + } - this.minecraft.getProfiler().pop(); -@@ -984,7 +_,7 @@ +@@ -1003,7 +_,7 @@ if (i != 0) { int j = (int)Math.ceil((double)livingentity.getHealth()); - this.minecraft.getProfiler().popPush("mountHealth"); + Profiler.get().popPush("mountHealth"); - int k = p_283368_.guiHeight() - 39; + int k = p_283368_.guiHeight() - rightHeight; int l = p_283368_.guiWidth() / 2 + 91; int i1 = k; - int j1 = 0; -@@ -1007,6 +_,7 @@ + +@@ -1024,6 +_,7 @@ } i1 -= 10; + rightHeight += 10; - j1 += 20; } - -@@ -1163,7 +_,7 @@ + } + } +@@ -1190,7 +_,7 @@ this.toolHighlightTimer = 0; } else if (this.lastToolHighlight.isEmpty() || !itemstack.is(this.lastToolHighlight.getItem()) @@ -390,7 +386,7 @@ this.toolHighlightTimer = (int)(40.0 * this.minecraft.options.notificationDisplayTime().get()); } else if (this.toolHighlightTimer > 0) { this.toolHighlightTimer--; -@@ -1292,8 +_,17 @@ +@@ -1319,8 +_,17 @@ } } @@ -409,7 +405,7 @@ CONTAINER( ResourceLocation.withDefaultNamespace("hud/heart/container"), ResourceLocation.withDefaultNamespace("hud/heart/container_blinking"), -@@ -1409,8 +_,13 @@ +@@ -1436,8 +_,13 @@ } else { gui$hearttype = NORMAL; } diff --git a/patches/net/minecraft/client/gui/GuiGraphics.java.patch b/patches/net/minecraft/client/gui/GuiGraphics.java.patch index 9ce42c48e9..60a00e141e 100644 --- a/patches/net/minecraft/client/gui/GuiGraphics.java.patch +++ b/patches/net/minecraft/client/gui/GuiGraphics.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/GuiGraphics.java +++ b/net/minecraft/client/gui/GuiGraphics.java -@@ -56,7 +_,7 @@ +@@ -53,7 +_,7 @@ import org.joml.Vector2ic; @OnlyIn(Dist.CLIENT) @@ -9,7 +9,7 @@ public static final float MAX_GUI_Z = 10000.0F; public static final float MIN_GUI_Z = -10000.0F; private static final int EXTRA_SPACE_AFTER_FIRST_TOOLTIP_LINE = 2; -@@ -268,6 +_,11 @@ +@@ -227,6 +_,11 @@ } public int drawString(Font p_283343_, @Nullable String p_281896_, int p_283569_, int p_283418_, int p_281560_, boolean p_282130_) { @@ -18,10 +18,10 @@ + + // Forge: Add float variant for x,y coordinates, with a string as input + public int drawString(Font p_283343_, @Nullable String p_281896_, float p_283569_, float p_283418_, int p_281560_, boolean p_282130_) { - if (p_281896_ == null) { - return 0; - } else { -@@ -294,6 +_,11 @@ + return p_281896_ == null + ? 0 + : p_283343_.drawInBatch( +@@ -248,6 +_,11 @@ } public int drawString(Font p_282636_, FormattedCharSequence p_281596_, int p_281586_, int p_282816_, int p_281743_, boolean p_282394_) { @@ -30,13 +30,14 @@ + + // Forge: Add float variant for x,y coordinates, with a formatted char sequence as input + public int drawString(Font p_282636_, FormattedCharSequence p_281596_, float p_281586_, float p_282816_, int p_281743_, boolean p_282394_) { - int i = p_282636_.drawInBatch( + return p_282636_.drawInBatch( p_281596_, (float)p_281586_, -@@ -873,19 +_,26 @@ - } - +@@ -870,10 +_,15 @@ + this.renderItemCount(p_282005_, p_283349_, p_282641_, p_282146_, p_282803_); + this.renderItemCooldown(p_283349_, p_282641_, p_282146_); this.pose.popPose(); ++ // TODO 1.21.2: This probably belongs in one of the sub-methods. + net.neoforged.neoforge.client.ItemDecoratorHandler.of(p_283349_).render(this, p_282005_, p_283349_, p_282641_, p_282146_); } } @@ -45,56 +46,93 @@ public void renderTooltip(Font p_282308_, ItemStack p_282781_, int p_282687_, int p_282292_) { + this.tooltipStack = p_282781_; - this.renderTooltip(p_282308_, Screen.getTooltipFromItem(this.minecraft, p_282781_), p_282781_.getTooltipImage(), p_282687_, p_282292_); + this.renderTooltip( + p_282308_, + Screen.getTooltipFromItem(this.minecraft, p_282781_), +@@ -882,6 +_,17 @@ + p_282292_, + p_282781_.get(DataComponents.TOOLTIP_STYLE) + ); + this.tooltipStack = ItemStack.EMPTY; + } + + public void renderTooltip(Font font, List textComponents, Optional tooltipComponent, ItemStack stack, int mouseX, int mouseY) { ++ renderTooltip(font, textComponents, tooltipComponent, stack, mouseX, mouseY, null); ++ } ++ ++ public void renderTooltip(Font font, List textComponents, Optional tooltipComponent, ItemStack stack, int mouseX, int mouseY, @Nullable ResourceLocation backgroundTexture) { + this.tooltipStack = stack; -+ this.renderTooltip(font, textComponents, tooltipComponent, mouseX, mouseY); ++ this.renderTooltip(font, textComponents, tooltipComponent, mouseX, mouseY, backgroundTexture); + this.tooltipStack = ItemStack.EMPTY; } public void renderTooltip(Font p_283128_, List p_282716_, Optional p_281682_, int p_283678_, int p_281696_) { -- List list = p_282716_.stream() +@@ -891,11 +_,7 @@ + public void renderTooltip( + Font p_371715_, List p_371741_, Optional p_371604_, int p_371500_, int p_371755_, @Nullable ResourceLocation p_371766_ + ) { +- List list = p_371741_.stream() - .map(Component::getVisualOrderText) - .map(ClientTooltipComponent::create) - .collect(Util.toMutableList()); -- p_281682_.ifPresent(p_337410_ -> list.add(list.isEmpty() ? 0 : 1, ClientTooltipComponent.create(p_337410_))); -+ List list = net.neoforged.neoforge.client.ClientHooks.gatherTooltipComponents(this.tooltipStack, p_282716_, p_281682_, p_283678_, guiWidth(), guiHeight(), p_283128_); - this.renderTooltipInternal(p_283128_, list, p_283678_, p_281696_, DefaultTooltipPositioner.INSTANCE); +- p_371604_.ifPresent(p_337410_ -> list.add(list.isEmpty() ? 0 : 1, ClientTooltipComponent.create(p_337410_))); ++ List list = net.neoforged.neoforge.client.ClientHooks.gatherTooltipComponents(this.tooltipStack, p_371741_, p_371604_, p_371500_, guiWidth(), guiHeight(), p_371715_); + this.renderTooltipInternal(p_371715_, list, p_371500_, p_371755_, DefaultTooltipPositioner.INSTANCE, p_371766_); } -@@ -894,7 +_,22 @@ +@@ -908,13 +_,14 @@ } public void renderComponentTooltip(Font p_282739_, List p_281832_, int p_282191_, int p_282446_) { -- this.renderTooltip(p_282739_, Lists.transform(p_281832_, Component::getVisualOrderText), p_282191_, p_282446_); -+ List components = net.neoforged.neoforge.client.ClientHooks.gatherTooltipComponents(this.tooltipStack, p_281832_, p_282191_, guiWidth(), guiHeight(), p_282739_); -+ this.renderTooltipInternal(p_282739_, components, p_282191_, p_282446_, DefaultTooltipPositioner.INSTANCE); +- this.renderComponentTooltip(p_282739_, p_281832_, p_282191_, p_282446_, null); ++ this.renderComponentTooltip(p_282739_, p_281832_, p_282191_, p_282446_, (ResourceLocation) null); + } + + public void renderComponentTooltip(Font p_371677_, List p_371519_, int p_371314_, int p_371389_, @Nullable ResourceLocation p_371458_) { ++ List components = net.neoforged.neoforge.client.ClientHooks.gatherTooltipComponents(this.tooltipStack, p_371519_, p_371314_, guiWidth(), guiHeight(), p_371677_); + this.renderTooltipInternal( + p_371677_, +- p_371519_.stream().map(Component::getVisualOrderText).map(ClientTooltipComponent::create).toList(), ++ components, + p_371314_, + p_371389_, + DefaultTooltipPositioner.INSTANCE, +@@ -922,6 +_,28 @@ + ); + } + ++ public void renderComponentTooltip(Font font, List tooltips, int mouseX, int mouseY, ItemStack stack) { ++ renderComponentTooltip(font, tooltips, mouseX, mouseY, stack, null); + } + -+ public void renderComponentTooltip(Font font, List tooltips, int mouseX, int mouseY, ItemStack stack) { ++ public void renderComponentTooltip(Font font, List tooltips, int mouseX, int mouseY, ItemStack stack, @Nullable ResourceLocation backgroundTexture) { + this.tooltipStack = stack; + List components = net.neoforged.neoforge.client.ClientHooks.gatherTooltipComponents(stack, tooltips, mouseX, guiWidth(), guiHeight(), font); -+ this.renderTooltipInternal(font, components, mouseX, mouseY, DefaultTooltipPositioner.INSTANCE); ++ this.renderTooltipInternal(font, components, mouseX, mouseY, DefaultTooltipPositioner.INSTANCE, backgroundTexture); + this.tooltipStack = ItemStack.EMPTY; + } + + public void renderComponentTooltipFromElements(Font font, List> elements, int mouseX, int mouseY, ItemStack stack) { ++ renderComponentTooltipFromElements(font, elements, mouseX, mouseY, stack, null); ++ } ++ ++ public void renderComponentTooltipFromElements(Font font, List> elements, int mouseX, int mouseY, ItemStack stack, @Nullable ResourceLocation backgroundTexture) { + this.tooltipStack = stack; + List components = net.neoforged.neoforge.client.ClientHooks.gatherTooltipComponentsFromElements(stack, elements, mouseX, guiWidth(), guiHeight(), font); -+ this.renderTooltipInternal(font, components, mouseX, mouseY, DefaultTooltipPositioner.INSTANCE); ++ this.renderTooltipInternal(font, components, mouseX, mouseY, DefaultTooltipPositioner.INSTANCE, backgroundTexture); + this.tooltipStack = ItemStack.EMPTY; - } - ++ } ++ public void renderTooltip(Font p_282192_, List p_282297_, int p_281680_, int p_283325_) { -@@ -915,11 +_,13 @@ - - private void renderTooltipInternal(Font p_282675_, List p_282615_, int p_283230_, int p_283417_, ClientTooltipPositioner p_282442_) { + this.renderTooltip(p_282192_, p_282297_, p_281680_, p_283325_, null); + } +@@ -954,41 +_,45 @@ + @Nullable ResourceLocation p_371327_ + ) { if (!p_282615_.isEmpty()) { + net.neoforged.neoforge.client.event.RenderTooltipEvent.Pre preEvent = net.neoforged.neoforge.client.ClientHooks.onRenderTooltipPre(this.tooltipStack, this, p_283230_, p_283417_, guiWidth(), guiHeight(), p_282615_, p_282675_, p_282442_); + if (preEvent.isCanceled()) return; ++ int i = 0; int j = p_282615_.size() == 1 ? -2 : 0; @@ -104,35 +142,40 @@ if (k > i) { i = k; } -@@ -929,18 +_,19 @@ + +- j += clienttooltipcomponent.getHeight(p_282675_); ++ j += clienttooltipcomponent.getHeight(preEvent.getFont()); + } int i2 = i; int j2 = j; -- Vector2ic vector2ic = p_282442_.positionTooltip(this.guiWidth(), this.guiHeight(), p_283230_, p_283417_, i2, j2); +- Vector2ic vector2ic = p_282442_.positionTooltip(this.guiWidth(), this.guiHeight(), p_283230_, p_283417_, i, j); + Vector2ic vector2ic = p_282442_.positionTooltip(this.guiWidth(), this.guiHeight(), preEvent.getX(), preEvent.getY(), i2, j2); int l = vector2ic.x(); int i1 = vector2ic.y(); this.pose.pushPose(); int j1 = 400; -- this.drawManaged(() -> TooltipRenderUtil.renderTooltipBackground(this, l, i1, i2, j2, 400)); + net.neoforged.neoforge.client.event.RenderTooltipEvent.Color colorEvent = net.neoforged.neoforge.client.ClientHooks.onRenderTooltipColor(this.tooltipStack, this, l, i1, preEvent.getFont(), p_282615_); -+ this.drawManaged(() -> TooltipRenderUtil.renderTooltipBackground(this, l, i1, i2, j2, 400, colorEvent.getBackgroundStart(), colorEvent.getBackgroundEnd(), colorEvent.getBorderStart(), colorEvent.getBorderEnd())); + TooltipRenderUtil.renderTooltipBackground(this, l, i1, i, j, 400, p_371327_); this.pose.translate(0.0F, 0.0F, 400.0F); int k1 = i1; for (int l1 = 0; l1 < p_282615_.size(); l1++) { ClientTooltipComponent clienttooltipcomponent1 = p_282615_.get(l1); - clienttooltipcomponent1.renderText(p_282675_, l, k1, this.pose.last().pose(), this.bufferSource); +- k1 += clienttooltipcomponent1.getHeight(p_282675_) + (l1 == 0 ? 2 : 0); + clienttooltipcomponent1.renderText(preEvent.getFont(), l, k1, this.pose.last().pose(), this.bufferSource); - k1 += clienttooltipcomponent1.getHeight() + (l1 == 0 ? 2 : 0); ++ k1 += clienttooltipcomponent1.getHeight(preEvent.getFont()) + (l1 == 0 ? 2 : 0); } -@@ -948,7 +_,7 @@ + k1 = i1; for (int k2 = 0; k2 < p_282615_.size(); k2++) { ClientTooltipComponent clienttooltipcomponent2 = p_282615_.get(k2); -- clienttooltipcomponent2.renderImage(p_282675_, l, k1, this); -+ clienttooltipcomponent2.renderImage(preEvent.getFont(), l, k1, this); - k1 += clienttooltipcomponent2.getHeight() + (k2 == 0 ? 2 : 0); +- clienttooltipcomponent2.renderImage(p_282675_, l, k1, i2, j2, this); +- k1 += clienttooltipcomponent2.getHeight(p_282675_) + (k2 == 0 ? 2 : 0); ++ clienttooltipcomponent2.renderImage(preEvent.getFont(), l, k1, i2, j2, this); ++ k1 += clienttooltipcomponent2.getHeight(preEvent.getFont()) + (k2 == 0 ? 2 : 0); } + this.pose.popPose(); diff --git a/patches/net/minecraft/client/gui/MapRenderer.java.patch b/patches/net/minecraft/client/gui/MapRenderer.java.patch deleted file mode 100644 index 756bcda934..0000000000 --- a/patches/net/minecraft/client/gui/MapRenderer.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/net/minecraft/client/gui/MapRenderer.java -+++ b/net/minecraft/client/gui/MapRenderer.java -@@ -122,6 +_,10 @@ - - for (MapDecoration mapdecoration : this.data.getDecorations()) { - if (!p_93294_ || mapdecoration.renderOnFrame()) { -+ if (net.neoforged.neoforge.client.gui.map.MapDecorationRendererManager.render(mapdecoration, p_93292_, p_93293_, data, MapRenderer.this.decorationTextures, p_93294_, p_93295_, k)) { -+ k++; -+ continue; -+ } - p_93292_.pushPose(); - p_93292_.translate(0.0F + (float)mapdecoration.x() / 2.0F + 64.0F, 0.0F + (float)mapdecoration.y() / 2.0F + 64.0F, -0.02F); - p_93292_.mulPose(Axis.ZP.rotationDegrees((float)(mapdecoration.rot() * 360) / 16.0F)); diff --git a/patches/net/minecraft/client/gui/components/AbstractButton.java.patch b/patches/net/minecraft/client/gui/components/AbstractButton.java.patch index 5d141a2e4f..56d0a21b54 100644 --- a/patches/net/minecraft/client/gui/components/AbstractButton.java.patch +++ b/patches/net/minecraft/client/gui/components/AbstractButton.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/client/gui/components/AbstractButton.java +++ b/net/minecraft/client/gui/components/AbstractButton.java -@@ -34,7 +_,7 @@ - RenderSystem.enableDepthTest(); - p_281670_.blitSprite(SPRITES.get(this.active, this.isHoveredOrFocused()), this.getX(), this.getY(), this.getWidth(), this.getHeight()); - p_281670_.setColor(1.0F, 1.0F, 1.0F, 1.0F); +@@ -39,7 +_,7 @@ + this.getHeight(), + ARGB.white(this.alpha) + ); - int i = this.active ? 16777215 : 10526880; + int i = getFGColor(); this.renderString(p_281670_, minecraft.font, i | Mth.ceil(this.alpha * 255.0F) << 24); diff --git a/patches/net/minecraft/client/gui/components/AbstractWidget.java.patch b/patches/net/minecraft/client/gui/components/AbstractWidget.java.patch index 0f5ac718d8..256cef46f4 100644 --- a/patches/net/minecraft/client/gui/components/AbstractWidget.java.patch +++ b/patches/net/minecraft/client/gui/components/AbstractWidget.java.patch @@ -27,7 +27,7 @@ return true; } } -@@ -253,6 +_,19 @@ +@@ -257,6 +_,19 @@ @Override public void setFocused(boolean p_93693_) { this.focused = p_93693_; diff --git a/patches/net/minecraft/client/gui/components/BossHealthOverlay.java.patch b/patches/net/minecraft/client/gui/components/BossHealthOverlay.java.patch index 4bc398fffe..2e911a86df 100644 --- a/patches/net/minecraft/client/gui/components/BossHealthOverlay.java.patch +++ b/patches/net/minecraft/client/gui/components/BossHealthOverlay.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/components/BossHealthOverlay.java +++ b/net/minecraft/client/gui/components/BossHealthOverlay.java -@@ -63,13 +_,16 @@ +@@ -66,13 +_,16 @@ for (LerpingBossEvent lerpingbossevent : this.events.values()) { int k = i / 2 - 91; diff --git a/patches/net/minecraft/client/gui/components/DebugScreenOverlay.java.patch b/patches/net/minecraft/client/gui/components/DebugScreenOverlay.java.patch index d47bc31435..3b4f7e321d 100644 --- a/patches/net/minecraft/client/gui/components/DebugScreenOverlay.java.patch +++ b/patches/net/minecraft/client/gui/components/DebugScreenOverlay.java.patch @@ -1,25 +1,24 @@ --- a/net/minecraft/client/gui/components/DebugScreenOverlay.java +++ b/net/minecraft/client/gui/components/DebugScreenOverlay.java -@@ -135,8 +_,15 @@ +@@ -141,8 +_,14 @@ + Entity entity = this.minecraft.getCameraEntity(); this.block = entity.pick(20.0, 0.0F, false); this.liquid = entity.pick(20.0, 0.0F, true); - p_281427_.drawManaged(() -> { -- this.drawGameInformation(p_281427_); -- this.drawSystemInformation(p_281427_); -+ final List gameInformation = this.collectGameInformationText(); -+ final List systemInformation = this.collectSystemInformationText(); +- this.drawGameInformation(p_281427_); +- this.drawSystemInformation(p_281427_); + -+ var event = new net.neoforged.neoforge.client.event.CustomizeGuiOverlayEvent.DebugText(minecraft.getWindow(), p_281427_, minecraft.getTimer(), gameInformation, systemInformation); -+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(event); ++ final List gameInformation = this.collectGameInformationText(); ++ final List systemInformation = this.collectSystemInformationText(); ++ var event = new net.neoforged.neoforge.client.event.CustomizeGuiOverlayEvent.DebugText(minecraft.getWindow(), p_281427_, minecraft.getDeltaTracker(), gameInformation, systemInformation); ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(event); ++ this.renderLines(p_281427_, gameInformation, true); ++ this.renderLines(p_281427_, systemInformation, false); + -+ this.renderLines(p_281427_, gameInformation, true); -+ this.renderLines(p_281427_, systemInformation, false); -+ - if (this.renderFpsCharts) { - int i = p_281427_.guiWidth(); - int j = i / 2; -@@ -161,7 +_,11 @@ - this.minecraft.getProfiler().pop(); + this.profilerPieChart.setBottomOffset(10); + if (this.renderFpsCharts) { + int i = p_281427_.guiWidth(); +@@ -175,7 +_,11 @@ + profilerfiller.pop(); } - protected void drawGameInformation(GuiGraphics p_281525_) { @@ -31,7 +30,7 @@ List list = this.getGameInformation(); list.add(""); boolean flag = this.minecraft.getSingleplayerServer() != null; -@@ -176,11 +_,25 @@ +@@ -190,11 +_,25 @@ + (this.renderNetworkCharts ? " visible" : " hidden") ); list.add("For help: press F3 + Q"); @@ -58,7 +57,7 @@ this.renderLines(p_281261_, list, false); } -@@ -509,6 +_,13 @@ +@@ -523,6 +_,13 @@ GlUtil.getRenderer(), GlUtil.getOpenGLVersion() ); @@ -72,7 +71,7 @@ if (this.minecraft.showOnlyReducedInfo()) { return list; } else { -@@ -545,6 +_,7 @@ +@@ -559,6 +_,7 @@ list.add(""); list.add(ChatFormatting.UNDERLINE + "Targeted Entity"); list.add(String.valueOf(BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()))); diff --git a/patches/net/minecraft/client/gui/components/toasts/ToastComponent.java.patch b/patches/net/minecraft/client/gui/components/toasts/ToastComponent.java.patch deleted file mode 100644 index 7c7e69a6d3..0000000000 --- a/patches/net/minecraft/client/gui/components/toasts/ToastComponent.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net/minecraft/client/gui/components/toasts/ToastComponent.java -+++ b/net/minecraft/client/gui/components/toasts/ToastComponent.java -@@ -99,6 +_,7 @@ - } - - public void addToast(Toast p_94923_) { -+ if (net.neoforged.neoforge.client.ClientHooks.onToastAdd(p_94923_)) return; - this.queued.add(p_94923_); - } - diff --git a/patches/net/minecraft/client/gui/components/toasts/ToastManager.java.patch b/patches/net/minecraft/client/gui/components/toasts/ToastManager.java.patch new file mode 100644 index 0000000000..f5bd0bffbc --- /dev/null +++ b/patches/net/minecraft/client/gui/components/toasts/ToastManager.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/client/gui/components/toasts/ToastManager.java ++++ b/net/minecraft/client/gui/components/toasts/ToastManager.java +@@ -107,6 +_,7 @@ + } + + public void addToast(Toast p_362712_) { ++ if (net.neoforged.neoforge.client.ClientHooks.onToastAdd(p_362712_)) return; + this.queued.add(p_362712_); + } + diff --git a/patches/net/minecraft/client/gui/screens/LoadingOverlay.java.patch b/patches/net/minecraft/client/gui/screens/LoadingOverlay.java.patch index 3729b1ae51..b607643c50 100644 --- a/patches/net/minecraft/client/gui/screens/LoadingOverlay.java.patch +++ b/patches/net/minecraft/client/gui/screens/LoadingOverlay.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/LoadingOverlay.java +++ b/net/minecraft/client/gui/screens/LoadingOverlay.java -@@ -133,6 +_,7 @@ +@@ -123,6 +_,7 @@ } if (this.fadeOutStart == -1L && this.reload.isDone() && (!this.fadeIn || f1 >= 2.0F)) { @@ -8,7 +8,7 @@ try { this.reload.checkExceptions(); this.onFinish.accept(Optional.empty()); -@@ -140,7 +_,6 @@ +@@ -130,7 +_,6 @@ this.onFinish.accept(Optional.of(throwable)); } diff --git a/patches/net/minecraft/client/gui/screens/PauseScreen.java.patch b/patches/net/minecraft/client/gui/screens/PauseScreen.java.patch index 7016a2712f..b8a1613d4e 100644 --- a/patches/net/minecraft/client/gui/screens/PauseScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/PauseScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/PauseScreen.java +++ b/net/minecraft/client/gui/screens/PauseScreen.java -@@ -96,6 +_,7 @@ +@@ -97,6 +_,7 @@ } else { gridlayout$rowhelper.addChild(this.openScreenButton(PLAYER_REPORTING, () -> new SocialInteractionsScreen(this))); } diff --git a/patches/net/minecraft/client/gui/screens/Screen.java.patch b/patches/net/minecraft/client/gui/screens/Screen.java.patch index cc93b39e1c..e7d7751d22 100644 --- a/patches/net/minecraft/client/gui/screens/Screen.java.patch +++ b/patches/net/minecraft/client/gui/screens/Screen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/Screen.java +++ b/net/minecraft/client/gui/screens/Screen.java -@@ -116,6 +_,7 @@ +@@ -115,6 +_,7 @@ } } @@ -8,7 +8,7 @@ @Override public void render(GuiGraphics p_281549_, int p_281550_, int p_282878_, float p_282465_) { this.renderBackground(p_281549_, p_281550_, p_282878_, p_282465_); -@@ -201,7 +_,7 @@ +@@ -200,7 +_,7 @@ } public void onClose() { @@ -17,7 +17,7 @@ } protected T addRenderableWidget(T p_169406_) { -@@ -242,7 +_,7 @@ +@@ -241,7 +_,7 @@ return p_282833_.getTooltipLines( Item.TooltipContext.of(p_281881_.level), p_281881_.player, @@ -26,7 +26,7 @@ ); } -@@ -312,8 +_,11 @@ +@@ -311,8 +_,11 @@ this.width = p_96608_; this.height = p_96609_; if (!this.initialized) { @@ -38,7 +38,7 @@ } else { this.repositionElements(); } -@@ -326,8 +_,11 @@ +@@ -325,8 +_,11 @@ protected void rebuildWidgets() { this.clearWidgets(); this.clearFocus(); @@ -50,15 +50,15 @@ } @Override -@@ -354,6 +_,7 @@ +@@ -353,6 +_,7 @@ - this.renderBlurredBackground(p_294317_); + this.renderBlurredBackground(); this.renderMenuBackground(p_283688_); + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.ScreenEvent.BackgroundRendered(this, p_283688_)); } - protected void renderBlurredBackground(float p_330683_) { -@@ -467,6 +_,10 @@ + protected void renderBlurredBackground() { +@@ -458,6 +_,10 @@ public void onFilesDrop(List p_96591_) { } @@ -69,7 +69,7 @@ private void scheduleNarration(long p_169381_, boolean p_169382_) { this.nextNarrationTime = Util.getMillis() + p_169381_; if (p_169382_) { -@@ -643,5 +_,13 @@ +@@ -642,5 +_,13 @@ this.index = p_169425_; this.priority = p_169426_; } diff --git a/patches/net/minecraft/client/gui/screens/TitleScreen.java.patch b/patches/net/minecraft/client/gui/screens/TitleScreen.java.patch index b4069b5603..39e436c46d 100644 --- a/patches/net/minecraft/client/gui/screens/TitleScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/TitleScreen.java.patch @@ -7,16 +7,16 @@ - int l = this.height / 4 + 48; + int l = this.height / 4 + 32; if (this.minecraft.isDemo()) { - this.createDemoMenuOptions(l, 24); + l = this.createDemoMenuOptions(l, 24); } else { - this.createNormalMenuOptions(l, 24); + l = this.createNormalMenuOptions(l, 24); + this.addRenderableWidget(new net.neoforged.neoforge.client.gui.widget.ModsButton(Button.builder(Component.translatable("fml.menu.mods"), button -> this.minecraft.setScreen(new net.neoforged.neoforge.client.gui.ModListScreen(this))) + .pos(this.width / 2 - 100, l + 24 * 3).size(200, 20))); + l += 22; // Move down Options, Quit, Language, and Accessibility buttons to make room for mods button } - SpriteIconButton spriteiconbutton = this.addRenderableWidget( -@@ -285,6 +_,7 @@ + l = this.createTestWorldButton(l, 24); +@@ -304,6 +_,7 @@ if ((i & -67108864) != 0) { super.render(p_282860_, p_281753_, p_283539_, p_282628_); this.logoRenderer.renderLogo(p_282860_, this.width, f); @@ -24,7 +24,7 @@ if (this.splash != null && !this.minecraft.options.hideSplashTexts().get()) { this.splash.render(p_282860_, this.width, this.font, i); } -@@ -300,7 +_,13 @@ +@@ -319,7 +_,13 @@ s = s + I18n.get("menu.modded"); } @@ -37,5 +37,5 @@ + p_282860_.drawString(this.font, brd, this.width - font.width(brd), this.height - (10 + (brdline + 1) * (this.font.lineHeight + 1)), 16777215 | i) + ); if (this.realmsNotificationsEnabled() && f >= 1.0F) { - RenderSystem.enableDepthTest(); this.realmsNotificationsScreen.render(p_282860_, p_281753_, p_283539_, p_282628_); + } diff --git a/patches/net/minecraft/client/gui/screens/advancements/AdvancementTab.java.patch b/patches/net/minecraft/client/gui/screens/advancements/AdvancementTab.java.patch index 01da559bba..f74b6000ef 100644 --- a/patches/net/minecraft/client/gui/screens/advancements/AdvancementTab.java.patch +++ b/patches/net/minecraft/client/gui/screens/advancements/AdvancementTab.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/advancements/AdvancementTab.java +++ b/net/minecraft/client/gui/screens/advancements/AdvancementTab.java -@@ -37,6 +_,7 @@ +@@ -38,6 +_,7 @@ private int maxY = Integer.MIN_VALUE; private float fade; private boolean centered; @@ -8,7 +8,7 @@ public AdvancementTab( Minecraft p_97145_, AdvancementsScreen p_97146_, AdvancementTabType p_97147_, int p_97148_, AdvancementNode p_300867_, DisplayInfo p_97150_ -@@ -53,6 +_,15 @@ +@@ -54,6 +_,15 @@ this.addWidget(this.root, p_300867_.holder()); } @@ -24,7 +24,7 @@ public AdvancementTabType getType() { return this.type; } -@@ -146,8 +_,8 @@ +@@ -147,8 +_,8 @@ return null; } else { for (AdvancementTabType advancementtabtype : AdvancementTabType.values()) { diff --git a/patches/net/minecraft/client/gui/screens/advancements/AdvancementTabType.java.patch b/patches/net/minecraft/client/gui/screens/advancements/AdvancementTabType.java.patch index 62e7224528..fbce35ac1f 100644 --- a/patches/net/minecraft/client/gui/screens/advancements/AdvancementTabType.java.patch +++ b/patches/net/minecraft/client/gui/screens/advancements/AdvancementTabType.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/advancements/AdvancementTabType.java +++ b/net/minecraft/client/gui/screens/advancements/AdvancementTabType.java -@@ -71,6 +_,7 @@ +@@ -72,6 +_,7 @@ private final AdvancementTabType.Sprites selectedSprites; private final AdvancementTabType.Sprites unselectedSprites; diff --git a/patches/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java.patch b/patches/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java.patch index 3e9f5ae794..30052bef01 100644 --- a/patches/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java +++ b/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java -@@ -49,6 +_,7 @@ +@@ -51,6 +_,7 @@ @Nullable private AdvancementTab selectedTab; private boolean isScrolling; @@ -8,7 +8,7 @@ public AdvancementsScreen(ClientAdvancements p_97340_) { this(p_97340_, null); -@@ -73,6 +_,16 @@ +@@ -75,6 +_,16 @@ this.advancements.setSelectedTab(this.selectedTab == null ? null : this.selectedTab.getRootNode().holder(), true); } @@ -25,7 +25,7 @@ this.layout.addToFooter(Button.builder(CommonComponents.GUI_DONE, p_331557_ -> this.onClose()).width(200).build()); this.layout.visitWidgets(p_332019_ -> { AbstractWidget abstractwidget = this.addRenderableWidget(p_332019_); -@@ -106,7 +_,7 @@ +@@ -108,7 +_,7 @@ int j = (this.height - 140) / 2; for (AdvancementTab advancementtab : this.tabs.values()) { @@ -34,7 +34,7 @@ this.advancements.setSelectedTab(advancementtab.getRootNode().holder(), true); break; } -@@ -132,6 +_,11 @@ +@@ -134,6 +_,11 @@ super.render(p_282589_, p_282255_, p_283354_, p_283123_); int i = (this.width - 252) / 2; int j = (this.height - 140) / 2; @@ -46,8 +46,8 @@ this.renderInside(p_282589_, p_282255_, p_283354_, i, j); this.renderWindow(p_282589_, i, j); this.renderTooltips(p_282589_, p_282255_, p_283354_, i, j); -@@ -180,10 +_,12 @@ - p_283395_.blit(WINDOW_LOCATION, p_281890_, p_282532_, 0, 0, 252, 140); +@@ -181,10 +_,12 @@ + p_283395_.blit(RenderType::guiTextured, WINDOW_LOCATION, p_281890_, p_282532_, 0.0F, 0.0F, 252, 140, 256, 256); if (this.tabs.size() > 1) { for (AdvancementTab advancementtab : this.tabs.values()) { + if (advancementtab.getPage() == tabPage) @@ -59,7 +59,7 @@ advancementtab1.drawIcon(p_283395_, p_281890_, p_282532_); } } -@@ -203,7 +_,7 @@ +@@ -202,7 +_,7 @@ if (this.tabs.size() > 1) { for (AdvancementTab advancementtab : this.tabs.values()) { diff --git a/patches/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java.patch b/patches/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java.patch index d00c918adb..be4ec4baf1 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java +++ b/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java -@@ -91,7 +_,12 @@ +@@ -107,7 +_,12 @@ public void render(GuiGraphics p_283479_, int p_283661_, int p_281248_, float p_281886_) { int i = this.leftPos; int j = this.topPos; @@ -11,56 +11,26 @@ + for (net.minecraft.client.gui.components.Renderable renderable : this.renderables) { + renderable.render(p_283479_, p_283661_, p_281248_, p_281886_); + } - RenderSystem.disableDepthTest(); p_283479_.pose().pushPose(); p_283479_.pose().translate((float)i, (float)j, 0.0F); -@@ -105,15 +_,12 @@ - - if (this.isHovering(slot, (double)p_283661_, (double)p_281248_) && slot.isActive()) { - this.hoveredSlot = slot; -- int l = slot.x; -- int i1 = slot.y; -- if (this.hoveredSlot.isHighlightable()) { -- renderSlotHighlight(p_283479_, l, i1, 0); -- } -+ this.renderSlotHighlight(p_283479_, slot, p_283661_, p_281248_, p_281886_); - } + Slot slot = this.hoveredSlot; +@@ -120,6 +_,7 @@ } this.renderLabels(p_283479_, p_283661_, p_281248_); + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.ContainerScreenEvent.Render.Foreground(this, p_283479_, p_283661_, p_281248_)); ItemStack itemstack = this.draggingItem.isEmpty() ? this.menu.getCarried() : this.draggingItem; if (!itemstack.isEmpty()) { - int l1 = 8; -@@ -156,13 +_,25 @@ - } - - public static void renderSlotHighlight(GuiGraphics p_283692_, int p_281453_, int p_281915_, int p_283504_) { -- p_283692_.fillGradient(RenderType.guiOverlay(), p_281453_, p_281915_, p_281453_ + 16, p_281915_ + 16, -2130706433, -2130706433, p_283504_); -+ renderSlotHighlight(p_283692_, p_281453_, p_281915_, p_283504_, -2130706433); -+ } -+ public static void renderSlotHighlight(GuiGraphics p_283692_, int p_281453_, int p_281915_, int p_283504_, int color) { -+ p_283692_.fillGradient(RenderType.guiOverlay(), p_281453_, p_281915_, p_281453_ + 16, p_281915_ + 16, color, color, p_283504_); -+ } -+ -+ /** -+ * Renders a highlight for the given slot to indicate the mouse is currently hovering over it. -+ */ -+ protected void renderSlotHighlight(GuiGraphics guiGraphics, Slot slot, int mouseX, int mouseY, float partialTick) { -+ if (slot.isHighlightable()) { -+ renderSlotHighlight(guiGraphics, slot.x, slot.y, 0, getSlotColor(slot.index)); -+ } - } - - protected void renderTooltip(GuiGraphics p_283594_, int p_282171_, int p_281909_) { - if (this.menu.getCarried().isEmpty() && this.hoveredSlot != null && this.hoveredSlot.hasItem()) { - ItemStack itemstack = this.hoveredSlot.getItem(); -- p_283594_.renderTooltip(this.font, this.getTooltipFromContainerItem(itemstack), itemstack.getTooltipImage(), p_282171_, p_281909_); -+ p_283594_.renderTooltip(this.font, this.getTooltipFromContainerItem(itemstack), itemstack.getTooltipImage(), itemstack, p_282171_, p_281909_); - } - } - -@@ -174,7 +_,8 @@ + int k = 8; +@@ -202,6 +_,7 @@ + this.font, + this.getTooltipFromContainerItem(itemstack), + itemstack.getTooltipImage(), ++ itemstack, + p_282171_, + p_281909_, + itemstack.get(DataComponents.TOOLTIP_STYLE) +@@ -222,7 +_,8 @@ p_282567_.pose().pushPose(); p_282567_.pose().translate(0.0F, 0.0F, 232.0F); p_282567_.renderItem(p_281330_, p_281772_, p_281689_); @@ -70,7 +40,7 @@ p_282567_.pose().popPose(); } -@@ -233,6 +_,14 @@ +@@ -281,6 +_,14 @@ p_281607_.fill(i, j, i + 16, j + 16, -2130706433); } @@ -85,7 +55,7 @@ int j1 = p_282613_.x + p_282613_.y * this.imageWidth; if (p_282613_.isFake()) { p_281607_.renderFakeItem(itemstack, i, j, j1); -@@ -241,9 +_,6 @@ +@@ -289,9 +_,6 @@ } p_281607_.renderItemDecorations(this.font, itemstack, i, j, s); @@ -95,17 +65,17 @@ } private void recalculateQuickCraftRemaining() { -@@ -282,7 +_,8 @@ +@@ -329,7 +_,8 @@ if (super.mouseClicked(p_97748_, p_97749_, p_97750_)) { return true; } else { - boolean flag = this.minecraft.options.keyPickItem.matchesMouse(p_97750_) && this.minecraft.gameMode.hasInfiniteItems(); + InputConstants.Key mouseKey = InputConstants.Type.MOUSE.getOrCreate(p_97750_); + boolean flag = this.minecraft.options.keyPickItem.isActiveAndMatches(mouseKey); - Slot slot = this.findSlot(p_97748_, p_97749_); + Slot slot = this.getHoveredSlot(p_97748_, p_97749_); long i = Util.getMillis(); this.doubleclick = this.lastClickSlot == slot && i - this.lastClickTime < 250L && this.lastClickButton == p_97750_; -@@ -293,6 +_,7 @@ +@@ -340,6 +_,7 @@ int j = this.leftPos; int k = this.topPos; boolean flag1 = this.hasClickedOutside(p_97748_, p_97749_, j, k, p_97750_); @@ -113,7 +83,7 @@ int l = -1; if (slot != null) { l = slot.index; -@@ -318,7 +_,7 @@ +@@ -365,7 +_,7 @@ } } else if (!this.isQuickCrafting) { if (this.menu.getCarried().isEmpty()) { @@ -122,7 +92,7 @@ this.slotClicked(slot, l, p_97750_, ClickType.CLONE); } else { boolean flag2 = l != -999 -@@ -346,7 +_,7 @@ +@@ -393,7 +_,7 @@ this.quickCraftingType = 0; } else if (p_97750_ == 1) { this.quickCraftingType = 1; @@ -131,12 +101,12 @@ this.quickCraftingType = 2; } } -@@ -425,10 +_,13 @@ +@@ -472,10 +_,13 @@ @Override public boolean mouseReleased(double p_97812_, double p_97813_, int p_97814_) { + super.mouseReleased(p_97812_, p_97813_, p_97814_); //Forge, Call parent to release buttons - Slot slot = this.findSlot(p_97812_, p_97813_); + Slot slot = this.getHoveredSlot(p_97812_, p_97813_); int i = this.leftPos; int j = this.topPos; boolean flag = this.hasClickedOutside(p_97812_, p_97813_, i, j, p_97814_); @@ -145,7 +115,7 @@ int k = -1; if (slot != null) { k = slot.index; -@@ -445,7 +_,7 @@ +@@ -492,7 +_,7 @@ if (slot2 != null && slot2.mayPickup(this.minecraft.player) && slot2.hasItem() @@ -154,7 +124,7 @@ && AbstractContainerMenu.canItemQuickReplace(slot2, this.lastQuickMoved, true)) { this.slotClicked(slot2, slot2.index, p_97814_, ClickType.QUICK_MOVE); } -@@ -509,7 +_,7 @@ +@@ -556,7 +_,7 @@ this.slotClicked(null, -999, AbstractContainerMenu.getQuickcraftMask(2, this.quickCraftingType), ClickType.QUICK_CRAFT); } else if (!this.menu.getCarried().isEmpty()) { @@ -163,7 +133,7 @@ this.slotClicked(slot, k, p_97814_, ClickType.CLONE); } else { boolean flag1 = k != -999 -@@ -568,34 +_,39 @@ +@@ -636,34 +_,39 @@ @Override public boolean keyPressed(int p_97765_, int p_97766_, int p_97767_) { @@ -210,7 +180,7 @@ this.slotClicked(this.hoveredSlot, this.hoveredSlot.index, i, ClickType.SWAP); return true; } -@@ -633,6 +_,18 @@ +@@ -701,6 +_,18 @@ @Override public T getMenu() { return this.menu; diff --git a/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch b/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch index 525825a442..37ccae8839 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java +++ b/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java -@@ -112,6 +_,8 @@ - private boolean hasClickedOutside; +@@ -115,6 +_,8 @@ private final Set> visibleTags = new HashSet<>(); private final boolean displayOperatorCreativeTab; + private final EffectsInInventory effects; + private final List pages = new java.util.ArrayList<>(); + private net.neoforged.neoforge.client.gui.CreativeTabsScreenPage currentPage = new net.neoforged.neoforge.client.gui.CreativeTabsScreenPage(new java.util.ArrayList<>()); public CreativeModeInventoryScreen(LocalPlayer p_346290_, FeatureFlagSet p_260074_, boolean p_259569_) { super(new CreativeModeInventoryScreen.ItemPickerMenu(p_346290_), p_346290_.getInventory(), CommonComponents.EMPTY); -@@ -147,9 +_,11 @@ +@@ -151,9 +_,11 @@ return false; } else { if (p_345591_ != null) { @@ -24,7 +24,7 @@ } return true; -@@ -159,7 +_,7 @@ +@@ -163,7 +_,7 @@ private void refreshCurrentTabContents(Collection p_261591_) { int i = this.menu.getRowIndexForScroll(this.scrollOffs); this.menu.items.clear(); @@ -33,7 +33,7 @@ this.refreshSearchResults(); } else { this.menu.items.addAll(p_261591_); -@@ -326,6 +_,34 @@ +@@ -337,6 +_,34 @@ protected void init() { if (this.minecraft.gameMode.hasInfiniteItems()) { super.init(); @@ -68,7 +68,7 @@ this.searchBox = new EditBox(this.font, this.leftPos + 82, this.topPos + 6, 80, 9, Component.translatable("itemGroup.search")); this.searchBox.setMaxLength(50); this.searchBox.setBordered(false); -@@ -372,7 +_,7 @@ +@@ -383,7 +_,7 @@ public boolean charTyped(char p_98521_, int p_98522_) { if (this.ignoreTextInput) { return false; @@ -77,7 +77,7 @@ return false; } else { String s = this.searchBox.getValue(); -@@ -391,7 +_,7 @@ +@@ -402,7 +_,7 @@ @Override public boolean keyPressed(int p_98547_, int p_98548_, int p_98549_) { this.ignoreTextInput = false; @@ -86,7 +86,7 @@ if (this.minecraft.options.keyChat.matches(p_98547_, p_98548_)) { this.ignoreTextInput = true; this.selectTab(CreativeModeTabs.searchTab()); -@@ -427,6 +_,7 @@ +@@ -438,6 +_,7 @@ } private void refreshSearchResults() { @@ -94,7 +94,7 @@ this.menu.items.clear(); this.visibleTags.clear(); String s = this.searchBox.getValue(); -@@ -439,10 +_,10 @@ +@@ -450,10 +_,10 @@ SearchTree searchtree; if (s.startsWith("#")) { s = s.substring(1); @@ -107,7 +107,7 @@ } this.menu.items.addAll(searchtree.search(s.toLowerCase(Locale.ROOT))); -@@ -470,7 +_,8 @@ +@@ -481,7 +_,8 @@ @Override protected void renderLabels(GuiGraphics p_283168_, int p_281774_, int p_281466_) { if (selectedTab.showTitle()) { @@ -117,7 +117,7 @@ } } -@@ -480,7 +_,7 @@ +@@ -491,7 +_,7 @@ double d0 = p_98531_ - (double)this.leftPos; double d1 = p_98532_ - (double)this.topPos; @@ -126,7 +126,7 @@ if (this.checkTabClicked(creativemodetab, d0, d1)) { return true; } -@@ -502,7 +_,7 @@ +@@ -513,7 +_,7 @@ double d1 = p_98623_ - (double)this.topPos; this.scrolling = false; @@ -135,7 +135,7 @@ if (this.checkTabClicked(creativemodetab, d0, d1)) { this.selectTab(creativemodetab); return true; -@@ -520,6 +_,7 @@ +@@ -531,6 +_,7 @@ private void selectTab(CreativeModeTab p_98561_) { CreativeModeTab creativemodetab = selectedTab; selectedTab = p_98561_; @@ -143,7 +143,7 @@ this.quickCraftSlots.clear(); this.menu.items.clear(); this.clearDraggingState(); -@@ -596,13 +_,15 @@ +@@ -607,13 +_,15 @@ this.originalSlots = null; } @@ -160,9 +160,9 @@ this.refreshSearchResults(); } else { -@@ -665,18 +_,27 @@ - public void render(GuiGraphics p_283000_, int p_281317_, int p_282770_, float p_281295_) { +@@ -679,18 +_,27 @@ super.render(p_283000_, p_281317_, p_282770_, p_281295_); + this.effects.render(p_283000_, p_281317_, p_282770_, p_281295_); - for (CreativeModeTab creativemodetab : CreativeModeTabs.tabs()) { - if (this.checkTabHovering(p_283000_, creativemodetab, p_281317_, p_282770_)) { @@ -194,7 +194,7 @@ this.renderTooltip(p_283000_, p_281317_, p_282770_); } -@@ -684,10 +_,10 @@ +@@ -703,10 +_,10 @@ public List getTooltipFromContainerItem(ItemStack p_281769_) { boolean flag = this.hoveredSlot != null && this.hoveredSlot instanceof CreativeModeInventoryScreen.CustomCreativeSlot; boolean flag1 = selectedTab.getType() == CreativeModeTab.Type.CATEGORY; @@ -207,7 +207,7 @@ if (flag1 && flag) { return list; } else { -@@ -703,7 +_,7 @@ +@@ -722,7 +_,7 @@ int i = 1; for (CreativeModeTab creativemodetab : CreativeModeTabs.tabs()) { @@ -216,7 +216,7 @@ list1.add(i++, creativemodetab.getDisplayName().copy().withStyle(ChatFormatting.BLUE)); } } -@@ -714,7 +_,7 @@ +@@ -733,7 +_,7 @@ @Override protected void renderBg(GuiGraphics p_282663_, float p_282504_, int p_282089_, int p_282249_) { @@ -225,20 +225,20 @@ if (creativemodetab != selectedTab) { this.renderTabButton(p_282663_, creativemodetab); } -@@ -726,10 +_,11 @@ +@@ -747,10 +_,11 @@ int k = this.topPos + 18; int i = k + 112; if (selectedTab.canScroll()) { - ResourceLocation resourcelocation = this.canScroll() ? SCROLLER_SPRITE : SCROLLER_DISABLED_SPRITE; + ResourceLocation resourcelocation = selectedTab.getScrollerSprite(); // this.canScroll() ? SCROLLER_SPRITE : SCROLLER_DISABLED_SPRITE; - p_282663_.blitSprite(resourcelocation, j, k + (int)((float)(i - k - 17) * this.scrollOffs), 12, 15); + p_282663_.blitSprite(RenderType::guiTextured, resourcelocation, j, k + (int)((float)(i - k - 17) * this.scrollOffs), 12, 15); } + if (currentPage.getVisibleTabs().contains(selectedTab)) //Forge: only display tab selection when the selected tab is on the current page this.renderTabButton(p_282663_, selectedTab); if (selectedTab.getType() == CreativeModeTab.Type.INVENTORY) { InventoryScreen.renderEntityInInventoryFollowsMouse( -@@ -748,7 +_,7 @@ +@@ -769,7 +_,7 @@ } private int getTabX(CreativeModeTab p_260136_) { @@ -247,7 +247,7 @@ int j = 27; int k = 27 * i; if (p_260136_.isAlignedRight()) { -@@ -760,7 +_,7 @@ +@@ -781,7 +_,7 @@ private int getTabY(CreativeModeTab p_260181_) { int i = 0; @@ -256,7 +256,7 @@ i -= 32; } else { i += this.imageHeight; -@@ -788,8 +_,8 @@ +@@ -809,8 +_,8 @@ protected void renderTabButton(GuiGraphics p_283590_, CreativeModeTab p_283489_) { boolean flag = p_283489_ == selectedTab; @@ -267,15 +267,15 @@ int j = this.leftPos + this.getTabX(p_283489_); int k = this.topPos - (flag1 ? 28 : -(this.imageHeight - 4)); ResourceLocation[] aresourcelocation; -@@ -799,6 +_,7 @@ +@@ -820,6 +_,7 @@ aresourcelocation = flag ? SELECTED_BOTTOM_TABS : UNSELECTED_BOTTOM_TABS; } + //PATCH 1.20.2: Deal with custom tab backgrounds, and deal with transparency. - p_283590_.blitSprite(aresourcelocation[Mth.clamp(i, 0, aresourcelocation.length)], j, k, 26, 32); + p_283590_.blitSprite(RenderType::guiTextured, aresourcelocation[Mth.clamp(i, 0, aresourcelocation.length)], j, k, 26, 32); p_283590_.pose().pushPose(); p_283590_.pose().translate(0.0F, 0.0F, 100.0F); -@@ -840,6 +_,14 @@ +@@ -861,6 +_,14 @@ } } @@ -290,7 +290,7 @@ @OnlyIn(Dist.CLIENT) static class CustomCreativeSlot extends Slot { public CustomCreativeSlot(Container p_98633_, int p_98634_, int p_98635_, int p_98636_) { -@@ -1024,6 +_,22 @@ +@@ -1042,6 +_,22 @@ @Override public boolean mayPickup(Player p_98665_) { return this.target.mayPickup(p_98665_); diff --git a/patches/net/minecraft/client/gui/screens/inventory/EffectRenderingInventoryScreen.java.patch b/patches/net/minecraft/client/gui/screens/inventory/EffectsInInventory.java.patch similarity index 64% rename from patches/net/minecraft/client/gui/screens/inventory/EffectRenderingInventoryScreen.java.patch rename to patches/net/minecraft/client/gui/screens/inventory/EffectsInInventory.java.patch index e194f8c32f..c3288a4316 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/EffectRenderingInventoryScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/EffectsInInventory.java.patch @@ -1,10 +1,10 @@ ---- a/net/minecraft/client/gui/screens/inventory/EffectRenderingInventoryScreen.java -+++ b/net/minecraft/client/gui/screens/inventory/EffectRenderingInventoryScreen.java -@@ -47,12 +_,17 @@ +--- a/net/minecraft/client/gui/screens/inventory/EffectsInInventory.java ++++ b/net/minecraft/client/gui/screens/inventory/EffectsInInventory.java +@@ -48,12 +_,16 @@ Collection collection = this.minecraft.player.getActiveEffects(); if (!collection.isEmpty() && j >= 32) { boolean flag = j >= 120; -+ var event = net.neoforged.neoforge.client.ClientHooks.onScreenPotionSize(this, j, !flag, i); ++ var event = net.neoforged.neoforge.client.ClientHooks.onScreenPotionSize(screen, j, !flag, i); + if (event.isCanceled()) return; + flag = !event.isCompact(); + i = event.getHorizontalOffset(); @@ -14,41 +14,40 @@ } - Iterable iterable = Ordering.natural().sortedCopy(collection); -+ + Iterable iterable = collection.stream().filter(net.neoforged.neoforge.client.ClientHooks::shouldRenderEffect).sorted().collect(java.util.stream.Collectors.toList()); - this.renderBackgrounds(p_281945_, i, k, iterable, flag); - this.renderIcons(p_281945_, i, k, iterable, flag); + this.renderBackgrounds(p_376884_, i, k, iterable, flag); + this.renderIcons(p_376884_, i, k, iterable, flag); if (flag) { -@@ -74,6 +_,8 @@ +@@ -75,6 +_,8 @@ this.getEffectName(mobeffectinstance), MobEffectUtil.formatDuration(mobeffectinstance, 1.0F, this.minecraft.level.tickRateManager().tickrate()) ); + // Neo: Allow mods to adjust the tooltip shown when hovering a mob effect. -+ list = net.neoforged.neoforge.client.ClientHooks.getEffectTooltip(this, mobeffectinstance, list); - p_281945_.renderTooltip(this.font, list, Optional.empty(), p_282601_, p_282335_); ++ list = net.neoforged.neoforge.client.ClientHooks.getEffectTooltip(screen, mobeffectinstance, list); + p_376884_.renderTooltip(this.screen.getFont(), list, Optional.empty(), p_376869_, p_376740_); } } -@@ -99,6 +_,11 @@ - int i = this.topPos; +@@ -100,6 +_,11 @@ + int i = this.screen.topPos; - for (MobEffectInstance mobeffectinstance : p_282642_) { + for (MobEffectInstance mobeffectinstance : p_376215_) { + var renderer = net.neoforged.neoforge.client.extensions.common.IClientMobEffectExtensions.of(mobeffectinstance); -+ if (renderer.renderInventoryIcon(mobeffectinstance, this, p_282745_, p_282521_ + (p_281536_ ? 6 : 7), i, 0)) { -+ i += p_282291_; ++ if (renderer.renderInventoryIcon(mobeffectinstance, screen, p_376734_, p_376350_ + (p_376312_ ? 6 : 7), i, 0)) { ++ i += p_376678_; + continue; + } Holder holder = mobeffectinstance.getEffect(); TextureAtlasSprite textureatlassprite = mobeffecttexturemanager.get(holder); - p_282745_.blit(p_282521_ + (p_281536_ ? 6 : 7), i + 7, 0, 18, 18, textureatlassprite); -@@ -110,6 +_,11 @@ - int i = this.topPos; + p_376734_.blitSprite(RenderType::guiTextured, textureatlassprite, p_376350_ + (p_376312_ ? 6 : 7), i + 7, 18, 18); +@@ -111,6 +_,11 @@ + int i = this.screen.topPos; - for (MobEffectInstance mobeffectinstance : p_281986_) { + for (MobEffectInstance mobeffectinstance : p_376910_) { + var renderer = net.neoforged.neoforge.client.extensions.common.IClientMobEffectExtensions.of(mobeffectinstance); -+ if (renderer.renderInventoryText(mobeffectinstance, this, p_281462_, p_283484_, i, 0)) { -+ i += p_282057_; ++ if (renderer.renderInventoryText(mobeffectinstance, screen, p_376227_, p_376372_, i, 0)) { ++ i += p_376395_; + continue; + } Component component = this.getEffectName(mobeffectinstance); - p_281462_.drawString(this.font, component, p_283484_ + 10 + 18, i + 6, 16777215); + p_376227_.drawString(this.screen.getFont(), component, p_376372_ + 10 + 18, i + 6, 16777215); Component component1 = MobEffectUtil.formatDuration(mobeffectinstance, 1.0F, this.minecraft.level.tickRateManager().tickrate()); diff --git a/patches/net/minecraft/client/gui/screens/inventory/EnchantmentScreen.java.patch b/patches/net/minecraft/client/gui/screens/inventory/EnchantmentScreen.java.patch index 9e0e4bfeca..66f9e706cc 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/EnchantmentScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/EnchantmentScreen.java.patch @@ -1,18 +1,18 @@ --- a/net/minecraft/client/gui/screens/inventory/EnchantmentScreen.java +++ b/net/minecraft/client/gui/screens/inventory/EnchantmentScreen.java -@@ -115,7 +_,7 @@ +@@ -113,7 +_,7 @@ int l1 = 86 - this.font.width(s); FormattedText formattedtext = EnchantmentNames.getInstance().getRandomName(this.font, l1); int i2 = 6839882; - if ((k < l + 1 || this.minecraft.player.experienceLevel < k1) && !this.minecraft.player.getAbilities().instabuild) { + if (((k < l + 1 || this.minecraft.player.experienceLevel < k1) && !this.minecraft.player.getAbilities().instabuild) || this.menu.enchantClue[l] == -1) { // Forge: render buttons as disabled when enchantable but enchantability not met on lower levels - RenderSystem.enableBlend(); - p_282430_.blitSprite(ENCHANTMENT_SLOT_DISABLED_SPRITE, i1, j + 14 + 19 * l, 108, 19); - p_282430_.blitSprite(DISABLED_LEVEL_SPRITES[l], i1 + 1, j + 15 + 19 * l, 16, 16); -@@ -181,13 +_,16 @@ + p_282430_.blitSprite(RenderType::guiTextured, ENCHANTMENT_SLOT_DISABLED_SPRITE, i1, j + 14 + 19 * l, 108, 19); + p_282430_.blitSprite(RenderType::guiTextured, DISABLED_LEVEL_SPRITES[l], i1 + 1, j + 15 + 19 * l, 16, 16); + p_282430_.drawWordWrap(this.font, formattedtext, j1, j + 16 + 19 * l, l1, (i2 & 16711422) >> 1); +@@ -179,13 +_,16 @@ .registryAccess() - .registryOrThrow(Registries.ENCHANTMENT) - .getHolder(this.menu.enchantClue[j]); + .lookupOrThrow(Registries.ENCHANTMENT) + .get(this.menu.enchantClue[j]); - if (!optional.isEmpty()) { + if (true) { int l = this.menu.levelClue[j]; diff --git a/patches/net/minecraft/client/gui/screens/inventory/HangingSignEditScreen.java.patch b/patches/net/minecraft/client/gui/screens/inventory/HangingSignEditScreen.java.patch index 74155da1f7..0b4bbf6b6e 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/HangingSignEditScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/HangingSignEditScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/inventory/HangingSignEditScreen.java +++ b/net/minecraft/client/gui/screens/inventory/HangingSignEditScreen.java -@@ -15,7 +_,7 @@ +@@ -16,7 +_,7 @@ private static final Vector3f TEXT_SCALE = new Vector3f(1.0F, 1.0F, 1.0F); private static final int TEXTURE_WIDTH = 16; private static final int TEXTURE_HEIGHT = 16; diff --git a/patches/net/minecraft/client/gui/screens/inventory/MerchantScreen.java.patch b/patches/net/minecraft/client/gui/screens/inventory/MerchantScreen.java.patch index bca6c08814..75ffaa276e 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/MerchantScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/MerchantScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/inventory/MerchantScreen.java +++ b/net/minecraft/client/gui/screens/inventory/MerchantScreen.java -@@ -236,7 +_,12 @@ +@@ -233,7 +_,12 @@ p_281357_.renderItemDecorations(this.font, p_283466_, p_282403_, p_283601_); } else { p_281357_.renderItemDecorations(this.font, p_282046_, p_282403_, p_283601_, p_282046_.getCount() == 1 ? "1" : null); @@ -9,8 +9,8 @@ + p_281357_.pose().pushPose(); + p_281357_.pose().translate(0.0F, 0.0F, 200.0F); + String count = p_283466_.getCount() == 1 ? "1" : String.valueOf(p_283466_.getCount()); -+ font.drawInBatch(count, (float) (p_282403_ + 14) + 19 - 2 - font.width(count), (float)p_283601_ + 6 + 3, 0xFFFFFF, true, p_281357_.pose().last().pose(), p_281357_.bufferSource(), net.minecraft.client.gui.Font.DisplayMode.NORMAL, 0, 15728880, false); ++ p_281357_.drawString(font, count, (float) (p_282403_ + 14) + 19 - 2 - font.width(count), (float)p_283601_ + 6 + 3, 0xFFFFFF, true); + p_281357_.pose().popPose(); p_281357_.pose().pushPose(); p_281357_.pose().translate(0.0F, 0.0F, 300.0F); - p_281357_.blitSprite(DISCOUNT_STRIKETHRUOGH_SPRITE, p_282403_ + 7, p_283601_ + 12, 0, 9, 2); + p_281357_.blitSprite(RenderType::guiTextured, DISCOUNT_STRIKETHRUOGH_SPRITE, p_282403_ + 7, p_283601_ + 12, 9, 2); diff --git a/patches/net/minecraft/client/gui/screens/inventory/tooltip/ClientTooltipComponent.java.patch b/patches/net/minecraft/client/gui/screens/inventory/tooltip/ClientTooltipComponent.java.patch index 65910b0a9d..fd3626d82c 100644 --- a/patches/net/minecraft/client/gui/screens/inventory/tooltip/ClientTooltipComponent.java.patch +++ b/patches/net/minecraft/client/gui/screens/inventory/tooltip/ClientTooltipComponent.java.patch @@ -1,11 +1,15 @@ --- a/net/minecraft/client/gui/screens/inventory/tooltip/ClientTooltipComponent.java +++ b/net/minecraft/client/gui/screens/inventory/tooltip/ClientTooltipComponent.java -@@ -22,6 +_,8 @@ - } else if (p_169951_ instanceof ClientActivePlayersTooltip.ActivePlayersTooltip clientactiveplayerstooltip$activeplayerstooltip) { - return new ClientActivePlayersTooltip(clientactiveplayerstooltip$activeplayerstooltip); - } else { -+ ClientTooltipComponent result = net.neoforged.neoforge.client.gui.ClientTooltipComponentManager.createClientTooltipComponent(p_169951_); -+ if (result != null) return result; - throw new IllegalArgumentException("Unknown TooltipComponent"); - } +@@ -25,7 +_,11 @@ + case ClientActivePlayersTooltip.ActivePlayersTooltip clientactiveplayerstooltip$activeplayerstooltip -> new ClientActivePlayersTooltip( + clientactiveplayerstooltip$activeplayerstooltip + ); +- default -> throw new IllegalArgumentException("Unknown TooltipComponent"); ++ default -> { ++ ClientTooltipComponent result = net.neoforged.neoforge.client.gui.ClientTooltipComponentManager.createClientTooltipComponent(p_169951_); ++ if (result != null) yield result; ++ throw new IllegalArgumentException("Unknown TooltipComponent"); ++ } + }); } + diff --git a/patches/net/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil.java.patch b/patches/net/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil.java.patch deleted file mode 100644 index 2a218d1fac..0000000000 --- a/patches/net/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil.java.patch +++ /dev/null @@ -1,49 +0,0 @@ ---- a/net/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil.java -+++ b/net/minecraft/client/gui/screens/inventory/tooltip/TooltipRenderUtil.java -@@ -17,16 +_,22 @@ - private static final int BORDER_COLOR_BOTTOM = 1344798847; - - public static void renderTooltipBackground(GuiGraphics p_282666_, int p_281901_, int p_281846_, int p_281559_, int p_283336_, int p_283422_) { -+ renderTooltipBackground(p_282666_, p_281901_, p_281846_, p_281559_, p_283336_, p_283422_, BACKGROUND_COLOR, BACKGROUND_COLOR, BORDER_COLOR_TOP, BORDER_COLOR_BOTTOM); -+ } -+ -+ // Forge: Allow specifying colors for the inner border gradient and a gradient instead of a single color for the background and outer border -+ public static void renderTooltipBackground(GuiGraphics p_282666_, int p_281901_, int p_281846_, int p_281559_, int p_283336_, int p_283422_, int backgroundTop, int backgroundBottom, int borderTop, int borderBottom) -+ { - int i = p_281901_ - 3; - int j = p_281846_ - 3; - int k = p_281559_ + 3 + 3; - int l = p_283336_ + 3 + 3; -- renderHorizontalLine(p_282666_, i, j - 1, k, p_283422_, -267386864); -- renderHorizontalLine(p_282666_, i, j + l, k, p_283422_, -267386864); -- renderRectangle(p_282666_, i, j, k, l, p_283422_, -267386864); -- renderVerticalLine(p_282666_, i - 1, j, l, p_283422_, -267386864); -- renderVerticalLine(p_282666_, i + k, j, l, p_283422_, -267386864); -- renderFrameGradient(p_282666_, i, j + 1, k, l, p_283422_, 1347420415, 1344798847); -+ renderHorizontalLine(p_282666_, i, j - 1, k, p_283422_, backgroundTop); -+ renderHorizontalLine(p_282666_, i, j + l, k, p_283422_, backgroundBottom); -+ renderRectangle(p_282666_, i, j, k, l, p_283422_, backgroundTop, backgroundBottom); -+ renderVerticalLineGradient(p_282666_, i - 1, j, l, p_283422_, backgroundTop, backgroundBottom); -+ renderVerticalLineGradient(p_282666_, i + k, j, l, p_283422_, backgroundTop, backgroundBottom); -+ renderFrameGradient(p_282666_, i, j + 1, k, l, p_283422_, borderTop, borderBottom); - } - - private static void renderFrameGradient( -@@ -52,7 +_,16 @@ - p_282981_.fill(p_282028_, p_282141_, p_282028_ + p_281771_, p_282141_ + 1, p_282734_, p_281979_); - } - -+ /** -+ * @deprecated Forge: Use gradient overload instead -+ */ -+ @Deprecated - private static void renderRectangle(GuiGraphics p_281392_, int p_282294_, int p_283353_, int p_282640_, int p_281964_, int p_283211_, int p_282349_) { -- p_281392_.fill(p_282294_, p_283353_, p_282294_ + p_282640_, p_283353_ + p_281964_, p_283211_, p_282349_); -+ renderRectangle(p_281392_, p_282294_, p_283353_, p_282640_, p_281964_, p_283211_, p_282349_, p_282349_); -+ } -+ -+ // Forge: Allow specifying a gradient instead of a single color for the background -+ private static void renderRectangle(GuiGraphics p_281392_, int p_282294_, int p_283353_, int p_282640_, int p_281964_, int p_283211_, int p_282349_, int colorTo) { -+ p_281392_.fillGradient(p_282294_, p_283353_, p_282294_ + p_282640_, p_283353_ + p_281964_, p_283211_, p_282349_, colorTo); - } - } diff --git a/patches/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java.patch b/patches/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java.patch index d0f6315ff6..789a7732ae 100644 --- a/patches/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java.patch +++ b/patches/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java.patch @@ -3,9 +3,9 @@ @@ -158,6 +_,7 @@ ) .build(); - this.resetButton = Button.builder(RESET_BUTTON_TITLE, p_346334_ -> { + this.resetButton = Button.builder(RESET_BUTTON_TITLE, p_359096_ -> { + this.key.setToDefault(); - KeyBindsList.this.minecraft.options.setKey(p_345998_, p_345998_.getDefaultKey()); + p_345998_.setKey(p_345998_.getDefaultKey()); KeyBindsList.this.resetMappingAndUpdateButtons(); }).bounds(0, 0, 50, 20).createNarration(p_344899_ -> Component.translatable("narrator.controls.reset", p_345196_)).build(); @@ -210,7 +_,7 @@ diff --git a/patches/net/minecraft/client/gui/screens/options/controls/KeyBindsScreen.java.patch b/patches/net/minecraft/client/gui/screens/options/controls/KeyBindsScreen.java.patch index 99b5c71de5..2698680313 100644 --- a/patches/net/minecraft/client/gui/screens/options/controls/KeyBindsScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/options/controls/KeyBindsScreen.java.patch @@ -46,13 +46,13 @@ + if (this.selectedKey != null) { + if (p_94715_ == 256) { + this.selectedKey.setKeyModifierAndCode(net.neoforged.neoforge.client.settings.KeyModifier.NONE, InputConstants.UNKNOWN); - this.options.setKey(this.selectedKey, InputConstants.UNKNOWN); + this.selectedKey.setKey(InputConstants.UNKNOWN); + lastPressedKey = InputConstants.UNKNOWN; + lastPressedModifier = InputConstants.UNKNOWN; + isLastKeyHeldDown = false; + isLastModifierHeldDown = false; } else { -- this.options.setKey(this.selectedKey, InputConstants.getKey(p_345810_, p_345447_)); +- this.selectedKey.setKey(InputConstants.getKey(p_345810_, p_345447_)); - } + var key = InputConstants.getKey(p_94715_, p_94716_); + if (lastPressedKey.equals(key)) { @@ -67,13 +67,13 @@ + net.neoforged.neoforge.client.settings.KeyModifier.getKeyModifier(lastPressedModifier), + lastPressedKey + ); -+ this.options.setKey(this.selectedKey, lastPressedKey); ++ this.selectedKey.setKey(lastPressedKey); + } else { + this.selectedKey.setKeyModifierAndCode( + net.neoforged.neoforge.client.settings.KeyModifier.NONE, + lastPressedModifier + ); -+ this.options.setKey(this.selectedKey, lastPressedModifier); ++ this.selectedKey.setKey(lastPressedModifier); + } + lastPressedKey = InputConstants.UNKNOWN; + lastPressedModifier = InputConstants.UNKNOWN; diff --git a/patches/net/minecraft/client/gui/screens/recipebook/GhostSlots.java.patch b/patches/net/minecraft/client/gui/screens/recipebook/GhostSlots.java.patch new file mode 100644 index 0000000000..126f6d6156 --- /dev/null +++ b/patches/net/minecraft/client/gui/screens/recipebook/GhostSlots.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/client/gui/screens/recipebook/GhostSlots.java ++++ b/net/minecraft/client/gui/screens/recipebook/GhostSlots.java +@@ -69,7 +_,7 @@ + if (ghostslots$ghostslot != null) { + ItemStack itemstack = ghostslots$ghostslot.getItem(this.slotSelectTime.currentIndex()); + p_363721_.renderComponentTooltip( +- p_365392_.font, Screen.getTooltipFromItem(p_365392_, itemstack), p_363797_, p_363310_, itemstack.get(DataComponents.TOOLTIP_STYLE) ++ p_365392_.font, Screen.getTooltipFromItem(p_365392_, itemstack), p_363797_, p_363310_, itemstack, itemstack.get(DataComponents.TOOLTIP_STYLE) + ); + } + } diff --git a/patches/net/minecraft/client/gui/screens/recipebook/RecipeBookComponent.java.patch b/patches/net/minecraft/client/gui/screens/recipebook/RecipeBookComponent.java.patch index 0eb3a5d0c1..46ae50aa8f 100644 --- a/patches/net/minecraft/client/gui/screens/recipebook/RecipeBookComponent.java.patch +++ b/patches/net/minecraft/client/gui/screens/recipebook/RecipeBookComponent.java.patch @@ -1,20 +1,12 @@ --- a/net/minecraft/client/gui/screens/recipebook/RecipeBookComponent.java +++ b/net/minecraft/client/gui/screens/recipebook/RecipeBookComponent.java -@@ -115,7 +_,7 @@ - this.initFilterButtonTextures(); - this.tabButtons.clear(); - -- for (RecipeBookCategories recipebookcategories : RecipeBookCategories.getCategories(this.menu.getRecipeBookType())) { -+ for(RecipeBookCategories recipebookcategories : this.menu.getRecipeBookCategories()) { - this.tabButtons.add(new RecipeBookTabButton(recipebookcategories)); - } - -@@ -297,7 +_,7 @@ - } - - if (itemstack != null && this.minecraft.screen != null) { -- p_282776_.renderComponentTooltip(this.minecraft.font, Screen.getTooltipFromItem(this.minecraft, itemstack), p_282948_, p_283050_); -+ p_282776_.renderComponentTooltip(this.minecraft.font, Screen.getTooltipFromItem(this.minecraft, itemstack), p_282948_, p_283050_, itemstack); - } - } - +@@ -268,7 +_,8 @@ + + for (RecipeBookTabButton recipebooktabbutton : this.tabButtons) { + ExtendedRecipeBookCategory extendedrecipebookcategory = recipebooktabbutton.getCategory(); +- if (extendedrecipebookcategory instanceof SearchRecipeBookCategory) { ++ // Neo: Add support for modded search categories. ++ if (extendedrecipebookcategory instanceof SearchRecipeBookCategory || net.neoforged.neoforge.client.RecipeBookManager.getSearchCategories().containsKey(extendedrecipebookcategory)) { + recipebooktabbutton.visible = true; + recipebooktabbutton.setPosition(i, j + 27 * l++); + } else if (recipebooktabbutton.updateVisibility(this.book)) { diff --git a/patches/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java.patch b/patches/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java.patch index 1c369de99a..55fa739634 100644 --- a/patches/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java.patch +++ b/patches/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java.patch @@ -1,25 +1,25 @@ --- a/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java +++ b/net/minecraft/client/gui/screens/worldselection/CreateWorldScreen.java -@@ -118,6 +_,7 @@ - public static void openFresh(Minecraft p_232897_, @Nullable Screen p_232898_) { - queueLoadScreen(p_232897_, PREPARING_WORLD_DATA); - PackRepository packrepository = new PackRepository(new ServerPacksSource(p_232897_.directoryValidator())); +@@ -169,6 +_,7 @@ + ) { + queueLoadScreen(p_372818_, PREPARING_WORLD_DATA); + PackRepository packrepository = new PackRepository(new ServerPacksSource(p_372818_.directoryValidator())); + net.neoforged.neoforge.resource.ResourcePackLoader.populatePackRepository(packrepository, net.minecraft.server.packs.PackType.SERVER_DATA, false); WorldLoader.InitConfig worldloader$initconfig = createDefaultLoadConfig(packrepository, WorldDataConfiguration.DEFAULT); CompletableFuture completablefuture = WorldLoader.load( worldloader$initconfig, -@@ -243,6 +_,10 @@ - WorldCreationContext worldcreationcontext = this.uiState.getSettings(); - LevelSettings levelsettings = this.createLevelSettings(flag); - WorldData worlddata = new PrimaryLevelData(levelsettings, worldcreationcontext.options(), p_250577_, p_249994_); -+ if(worlddata.worldGenSettingsLifecycle() != Lifecycle.stable()) { +@@ -307,6 +_,10 @@ + SystemToast.onPackCopyFailure(this.minecraft, s); + return false; + } else { ++ if (p_374211_.worldGenSettingsLifecycle() != Lifecycle.stable()) { + // Neo: set experimental settings confirmation flag so user is not shown warning on next open -+ ((PrimaryLevelData)worlddata).withConfirmedWarning(true); ++ ((PrimaryLevelData)p_374211_).withConfirmedWarning(true); + } this.minecraft .createWorldOpenFlows() - .createLevelFromExistingSettings(optional.get(), worldcreationcontext.dataPackResources(), p_249152_, worlddata); -@@ -428,7 +_,7 @@ + .createLevelFromExistingSettings(optional.get(), worldcreationcontext.dataPackResources(), p_249152_, p_374211_); +@@ -491,7 +_,7 @@ if (p_269627_) { p_270552_.accept(this.uiState.getSettings().dataConfiguration()); } else { @@ -28,7 +28,7 @@ } }, Component.translatable("dataPack.validation.failed"), -@@ -547,6 +_,7 @@ +@@ -605,6 +_,7 @@ if (path != null) { if (this.tempDataPackRepository == null) { this.tempDataPackRepository = ServerPacksSource.createPackRepository(path, this.packValidator); diff --git a/patches/net/minecraft/client/gui/screens/worldselection/WorldCreationContext.java.patch b/patches/net/minecraft/client/gui/screens/worldselection/WorldCreationContext.java.patch index d7e34577d4..deb2ee6006 100644 --- a/patches/net/minecraft/client/gui/screens/worldselection/WorldCreationContext.java.patch +++ b/patches/net/minecraft/client/gui/screens/worldselection/WorldCreationContext.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/client/gui/screens/worldselection/WorldCreationContext.java +++ b/net/minecraft/client/gui/screens/worldselection/WorldCreationContext.java -@@ -74,6 +_,10 @@ +@@ -95,6 +_,10 @@ ); } + public WorldCreationContext withDataConfiguration(WorldDataConfiguration dataConfiguration) { -+ return new WorldCreationContext(this.options, this.datapackDimensions, this.selectedDimensions, this.worldgenRegistries, this.dataPackResources, dataConfiguration); ++ return new WorldCreationContext(this.options, this.datapackDimensions, this.selectedDimensions, this.worldgenRegistries, this.dataPackResources, dataConfiguration, this.initialWorldCreationOptions); + } + public RegistryAccess.Frozen worldgenLoadContext() { diff --git a/patches/net/minecraft/client/gui/screens/worldselection/WorldCreationUiState.java.patch b/patches/net/minecraft/client/gui/screens/worldselection/WorldCreationUiState.java.patch index b1747f20d9..c362174fd4 100644 --- a/patches/net/minecraft/client/gui/screens/worldselection/WorldCreationUiState.java.patch +++ b/patches/net/minecraft/client/gui/screens/worldselection/WorldCreationUiState.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/worldselection/WorldCreationUiState.java +++ b/net/minecraft/client/gui/screens/worldselection/WorldCreationUiState.java -@@ -225,7 +_,7 @@ +@@ -236,7 +_,7 @@ @Nullable public PresetEditor getPresetEditor() { Holder holder = this.getWorldType().preset(); diff --git a/patches/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java.patch b/patches/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java.patch index 9dc24fd572..37bde45b2d 100644 --- a/patches/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java.patch +++ b/patches/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java +++ b/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java -@@ -65,7 +_,7 @@ +@@ -66,7 +_,7 @@ import org.slf4j.Logger; @OnlyIn(Dist.CLIENT) @@ -9,7 +9,7 @@ private static final Logger LOGGER = LogUtils.getLogger(); private static final UUID WORLD_PACK_ID = UUID.fromString("640a6a92-b6cb-48a0-b391-831586500359"); private final Minecraft minecraft; -@@ -210,7 +_,10 @@ +@@ -215,7 +_,10 @@ component1 = Component.translatable("selectWorld.backupWarning.customized"); } else { component = Component.translatable("selectWorld.backupQuestion.experimental"); @@ -21,7 +21,7 @@ } this.minecraft.setScreen(new BackupConfirmScreen(p_307323_, (p_307085_, p_307086_) -> { -@@ -377,10 +_,19 @@ +@@ -381,10 +_,19 @@ WorldData worlddata = p_330774_.worldData(); boolean flag = worlddata.worldGenOptions().isOldCustomizedWorld(); boolean flag1 = worlddata.worldGenSettingsLifecycle() != Lifecycle.stable(); diff --git a/patches/net/minecraft/client/gui/screens/worldselection/WorldSelectionList.java.patch b/patches/net/minecraft/client/gui/screens/worldselection/WorldSelectionList.java.patch index 93857dce7b..bd2c7fd8b2 100644 --- a/patches/net/minecraft/client/gui/screens/worldselection/WorldSelectionList.java.patch +++ b/patches/net/minecraft/client/gui/screens/worldselection/WorldSelectionList.java.patch @@ -8,15 +8,15 @@ static final Logger LOGGER = LogUtils.getLogger(); static final Component FROM_NEWER_TOOLTIP_1 = Component.translatable("selectWorld.tooltip.fromNewerVersion1").withStyle(ChatFormatting.RED); static final Component FROM_NEWER_TOOLTIP_2 = Component.translatable("selectWorld.tooltip.fromNewerVersion2").withStyle(ChatFormatting.RED); -@@ -405,6 +_,7 @@ - RenderSystem.enableBlend(); - p_281612_.blit(this.icon.textureLocation(), p_282820_, p_283181_, 0.0F, 0.0F, 32, 32, 32, 32); - RenderSystem.disableBlend(); +@@ -403,6 +_,7 @@ + p_281612_.drawString(this.minecraft.font, s1, p_282820_ + 32 + 3, p_283181_ + 9 + 3, -8355712, false); + p_281612_.drawString(this.minecraft.font, component, p_282820_ + 32 + 3, p_283181_ + 9 + 9 + 3, -8355712, false); + p_281612_.blit(RenderType::guiTextured, this.icon.textureLocation(), p_282820_, p_283181_, 0.0F, 0.0F, 32, 32, 32, 32); + renderExperimentalWarning(p_281612_, p_283204_, p_283025_, p_283181_, p_282820_); if (this.minecraft.options.touchscreen().get() || p_283396_) { p_281612_.fill(p_282820_, p_283181_, p_282820_ + 32, p_283181_ + 32, -1601138544); int j = p_283204_ - p_282820_; -@@ -511,6 +_,7 @@ +@@ -509,6 +_,7 @@ this.doDeleteWorld(); } @@ -24,7 +24,7 @@ this.minecraft.setScreen(this.screen); }, Component.translatable("selectWorld.deleteQuestion"), -@@ -647,6 +_,19 @@ +@@ -645,6 +_,19 @@ public String getLevelName() { return this.summary.getLevelName(); @@ -34,7 +34,7 @@ + private void renderExperimentalWarning(GuiGraphics guiGraphics, int mouseX, int mouseY, int top, int left) { + if (this.summary.getSettings() != null && this.summary.getSettings().getLifecycle().equals(com.mojang.serialization.Lifecycle.experimental())) { + int leftStart = left + WorldSelectionList.this.getRowWidth(); -+ guiGraphics.blit(WorldSelectionList.FORGE_EXPERIMENTAL_WARNING_ICON, leftStart - 36, top, 0.0F, 0.0F, 32, 32, 32, 32); ++ guiGraphics.blit(RenderType::guiTextured, WorldSelectionList.FORGE_EXPERIMENTAL_WARNING_ICON, leftStart - 36, top, 0.0F, 0.0F, 32, 32, 32, 32); + if (WorldSelectionList.this.getEntryAtPosition(mouseX, mouseY) == this && mouseX > leftStart - 36 && mouseX < leftStart) { + var font = Minecraft.getInstance().font; + List tooltip = font.split(Component.translatable("neoforge.experimentalsettings.tooltip"), 200); diff --git a/patches/net/minecraft/client/main/Main.java.patch b/patches/net/minecraft/client/main/Main.java.patch index 4f5d0f090e..c66fe4ba49 100644 --- a/patches/net/minecraft/client/main/Main.java.patch +++ b/patches/net/minecraft/client/main/Main.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/main/Main.java +++ b/net/minecraft/client/main/Main.java -@@ -111,7 +_,7 @@ +@@ -120,7 +_,7 @@ CrashReport.preload(); logger = LogUtils.getLogger(); s1 = "Bootstrap"; diff --git a/patches/net/minecraft/client/model/HumanoidModel.java.patch b/patches/net/minecraft/client/model/HumanoidModel.java.patch index b067ead7de..5d2e521e41 100644 --- a/patches/net/minecraft/client/model/HumanoidModel.java.patch +++ b/patches/net/minecraft/client/model/HumanoidModel.java.patch @@ -1,24 +1,24 @@ --- a/net/minecraft/client/model/HumanoidModel.java +++ b/net/minecraft/client/model/HumanoidModel.java -@@ -306,6 +_,8 @@ +@@ -257,6 +_,8 @@ case BRUSH: this.rightArm.xRot = this.rightArm.xRot * 0.5F - (float) (Math.PI / 5); this.rightArm.yRot = 0.0F; + default: -+ this.rightArmPose.applyTransform(this, p_102876_, net.minecraft.world.entity.HumanoidArm.RIGHT); ++ p_362238_.applyTransform(this, p_364666_, net.minecraft.world.entity.HumanoidArm.RIGHT); } } -@@ -348,6 +_,8 @@ +@@ -299,6 +_,8 @@ case BRUSH: this.leftArm.xRot = this.leftArm.xRot * 0.5F - (float) (Math.PI / 5); this.leftArm.yRot = 0.0F; + default: -+ this.leftArmPose.applyTransform(this, p_102879_, net.minecraft.world.entity.HumanoidArm.LEFT); ++ p_361463_.applyTransform(this, p_361741_, net.minecraft.world.entity.HumanoidArm.LEFT); } } -@@ -446,7 +_,7 @@ +@@ -376,7 +_,7 @@ } @OnlyIn(Dist.CLIENT) @@ -27,7 +27,7 @@ EMPTY(false), ITEM(false), BLOCK(false), -@@ -459,13 +_,31 @@ +@@ -389,13 +_,31 @@ BRUSH(false); private final boolean twoHanded; @@ -50,7 +50,7 @@ return this.twoHanded; + } + -+ public void applyTransform(HumanoidModel model, T entity, net.minecraft.world.entity.HumanoidArm arm) { ++ public void applyTransform(HumanoidModel model, T entity, net.minecraft.world.entity.HumanoidArm arm) { + if (this.forgeArmPose != null) this.forgeArmPose.applyTransform(model, entity, arm); + } + diff --git a/patches/net/minecraft/client/model/HierarchicalModel.java.patch b/patches/net/minecraft/client/model/Model.java.patch similarity index 52% rename from patches/net/minecraft/client/model/HierarchicalModel.java.patch rename to patches/net/minecraft/client/model/Model.java.patch index b9e5a58ff6..8dfabd2621 100644 --- a/patches/net/minecraft/client/model/HierarchicalModel.java.patch +++ b/patches/net/minecraft/client/model/Model.java.patch @@ -1,48 +1,51 @@ ---- a/net/minecraft/client/model/HierarchicalModel.java -+++ b/net/minecraft/client/model/HierarchicalModel.java -@@ -27,6 +_,10 @@ - super(p_170623_); +--- a/net/minecraft/client/model/Model.java ++++ b/net/minecraft/client/model/Model.java +@@ -28,6 +_,10 @@ + this.allParts = p_368583_.getAllParts().toList(); } + protected static net.neoforged.neoforge.client.entity.animation.json.AnimationHolder getAnimation(ResourceLocation key) { + return net.neoforged.neoforge.client.entity.animation.json.AnimationLoader.INSTANCE.getAnimationHolder(key); + } + - @Override - public void renderToBuffer(PoseStack p_170625_, VertexConsumer p_170626_, int p_170627_, int p_170628_, int p_350603_) { - this.root().render(p_170625_, p_170626_, p_170627_, p_170628_, p_350603_); -@@ -44,18 +_,34 @@ - this.animate(p_233382_, p_233383_, p_233384_, 1.0F); + public final RenderType renderType(ResourceLocation p_103120_) { + return this.renderType.apply(p_103120_); + } +@@ -64,12 +_,20 @@ + this.animate(p_364820_, p_361968_, p_362503_, 1.0F); } + protected void animate(AnimationState animationState, net.neoforged.neoforge.client.entity.animation.json.AnimationHolder animation, float ageInTicks) { + this.animate(animationState, animation.get(), ageInTicks); + } + - protected void animateWalk(AnimationDefinition p_268159_, float p_268057_, float p_268347_, float p_268138_, float p_268165_) { - long i = (long)(p_268057_ * 50.0F * p_268138_); - float f = Math.min(p_268347_ * p_268165_, 1.0F); - KeyframeAnimations.animate(this, p_268159_, i, f, ANIMATION_VECTOR_CACHE); + protected void animateWalk(AnimationDefinition p_362453_, float p_365353_, float p_364840_, float p_362983_, float p_361956_) { + long i = (long)(p_365353_ * 50.0F * p_362983_); + float f = Math.min(p_364840_ * p_361956_, 1.0F); + KeyframeAnimations.animate(this, p_362453_, i, f, ANIMATION_VECTOR_CACHE); } + protected void animateWalk(net.neoforged.neoforge.client.entity.animation.json.AnimationHolder animation, float limbSwing, float limbSwingAmount, float maxAnimationSpeed, float animationScaleFactor) { + this.animateWalk(animation.get(), limbSwing, limbSwingAmount, maxAnimationSpeed, animationScaleFactor); + } + - protected void animate(AnimationState p_233386_, AnimationDefinition p_233387_, float p_233388_, float p_233389_) { - p_233386_.updateTime(p_233388_, p_233389_); - p_233386_.ifStarted(p_233392_ -> KeyframeAnimations.animate(this, p_233387_, p_233392_.getAccumulatedTime(), 1.0F, ANIMATION_VECTOR_CACHE)); + protected void animate(AnimationState p_364413_, AnimationDefinition p_361459_, float p_361947_, float p_362164_) { + p_364413_.ifStarted( + p_361743_ -> KeyframeAnimations.animate( +@@ -78,8 +_,16 @@ + ); } + protected void animate(AnimationState animationState, net.neoforged.neoforge.client.entity.animation.json.AnimationHolder animation, float ageInTicks, float speed) { + this.animate(animationState, animation.get(), ageInTicks, speed); + } + - protected void applyStatic(AnimationDefinition p_288996_) { - KeyframeAnimations.animate(this, p_288996_, 0L, 1.0F, ANIMATION_VECTOR_CACHE); + protected void applyStatic(AnimationDefinition p_362055_) { + KeyframeAnimations.animate(this, p_362055_, 0L, 1.0F, ANIMATION_VECTOR_CACHE); + } + + protected void applyStatic(net.neoforged.neoforge.client.entity.animation.json.AnimationHolder animation) { + this.applyStatic(animation.get()); } - } + + @OnlyIn(Dist.CLIENT) diff --git a/patches/net/minecraft/client/model/geom/LayerDefinitions.java.patch b/patches/net/minecraft/client/model/geom/LayerDefinitions.java.patch index 2bb68d9584..de5171aeea 100644 --- a/patches/net/minecraft/client/model/geom/LayerDefinitions.java.patch +++ b/patches/net/minecraft/client/model/geom/LayerDefinitions.java.patch @@ -1,18 +1,9 @@ --- a/net/minecraft/client/model/geom/LayerDefinitions.java +++ b/net/minecraft/client/model/geom/LayerDefinitions.java -@@ -316,7 +_,7 @@ - LayerDefinition layerdefinition22 = ChestRaftModel.createBodyModel(); - - for (Boat.Type boat$type : Boat.Type.values()) { -- if (boat$type == Boat.Type.BAMBOO) { -+ if (boat$type.isRaft()) { - builder.put(ModelLayers.createBoatModelName(boat$type), layerdefinition21); - builder.put(ModelLayers.createChestBoatModelName(boat$type), layerdefinition22); - } else { -@@ -329,6 +_,7 @@ - WoodType.values().forEach(p_171114_ -> builder.put(ModelLayers.createSignModelName(p_171114_), layerdefinition23)); - LayerDefinition layerdefinition24 = HangingSignRenderer.createHangingSignLayer(); - WoodType.values().forEach(p_247864_ -> builder.put(ModelLayers.createHangingSignModelName(p_247864_), layerdefinition24)); +@@ -454,6 +_,7 @@ + builder.put(ModelLayers.createWallSignModelName(p_359128_), layerdefinition54); + builder.put(ModelLayers.createHangingSignModelName(p_359128_), layerdefinition55); + }); + net.neoforged.neoforge.client.ClientHooks.loadLayerDefinitions(builder); ImmutableMap immutablemap = builder.build(); List list = ModelLayers.getKnownLocations().filter(p_171117_ -> !immutablemap.containsKey(p_171117_)).collect(Collectors.toList()); diff --git a/patches/net/minecraft/client/model/geom/ModelLayers.java.patch b/patches/net/minecraft/client/model/geom/ModelLayers.java.patch index cbb66bf895..9b9691073a 100644 --- a/patches/net/minecraft/client/model/geom/ModelLayers.java.patch +++ b/patches/net/minecraft/client/model/geom/ModelLayers.java.patch @@ -1,36 +1,18 @@ --- a/net/minecraft/client/model/geom/ModelLayers.java +++ b/net/minecraft/client/model/geom/ModelLayers.java -@@ -213,27 +_,33 @@ +@@ -301,15 +_,18 @@ } - public static ModelLayerLocation createRaftModelName(Boat.Type p_252002_) { -- return createLocation("raft/" + p_252002_.getName(), "main"); -+ ResourceLocation location = ResourceLocation.parse(p_252002_.getName()); -+ return new ModelLayerLocation(location.withPrefix("raft/"), "main"); - } - - public static ModelLayerLocation createChestRaftModelName(Boat.Type p_248520_) { -- return createLocation("chest_raft/" + p_248520_.getName(), "main"); -+ ResourceLocation location = ResourceLocation.parse(p_248520_.getName()); -+ return new ModelLayerLocation(location.withPrefix("chest_raft/"), "main"); - } - - public static ModelLayerLocation createBoatModelName(Boat.Type p_171290_) { -- return createLocation("boat/" + p_171290_.getName(), "main"); -+ ResourceLocation location = ResourceLocation.parse(p_171290_.getName()); -+ return new ModelLayerLocation(location.withPrefix("boat/"), "main"); - } - - public static ModelLayerLocation createChestBoatModelName(Boat.Type p_233551_) { -- return createLocation("chest_boat/" + p_233551_.getName(), "main"); -+ ResourceLocation location = ResourceLocation.parse(p_233551_.getName()); -+ return new ModelLayerLocation(location.withPrefix("chest_boat/"), "main"); + public static ModelLayerLocation createStandingSignModelName(WoodType p_171292_) { +- return createLocation("sign/standing/" + p_171292_.name(), "main"); ++ ResourceLocation location = ResourceLocation.parse(p_171292_.name()); ++ return new ModelLayerLocation(location.withPrefix("sign/standing/"), "main"); } - public static ModelLayerLocation createSignModelName(WoodType p_171292_) { -- return createLocation("sign/" + p_171292_.name(), "main"); -+ ResourceLocation location = ResourceLocation.parse(p_171292_.name()); -+ return new ModelLayerLocation(location.withPrefix("sign/"), "main"); + public static ModelLayerLocation createWallSignModelName(WoodType p_360963_) { +- return createLocation("sign/wall/" + p_360963_.name(), "main"); ++ ResourceLocation location = ResourceLocation.parse(p_360963_.name()); ++ return new ModelLayerLocation(location.withPrefix("sign/wall/"), "main"); } public static ModelLayerLocation createHangingSignModelName(WoodType p_252225_) { diff --git a/patches/net/minecraft/client/multiplayer/ClientChunkCache.java.patch b/patches/net/minecraft/client/multiplayer/ClientChunkCache.java.patch index 8729039cea..768dd4d9eb 100644 --- a/patches/net/minecraft/client/multiplayer/ClientChunkCache.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientChunkCache.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/client/multiplayer/ClientChunkCache.java +++ b/net/minecraft/client/multiplayer/ClientChunkCache.java -@@ -63,6 +_,7 @@ +@@ -65,6 +_,7 @@ int i = this.storage.getIndex(p_295783_.x, p_295783_.z); LevelChunk levelchunk = this.storage.getChunk(i); if (isValidChunk(levelchunk, p_295783_.x, p_295783_.z)) { + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.ChunkEvent.Unload(levelchunk)); - this.storage.replace(i, levelchunk, null); + this.storage.drop(i, levelchunk); } } -@@ -123,6 +_,7 @@ +@@ -125,6 +_,7 @@ } this.level.onChunkLoaded(chunkpos); diff --git a/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch b/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch index 8bc8fe4f9c..0cafb8a7b2 100644 --- a/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java +++ b/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java -@@ -88,6 +_,10 @@ +@@ -84,6 +_,10 @@ protected final Map serverCookies; protected Map customReportDetails; protected ServerLinks serverLinks; @@ -11,8 +11,8 @@ protected ClientCommonPacketListenerImpl(Minecraft p_295454_, Connection p_294773_, CommonListenerCookie p_294647_) { this.minecraft = p_295454_; -@@ -100,6 +_,8 @@ - this.strictErrorHandling = p_294647_.strictErrorHandling(); +@@ -95,6 +_,8 @@ + this.serverCookies = p_294647_.serverCookies(); this.customReportDetails = p_294647_.customReportDetails(); this.serverLinks = p_294647_.serverLinks(); + // Neo: Set the connection type based on the cookie from the previous phase. @@ -20,7 +20,7 @@ } @Override -@@ -149,6 +_,33 @@ +@@ -142,6 +_,33 @@ @Override public void handleCustomPayload(ClientboundCustomPayloadPacket p_295727_) { @@ -54,7 +54,7 @@ CustomPacketPayload custompacketpayload = p_295727_.payload(); if (!(custompacketpayload instanceof DiscardedPayload)) { PacketUtils.ensureRunningOnSameThread(p_295727_, this, this.minecraft); -@@ -285,6 +_,8 @@ +@@ -278,6 +_,8 @@ } public void send(Packet p_295097_) { @@ -63,7 +63,7 @@ this.connection.send(p_295097_); } -@@ -292,6 +_,9 @@ +@@ -285,6 +_,9 @@ public void onDisconnect(DisconnectionDetails p_350760_) { this.telemetryManager.onDisconnect(); this.minecraft.disconnect(this.createDisconnectScreen(p_350760_), this.isTransferring); @@ -73,7 +73,7 @@ LOGGER.warn("Client disconnected with reason: {}", p_350760_.reason().getString()); } -@@ -415,5 +_,10 @@ +@@ -409,5 +_,10 @@ @OnlyIn(Dist.CLIENT) static record PendingRequest(UUID id, URL url, String hash) { } diff --git a/patches/net/minecraft/client/multiplayer/ClientConfigurationPacketListenerImpl.java.patch b/patches/net/minecraft/client/multiplayer/ClientConfigurationPacketListenerImpl.java.patch index 5f8469c35d..d26216aa13 100644 --- a/patches/net/minecraft/client/multiplayer/ClientConfigurationPacketListenerImpl.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientConfigurationPacketListenerImpl.java.patch @@ -31,9 +31,9 @@ new ClientPacketListener( this.minecraft, this.connection, -@@ -137,12 +_,19 @@ +@@ -136,12 +_,19 @@ + this.serverCookies, this.chatState, - this.strictErrorHandling, this.customReportDetails, - this.serverLinks + this.serverLinks, @@ -53,7 +53,7 @@ } @Override -@@ -154,5 +_,51 @@ +@@ -153,5 +_,51 @@ public void onDisconnect(DisconnectionDetails p_351005_) { super.onDisconnect(p_351005_); this.minecraft.clearDownloadedResourcePacks(); diff --git a/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch b/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch index e3eabb22b7..a1d3332be3 100644 --- a/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientLevel.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/multiplayer/ClientLevel.java +++ b/net/minecraft/client/multiplayer/ClientLevel.java -@@ -121,6 +_,7 @@ +@@ -126,6 +_,7 @@ p_194170_.put( BiomeColors.WATER_COLOR_RESOLVER, new BlockTintCache(p_194168_ -> this.calculateBlockTint(p_194168_, BiomeColors.WATER_COLOR_RESOLVER)) ); @@ -8,16 +8,16 @@ } ); private final ClientChunkCache chunkSource; -@@ -128,6 +_,8 @@ - private int serverSimulationDistance; - private final BlockStatePredictionHandler blockStatePredictionHandler = new BlockStatePredictionHandler(); +@@ -135,6 +_,8 @@ + private final int seaLevel; + private boolean tickDayTime; private static final Set MARKER_PARTICLE_ITEMS = Set.of(Items.BARRIER, Items.LIGHT); + private final it.unimi.dsi.fastutil.ints.Int2ObjectMap> partEntities = new it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap<>(); + private final net.neoforged.neoforge.client.model.data.ModelDataManager modelDataManager = new net.neoforged.neoforge.client.model.data.ModelDataManager(this); public void handleBlockChangedAck(int p_233652_) { this.blockStatePredictionHandler.endPredictionsUpTo(p_233652_, this); -@@ -157,10 +_,15 @@ +@@ -164,10 +_,15 @@ @Override public boolean setBlock(BlockPos p_233643_, BlockState p_233644_, int p_233645_, int p_233646_) { if (this.blockStatePredictionHandler.isPredicting()) { @@ -33,37 +33,37 @@ } return flag; -@@ -192,6 +_,7 @@ - this.serverSimulationDistance = p_205510_; +@@ -201,6 +_,7 @@ + this.serverSimulationDistance = p_363776_; this.updateSkyBrightness(); this.prepareWeather(); + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.LevelEvent.Load(this)); } public void queueLightUpdate(Runnable p_194172_) { -@@ -238,7 +_,7 @@ +@@ -244,7 +_,7 @@ private void tickTime() { - this.setGameTime(this.levelData.getGameTime() + 1L); - if (this.levelData.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) { -- this.setDayTime(this.levelData.getDayTime() + 1L); -+ this.setDayTime(this.levelData.getDayTime() + advanceDaytime()); + this.clientLevelData.setGameTime(this.clientLevelData.getGameTime() + 1L); + if (this.tickDayTime) { +- this.clientLevelData.setDayTime(this.clientLevelData.getDayTime() + 1L); ++ this.clientLevelData.setDayTime(this.clientLevelData.getDayTime() + advanceDaytime()); } } -@@ -282,7 +_,11 @@ +@@ -283,7 +_,11 @@ p_104640_.setOldPosAndRot(); p_104640_.tickCount++; - this.getProfiler().push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(p_104640_.getType()).toString()); + Profiler.get().push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(p_104640_.getType()).toString()); - p_104640_.tick(); + // Neo: Permit cancellation of Entity#tick via EntityTickEvent.Pre + if (!net.neoforged.neoforge.event.EventHooks.fireEntityTickPre(p_104640_).isCanceled()) { + p_104640_.tick(); + net.neoforged.neoforge.event.EventHooks.fireEntityTickPost(p_104640_); + } - this.getProfiler().pop(); + Profiler.get().pop(); for (Entity entity : p_104640_.getPassengers()) { -@@ -330,8 +_,10 @@ +@@ -335,8 +_,10 @@ } public void addEntity(Entity p_104741_) { @@ -74,7 +74,7 @@ } public void removeEntity(int p_171643_, Entity.RemovalReason p_171644_) { -@@ -502,6 +_,13 @@ +@@ -507,6 +_,13 @@ float p_263349_, long p_263408_ ) { @@ -88,7 +88,7 @@ if (p_263381_ == this.minecraft.player) { this.playSound(p_263372_, p_263404_, p_263365_, p_263335_.value(), p_263417_, p_263416_, p_263349_, false, p_263408_); } -@@ -511,6 +_,12 @@ +@@ -516,6 +_,12 @@ public void playSeededSound( @Nullable Player p_263514_, Entity p_263536_, Holder p_263518_, SoundSource p_263487_, float p_263538_, float p_263524_, long p_263509_ ) { @@ -101,7 +101,7 @@ if (p_263514_ == this.minecraft.player) { this.minecraft.getSoundManager().play(new EntityBoundSoundInstance(p_263518_.value(), p_263487_, p_263538_, p_263524_, p_263536_, p_263509_)); } -@@ -1033,6 +_,7 @@ +@@ -1045,6 +_,7 @@ } public void setDifficulty(Difficulty p_104852_) { @@ -109,7 +109,7 @@ this.difficulty = p_104852_; } -@@ -1069,14 +_,75 @@ +@@ -1081,14 +_,75 @@ if (p_171712_ instanceof AbstractClientPlayer) { ClientLevel.this.players.add((AbstractClientPlayer)p_171712_); } diff --git a/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch b/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch index c244326521..a1ad4df3f6 100644 --- a/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientPacketListener.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/multiplayer/ClientPacketListener.java +++ b/net/minecraft/client/multiplayer/ClientPacketListener.java -@@ -344,6 +_,7 @@ +@@ -367,6 +_,7 @@ private final ChunkBatchSizeCalculator chunkBatchSizeCalculator = new ChunkBatchSizeCalculator(); private final PingDebugMonitor pingDebugMonitor; private final DebugSampleSubscriber debugSampleSubscriber; @@ -8,17 +8,17 @@ @Nullable private LevelLoadStatusManager levelLoadStatusManager; private boolean serverEnforcesSecureChat; -@@ -366,7 +_,8 @@ +@@ -388,7 +_,8 @@ p_253924_.gui.getChat().restoreState(p_295121_.chatState()); } - this.potionBrewing = PotionBrewing.bootstrap(this.enabledFeatures); + this.connectionType = p_295121_.connectionType(); + this.potionBrewing = PotionBrewing.bootstrap(this.enabledFeatures, this.registryAccess); + this.fuelValues = FuelValues.vanillaBurnTimes(p_295121_.receivedRegistries(), this.enabledFeatures); } - public ClientSuggestionProvider getSuggestionsProvider() { -@@ -427,12 +_,13 @@ +@@ -451,12 +_,13 @@ this.minecraft.debugRenderer.clear(); this.minecraft.player.resetPos(); @@ -33,9 +33,9 @@ this.minecraft.player.setReducedDebugInfo(p_105030_.reducedDebugInfo()); this.minecraft.player.setShowDeathScreen(p_105030_.showDeathScreen()); this.minecraft.player.setDoLimitedCrafting(p_105030_.doLimitedCrafting()); -@@ -828,7 +_,8 @@ +@@ -900,7 +_,8 @@ + this.serverCookies, chatcomponent$state, - this.strictErrorHandling, this.customReportDetails, - this.serverLinks + this.serverLinks, @@ -43,7 +43,7 @@ ) ) ); -@@ -1142,7 +_,7 @@ +@@ -1217,7 +_,7 @@ localplayer1 = this.minecraft.gameMode.createPlayer(this.level, localplayer.getStats(), localplayer.getRecipeBook()); } @@ -52,15 +52,15 @@ localplayer1.setId(localplayer.getId()); this.minecraft.player = localplayer1; if (flag) { -@@ -1164,6 +_,7 @@ +@@ -1245,6 +_,7 @@ + localplayer1.getAttributes().assignBaseValues(localplayer.getAttributes()); } - localplayer1.resetPos(); + net.neoforged.neoforge.client.ClientHooks.firePlayerRespawn(this.minecraft.gameMode, localplayer, localplayer1, localplayer1.connection.connection); this.level.addEntity(localplayer1); - localplayer1.setYRot(-180.0F); localplayer1.input = new KeyboardInput(this.minecraft.options); -@@ -1306,10 +_,7 @@ + this.minecraft.gameMode.adjustPlayer(localplayer1); +@@ -1391,10 +_,7 @@ PacketUtils.ensureRunningOnSameThread(p_104976_, this, this.minecraft); BlockPos blockpos = p_104976_.getPos(); this.minecraft.level.getBlockEntity(blockpos, p_104976_.getType()).ifPresent(p_337415_ -> { @@ -72,7 +72,7 @@ if (p_337415_ instanceof CommandBlockEntity && this.minecraft.screen instanceof CommandBlockEditScreen) { ((CommandBlockEditScreen)this.minecraft.screen).updateGui(); -@@ -1420,9 +_,15 @@ +@@ -1505,9 +_,15 @@ } } @@ -89,7 +89,7 @@ } @Override -@@ -1471,7 +_,9 @@ +@@ -1555,7 +_,9 @@ @Override public void handleCommands(ClientboundCommandsPacket p_104990_) { PacketUtils.ensureRunningOnSameThread(p_104990_, this, this.minecraft); @@ -100,28 +100,33 @@ } @Override -@@ -1493,6 +_,7 @@ - ClientRecipeBook clientrecipebook = this.minecraft.player.getRecipeBook(); - clientrecipebook.setupCollections(this.recipeManager.getOrderedRecipes(), this.minecraft.level.registryAccess()); - this.searchTrees.updateRecipes(clientrecipebook, this.registryAccess); -+ net.neoforged.neoforge.client.ClientHooks.onRecipesUpdated(this.recipeManager); +@@ -1574,6 +_,11 @@ + public void handleUpdateRecipes(ClientboundUpdateRecipesPacket p_105132_) { + PacketUtils.ensureRunningOnSameThread(p_105132_, this, this.minecraft); + this.recipes = new ClientRecipeContainer(p_105132_.itemSets(), p_105132_.stonecutterRecipes()); ++ ++ // Neo: abuse recipe sync to overwrite fuel values with datamap values after their sync (tag update doesn't fire on initial sync and the constructor is too early) ++ if (this.connectionType.isNeoForge()) { ++ this.fuelValues = net.neoforged.neoforge.common.DataMapHooks.populateFuelValues(this.registryAccess, this.enabledFeatures); ++ } } @Override -@@ -1595,8 +_,10 @@ - TagCollector tagcollector = new TagCollector(); - p_294888_.getTags().forEach(tagcollector::append); - tagcollector.updateTags(this.registryAccess, this.connection.isMemoryConnection()); -- List list = List.copyOf(CreativeModeTabs.searchTab().getDisplayItems()); -- this.searchTrees.updateCreativeTags(list); +@@ -1698,8 +_,11 @@ + }); + list.forEach(Registry.PendingTags::apply); + this.fuelValues = FuelValues.vanillaBurnTimes(this.registryAccess, this.enabledFeatures); +- List list1 = List.copyOf(CreativeModeTabs.searchTab().getDisplayItems()); +- this.searchTrees.updateCreativeTags(list1); ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.TagsUpdatedEvent(this.registryAccess, true, flag)); + CreativeModeTabs.allTabs().stream().filter(net.minecraft.world.item.CreativeModeTab::hasSearchBar).forEach(tab -> { -+ List list = List.copyOf(tab.getDisplayItems()); -+ this.searchTrees.updateCreativeTags(list, net.neoforged.neoforge.client.CreativeModeTabSearchRegistry.getTagSearchKey(tab)); ++ List stacks = List.copyOf(tab.getDisplayItems()); ++ this.searchTrees.updateCreativeTags(stacks, net.neoforged.neoforge.client.CreativeModeTabSearchRegistry.getTagSearchKey(tab)); + }); } @Override -@@ -2407,6 +_,8 @@ +@@ -2526,6 +_,8 @@ } public void sendChat(String p_249888_) { @@ -130,7 +135,7 @@ Instant instant = Instant.now(); long i = Crypt.SaltSupplier.getLong(); LastSeenMessagesTracker.Update lastseenmessagestracker$update = this.lastSeenMessages.generateAndApplyUpdate(); -@@ -2416,6 +_,7 @@ +@@ -2535,6 +_,7 @@ } public void sendCommand(String p_250092_) { @@ -138,7 +143,7 @@ SignableCommand signablecommand = SignableCommand.of(this.parseCommand(p_250092_)); if (signablecommand.arguments().isEmpty()) { this.send(new ServerboundChatCommandPacket(p_250092_)); -@@ -2490,6 +_,10 @@ +@@ -2622,6 +_,10 @@ public Scoreboard scoreboard() { return this.scoreboard; diff --git a/patches/net/minecraft/client/multiplayer/CommonListenerCookie.java.patch b/patches/net/minecraft/client/multiplayer/CommonListenerCookie.java.patch index 40db5789ae..da0f788ed2 100644 --- a/patches/net/minecraft/client/multiplayer/CommonListenerCookie.java.patch +++ b/patches/net/minecraft/client/multiplayer/CommonListenerCookie.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/client/multiplayer/CommonListenerCookie.java +++ b/net/minecraft/client/multiplayer/CommonListenerCookie.java -@@ -26,6 +_,28 @@ +@@ -25,6 +_,27 @@ + Map serverCookies, @Nullable ChatComponent.State chatState, - @Deprecated(forRemoval = true) boolean strictErrorHandling, Map customReportDetails, - ServerLinks serverLinks + ServerLinks serverLinks, + net.neoforged.neoforge.network.connection.ConnectionType connectionType ) { + /** -+ * @deprecated Use {@link #CommonListenerCookie(GameProfile, WorldSessionTelemetryManager, RegistryAccess.Frozen, FeatureFlagSet, String, ServerData, Screen, Map, ChatComponent.State, boolean, Map, ServerLinks, net.neoforged.neoforge.network.connection.ConnectionType)} ++ * @deprecated Use {@link #CommonListenerCookie(GameProfile, WorldSessionTelemetryManager, RegistryAccess.Frozen, FeatureFlagSet, String, ServerData, Screen, Map, ChatComponent.State, Map, ServerLinks, net.neoforged.neoforge.network.connection.ConnectionType)} + * instead,to indicate whether the connection is modded. + */ + @Deprecated @@ -23,10 +23,9 @@ + @Nullable Screen postDisconnectScreen, + Map serverCookies, + @Nullable ChatComponent.State chatState, -+ @Deprecated(forRemoval = true) boolean strictErrorHandling, + Map customReportDetails, + ServerLinks serverLinks + ) { -+ this(localGameProfile, telemetryManager, receivedRegistries, enabledFeatures, serverBrand, serverData, postDisconnectScreen, serverCookies, chatState, strictErrorHandling, customReportDetails, serverLinks, net.neoforged.neoforge.network.connection.ConnectionType.OTHER); ++ this(localGameProfile, telemetryManager, receivedRegistries, enabledFeatures, serverBrand, serverData, postDisconnectScreen, serverCookies, chatState, customReportDetails, serverLinks, net.neoforged.neoforge.network.connection.ConnectionType.OTHER); + } } diff --git a/patches/net/minecraft/client/multiplayer/MultiPlayerGameMode.java.patch b/patches/net/minecraft/client/multiplayer/MultiPlayerGameMode.java.patch index 40bda7642f..4a88a77d66 100644 --- a/patches/net/minecraft/client/multiplayer/MultiPlayerGameMode.java.patch +++ b/patches/net/minecraft/client/multiplayer/MultiPlayerGameMode.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/multiplayer/MultiPlayerGameMode.java +++ b/net/minecraft/client/multiplayer/MultiPlayerGameMode.java -@@ -119,11 +_,12 @@ +@@ -120,11 +_,12 @@ } else if (blockstate.isAir()) { return false; } else { @@ -15,7 +15,7 @@ } return flag; -@@ -142,6 +_,7 @@ +@@ -143,6 +_,7 @@ BlockState blockstate = this.minecraft.level.getBlockState(p_105270_); this.minecraft.getTutorial().onDestroyBlock(this.minecraft.level, p_105270_, blockstate, 1.0F); this.startPrediction(this.minecraft.level, p_233757_ -> { @@ -23,7 +23,7 @@ this.destroyBlock(p_105270_); return new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, p_105270_, p_105271_, p_233757_); }); -@@ -151,15 +_,19 @@ +@@ -152,15 +_,19 @@ this.connection .send(new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, this.destroyBlockPos, p_105271_)); } @@ -43,7 +43,7 @@ if (flag && blockstate1.getDestroyProgress(this.minecraft.player, this.minecraft.player.level(), p_105270_) >= 1.0F) { this.destroyBlock(p_105270_); } else { -@@ -171,7 +_,7 @@ +@@ -172,7 +_,7 @@ this.minecraft.level.destroyBlockProgress(this.minecraft.player.getId(), this.destroyBlockPos, this.getDestroyStage()); } @@ -52,7 +52,7 @@ }); } -@@ -202,6 +_,7 @@ +@@ -203,6 +_,7 @@ BlockState blockstate1 = this.minecraft.level.getBlockState(p_105284_); this.minecraft.getTutorial().onDestroyBlock(this.minecraft.level, p_105284_, blockstate1, 1.0F); this.startPrediction(this.minecraft.level, p_233753_ -> { @@ -60,7 +60,7 @@ this.destroyBlock(p_105284_); return new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, p_105284_, p_105285_, p_233753_); }); -@@ -214,7 +_,7 @@ +@@ -215,7 +_,7 @@ } else { this.destroyProgress = this.destroyProgress + blockstate.getDestroyProgress(this.minecraft.player, this.minecraft.player.level(), p_105284_); if (this.destroyTicks % 4.0F == 0.0F) { @@ -69,7 +69,7 @@ this.minecraft .getSoundManager() .play( -@@ -231,6 +_,7 @@ +@@ -232,6 +_,7 @@ this.destroyTicks++; this.minecraft.getTutorial().onDestroyBlock(this.minecraft.level, p_105284_, blockstate, Mth.clamp(this.destroyProgress, 0.0F, 1.0F)); @@ -77,7 +77,7 @@ if (this.destroyProgress >= 1.0F) { this.isDestroying = false; this.startPrediction(this.minecraft.level, p_233739_ -> { -@@ -269,7 +_,7 @@ +@@ -270,7 +_,7 @@ private boolean sameDestroyTarget(BlockPos p_105282_) { ItemStack itemstack = this.minecraft.player.getMainHandItem(); @@ -86,7 +86,7 @@ } private void ensureHasSentCarriedItem() { -@@ -297,12 +_,23 @@ +@@ -298,12 +_,23 @@ private InteractionResult performUseItemOn(LocalPlayer p_233747_, InteractionHand p_233748_, BlockHitResult p_233749_) { BlockPos blockpos = p_233749_.getBlockPos(); ItemStack itemstack = p_233747_.getItemInHand(p_233748_); @@ -95,7 +95,7 @@ + return event.getCancellationResult(); + } if (this.localPlayerMode == GameType.SPECTATOR) { - return InteractionResult.SUCCESS; + return InteractionResult.CONSUME; } else { - boolean flag = !p_233747_.getMainHandItem().isEmpty() || !p_233747_.getOffhandItem().isEmpty(); + UseOnContext useoncontext = new UseOnContext(p_233747_, p_233748_, p_233749_); @@ -112,20 +112,20 @@ BlockState blockstate = this.minecraft.level.getBlockState(blockpos); if (!this.connection.isFeatureEnabled(blockstate.getBlock().requiredFeatures())) { return InteractionResult.FAIL; -@@ -323,8 +_,10 @@ +@@ -324,8 +_,10 @@ } } -- if (!itemstack.isEmpty() && !p_233747_.getCooldowns().isOnCooldown(itemstack.getItem())) { +- if (!itemstack.isEmpty() && !p_233747_.getCooldowns().isOnCooldown(itemstack)) { - UseOnContext useoncontext = new UseOnContext(p_233747_, p_233748_, p_233749_); + if (event.getUseItem().isFalse()) { + return InteractionResult.PASS; + } -+ if (event.getUseItem().isTrue() || (!itemstack.isEmpty() && !p_233747_.getCooldowns().isOnCooldown(itemstack.getItem()))) { - InteractionResult interactionresult1; ++ if (event.getUseItem().isTrue() || (!itemstack.isEmpty() && !p_233747_.getCooldowns().isOnCooldown(itemstack))) { + InteractionResult interactionresult2; if (this.localPlayerMode.isCreative()) { int i = itemstack.getCount(); -@@ -358,10 +_,17 @@ +@@ -359,6 +_,11 @@ mutableobject.setValue(InteractionResult.PASS); return serverbounduseitempacket; } else { @@ -134,22 +134,25 @@ + mutableobject.setValue(cancelResult); + return serverbounduseitempacket; + } - InteractionResultHolder interactionresultholder = itemstack.use(this.minecraft.level, p_233722_, p_233723_); - ItemStack itemstack1 = interactionresultholder.getObject(); + InteractionResult interactionresult = itemstack.use(this.minecraft.level, p_233722_, p_233723_); + ItemStack itemstack1; + if (interactionresult instanceof InteractionResult.Success interactionresult$success) { +@@ -371,6 +_,8 @@ + if (itemstack1 != itemstack) { p_233722_.setItemInHand(p_233723_, itemstack1); + if (itemstack1.isEmpty()) + net.neoforged.neoforge.event.EventHooks.onPlayerDestroyItem(p_233722_, itemstack, p_233723_); } - mutableobject.setValue(interactionresultholder.getResult()); -@@ -400,6 +_,9 @@ + mutableobject.setValue(interactionresult); +@@ -409,6 +_,9 @@ this.ensureHasSentCarriedItem(); Vec3 vec3 = p_105233_.getLocation().subtract(p_105232_.getX(), p_105232_.getY(), p_105232_.getZ()); this.connection.send(ServerboundInteractPacket.createInteractionPacket(p_105232_, p_105231_.isShiftKeyDown(), p_105234_, vec3)); + if (this.localPlayerMode == GameType.SPECTATOR) return InteractionResult.PASS; // don't fire for spectators to match non-specific EntityInteract + InteractionResult cancelResult = net.neoforged.neoforge.common.CommonHooks.onInteractEntityAt(p_105231_, p_105232_, p_105233_, p_105234_); + if(cancelResult != null) return cancelResult; - return this.localPlayerMode == GameType.SPECTATOR ? InteractionResult.PASS : p_105232_.interactAt(p_105231_, vec3, p_105234_); + return (InteractionResult)(this.localPlayerMode == GameType.SPECTATOR ? InteractionResult.PASS : p_105232_.interactAt(p_105231_, vec3, p_105234_)); } diff --git a/patches/net/minecraft/client/multiplayer/PlayerInfo.java.patch b/patches/net/minecraft/client/multiplayer/PlayerInfo.java.patch index 1609a2b5e2..27972460ce 100644 --- a/patches/net/minecraft/client/multiplayer/PlayerInfo.java.patch +++ b/patches/net/minecraft/client/multiplayer/PlayerInfo.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/multiplayer/PlayerInfo.java +++ b/net/minecraft/client/multiplayer/PlayerInfo.java -@@ -85,6 +_,7 @@ +@@ -86,6 +_,7 @@ } protected void setGameMode(GameType p_105318_) { diff --git a/patches/net/minecraft/client/multiplayer/SessionSearchTrees.java.patch b/patches/net/minecraft/client/multiplayer/SessionSearchTrees.java.patch index 70a7eabfac..1010c8ad04 100644 --- a/patches/net/minecraft/client/multiplayer/SessionSearchTrees.java.patch +++ b/patches/net/minecraft/client/multiplayer/SessionSearchTrees.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/client/multiplayer/SessionSearchTrees.java +++ b/net/minecraft/client/multiplayer/SessionSearchTrees.java -@@ -60,7 +_,7 @@ - List list = p_346233_.getCollections(); - Registry registry = p_345600_.registryOrThrow(Registries.ITEM); - Item.TooltipContext item$tooltipcontext = Item.TooltipContext.of(p_345600_); +@@ -65,7 +_,7 @@ + Registry registry = registryaccess.lookupOrThrow(Registries.ITEM); + Item.TooltipContext item$tooltipcontext = Item.TooltipContext.of(registryaccess); + ContextMap contextmap = SlotDisplayContext.fromLevel(p_379752_); - TooltipFlag tooltipflag = TooltipFlag.Default.NORMAL; + TooltipFlag tooltipflag = net.neoforged.neoforge.client.ClientTooltipFlag.of(TooltipFlag.Default.NORMAL); CompletableFuture completablefuture = this.recipeSearch; this.recipeSearch = CompletableFuture.supplyAsync( () -> new FullTextSearchTree<>( -@@ -86,44 +_,60 @@ +@@ -92,44 +_,60 @@ } public void updateCreativeTags(List p_346121_) { diff --git a/patches/net/minecraft/client/multiplayer/TagCollector.java.patch b/patches/net/minecraft/client/multiplayer/TagCollector.java.patch deleted file mode 100644 index db75c16b16..0000000000 --- a/patches/net/minecraft/client/multiplayer/TagCollector.java.patch +++ /dev/null @@ -1,9 +0,0 @@ ---- a/net/minecraft/client/multiplayer/TagCollector.java -+++ b/net/minecraft/client/multiplayer/TagCollector.java -@@ -44,5 +_,6 @@ - this.applyTags(p_326147_, p_326446_ -> true); - refreshBuiltInTagDependentData(); - } -+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.TagsUpdatedEvent(p_326147_, true, p_326486_)); - } - } diff --git a/patches/net/minecraft/client/particle/BreakingItemParticle.java.patch b/patches/net/minecraft/client/particle/BreakingItemParticle.java.patch index dc96475e87..3d9b32361f 100644 --- a/patches/net/minecraft/client/particle/BreakingItemParticle.java.patch +++ b/patches/net/minecraft/client/particle/BreakingItemParticle.java.patch @@ -1,12 +1,11 @@ --- a/net/minecraft/client/particle/BreakingItemParticle.java +++ b/net/minecraft/client/particle/BreakingItemParticle.java -@@ -33,7 +_,8 @@ +@@ -33,7 +_,7 @@ protected BreakingItemParticle(ClientLevel p_105665_, double p_105666_, double p_105667_, double p_105668_, ItemStack p_105669_) { super(p_105665_, p_105666_, p_105667_, p_105668_, 0.0, 0.0, 0.0); - this.setSprite(Minecraft.getInstance().getItemRenderer().getModel(p_105669_, p_105665_, null, 0).getParticleIcon()); -+ var model = Minecraft.getInstance().getItemRenderer().getModel(p_105669_, p_105665_, null, 0); -+ this.setSprite(model.getOverrides().resolve(model, p_105669_, p_105665_, null, 0).getParticleIcon(net.neoforged.neoforge.client.model.data.ModelData.EMPTY)); ++ this.setSprite(Minecraft.getInstance().getItemRenderer().getModel(p_105669_, p_105665_, null, 0).getParticleIcon(net.neoforged.neoforge.client.model.data.ModelData.EMPTY)); this.gravity = 1.0F; this.quadSize /= 2.0F; this.uo = this.random.nextFloat() * 3.0F; diff --git a/patches/net/minecraft/client/particle/ItemPickupParticle.java.patch b/patches/net/minecraft/client/particle/ItemPickupParticle.java.patch index b0309a1a4e..fbf0a1e746 100644 --- a/patches/net/minecraft/client/particle/ItemPickupParticle.java.patch +++ b/patches/net/minecraft/client/particle/ItemPickupParticle.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/particle/ItemPickupParticle.java +++ b/net/minecraft/client/particle/ItemPickupParticle.java -@@ -103,4 +_,11 @@ +@@ -102,4 +_,11 @@ this.targetYOld = this.targetY; this.targetZOld = this.targetZ; } diff --git a/patches/net/minecraft/client/particle/ParticleEngine.java.patch b/patches/net/minecraft/client/particle/ParticleEngine.java.patch index ffbb1d2839..de43669f57 100644 --- a/patches/net/minecraft/client/particle/ParticleEngine.java.patch +++ b/patches/net/minecraft/client/particle/ParticleEngine.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/client/particle/ParticleEngine.java +++ b/net/minecraft/client/particle/ParticleEngine.java -@@ -81,11 +_,11 @@ - ParticleRenderType.CUSTOM +@@ -77,11 +_,11 @@ + ParticleRenderType.TERRAIN_SHEET, ParticleRenderType.PARTICLE_SHEET_OPAQUE, ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT, ParticleRenderType.CUSTOM ); protected ClientLevel level; - private final Map> particles = Maps.newIdentityHashMap(); @@ -14,8 +14,8 @@ private final Queue particlesToAdd = Queues.newArrayDeque(); private final Map spriteSets = Maps.newHashMap(); private final TextureAtlas textureAtlas; -@@ -216,10 +_,14 @@ - this.register(ParticleTypes.OMINOUS_SPAWNING, FlyStraightTowardsParticle.OminousSpawnProvider::new); +@@ -214,10 +_,14 @@ + this.register(ParticleTypes.BLOCK_CRUMBLE, new TerrainParticle.CrumblingProvider()); } + /** @deprecated Register via {@link net.neoforged.neoforge.client.event.RegisterParticleProvidersEvent} */ @@ -30,7 +30,7 @@ public void register(ParticleType p_273423_, ParticleProvider.Sprite p_273134_) { this.register( p_273423_, -@@ -236,10 +_,12 @@ +@@ -234,10 +_,12 @@ ); } @@ -44,7 +44,7 @@ } @Override -@@ -365,7 +_,7 @@ +@@ -357,7 +_,7 @@ private Particle makeParticle( T p_107396_, double p_107397_, double p_107398_, double p_107399_, double p_107400_, double p_107401_, double p_107402_ ) { @@ -53,7 +53,7 @@ return particleprovider == null ? null : particleprovider.createParticle(p_107396_, this.level, p_107397_, p_107398_, p_107399_, p_107400_, p_107401_, p_107402_); -@@ -441,11 +_,20 @@ +@@ -433,17 +_,27 @@ } } @@ -74,8 +74,7 @@ + if (particlerendertype == ParticleRenderType.NO_RENDER || !renderTypePredicate.test(particlerendertype)) continue; Queue queue = this.particles.get(particlerendertype); if (queue != null && !queue.isEmpty()) { - RenderSystem.setShader(GameRenderer::getParticleShader); -@@ -453,6 +_,7 @@ + Tesselator tesselator = Tesselator.getInstance(); BufferBuilder bufferbuilder = particlerendertype.begin(tesselator, this.textureManager); if (bufferbuilder != null) { for (Particle particle : queue) { @@ -83,7 +82,7 @@ try { particle.render(bufferbuilder, p_107340_, p_107341_); } catch (Throwable throwable) { -@@ -484,7 +_,7 @@ +@@ -475,7 +_,7 @@ } public void destroy(BlockPos p_107356_, BlockState p_107357_) { @@ -92,7 +91,7 @@ VoxelShape voxelshape = p_107357_.getShape(this.level, p_107356_); double d0 = 0.25; voxelshape.forAllBoxes( -@@ -516,7 +_,7 @@ +@@ -507,7 +_,7 @@ d6 - 0.5, p_107357_, p_107356_ @@ -101,7 +100,7 @@ ); } } -@@ -561,12 +_,28 @@ +@@ -552,12 +_,28 @@ d0 = (double)i + aabb.maxX + 0.1F; } diff --git a/patches/net/minecraft/client/particle/ParticleRenderType.java.patch b/patches/net/minecraft/client/particle/ParticleRenderType.java.patch index 4a648c99e5..47a53ce490 100644 --- a/patches/net/minecraft/client/particle/ParticleRenderType.java.patch +++ b/patches/net/minecraft/client/particle/ParticleRenderType.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/particle/ParticleRenderType.java +++ b/net/minecraft/client/particle/ParticleRenderType.java -@@ -43,6 +_,11 @@ +@@ -44,6 +_,11 @@ public String toString() { return "PARTICLE_SHEET_OPAQUE"; } @@ -12,9 +12,9 @@ }; ParticleRenderType PARTICLE_SHEET_TRANSLUCENT = new ParticleRenderType() { @Override -@@ -72,6 +_,11 @@ +@@ -60,6 +_,11 @@ public String toString() { - return "PARTICLE_SHEET_LIT"; + return "PARTICLE_SHEET_TRANSLUCENT"; } + + @Override @@ -24,7 +24,7 @@ }; ParticleRenderType CUSTOM = new ParticleRenderType() { @Override -@@ -101,4 +_,9 @@ +@@ -89,4 +_,9 @@ @Nullable BufferBuilder begin(Tesselator p_350949_, TextureManager p_107437_); diff --git a/patches/net/minecraft/client/player/AbstractClientPlayer.java.patch b/patches/net/minecraft/client/player/AbstractClientPlayer.java.patch index 48705c0461..6e8a8c5540 100644 --- a/patches/net/minecraft/client/player/AbstractClientPlayer.java.patch +++ b/patches/net/minecraft/client/player/AbstractClientPlayer.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/client/player/AbstractClientPlayer.java +++ b/net/minecraft/client/player/AbstractClientPlayer.java -@@ -96,6 +_,6 @@ +@@ -91,6 +_,6 @@ } } -- return Mth.lerp(Minecraft.getInstance().options.fovEffectScale().get().floatValue(), 1.0F, f); -+ return net.neoforged.neoforge.client.ClientHooks.getFieldOfViewModifier(this, f); +- return Mth.lerp(p_366686_, 1.0F, f); ++ return net.neoforged.neoforge.client.ClientHooks.getFieldOfViewModifier(this, f, p_366686_); } } diff --git a/patches/net/minecraft/client/player/LocalPlayer.java.patch b/patches/net/minecraft/client/player/LocalPlayer.java.patch index 632b558ef9..d772181669 100644 --- a/patches/net/minecraft/client/player/LocalPlayer.java.patch +++ b/patches/net/minecraft/client/player/LocalPlayer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/player/LocalPlayer.java +++ b/net/minecraft/client/player/LocalPlayer.java -@@ -297,6 +_,7 @@ +@@ -302,6 +_,7 @@ ServerboundPlayerActionPacket.Action serverboundplayeractionpacket$action = p_108701_ ? ServerboundPlayerActionPacket.Action.DROP_ALL_ITEMS : ServerboundPlayerActionPacket.Action.DROP_ITEM; @@ -8,7 +8,7 @@ ItemStack itemstack = this.getInventory().removeFromSelected(p_108701_); this.connection.send(new ServerboundPlayerActionPacket(serverboundplayeractionpacket$action, BlockPos.ZERO, Direction.DOWN)); return !itemstack.isEmpty(); -@@ -489,7 +_,14 @@ +@@ -482,7 +_,14 @@ @Override public void playSound(SoundEvent p_108651_, float p_108652_, float p_108653_) { @@ -24,7 +24,7 @@ } @Override -@@ -682,6 +_,7 @@ +@@ -676,6 +_,7 @@ && (this.isShiftKeyDown() || !this.isSleeping() && !this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.STANDING)); float f = (float)this.getAttributeValue(Attributes.SNEAKING_SPEED); this.input.tick(this.isMovingSlowly(), f); @@ -32,7 +32,7 @@ this.minecraft.getTutorial().onInput(this.input); if (this.isUsingItem() && !this.isPassenger()) { this.input.leftImpulse *= 0.2F; -@@ -710,7 +_,7 @@ +@@ -704,7 +_,7 @@ boolean flag4 = this.canStartSprinting(); boolean flag5 = this.isPassenger() ? this.getVehicle().onGround() : this.onGround(); boolean flag6 = !flag1 && !flag2; @@ -41,7 +41,7 @@ if (this.sprintTriggerTime <= 0 && !this.minecraft.options.keySprint.isDown()) { this.sprintTriggerTime = 7; } else { -@@ -718,15 +_,15 @@ +@@ -712,15 +_,15 @@ } } @@ -55,12 +55,12 @@ - boolean flag8 = flag7 || this.horizontalCollision && !this.minorHorizontalCollision || this.isInWater() && !this.isUnderWater(); + boolean flag8 = flag7 || this.horizontalCollision && !this.minorHorizontalCollision || this.isInWater() && !this.isUnderWater() || (this.isInFluidType((fluidType, height) -> this.canSwimInFluidType(fluidType)) && !this.canStartSwimming()); if (this.isSwimming()) { -- if (!this.onGround() && !this.input.shiftKeyDown && flag7 || !this.isInWater()) { -+ if (!this.onGround() && !this.input.shiftKeyDown && flag7 || !(this.isInWater() || this.isInFluidType((fluidType, height) -> this.canSwimInFluidType(fluidType)))) { +- if (!this.onGround() && !this.input.keyPresses.shift() && flag7 || !this.isInWater()) { ++ if (!this.onGround() && !this.input.keyPresses.shift() && flag7 || !(this.isInWater() || this.isInFluidType((fluidType, height) -> this.canSwimInFluidType(fluidType)))) { this.setSprinting(false); } } else if (flag8) { -@@ -735,7 +_,7 @@ +@@ -729,7 +_,7 @@ } boolean flag9 = false; @@ -69,34 +69,18 @@ if (this.minecraft.gameMode.isAlwaysFlying()) { if (!abilities.flying) { abilities.flying = true; -@@ -760,14 +_,15 @@ - - if (this.input.jumping && !flag9 && !flag && !abilities.flying && !this.isPassenger() && !this.onClimbable()) { - ItemStack itemstack = this.getItemBySlot(EquipmentSlot.CHEST); -- if (itemstack.is(Items.ELYTRA) && ElytraItem.isFlyEnabled(itemstack) && this.tryToStartFallFlying()) { -+ if (itemstack.canElytraFly(this) && this.tryToStartFallFlying()) { - this.connection.send(new ServerboundPlayerCommandPacket(this, ServerboundPlayerCommandPacket.Action.START_FALL_FLYING)); - } - } - - this.wasFallFlying = this.isFallFlying(); -- if (this.isInWater() && this.input.shiftKeyDown && this.isAffectedByFluids()) { -- this.goDownInWater(); -+ net.neoforged.neoforge.fluids.FluidType fluidType = this.getMaxHeightFluidType(); -+ if ((this.isInWater() || (!fluidType.isAir() && this.canSwimInFluidType(fluidType))) && this.input.shiftKeyDown && this.isAffectedByFluids()) { -+ this.sinkInFluid(this.isInWater() ? net.neoforged.neoforge.common.NeoForgeMod.WATER_TYPE.value() : fluidType); - } - - if (this.isEyeInFluid(FluidTags.WATER)) { -@@ -875,6 +_,7 @@ +@@ -866,6 +_,10 @@ @Override public void rideTick() { super.rideTick(); -+ if (this.wantsToStopRiding() && this.isPassenger()) this.input.shiftKeyDown = false; ++ if (this.wantsToStopRiding() && this.isPassenger()) { ++ Input input = this.input.keyPresses; ++ this.input.keyPresses = new Input(input.forward(), input.backward(), input.left(), input.right(), input.jump(), false, input.sprint()); ++ } this.handsBusy = false; - if (this.getControlledVehicle() instanceof Boat boat) { - boat.setInput(this.input.left, this.input.right, this.input.up, this.input.down); -@@ -1061,7 +_,7 @@ + if (this.getControlledVehicle() instanceof AbstractBoat abstractboat) { + abstractboat.setInput( +@@ -1063,7 +_,7 @@ } private boolean hasEnoughFoodToStartSprinting() { diff --git a/patches/net/minecraft/client/renderer/DimensionSpecialEffects.java.patch b/patches/net/minecraft/client/renderer/DimensionSpecialEffects.java.patch index 641642c10f..285c14a5b2 100644 --- a/patches/net/minecraft/client/renderer/DimensionSpecialEffects.java.patch +++ b/patches/net/minecraft/client/renderer/DimensionSpecialEffects.java.patch @@ -9,7 +9,7 @@ private static final Object2ObjectMap EFFECTS = Util.make(new Object2ObjectArrayMap<>(), p_108881_ -> { DimensionSpecialEffects.OverworldEffects dimensionspecialeffects$overworldeffects = new DimensionSpecialEffects.OverworldEffects(); p_108881_.defaultReturnValue(dimensionspecialeffects$overworldeffects); -@@ -37,7 +_,7 @@ +@@ -36,7 +_,7 @@ } public static DimensionSpecialEffects forType(DimensionType p_108877_) { @@ -17,4 +17,4 @@ + return net.neoforged.neoforge.client.DimensionSpecialEffectsManager.getForType(p_108877_.effectsLocation()); } - @Nullable + public boolean isSunriseOrSunset(float p_365312_) { diff --git a/patches/net/minecraft/client/renderer/EffectInstance.java.patch b/patches/net/minecraft/client/renderer/EffectInstance.java.patch deleted file mode 100644 index 8ceff68f59..0000000000 --- a/patches/net/minecraft/client/renderer/EffectInstance.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/net/minecraft/client/renderer/EffectInstance.java -+++ b/net/minecraft/client/renderer/EffectInstance.java -@@ -58,7 +_,8 @@ - private final EffectProgram fragmentProgram; - - public EffectInstance(ResourceProvider p_331011_, String p_108942_) throws IOException { -- ResourceLocation resourcelocation = ResourceLocation.withDefaultNamespace("shaders/program/" + p_108942_ + ".json"); -+ ResourceLocation rl = ResourceLocation.tryParse(p_108942_); -+ ResourceLocation resourcelocation = ResourceLocation.fromNamespaceAndPath(rl.getNamespace(), "shaders/program/" + rl.getPath() + ".json"); - this.name = p_108942_; - Resource resource = p_331011_.getResourceOrThrow(resourcelocation); - -@@ -150,7 +_,8 @@ - } else { - EffectProgram effectprogram; - if (program == null) { -- ResourceLocation resourcelocation = ResourceLocation.withDefaultNamespace("shaders/program/" + p_172569_ + p_172568_.getExtension()); -+ ResourceLocation rl = ResourceLocation.tryParse(p_172569_); -+ ResourceLocation resourcelocation = ResourceLocation.fromNamespaceAndPath(rl.getNamespace(), "shaders/program/" + rl.getPath() + p_172568_.getExtension()); - Resource resource = p_330579_.getResourceOrThrow(resourcelocation); - - try (InputStream inputstream = resource.open()) { diff --git a/patches/net/minecraft/client/renderer/FogRenderer.java.patch b/patches/net/minecraft/client/renderer/FogRenderer.java.patch index 25aa279988..f2443a835c 100644 --- a/patches/net/minecraft/client/renderer/FogRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/FogRenderer.java.patch @@ -1,23 +1,23 @@ --- a/net/minecraft/client/renderer/FogRenderer.java +++ b/net/minecraft/client/renderer/FogRenderer.java -@@ -197,6 +_,12 @@ - fogBlue = fogBlue * (1.0F - f7) + fogBlue * f9 * f7; +@@ -196,7 +_,7 @@ + f2 = f2 * (1.0F - f10) + f2 * f12 * f10; } -+ Vector3f fogColor = net.neoforged.neoforge.client.ClientHooks.getFogColor(p_109019_, p_109020_, p_109021_, p_109022_, p_109023_, fogRed, fogGreen, fogBlue); -+ -+ fogRed = fogColor.x(); -+ fogGreen = fogColor.y(); -+ fogBlue = fogColor.z(); -+ - RenderSystem.clearColor(fogRed, fogGreen, fogBlue, 0.0F); +- return new Vector4f(f, f1, f2, 1.0F); ++ return net.neoforged.neoforge.client.ClientHooks.getFogColor(p_363451_, p_364931_, p_363033_, p_363851_, p_363957_, f, f1, f2); } -@@ -273,6 +_,7 @@ - RenderSystem.setShaderFogStart(fogrenderer$fogdata.start); - RenderSystem.setShaderFogEnd(fogrenderer$fogdata.end); - RenderSystem.setShaderFogShape(fogrenderer$fogdata.shape); -+ net.neoforged.neoforge.client.ClientHooks.onFogRender(p_234174_, fogtype, p_234173_, p_234177_, p_234175_, fogrenderer$fogdata.start, fogrenderer$fogdata.end, fogrenderer$fogdata.shape); + public static boolean toggleFog() { +@@ -274,9 +_,9 @@ + fogrenderer$fogdata.shape = FogShape.CYLINDER; + } + +- return new FogParameters( ++ return net.neoforged.neoforge.client.ClientHooks.onFogRender(p_234174_, fogtype, p_234173_, p_234177_, p_234175_, new FogParameters( + fogrenderer$fogdata.start, fogrenderer$fogdata.end, fogrenderer$fogdata.shape, p_365467_.x, p_365467_.y, p_365467_.z, p_365467_.w +- ); ++ )); + } } - public static void levelFogColor() { diff --git a/patches/net/minecraft/client/renderer/GameRenderer.java.patch b/patches/net/minecraft/client/renderer/GameRenderer.java.patch index 7d1c353a22..4245210909 100644 --- a/patches/net/minecraft/client/renderer/GameRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/GameRenderer.java.patch @@ -1,32 +1,24 @@ --- a/net/minecraft/client/renderer/GameRenderer.java +++ b/net/minecraft/client/renderer/GameRenderer.java -@@ -311,6 +_,8 @@ - this.loadEffect(ResourceLocation.withDefaultNamespace("shaders/post/spider.json")); +@@ -158,6 +_,8 @@ + this.setPostEffect(ResourceLocation.withDefaultNamespace("spider")); } else if (p_109107_ instanceof EnderMan) { - this.loadEffect(ResourceLocation.withDefaultNamespace("shaders/post/invert.json")); + this.setPostEffect(ResourceLocation.withDefaultNamespace("invert")); + } else { + net.neoforged.neoforge.client.ClientHooks.loadEntityShader(p_109107_, this); } } -@@ -714,6 +_,7 @@ - ) - ); - this.loadBlurEffect(p_250719_); -+ net.neoforged.fml.ModLoader.postEvent(new net.neoforged.neoforge.client.event.RegisterShadersEvent(p_250719_, list1)); - } catch (IOException ioexception) { - list1.forEach(p_172729_ -> p_172729_.getFirst().close()); - throw new RuntimeException("could not reload shaders", ioexception); -@@ -872,7 +_,7 @@ - d0 *= Mth.lerp(this.minecraft.options.fovEffectScale().get(), 1.0, 0.85714287F); +@@ -312,7 +_,7 @@ + f *= Mth.lerp(f2, 1.0F, 0.85714287F); } -- return d0; -+ return net.neoforged.neoforge.client.ClientHooks.getFieldOfView(this, p_109142_, p_109143_, d0, p_109144_); +- return f; ++ return net.neoforged.neoforge.client.ClientHooks.getFieldOfView(this, p_109142_, p_109143_, f, p_109144_); } } -@@ -888,6 +_,10 @@ +@@ -328,6 +_,10 @@ return; } @@ -37,48 +29,48 @@ f2 /= (float)livingentity.hurtDuration; f2 = Mth.sin(f2 * f2 * f2 * f2 * (float) Math.PI); float f3 = livingentity.getHurtDir(); -@@ -1036,12 +_,12 @@ +@@ -474,12 +_,12 @@ (float)((double)window.getHeight() / window.getGuiScale()), 0.0F, 1000.0F, - 21000.0F + net.neoforged.neoforge.client.ClientHooks.getGuiFarPlane() ); - RenderSystem.setProjectionMatrix(matrix4f, VertexSorting.ORTHOGRAPHIC_Z); + RenderSystem.setProjectionMatrix(matrix4f, ProjectionType.ORTHOGRAPHIC); Matrix4fStack matrix4fstack = RenderSystem.getModelViewStack(); matrix4fstack.pushMatrix(); - matrix4fstack.translation(0.0F, 0.0F, -11000.0F); + matrix4fstack.translation(0.0F, 0.0F, 10000F - net.neoforged.neoforge.client.ClientHooks.getGuiFarPlane()); - RenderSystem.applyModelViewMatrix(); Lighting.setupFor3DItems(); GuiGraphics guigraphics = new GuiGraphics(this.minecraft, this.renderBuffers.bufferSource()); -@@ -1070,7 +_,8 @@ + if (flag && p_109096_ && this.minecraft.level != null) { +@@ -496,7 +_,8 @@ if (this.minecraft.getOverlay() != null) { try { -- this.minecraft.getOverlay().render(guigraphics, i, j, p_348648_.getRealtimeDeltaTicks()); +- this.minecraft.getOverlay().render(guigraphics, i, j, p_348648_.getGameTimeDeltaTicks()); + // Neo: Fix https://bugs.mojang.com/browse/MC-273464 + this.minecraft.getOverlay().render(guigraphics, i, j, p_348648_.getGameTimeDeltaPartialTick(false)); } catch (Throwable throwable2) { CrashReport crashreport = CrashReport.forThrowable(throwable2, "Rendering overlay"); CrashReportCategory crashreportcategory = crashreport.addCategory("Overlay render details"); -@@ -1079,7 +_,9 @@ +@@ -505,7 +_,9 @@ } } else if (flag && this.minecraft.screen != null) { try { -- this.minecraft.screen.renderWithTooltip(guigraphics, i, j, p_348648_.getRealtimeDeltaTicks()); +- this.minecraft.screen.renderWithTooltip(guigraphics, i, j, p_348648_.getGameTimeDeltaTicks()); + // Neo: Wrap Screen#render to allow for GUI Layers and ScreenEvent.Render.[Pre/Post] + // Also fixes https://bugs.mojang.com/browse/MC-273464 + net.neoforged.neoforge.client.ClientHooks.drawScreen(this.minecraft.screen, guigraphics, i, j, p_348648_.getGameTimeDeltaPartialTick(false)); } catch (Throwable throwable1) { CrashReport crashreport1 = CrashReport.forThrowable(throwable1, "Rendering screen"); CrashReportCategory crashreportcategory1 = crashreport1.addCategory("Screen render details"); -@@ -1259,6 +_,8 @@ - .levelRenderer - .prepareCullFrustum(camera.getPosition(), matrix4f1, this.getProjectionMatrix(Math.max(d0, (double)this.minecraft.options.fov().get().intValue()))); - this.minecraft.levelRenderer.renderLevel(p_348589_, flag, camera, this, this.lightTexture, matrix4f1, matrix4f); -+ this.minecraft.getProfiler().popPush("neoforge_render_last"); +@@ -687,6 +_,8 @@ + this.minecraft.levelRenderer.prepareCullFrustum(camera.getPosition(), matrix4f2, matrix4f1); + this.minecraft.getMainRenderTarget().bindWrite(true); + this.minecraft.levelRenderer.renderLevel(this.resourcePool, p_348589_, flag, camera, this, this.lightTexture, matrix4f2, matrix4f); ++ profilerfiller.popPush("neoforge_render_last"); + net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_LEVEL, this.minecraft.levelRenderer, null, matrix4f1, matrix4f, this.minecraft.levelRenderer.getTicks(), camera, this.minecraft.levelRenderer.getFrustum()); - this.minecraft.getProfiler().popPush("hand"); + profilerfiller.popPush("hand"); if (this.renderHand) { - RenderSystem.clear(256, Minecraft.ON_OSX); + RenderSystem.clear(256); diff --git a/patches/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch b/patches/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch index d66d2a4c3a..1bf5aead8b 100644 --- a/patches/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch +++ b/patches/net/minecraft/client/renderer/ItemBlockRenderTypes.java.patch @@ -1,22 +1,22 @@ --- a/net/minecraft/client/renderer/ItemBlockRenderTypes.java +++ b/net/minecraft/client/renderer/ItemBlockRenderTypes.java -@@ -20,6 +_,7 @@ +@@ -18,6 +_,7 @@ @OnlyIn(Dist.CLIENT) public class ItemBlockRenderTypes { + @Deprecated - private static final Map TYPE_BY_BLOCK = Util.make(Maps.newHashMap(), p_353020_ -> { + private static final Map TYPE_BY_BLOCK = Util.make(Maps.newHashMap(), p_378824_ -> { RenderType rendertype = RenderType.tripwire(); - p_353020_.put(Blocks.TRIPWIRE, rendertype); -@@ -335,6 +_,7 @@ - p_353020_.put(Blocks.BUBBLE_COLUMN, rendertype3); - p_353020_.put(Blocks.TINTED_GLASS, rendertype3); + p_378824_.put(Blocks.TRIPWIRE, rendertype); +@@ -340,6 +_,7 @@ + p_378824_.put(Blocks.BUBBLE_COLUMN, rendertype3); + p_378824_.put(Blocks.TINTED_GLASS, rendertype3); }); + @Deprecated private static final Map TYPE_BY_FLUID = Util.make(Maps.newHashMap(), p_109290_ -> { RenderType rendertype = RenderType.translucent(); p_109290_.put(Fluids.FLOWING_WATER, rendertype); -@@ -342,6 +_,8 @@ +@@ -347,6 +_,8 @@ }); private static boolean renderCutout; @@ -25,7 +25,7 @@ public static RenderType getChunkRenderType(BlockState p_109283_) { Block block = p_109283_.getBlock(); if (block instanceof LeavesBlock) { -@@ -352,6 +_,8 @@ +@@ -357,6 +_,8 @@ } } @@ -34,25 +34,23 @@ public static RenderType getMovingBlockRenderType(BlockState p_109294_) { Block block = p_109294_.getBlock(); if (block instanceof LeavesBlock) { -@@ -366,6 +_,8 @@ +@@ -371,11 +_,15 @@ } } -+ /** @deprecated Forge: Use {@link net.neoforged.neoforge.client.RenderTypeHelper#getEntityRenderType(RenderType, boolean)} while iterating through {@link net.minecraft.client.resources.model.BakedModel#getRenderTypes(BlockState, net.minecraft.util.RandomSource, net.neoforged.neoforge.client.model.data.ModelData)}. */ ++ /** @deprecated Forge: Use {@link net.neoforged.neoforge.client.RenderTypeHelper#getEntityRenderType(RenderType)} while iterating through {@link net.minecraft.client.resources.model.BakedModel#getRenderTypes(BlockState, net.minecraft.util.RandomSource, net.neoforged.neoforge.client.model.data.ModelData)}. */ + @Deprecated // Note: this method does NOT support model-based render types - public static RenderType getRenderType(BlockState p_109285_, boolean p_109286_) { - RenderType rendertype = getChunkRenderType(p_109285_); - if (rendertype == RenderType.translucent()) { -@@ -379,6 +_,8 @@ - } + public static RenderType getRenderType(BlockState p_366653_) { + RenderType rendertype = getChunkRenderType(p_366653_); + return rendertype == RenderType.translucent() ? Sheets.translucentItemSheet() : Sheets.cutoutBlockSheet(); } -+ /** @deprecated Forge: Use {@link net.minecraft.client.resources.model.BakedModel#getRenderPasses(ItemStack, boolean)} and {@link net.minecraft.client.resources.model.BakedModel#getRenderTypes(ItemStack, boolean)}. */ ++ /** @deprecated Forge: Use {@link net.minecraft.client.resources.model.BakedModel#getRenderPasses(ItemStack)} and {@link net.minecraft.client.resources.model.BakedModel#getRenderTypes(ItemStack)}. */ + @Deprecated // Note: this method does NOT support model-based render types - public static RenderType getRenderType(ItemStack p_109280_, boolean p_109281_) { - Item item = p_109280_.getItem(); - if (item instanceof BlockItem) { -@@ -396,5 +_,78 @@ + public static RenderType getRenderType(ItemStack p_366701_) { + if (p_366701_.getItem() instanceof BlockItem blockitem) { + Block block = blockitem.getBlock(); +@@ -392,5 +_,78 @@ public static void setFancy(boolean p_109292_) { renderCutout = p_109292_; diff --git a/patches/net/minecraft/client/renderer/ItemInHandRenderer.java.patch b/patches/net/minecraft/client/renderer/ItemInHandRenderer.java.patch index 8497dbd1cc..50e02aa55f 100644 --- a/patches/net/minecraft/client/renderer/ItemInHandRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/ItemInHandRenderer.java.patch @@ -1,6 +1,20 @@ --- a/net/minecraft/client/renderer/ItemInHandRenderer.java +++ b/net/minecraft/client/renderer/ItemInHandRenderer.java -@@ -226,7 +_,7 @@ +@@ -168,11 +_,11 @@ + ResourceLocation resourcelocation = this.minecraft.player.getSkin().texture(); + if (p_109365_ == HumanoidArm.RIGHT) { + playerrenderer.renderRightHand( +- p_109362_, p_109363_, p_109364_, resourcelocation, this.minecraft.player.isModelPartShown(PlayerModelPart.RIGHT_SLEEVE) ++ p_109362_, p_109363_, p_109364_, resourcelocation, this.minecraft.player.isModelPartShown(PlayerModelPart.RIGHT_SLEEVE), this.minecraft.player + ); + } else { + playerrenderer.renderLeftHand( +- p_109362_, p_109363_, p_109364_, resourcelocation, this.minecraft.player.isModelPartShown(PlayerModelPart.LEFT_SLEEVE) ++ p_109362_, p_109363_, p_109364_, resourcelocation, this.minecraft.player.isModelPartShown(PlayerModelPart.LEFT_SLEEVE), this.minecraft.player + ); + } + +@@ -234,7 +_,7 @@ p_109367_.translate(-0.5F, -0.5F, 0.0F); p_109367_.scale(0.0078125F, 0.0078125F, 0.0078125F); MapId mapid = p_109370_.get(DataComponents.MAP_ID); @@ -9,7 +23,20 @@ VertexConsumer vertexconsumer = p_109368_.getBuffer(mapitemsaveddata == null ? MAP_BACKGROUND : MAP_BACKGROUND_CHECKERBOARD); Matrix4f matrix4f = p_109367_.last().pose(); vertexconsumer.addVertex(matrix4f, -7.0F, 135.0F, 0.0F).setColor(-1).setUv(0.0F, 1.0F).setLight(p_109369_); -@@ -334,12 +_,14 @@ +@@ -271,10 +_,10 @@ + ResourceLocation resourcelocation = abstractclientplayer.getSkin().texture(); + if (flag) { + playerrenderer.renderRightHand( +- p_109347_, p_109348_, p_109349_, resourcelocation, abstractclientplayer.isModelPartShown(PlayerModelPart.RIGHT_SLEEVE) ++ p_109347_, p_109348_, p_109349_, resourcelocation, abstractclientplayer.isModelPartShown(PlayerModelPart.RIGHT_SLEEVE), abstractclientplayer + ); + } else { +- playerrenderer.renderLeftHand(p_109347_, p_109348_, p_109349_, resourcelocation, abstractclientplayer.isModelPartShown(PlayerModelPart.LEFT_SLEEVE)); ++ playerrenderer.renderLeftHand(p_109347_, p_109348_, p_109349_, resourcelocation, abstractclientplayer.isModelPartShown(PlayerModelPart.LEFT_SLEEVE), abstractclientplayer); + } + } + +@@ -347,12 +_,14 @@ if (iteminhandrenderer$handrenderselection.renderMainHand) { float f4 = interactionhand == InteractionHand.MAIN_HAND ? f : 0.0F; float f5 = 1.0F - Mth.lerp(p_109315_, this.oMainHandHeight, this.mainHandHeight); @@ -24,11 +51,11 @@ this.renderArmWithItem(p_109318_, p_109315_, f1, InteractionHand.OFF_HAND, f6, this.offHandItem, f7, p_109316_, p_109317_, p_109319_); } -@@ -399,13 +_,13 @@ +@@ -412,13 +_,13 @@ if (flag && !p_109372_.isInvisible()) { this.renderPlayerArm(p_109379_, p_109380_, p_109381_, p_109378_, p_109376_, humanoidarm); } -- } else if (p_109377_.is(Items.FILLED_MAP)) { +- } else if (p_109377_.has(DataComponents.MAP_ID)) { + } else if (p_109377_.getItem() instanceof MapItem) { if (flag && this.offHandItem.isEmpty()) { this.renderTwoHandedMap(p_109379_, p_109380_, p_109381_, p_109374_, p_109378_, p_109376_); @@ -40,7 +67,7 @@ boolean flag1 = CrossbowItem.isCharged(p_109377_); boolean flag2 = humanoidarm == HumanoidArm.RIGHT; int i = flag2 ? 1 : -1; -@@ -455,6 +_,7 @@ +@@ -468,6 +_,7 @@ ); } else { boolean flag3 = humanoidarm == HumanoidArm.RIGHT; @@ -48,7 +75,7 @@ if (p_109372_.isUsingItem() && p_109372_.getUseItemRemainingTicks() > 0 && p_109372_.getUsedItemHand() == p_109375_) { int k = flag3 ? 1 : -1; switch (p_109377_.getUseAnimation()) { -@@ -569,8 +_,16 @@ +@@ -582,8 +_,16 @@ this.offHandHeight = Mth.clamp(this.offHandHeight - 0.4F, 0.0F, 1.0F); } else { float f = localplayer.getAttackStrengthScale(1.0F); diff --git a/patches/net/minecraft/client/renderer/LevelEventHandler.java.patch b/patches/net/minecraft/client/renderer/LevelEventHandler.java.patch new file mode 100644 index 0000000000..9babaa65c3 --- /dev/null +++ b/patches/net/minecraft/client/renderer/LevelEventHandler.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/client/renderer/LevelEventHandler.java ++++ b/net/minecraft/client/renderer/LevelEventHandler.java +@@ -435,8 +_,8 @@ + break; + case 2001: + BlockState blockstate1 = Block.stateById(p_360434_); +- if (!blockstate1.isAir()) { +- SoundType soundtype = blockstate1.getSoundType(); ++ if (!blockstate1.isAir() && !net.neoforged.neoforge.client.extensions.common.IClientBlockExtensions.of(blockstate1).playBreakSound(blockstate1, this.level, p_362181_)) { ++ SoundType soundtype = blockstate1.getSoundType(this.level, p_362181_, null); + this.level + .playLocalSound( + p_362181_, soundtype.getBreakSound(), SoundSource.BLOCKS, (soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F, false diff --git a/patches/net/minecraft/client/renderer/LevelRenderer.java.patch b/patches/net/minecraft/client/renderer/LevelRenderer.java.patch index 82e084e8b4..bb8448e40d 100644 --- a/patches/net/minecraft/client/renderer/LevelRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/LevelRenderer.java.patch @@ -1,229 +1,238 @@ --- a/net/minecraft/client/renderer/LevelRenderer.java +++ b/net/minecraft/client/renderer/LevelRenderer.java -@@ -233,6 +_,10 @@ - private int rainSoundTime; - private final float[] rainSizeX = new float[1024]; - private final float[] rainSizeZ = new float[1024]; +@@ -485,7 +_,7 @@ + RenderSystem.clear(16640); + }); + if (!flag1) { +- this.addSkyPass(framegraphbuilder, p_109604_, f, fogparameters1); ++ this.addSkyPass(framegraphbuilder, p_109604_, f, fogparameters1, p_254120_, p_323920_); + } + + this.addMainPass(framegraphbuilder, frustum, p_109604_, p_254120_, p_323920_, fogparameters, p_109603_, flag2, p_348530_, profilerfiller); +@@ -494,7 +_,7 @@ + postchain1.addToFrame(framegraphbuilder, i, j, this.targets); + } + +- this.addParticlesPass(framegraphbuilder, p_109604_, p_109606_, f, fogparameters); ++ this.addParticlesPass(framegraphbuilder, p_109604_, p_109606_, f, fogparameters, frustum, p_254120_, p_323920_); + CloudStatus cloudstatus = this.minecraft.options.getCloudsType(); + if (cloudstatus != CloudStatus.OFF) { + float f2 = this.level.effects().getCloudHeight(); +@@ -505,7 +_,7 @@ + } + } + +- this.addWeatherPass(framegraphbuilder, p_109606_, p_109604_.getPosition(), f, fogparameters); ++ this.addWeatherPass(framegraphbuilder, p_109606_, p_109604_.getPosition(), f, fogparameters, p_254120_, p_323920_, p_109604_); + if (postchain != null) { + postchain.addToFrame(framegraphbuilder, i, j, this.targets); + } +@@ -576,7 +_,9 @@ + double d2 = vec3.z(); + p_362234_.push("terrain"); + this.renderSectionLayer(RenderType.solid(), d0, d1, d2, p_362420_, p_361272_); ++ this.minecraft.getModelManager().getAtlas(net.minecraft.client.renderer.texture.TextureAtlas.LOCATION_BLOCKS).setBlurMipmap(false, this.minecraft.options.mipmapLevels().get() > 0); // Neo: fix flickering leaves when mods mess up the blurMipmap settings + this.renderSectionLayer(RenderType.cutoutMipped(), d0, d1, d2, p_362420_, p_361272_); ++ this.minecraft.getModelManager().getAtlas(net.minecraft.client.renderer.texture.TextureAtlas.LOCATION_BLOCKS).restoreLastBlurMipmap(); + this.renderSectionLayer(RenderType.cutout(), d0, d1, d2, p_362420_, p_361272_); + if (this.level.effects().constantAmbientLight()) { + Lighting.setupNetherLevel(); +@@ -608,6 +_,7 @@ + p_362234_.popPush("entities"); + this.renderEntities(posestack, multibuffersource$buffersource, p_363453_, p_360931_, this.visibleEntities); + multibuffersource$buffersource.endLastBatch(); ++ net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_ENTITIES, this, posestack, p_362420_, p_361272_, this.ticks, p_363453_, p_366590_); + this.checkPoseStack(posestack); + p_362234_.popPush("blockentities"); + this.renderBlockEntities(posestack, multibuffersource$buffersource, multibuffersource$buffersource1, p_363453_, f); +@@ -624,6 +_,7 @@ + multibuffersource$buffersource.endBatch(Sheets.hangingSignSheet()); + multibuffersource$buffersource.endBatch(Sheets.chestSheet()); + this.renderBuffers.outlineBufferSource().endOutlineBatch(); ++ net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_BLOCK_ENTITIES, this, posestack, p_362420_, p_361272_, this.ticks, p_363453_, p_366590_); + if (p_363964_) { + this.renderBlockOutline(p_363453_, multibuffersource$buffersource, posestack, false); + } +@@ -644,6 +_,11 @@ + multibuffersource$buffersource1.endBatch(); + this.checkPoseStack(posestack); + multibuffersource$buffersource.endBatch(RenderType.waterMask()); ++ // Neo: in Fast/Fancy, render solid particles before translucent geometry so they don't disappear underwater (MC-161917) ++ if (this.targets.particles == null) { ++ p_362234_.popPush("solid_particles"); ++ this.minecraft.particleEngine.render(this.minecraft.gameRenderer.lightTexture(), p_363453_, f, p_366590_, type -> !type.isTranslucent()); ++ } + multibuffersource$buffersource.endBatch(); + if (resourcehandle1 != null) { + resourcehandle1.get().setClearColor(0.0F, 0.0F, 0.0F, 0.0F); +@@ -664,7 +_,15 @@ + }); + } + + /** -+ * Neo: Indicates whether outline effect post-processing was requested for the current frame outside of vanilla codepaths ++ * @deprecated Neo: use {@link #addParticlesPass(FrameGraphBuilder, Camera, LightTexture, float, FogParameters, Frustum, Matrix4f, Matrix4f)} instead + */ -+ private boolean outlineEffectRequested = false; ++ @Deprecated + private void addParticlesPass(FrameGraphBuilder p_363357_, Camera p_365299_, LightTexture p_364308_, float p_364282_, FogParameters p_362149_) { ++ addParticlesPass(p_363357_, p_365299_, p_364308_, p_364282_, p_362149_, this.capturedFrustum != null ? this.capturedFrustum : this.cullingFrustum, RenderSystem.getModelViewMatrix(), RenderSystem.getProjectionMatrix()); ++ } ++ ++ private void addParticlesPass(FrameGraphBuilder p_363357_, Camera p_365299_, LightTexture p_364308_, float p_364282_, FogParameters p_362149_, Frustum frustum, Matrix4f modelViewMatrix, Matrix4f projectionMatrix) { + FramePass framepass = p_363357_.addPass("particles"); + if (this.targets.particles != null) { + this.targets.particles = framepass.readsAndWrites(this.targets.particles); +@@ -684,7 +_,8 @@ + } - public LevelRenderer(Minecraft p_234245_, EntityRenderDispatcher p_234246_, BlockEntityRenderDispatcher p_234247_, RenderBuffers p_234248_) { - this.minecraft = p_234245_; -@@ -256,6 +_,8 @@ + RenderStateShard.PARTICLES_TARGET.setupRenderState(); +- this.minecraft.particleEngine.render(p_364308_, p_365299_, p_364282_); ++ this.minecraft.particleEngine.render(p_364308_, p_365299_, p_364282_, frustum, resourcehandle1 == null ? type -> type.isTranslucent() : type -> true); // Neo: only render translucent particles here in Fast/Fancy ++ net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_PARTICLES, this, null, modelViewMatrix, projectionMatrix, this.ticks, p_365299_, getFrustum()); + RenderStateShard.PARTICLES_TARGET.clearRenderState(); + }); } +@@ -713,11 +_,20 @@ + resourcehandle.get().clear(); + } - private void renderSnowAndRain(LightTexture p_109704_, float p_109705_, double p_109706_, double p_109707_, double p_109708_) { -+ if (level.effects().renderSnowAndRain(level, ticks, p_109705_, p_109704_, p_109706_, p_109707_, p_109708_)) -+ return; - float f = this.minecraft.level.getRainLevel(p_109705_); - if (!(f <= 0.0F)) { - p_109704_.turnOnLightLayer(); -@@ -418,6 +_,8 @@ ++ if (!level.effects().renderClouds(level, ticks, p_365209_, p_362985_.x, p_362985_.y, p_362985_.z, p_362864_, p_360602_)) + this.cloudRenderer.render(p_362342_, p_364196_, p_362337_, p_362864_, p_360602_, p_362985_, p_365209_); + }); } - public void tickRain(Camera p_109694_) { -+ if (level.effects().tickRain(level, ticks, p_109694_)) -+ return; - float f = this.minecraft.level.getRainLevel(1.0F) / (Minecraft.useFancyGraphics() ? 1.0F : 2.0F); - if (!(f <= 0.0F)) { - RandomSource randomsource = RandomSource.create((long)this.ticks * 312987231L); -@@ -942,9 +_,11 @@ - RenderSystem.clear(16640, Minecraft.ON_OSX); - float f1 = p_109605_.getRenderDistance(); - boolean flag1 = this.minecraft.level.effects().isFoggyAt(Mth.floor(d0), Mth.floor(d1)) || this.minecraft.gui.getBossOverlay().shouldCreateWorldFog(); -+ FogRenderer.setupFog(p_109604_, FogRenderer.FogMode.FOG_SKY, f1, flag1, f); - profilerfiller.popPush("sky"); - RenderSystem.setShader(GameRenderer::getPositionShader); - this.renderSky(p_254120_, p_323920_, f, p_109604_, flag1, () -> FogRenderer.setupFog(p_109604_, FogRenderer.FogMode.FOG_SKY, f1, flag1, f)); -+ net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_SKY, this, null, p_254120_, p_323920_, this.ticks, p_109604_, frustum); - profilerfiller.popPush("fog"); - FogRenderer.setupFog(p_109604_, FogRenderer.FogMode.FOG_TERRAIN, Math.max(f1, 32.0F), flag1, f); - profilerfiller.popPush("terrain_setup"); -@@ -953,7 +_,9 @@ - this.compileSections(p_109604_); - profilerfiller.popPush("terrain"); - this.renderSectionLayer(RenderType.solid(), d0, d1, d2, p_254120_, p_323920_); -+ this.minecraft.getModelManager().getAtlas(TextureAtlas.LOCATION_BLOCKS).setBlurMipmap(false, this.minecraft.options.mipmapLevels().get() > 0); // Neo: fix flickering leaves when mods mess up the blurMipmap settings - this.renderSectionLayer(RenderType.cutoutMipped(), d0, d1, d2, p_254120_, p_323920_); -+ this.minecraft.getModelManager().getAtlas(TextureAtlas.LOCATION_BLOCKS).restoreLastBlurMipmap(); - this.renderSectionLayer(RenderType.cutout(), d0, d1, d2, p_254120_, p_323920_); - if (this.level.effects().constantAmbientLight()) { - Lighting.setupNetherLevel(); -@@ -996,7 +_,7 @@ - || p_109604_.isDetached() - || p_109604_.getEntity() instanceof LivingEntity && ((LivingEntity)p_109604_.getEntity()).isSleeping() ++ /** ++ * @deprecated Neo: use {@link #addWeatherPass(FrameGraphBuilder, LightTexture, Vec3, float, FogParameters, Matrix4f, Matrix4f, Camera)} instead ++ */ ++ @Deprecated + private void addWeatherPass(FrameGraphBuilder p_364025_, LightTexture p_361536_, Vec3 p_360771_, float p_362434_, FogParameters p_360974_) { ++ addWeatherPass(p_364025_, p_361536_, p_360771_, p_362434_, p_360974_, RenderSystem.getModelViewMatrix(), RenderSystem.getProjectionMatrix(), this.minecraft.gameRenderer.getMainCamera()); ++ } ++ ++ private void addWeatherPass(FrameGraphBuilder p_364025_, LightTexture p_361536_, Vec3 p_360771_, float p_362434_, FogParameters p_360974_, Matrix4f modelViewMatrix, Matrix4f projectionMatrix, Camera camera) { + int i = this.minecraft.options.getEffectiveRenderDistance() * 16; + float f = this.minecraft.gameRenderer.getDepthFar(); + FramePass framepass = p_364025_.addPass("weather"); +@@ -731,6 +_,7 @@ + RenderSystem.setShaderFog(p_360974_); + RenderStateShard.WEATHER_TARGET.setupRenderState(); + this.weatherEffectRenderer.render(this.minecraft.level, p_361536_, this.ticks, p_362434_, p_360771_); ++ net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_WEATHER, this, null, modelViewMatrix, projectionMatrix, this.ticks, camera, getFrustum()); + this.worldBorderRenderer.render(this.level.getWorldBorder(), p_360771_, (double)i, (double)f); + RenderStateShard.WEATHER_TARGET.clearRenderState(); + }); +@@ -775,11 +_,14 @@ + || p_363510_.isDetached() + || p_363510_.getEntity() instanceof LivingEntity && ((LivingEntity)p_363510_.getEntity()).isSleeping() ) -- && (!(entity instanceof LocalPlayer) || p_109604_.getEntity() == entity)) { -+ && (!(entity instanceof LocalPlayer) || p_109604_.getEntity() == entity || (entity == minecraft.player && !minecraft.player.isSpectator()))) { // Neo: render local player entity when it is not the camera entity - this.renderedEntities++; - if (entity.tickCount == 0) { - entity.xOld = entity.getX(); -@@ -1012,6 +_,9 @@ - int i = entity.getTeamColor(); - outlinebuffersource.setColor(FastColor.ARGB32.red(i), FastColor.ARGB32.green(i), FastColor.ARGB32.blue(i), 255); - } else { -+ if (this.shouldShowEntityOutlines() && entity.hasCustomOutlineRendering(this.minecraft.player)) { // FORGE: allow custom outline rendering -+ flag2 = true; -+ } - multibuffersource = multibuffersource$buffersource; +- && (!(entity instanceof LocalPlayer) || p_363510_.getEntity() == entity)) { ++ && (!(entity instanceof LocalPlayer) || p_363510_.getEntity() == entity || (entity == minecraft.player && !minecraft.player.isSpectator()))) { // Neo: render local player entity when it is not the camera entity + p_363380_.add(entity); + if (flag1 && this.minecraft.shouldEntityAppearGlowing(entity)) { + flag = true; } ++ else if (flag1 && entity.hasCustomOutlineRendering(this.minecraft.player)) { // FORGE: allow custom outline rendering ++ flag = true; ++ } + } + } + } +@@ -825,10 +_,12 @@ + double d1 = vec3.y(); + double d2 = vec3.z(); -@@ -1027,12 +_,14 @@ - multibuffersource$buffersource.endBatch(RenderType.entityCutout(TextureAtlas.LOCATION_BLOCKS)); - multibuffersource$buffersource.endBatch(RenderType.entityCutoutNoCull(TextureAtlas.LOCATION_BLOCKS)); - multibuffersource$buffersource.endBatch(RenderType.entitySmoothCutout(TextureAtlas.LOCATION_BLOCKS)); -+ net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_ENTITIES, this, posestack, p_254120_, p_323920_, this.ticks, p_109604_, frustum); - profilerfiller.popPush("blockentities"); - ++ Frustum frustum = getFrustum(); for (SectionRenderDispatcher.RenderSection sectionrenderdispatcher$rendersection : this.visibleSections) { List list = sectionrenderdispatcher$rendersection.getCompiled().getRenderableBlockEntities(); if (!list.isEmpty()) { - for (BlockEntity blockentity1 : list) { -+ if (!net.neoforged.neoforge.client.ClientHooks.isBlockEntityRendererVisible(blockEntityRenderDispatcher, blockentity1, frustum)) continue; - BlockPos blockpos4 = blockentity1.getBlockPos(); - MultiBufferSource multibuffersource1 = multibuffersource$buffersource; - posestack.pushPose(); -@@ -1051,6 +_,9 @@ - }; - } - } -+ if (this.shouldShowEntityOutlines() && blockentity1.hasCustomOutlineRendering(this.minecraft.player)) { // Neo: allow custom outline rendering -+ flag2 = true; -+ } - - this.blockEntityRenderDispatcher.render(blockentity1, f, posestack, multibuffersource1); - posestack.popPose(); -@@ -1060,9 +_,13 @@ + for (BlockEntity blockentity : list) { ++ if (!net.neoforged.neoforge.client.ClientHooks.isBlockEntityRendererVisible(blockEntityRenderDispatcher, blockentity, frustum)) continue; + BlockPos blockpos = blockentity.getBlockPos(); + MultiBufferSource multibuffersource = p_363819_; + p_362832_.pushPose(); +@@ -856,6 +_,7 @@ synchronized (this.globalBlockEntities) { - for (BlockEntity blockentity : this.globalBlockEntities) { -+ if (!net.neoforged.neoforge.client.ClientHooks.isBlockEntityRendererVisible(blockEntityRenderDispatcher, blockentity, frustum)) continue; - BlockPos blockpos3 = blockentity.getBlockPos(); - posestack.pushPose(); - posestack.translate((double)blockpos3.getX() - d0, (double)blockpos3.getY() - d1, (double)blockpos3.getZ() - d2); -+ if (this.shouldShowEntityOutlines() && blockentity.hasCustomOutlineRendering(this.minecraft.player)) { // Neo: allow custom outline rendering -+ flag2 = true; -+ } - this.blockEntityRenderDispatcher.render(blockentity, f, posestack, multibuffersource$buffersource); - posestack.popPose(); - } -@@ -1080,11 +_,17 @@ - multibuffersource$buffersource.endBatch(Sheets.hangingSignSheet()); - multibuffersource$buffersource.endBatch(Sheets.chestSheet()); - this.renderBuffers.outlineBufferSource().endOutlineBatch(); -+ // Neo: handle outline effect requests outside glowing entities -+ if (this.outlineEffectRequested) { -+ flag2 |= this.shouldShowEntityOutlines(); -+ this.outlineEffectRequested = false; -+ } - if (flag2) { - this.entityEffect.process(p_348530_.getGameTimeDeltaTicks()); - this.minecraft.getMainRenderTarget().bindWrite(false); - } - -+ net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_BLOCK_ENTITIES, this, posestack, p_254120_, p_323920_, this.ticks, p_109604_, frustum); - profilerfiller.popPush("destroyProgress"); - - for (Entry> entry : this.destructionProgress.long2ObjectEntrySet()) { -@@ -1102,9 +_,10 @@ - VertexConsumer vertexconsumer1 = new SheetedDecalTextureGenerator( - this.renderBuffers.crumblingBufferSource().getBuffer(ModelBakery.DESTROY_TYPES.get(k)), posestack$pose1, 1.0F + for (BlockEntity blockentity1 : this.globalBlockEntities) { ++ if (!net.neoforged.neoforge.client.ClientHooks.isBlockEntityRendererVisible(blockEntityRenderDispatcher, blockentity1, frustum)) continue; + BlockPos blockpos1 = blockentity1.getBlockPos(); + p_362832_.pushPose(); + p_362832_.translate((double)blockpos1.getX() - d0, (double)blockpos1.getY() - d1, (double)blockpos1.getZ() - d2); +@@ -883,9 +_,10 @@ + VertexConsumer vertexconsumer = new SheetedDecalTextureGenerator( + p_365216_.getBuffer(ModelBakery.DESTROY_TYPES.get(i)), posestack$pose, 1.0F ); -+ net.neoforged.neoforge.client.model.data.ModelData modelData = level.getModelData(blockpos2); ++ net.neoforged.neoforge.client.model.data.ModelData modelData = level.getModelData(blockpos); this.minecraft .getBlockRenderer() -- .renderBreakingTexture(this.level.getBlockState(blockpos2), blockpos2, this.level, posestack, vertexconsumer1); -+ .renderBreakingTexture(this.level.getBlockState(blockpos2), blockpos2, this.level, posestack, vertexconsumer1, modelData); - posestack.popPose(); +- .renderBreakingTexture(this.level.getBlockState(blockpos), blockpos, this.level, p_363901_, vertexconsumer); ++ .renderBreakingTexture(this.level.getBlockState(blockpos), blockpos, this.level, p_363901_, vertexconsumer, modelData); + p_363901_.popPose(); } } -@@ -1116,10 +_,13 @@ - profilerfiller.popPush("outline"); - BlockPos blockpos1 = ((BlockHitResult)hitresult).getBlockPos(); - BlockState blockstate = this.level.getBlockState(blockpos1); -+ if (!net.neoforged.neoforge.client.ClientHooks.onDrawHighlight(this, p_109604_, hitresult, p_348530_, posestack, multibuffersource$buffersource)) - if (!blockstate.isAir() && this.level.getWorldBorder().isWithinBounds(blockpos1)) { - VertexConsumer vertexconsumer2 = multibuffersource$buffersource.getBuffer(RenderType.lines()); - this.renderHitOutline(posestack, vertexconsumer2, p_109604_.getEntity(), d0, d1, d2, blockpos1, blockstate); - } -+ } else if (hitresult != null && hitresult.getType() == HitResult.Type.ENTITY) { -+ net.neoforged.neoforge.client.ClientHooks.onDrawHighlight(this, p_109604_, hitresult, p_348530_, posestack, multibuffersource$buffersource); - } - - this.minecraft.debugRenderer.render(posestack, multibuffersource$buffersource, d0, d1, d2); -@@ -1147,9 +_,13 @@ - this.particlesTarget.copyDepthFrom(this.minecraft.getMainRenderTarget()); - RenderStateShard.PARTICLES_TARGET.setupRenderState(); - profilerfiller.popPush("particles"); -- this.minecraft.particleEngine.render(p_109606_, p_109604_, f); -+ this.minecraft.particleEngine.render(p_109606_, p_109604_, f, frustum, type -> true); -+ net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_PARTICLES, this, posestack, p_254120_, p_323920_, this.ticks, p_109604_, frustum); - RenderStateShard.PARTICLES_TARGET.clearRenderState(); - } else { -+ // Neo: render solid particles before translucent geometry to match order of chunk render types, fixes solid particles disappearing underwater in Fast/Fancy (MC-161917) -+ profilerfiller.popPush("solid_particles"); -+ this.minecraft.particleEngine.render(p_109606_, p_109604_, f, frustum, type -> !type.isTranslucent()); - profilerfiller.popPush("translucent"); - if (this.translucentTarget != null) { - this.translucentTarget.clear(Minecraft.ON_OSX); -@@ -1161,7 +_,8 @@ - profilerfiller.popPush("string"); - this.renderSectionLayer(RenderType.tripwire(), d0, d1, d2, p_254120_, p_323920_); - profilerfiller.popPush("particles"); -- this.minecraft.particleEngine.render(p_109606_, p_109604_, f); -+ this.minecraft.particleEngine.render(p_109606_, p_109604_, f, frustum, type -> type.isTranslucent()); // Neo: only render translucent particles at this stage -+ net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_PARTICLES, this, posestack, p_254120_, p_323920_, this.ticks, p_109604_, frustum); +@@ -897,6 +_,7 @@ + if (blockhitresult.getType() != HitResult.Type.MISS) { + BlockPos blockpos = blockhitresult.getBlockPos(); + BlockState blockstate = this.level.getBlockState(blockpos); ++ if (!net.neoforged.neoforge.client.ClientHooks.onDrawHighlight(this, p_363911_, blockhitresult, this.minecraft.getDeltaTracker(), p_361893_, p_362782_, p_361698_)) + if (!blockstate.isAir() && this.level.getWorldBorder().isWithinBounds(blockpos)) { + boolean flag = ItemBlockRenderTypes.getChunkRenderType(blockstate).sortOnUpload(); + if (flag != p_361698_) { +@@ -1026,6 +_,7 @@ + compiledshaderprogram.clear(); + VertexBuffer.unbind(); + zone.close(); ++ net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(p_294513_, this, p_294782_, p_324517_, this.ticks, this.minecraft.gameRenderer.getMainCamera(), this.getFrustum()); + p_294513_.clearRenderState(); } - - if (this.minecraft.options.getCloudsType() != CloudStatus.OFF) { -@@ -1177,6 +_,7 @@ - RenderStateShard.WEATHER_TARGET.setupRenderState(); - profilerfiller.popPush("weather"); - this.renderSnowAndRain(p_109606_, f, d0, d1, d2); -+ net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_WEATHER, this, posestack, p_254120_, p_323920_, this.ticks, p_109604_, frustum); - this.renderWorldBorder(p_109604_); - RenderStateShard.WEATHER_TARGET.clearRenderState(); - this.transparencyChain.process(p_348530_.getGameTimeDeltaTicks()); -@@ -1185,6 +_,7 @@ - RenderSystem.depthMask(false); - profilerfiller.popPush("weather"); - this.renderSnowAndRain(p_109606_, f, d0, d1, d2); -+ net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_WEATHER, this, posestack, p_254120_, p_323920_, this.ticks, p_109604_, frustum); - this.renderWorldBorder(p_109604_); - RenderSystem.depthMask(true); - } -@@ -1293,6 +_,7 @@ - shaderinstance.clear(); - VertexBuffer.unbind(); - this.minecraft.getProfiler().pop(); -+ net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(p_294513_, this, p_294782_, p_324517_, this.ticks, this.minecraft.gameRenderer.getMainCamera(), this.getFrustum()); - p_294513_.clearRenderState(); - } - -@@ -1543,6 +_,8 @@ } - - public void renderSky(Matrix4f p_254034_, Matrix4f p_324386_, float p_202426_, Camera p_202427_, boolean p_202428_, Runnable p_202429_) { -+ if (level.effects().renderSky(level, ticks, p_202426_, p_254034_, p_202427_, p_324386_, p_202428_, p_202429_)) -+ return; - p_202429_.run(); - if (!p_202428_) { - FogType fogtype = p_202427_.getFluidInCamera(); -@@ -1666,6 +_,8 @@ +@@ -1066,7 +_,15 @@ + } } - public void renderClouds(PoseStack p_254145_, Matrix4f p_254537_, Matrix4f p_324366_, float p_254364_, double p_253843_, double p_253663_, double p_253795_) { -+ if (level.effects().renderClouds(level, ticks, p_254364_, p_254145_, p_253843_, p_253663_, p_253795_, p_254537_, p_324366_)) -+ return; - float f = this.level.effects().getCloudHeight(); - if (!Float.isNaN(f)) { - float f1 = 12.0F; -@@ -2488,6 +_,31 @@ - this.viewArea.setDirty(p_109502_, p_109503_, p_109504_, p_109505_); - } ++ /** ++ * @deprecated Neo: use {@link #addSkyPass(FrameGraphBuilder, Camera, float, FogParameters, Matrix4f, Matrix4f)} instead ++ */ ++ @Deprecated + private void addSkyPass(FrameGraphBuilder p_362870_, Camera p_362177_, float p_363799_, FogParameters p_364999_) { ++ addSkyPass(p_362870_, p_362177_, p_363799_, p_364999_, RenderSystem.getModelViewMatrix(), RenderSystem.getProjectionMatrix()); ++ } ++ ++ private void addSkyPass(FrameGraphBuilder p_362870_, Camera p_362177_, float p_363799_, FogParameters p_364999_, Matrix4f modelViewMatrix, Matrix4f projectionMatrix) { + FogType fogtype = p_362177_.getFluidInCamera(); + if (fogtype != FogType.POWDER_SNOW && fogtype != FogType.LAVA && !this.doesMobEffectBlockSky(p_362177_)) { + DimensionSpecialEffects dimensionspecialeffects = this.level.effects(); +@@ -1075,6 +_,7 @@ + FramePass framepass = p_362870_.addPass("sky"); + this.targets.main = framepass.readsAndWrites(this.targets.main); + framepass.executes(() -> { ++ if (!level.effects().renderSky(level, ticks, p_363799_, modelViewMatrix, p_362177_, projectionMatrix, () -> RenderSystem.setShaderFog(p_364999_))) { + RenderSystem.setShaderFog(p_364999_); + RenderStateShard.MAIN_TARGET.setupRenderState(); + PoseStack posestack = new PoseStack(); +@@ -1102,6 +_,8 @@ + this.skyRenderer.renderDarkDisc(posestack); + } + } ++ } ++ net.neoforged.neoforge.client.ClientHooks.dispatchRenderStage(net.neoforged.neoforge.client.event.RenderLevelStageEvent.Stage.AFTER_SKY, this, null, modelViewMatrix, projectionMatrix, this.ticks, p_362177_, getFrustum()); + }); + } + } +@@ -1413,7 +_,7 @@ + } else { + int i = p_109538_.getBrightness(LightLayer.SKY, p_109540_); + int j = p_109538_.getBrightness(LightLayer.BLOCK, p_109540_); +- int k = p_109539_.getLightEmission(); ++ int k = p_109539_.getLightEmission(p_109538_, p_109540_); + if (j < k) { + j = k; + } +@@ -1475,5 +_,22 @@ + public CloudRenderer getCloudRenderer() { + return this.cloudRenderer; ++ } ++ + public Frustum getFrustum() { + return this.capturedFrustum != null ? this.capturedFrustum : this.cullingFrustum; + } @@ -239,36 +248,5 @@ + synchronized (this.globalBlockEntities) { + this.globalBlockEntities.forEach(blockEntityConsumer); + } -+ } -+ -+ /** -+ * Neo: Request outline effect post-processing to be enabled for the current frame. Must be called before block -+ * entities are done rendering, ideally early during the frame -+ */ -+ public void requestOutlineEffect() { -+ this.outlineEffectRequested = true; -+ } -+ - public void playJukeboxSong(Holder p_350918_, BlockPos p_350830_) { - if (this.level != null) { - this.stopJukeboxSong(p_350830_); -@@ -3008,8 +_,8 @@ - break; - case 2001: - BlockState blockstate1 = Block.stateById(p_234307_); -- if (!blockstate1.isAir()) { -- SoundType soundtype = blockstate1.getSoundType(); -+ if (!blockstate1.isAir() && !net.neoforged.neoforge.client.extensions.common.IClientBlockExtensions.of(blockstate1).playBreakSound(blockstate1, this.level, p_234306_)) { -+ SoundType soundtype = blockstate1.getSoundType(this.level, p_234306_, null); - this.level - .playLocalSound( - p_234306_, soundtype.getBreakSound(), SoundSource.BLOCKS, (soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F, false -@@ -3495,7 +_,7 @@ - } else { - int i = p_109538_.getBrightness(LightLayer.SKY, p_109540_); - int j = p_109538_.getBrightness(LightLayer.BLOCK, p_109540_); -- int k = p_109539_.getLightEmission(); -+ int k = p_109539_.getLightEmission(p_109538_, p_109540_); - if (j < k) { - j = k; - } + } + } diff --git a/patches/net/minecraft/client/renderer/LightTexture.java.patch b/patches/net/minecraft/client/renderer/LightTexture.java.patch index 72db3bdff6..da6b2dc076 100644 --- a/patches/net/minecraft/client/renderer/LightTexture.java.patch +++ b/patches/net/minecraft/client/renderer/LightTexture.java.patch @@ -1,19 +1,10 @@ --- a/net/minecraft/client/renderer/LightTexture.java +++ b/net/minecraft/client/renderer/LightTexture.java -@@ -129,6 +_,8 @@ - } - } - -+ clientlevel.effects().adjustLightmapColors(clientlevel, p_109882_, f, f7, f8, j, i, vector3f1); -+ - if (f5 > 0.0F) { - float f13 = Math.max(vector3f1.x(), Math.max(vector3f1.y(), vector3f1.z())); - if (f13 < 1.0F) { -@@ -186,7 +_,7 @@ +@@ -141,7 +_,7 @@ } public static int block(int p_109884_) { -- return p_109884_ >> 4 & 65535; +- return p_109884_ >>> 4 & 15; + return (p_109884_ & 0xFFFF) >> 4; // Forge: Fix fullbright quads showing dark artifacts. Reported as MC-169806 } diff --git a/patches/net/minecraft/client/renderer/MapRenderer.java.patch b/patches/net/minecraft/client/renderer/MapRenderer.java.patch new file mode 100644 index 0000000000..8d0c96067c --- /dev/null +++ b/patches/net/minecraft/client/renderer/MapRenderer.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/client/renderer/MapRenderer.java ++++ b/net/minecraft/client/renderer/MapRenderer.java +@@ -42,6 +_,10 @@ + + for (MapRenderState.MapDecorationRenderState maprenderstate$mapdecorationrenderstate : p_360365_.decorations) { + if (!p_362262_ || maprenderstate$mapdecorationrenderstate.renderOnFrame) { ++ if (net.neoforged.neoforge.client.gui.map.MapDecorationRendererManager.render(maprenderstate$mapdecorationrenderstate, p_362483_, p_363581_, p_360365_, MapRenderer.this.decorationTextures, p_362262_, p_364872_, i)) { ++ i++; ++ continue; ++ } + p_362483_.pushPose(); + p_362483_.translate( + (float)maprenderstate$mapdecorationrenderstate.x / 2.0F + 64.0F, (float)maprenderstate$mapdecorationrenderstate.y / 2.0F + 64.0F, -0.02F +@@ -116,6 +_,7 @@ + + private MapRenderState.MapDecorationRenderState extractDecorationRenderState(MapDecoration p_364175_) { + MapRenderState.MapDecorationRenderState maprenderstate$mapdecorationrenderstate = new MapRenderState.MapDecorationRenderState(); ++ maprenderstate$mapdecorationrenderstate.type = p_364175_.type(); + maprenderstate$mapdecorationrenderstate.atlasSprite = this.decorationTextures.get(p_364175_); + maprenderstate$mapdecorationrenderstate.x = p_364175_.x(); + maprenderstate$mapdecorationrenderstate.y = p_364175_.y(); diff --git a/patches/net/minecraft/client/renderer/PanoramaRenderer.java.patch b/patches/net/minecraft/client/renderer/PanoramaRenderer.java.patch deleted file mode 100644 index 4111b68d7d..0000000000 --- a/patches/net/minecraft/client/renderer/PanoramaRenderer.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/client/renderer/PanoramaRenderer.java -+++ b/net/minecraft/client/renderer/PanoramaRenderer.java -@@ -30,6 +_,8 @@ - p_334063_.blit(PANORAMA_OVERLAY, 0, 0, p_333839_, p_333923_, 0.0F, 0.0F, 16, 128, 16, 128); - p_334063_.setColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.disableBlend(); -+ // Neo: disable depth test again to prevent issues with extended far plane values for screen layers and HUD layers -+ RenderSystem.disableDepthTest(); - } - - private static float wrap(float p_249058_, float p_249548_) { diff --git a/patches/net/minecraft/client/renderer/PostChain.java.patch b/patches/net/minecraft/client/renderer/PostChain.java.patch deleted file mode 100644 index 7dbfffbbf7..0000000000 --- a/patches/net/minecraft/client/renderer/PostChain.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/net/minecraft/client/renderer/PostChain.java -+++ b/net/minecraft/client/renderer/PostChain.java -@@ -156,7 +_,8 @@ - throw new ChainedJsonException("Render target '" + s4 + "' can't be used as depth buffer"); - } - -- ResourceLocation resourcelocation = ResourceLocation.withDefaultNamespace("textures/effect/" + s4 + ".png"); -+ ResourceLocation rl = ResourceLocation.tryParse(s4); -+ ResourceLocation resourcelocation = ResourceLocation.fromNamespaceAndPath(rl.getNamespace(), "textures/effect/" + rl.getPath() + ".png"); - this.resourceProvider - .getResource(resourcelocation) - .orElseThrow(() -> new ChainedJsonException("Render target or texture '" + s4 + "' does not exist")); -@@ -257,6 +_,7 @@ - public void addTempTarget(String p_110039_, int p_110040_, int p_110041_) { - RenderTarget rendertarget = new TextureTarget(p_110040_, p_110041_, true, Minecraft.ON_OSX); - rendertarget.setClearColor(0.0F, 0.0F, 0.0F, 0.0F); -+ if (screenTarget.isStencilEnabled()) { rendertarget.enableStencil(); } - this.customRenderTargets.put(p_110039_, rendertarget); - if (p_110040_ == this.screenWidth && p_110041_ == this.screenHeight) { - this.fullSizedTargets.add(rendertarget); diff --git a/patches/net/minecraft/client/renderer/RenderBuffers.java.patch b/patches/net/minecraft/client/renderer/RenderBuffers.java.patch index 97da5ee8f4..ad6b76cc6e 100644 --- a/patches/net/minecraft/client/renderer/RenderBuffers.java.patch +++ b/patches/net/minecraft/client/renderer/RenderBuffers.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/client/renderer/RenderBuffers.java +++ b/net/minecraft/client/renderer/RenderBuffers.java -@@ -37,6 +_,7 @@ - put((Object2ObjectLinkedOpenHashMap)p_349871_, RenderType.waterMask()); - ModelBakery.DESTROY_TYPES.forEach(p_173062_ -> put(p_349871_, p_173062_)); +@@ -35,6 +_,7 @@ + put((Object2ObjectLinkedOpenHashMap)p_366352_, RenderType.entityGlint()); + put((Object2ObjectLinkedOpenHashMap)p_366352_, RenderType.waterMask()); }); + net.neoforged.fml.ModLoader.postEvent(new net.neoforged.neoforge.client.event.RegisterRenderBuffersEvent(sequencedmap)); - this.crumblingBufferSource = MultiBufferSource.immediate(new ByteBufferBuilder(1536)); this.bufferSource = MultiBufferSource.immediateWithBuffers(sequencedmap, new ByteBufferBuilder(786432)); this.outlineBufferSource = new OutlineBufferSource(this.bufferSource); + SequencedMap sequencedmap1 = Util.make( diff --git a/patches/net/minecraft/client/renderer/RenderType.java.patch b/patches/net/minecraft/client/renderer/RenderType.java.patch index 568f074649..3186edd211 100644 --- a/patches/net/minecraft/client/renderer/RenderType.java.patch +++ b/patches/net/minecraft/client/renderer/RenderType.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/RenderType.java +++ b/net/minecraft/client/renderer/RenderType.java -@@ -968,7 +_,7 @@ +@@ -1098,7 +_,7 @@ } public static RenderType text(ResourceLocation p_110498_) { @@ -9,7 +9,7 @@ } public static RenderType textBackground() { -@@ -976,19 +_,19 @@ +@@ -1106,19 +_,19 @@ } public static RenderType textIntensity(ResourceLocation p_173238_) { @@ -33,7 +33,7 @@ } public static RenderType textBackgroundSeeThrough() { -@@ -996,7 +_,7 @@ +@@ -1126,7 +_,7 @@ } public static RenderType textIntensitySeeThrough(ResourceLocation p_173241_) { @@ -42,7 +42,7 @@ } public static RenderType lightning() { -@@ -1453,5 +_,17 @@ +@@ -1622,5 +_,17 @@ public String toString() { return this.name; } diff --git a/patches/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch b/patches/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch index ca33ed7840..901854e375 100644 --- a/patches/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch @@ -55,7 +55,7 @@ + } + + public static void renderFluid(Minecraft p_110726_, PoseStack p_110727_, ResourceLocation texture) { - RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShader(CoreShaders.POSITION_TEX); - RenderSystem.setShaderTexture(0, UNDERWATER_LOCATION); + RenderSystem.setShaderTexture(0, texture); BlockPos blockpos = BlockPos.containing(p_110726_.player.getX(), p_110726_.player.getEyeY(), p_110726_.player.getZ()); diff --git a/patches/net/minecraft/client/renderer/ShaderInstance.java.patch b/patches/net/minecraft/client/renderer/ShaderInstance.java.patch deleted file mode 100644 index 2192fa0913..0000000000 --- a/patches/net/minecraft/client/renderer/ShaderInstance.java.patch +++ /dev/null @@ -1,57 +0,0 @@ ---- a/net/minecraft/client/renderer/ShaderInstance.java -+++ b/net/minecraft/client/renderer/ShaderInstance.java -@@ -94,10 +_,14 @@ - @Nullable - public final Uniform CHUNK_OFFSET; - -+ @Deprecated // FORGE: Use the ResourceLocation variant below - public ShaderInstance(ResourceProvider p_173336_, String p_173337_, VertexFormat p_173338_) throws IOException { -- this.name = p_173337_; -+ this(p_173336_, ResourceLocation.parse(p_173337_), p_173338_); -+ } -+ public ShaderInstance(ResourceProvider p_173336_, ResourceLocation shaderLocation, VertexFormat p_173338_) throws IOException { -+ this.name = shaderLocation.getNamespace().equals("minecraft") ? shaderLocation.getPath() : shaderLocation.toString(); - this.vertexFormat = p_173338_; -- ResourceLocation resourcelocation = ResourceLocation.withDefaultNamespace("shaders/core/" + p_173337_ + ".json"); -+ ResourceLocation resourcelocation = ResourceLocation.fromNamespaceAndPath(shaderLocation.getNamespace(), "shaders/core/" + shaderLocation.getPath() + ".json"); - - try (Reader reader = p_173336_.openAsReader(resourcelocation)) { - JsonObject jsonobject = GsonHelper.parse(reader); -@@ -177,8 +_,10 @@ - Program program1 = p_173342_.getPrograms().get(p_173343_); - Program program; - if (program1 == null) { -- String s = "shaders/core/" + p_173343_ + p_173342_.getExtension(); -- Resource resource = p_173341_.getResourceOrThrow(ResourceLocation.withDefaultNamespace(s)); -+ ResourceLocation loc = ResourceLocation.parse(p_173343_); -+ String s = "shaders/core/" + loc.getPath() + p_173342_.getExtension(); -+ ResourceLocation resourcelocation = ResourceLocation.fromNamespaceAndPath(loc.getNamespace(), s); -+ Resource resource = p_173341_.getResourceOrThrow(resourcelocation); - - try (InputStream inputstream = resource.open()) { - final String s1 = FileUtil.getFullResourcePath(s); -@@ -187,11 +_,11 @@ - - @Override - public String applyImport(boolean p_173374_, String p_173375_) { -- p_173375_ = FileUtil.normalizeResourcePath((p_173374_ ? s1 : "shaders/include/") + p_173375_); -- if (!this.importedPaths.add(p_173375_)) { -+ // FORGE: use the mod's namespace to look up resources if specified -+ ResourceLocation resourcelocation = net.neoforged.neoforge.client.ClientHooks.getShaderImportLocation(s1, p_173374_, p_173375_); -+ if (!this.importedPaths.add(resourcelocation.toString())) { - return null; - } else { -- ResourceLocation resourcelocation = ResourceLocation.parse(p_173375_); - - try { - String s2; -@@ -201,7 +_,8 @@ - - return s2; - } catch (IOException ioexception) { -- ShaderInstance.LOGGER.error("Could not open GLSL import {}: {}", p_173375_, ioexception.getMessage()); -+ // FORGE: specify the namespace of the failed import in case of duplicates from multiple mods -+ ShaderInstance.LOGGER.error("Could not open GLSL import {}: {}", resourcelocation, ioexception.getMessage()); - return "#error " + ioexception.getMessage(); - } - } diff --git a/patches/net/minecraft/client/renderer/ShaderManager.java.patch b/patches/net/minecraft/client/renderer/ShaderManager.java.patch new file mode 100644 index 0000000000..4e634d23e7 --- /dev/null +++ b/patches/net/minecraft/client/renderer/ShaderManager.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/client/renderer/ShaderManager.java ++++ b/net/minecraft/client/renderer/ShaderManager.java +@@ -169,7 +_,7 @@ + ShaderManager.CompilationCache shadermanager$compilationcache = new ShaderManager.CompilationCache(p_366597_); + Map map = new HashMap<>(); + +- for (ShaderProgram shaderprogram : CoreShaders.getProgramsToPreload()) { ++ for (ShaderProgram shaderprogram : net.neoforged.neoforge.client.CoreShaderManager.getProgramsToPreload()) { + try { + shadermanager$compilationcache.programs.put(shaderprogram, Optional.of(shadermanager$compilationcache.compileProgram(shaderprogram))); + } catch (ShaderManager.CompilationException shadermanager$compilationexception) { diff --git a/patches/net/minecraft/client/renderer/Sheets.java.patch b/patches/net/minecraft/client/renderer/Sheets.java.patch index b2ff568d8a..cb01eb86db 100644 --- a/patches/net/minecraft/client/renderer/Sheets.java.patch +++ b/patches/net/minecraft/client/renderer/Sheets.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/Sheets.java +++ b/net/minecraft/client/renderer/Sheets.java -@@ -146,11 +_,13 @@ +@@ -141,11 +_,13 @@ } private static Material createSignMaterial(WoodType p_173386_) { @@ -16,7 +16,7 @@ } public static Material getSignMaterial(WoodType p_173382_) { -@@ -209,6 +_,23 @@ +@@ -204,6 +_,23 @@ case SINGLE: default: return p_110773_; diff --git a/patches/net/minecraft/client/renderer/WeatherEffectRenderer.java.patch b/patches/net/minecraft/client/renderer/WeatherEffectRenderer.java.patch new file mode 100644 index 0000000000..180f282591 --- /dev/null +++ b/patches/net/minecraft/client/renderer/WeatherEffectRenderer.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/client/renderer/WeatherEffectRenderer.java ++++ b/net/minecraft/client/renderer/WeatherEffectRenderer.java +@@ -61,6 +_,8 @@ + } + + public void render(Level p_364994_, LightTexture p_363130_, int p_363664_, float p_361655_, Vec3 p_363375_) { ++ if (((ClientLevel) p_364994_).effects().renderSnowAndRain((ClientLevel) p_364994_, p_363664_, p_361655_, p_363130_, p_363375_.x, p_363375_.y, p_363375_.z)) ++ return; + float f = p_364994_.getRainLevel(p_361655_); + if (!(f <= 0.0F)) { + int i = Minecraft.useFancyGraphics() ? 10 : 5; +@@ -201,6 +_,8 @@ + } + + public void tickRainParticles(ClientLevel p_361823_, Camera p_364990_, int p_361788_, ParticleStatus p_363302_) { ++ if (p_361823_.effects().tickRain(p_361823_, p_361788_, p_364990_)) ++ return; + float f = p_361823_.getRainLevel(1.0F) / (Minecraft.useFancyGraphics() ? 1.0F : 2.0F); + if (!(f <= 0.0F)) { + RandomSource randomsource = RandomSource.create((long)p_361788_ * 312987231L); diff --git a/patches/net/minecraft/client/renderer/block/BlockRenderDispatcher.java.patch b/patches/net/minecraft/client/renderer/block/BlockRenderDispatcher.java.patch index b393006515..5ee7f47292 100644 --- a/patches/net/minecraft/client/renderer/block/BlockRenderDispatcher.java.patch +++ b/patches/net/minecraft/client/renderer/block/BlockRenderDispatcher.java.patch @@ -91,8 +91,8 @@ this.modelRenderer .renderModel( p_110914_.last(), -- p_110915_.getBuffer(ItemBlockRenderTypes.getRenderType(p_110913_, false)), -+ p_110915_.getBuffer(renderType != null ? renderType : net.neoforged.neoforge.client.RenderTypeHelper.getEntityRenderType(rt, false)), +- p_110915_.getBuffer(ItemBlockRenderTypes.getRenderType(p_110913_)), ++ p_110915_.getBuffer(renderType != null ? renderType : net.neoforged.neoforge.client.RenderTypeHelper.getEntityRenderType(rt)), p_110913_, bakedmodel, f, diff --git a/patches/net/minecraft/client/renderer/block/LiquidBlockRenderer.java.patch b/patches/net/minecraft/client/renderer/block/LiquidBlockRenderer.java.patch index 5eab04bb47..f2ca146f9c 100644 --- a/patches/net/minecraft/client/renderer/block/LiquidBlockRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/block/LiquidBlockRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/block/LiquidBlockRenderer.java +++ b/net/minecraft/client/renderer/block/LiquidBlockRenderer.java -@@ -38,6 +_,7 @@ +@@ -37,6 +_,7 @@ this.waterIcons[0] = Minecraft.getInstance().getModelManager().getBlockModelShaper().getBlockModel(Blocks.WATER.defaultBlockState()).getParticleIcon(); this.waterIcons[1] = ModelBakery.WATER_FLOW.sprite(); this.waterOverlay = ModelBakery.WATER_OVERLAY.sprite(); @@ -20,7 +20,7 @@ float f = (float)(i >> 16 & 0xFF) / 255.0F; float f1 = (float)(i >> 8 & 0xFF) / 255.0F; float f2 = (float)(i & 0xFF) / 255.0F; -@@ -181,15 +_,15 @@ +@@ -180,15 +_,15 @@ float f57 = f4 * f; float f29 = f4 * f1; float f30 = f4 * f2; @@ -44,7 +44,7 @@ } } -@@ -202,10 +_,10 @@ +@@ -201,10 +_,10 @@ float f46 = f3 * f; float f48 = f3 * f1; float f50 = f3 * f2; @@ -59,8 +59,8 @@ } int j = this.getLightColor(p_234370_, p_234371_); -@@ -260,10 +_,9 @@ - && !isFaceOccludedByNeighbor(p_234370_, p_234371_, direction, Math.max(f44, f45), p_234370_.getBlockState(p_234371_.relative(direction)))) { +@@ -258,10 +_,9 @@ + if (flag7 && !isFaceOccludedByNeighbor(direction, Math.max(f44, f45), p_234370_.getBlockState(p_234371_.relative(direction)))) { BlockPos blockpos = p_234371_.relative(direction); TextureAtlasSprite textureatlassprite2 = atextureatlassprite[1]; - if (!flag) { @@ -73,7 +73,7 @@ } } -@@ -276,15 +_,15 @@ +@@ -274,15 +_,15 @@ float f33 = f4 * f32 * f; float f34 = f4 * f32 * f1; float f35 = f4 * f32 * f2; @@ -98,7 +98,7 @@ } } } -@@ -325,6 +_,26 @@ +@@ -323,6 +_,26 @@ private float getHeight(BlockAndTintGetter p_203157_, Fluid p_203158_, BlockPos p_203159_) { BlockState blockstate = p_203157_.getBlockState(p_203159_); return this.getHeight(p_203157_, p_203158_, p_203159_, blockstate, blockstate.getFluidState()); diff --git a/patches/net/minecraft/client/renderer/block/ModelBlockRenderer.java.patch b/patches/net/minecraft/client/renderer/block/ModelBlockRenderer.java.patch index 94bd0b01f0..49d5af1f7a 100644 --- a/patches/net/minecraft/client/renderer/block/ModelBlockRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/block/ModelBlockRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/block/ModelBlockRenderer.java +++ b/net/minecraft/client/renderer/block/ModelBlockRenderer.java -@@ -40,6 +_,7 @@ +@@ -39,6 +_,7 @@ this.blockColors = p_110999_; } @@ -8,34 +8,34 @@ public void tesselateBlock( BlockAndTintGetter p_234380_, BakedModel p_234381_, -@@ -52,15 +_,35 @@ +@@ -51,14 +_,35 @@ long p_234388_, int p_234389_ ) { - boolean flag = Minecraft.useAmbientOcclusion() && p_234382_.getLightEmission() == 0 && p_234381_.useAmbientOcclusion(); + tesselateBlock(p_234380_, p_234381_, p_234382_, p_234383_, p_234384_, p_234385_, p_234386_, p_234387_, p_234388_, p_234389_, net.neoforged.neoforge.client.model.data.ModelData.EMPTY, null); + } ++ + public void tesselateBlock( -+ BlockAndTintGetter p_234380_, -+ BakedModel p_234381_, -+ BlockState p_234382_, -+ BlockPos p_234383_, -+ PoseStack p_234384_, -+ VertexConsumer p_234385_, -+ boolean p_234386_, -+ RandomSource p_234387_, -+ long p_234388_, -+ int p_234389_, -+ net.neoforged.neoforge.client.model.data.ModelData modelData, -+ net.minecraft.client.renderer.RenderType renderType ++ BlockAndTintGetter p_234380_, ++ BakedModel p_234381_, ++ BlockState p_234382_, ++ BlockPos p_234383_, ++ PoseStack p_234384_, ++ VertexConsumer p_234385_, ++ boolean p_234386_, ++ RandomSource p_234387_, ++ long p_234388_, ++ int p_234389_, ++ net.neoforged.neoforge.client.model.data.ModelData modelData, ++ net.minecraft.client.renderer.RenderType renderType + ) { + boolean flag = Minecraft.useAmbientOcclusion() && switch(p_234381_.useAmbientOcclusion(p_234382_, modelData, renderType)) { + case TRUE -> true; + case DEFAULT -> p_234382_.getLightEmission(p_234380_, p_234383_) == 0; + case FALSE -> false; + }; - Vec3 vec3 = p_234382_.getOffset(p_234380_, p_234383_); - p_234384_.translate(vec3.x, vec3.y, vec3.z); + p_234384_.translate(p_234382_.getOffset(p_234383_)); try { if (flag) { @@ -47,7 +47,7 @@ } } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Tesselating block model"); -@@ -71,6 +_,7 @@ +@@ -69,6 +_,7 @@ } } @@ -55,12 +55,13 @@ public void tesselateWithAO( BlockAndTintGetter p_234391_, BakedModel p_234392_, -@@ -83,6 +_,22 @@ +@@ -81,6 +_,23 @@ long p_234399_, int p_234400_ ) { + tesselateWithAO(p_234391_, p_234392_, p_234393_, p_234394_, p_234395_, p_234396_, p_234397_, p_234398_, p_234399_, p_234400_, net.neoforged.neoforge.client.model.data.ModelData.EMPTY, null); + } ++ + public void tesselateWithAO( + BlockAndTintGetter p_234391_, + BakedModel p_234392_, @@ -78,7 +79,7 @@ float[] afloat = new float[DIRECTIONS.length * 2]; BitSet bitset = new BitSet(3); ModelBlockRenderer.AmbientOcclusionFace modelblockrenderer$ambientocclusionface = new ModelBlockRenderer.AmbientOcclusionFace(); -@@ -90,7 +_,7 @@ +@@ -88,10 +_,10 @@ for (Direction direction : DIRECTIONS) { p_234398_.setSeed(p_234399_); @@ -86,8 +87,12 @@ + List list = p_234392_.getQuads(p_234393_, direction, p_234398_, modelData, renderType); if (!list.isEmpty()) { blockpos$mutableblockpos.setWithOffset(p_234394_, direction); - if (!p_234397_ || Block.shouldRenderFace(p_234393_, p_234391_, p_234394_, direction, blockpos$mutableblockpos)) { -@@ -102,7 +_,7 @@ +- if (!p_234397_ || Block.shouldRenderFace(p_234393_, p_234391_.getBlockState(blockpos$mutableblockpos), direction)) { ++ if (!p_234397_ || Block.shouldRenderFace(p_234391_, p_234394_, p_234393_, p_234391_.getBlockState(blockpos$mutableblockpos), direction)) { + this.renderModelFaceAO( + p_234391_, p_234393_, p_234394_, p_234395_, p_234396_, list, afloat, bitset, modelblockrenderer$ambientocclusionface, p_234400_ + ); +@@ -100,7 +_,7 @@ } p_234398_.setSeed(p_234399_); @@ -96,7 +101,7 @@ if (!list1.isEmpty()) { this.renderModelFaceAO( p_234391_, p_234393_, p_234394_, p_234395_, p_234396_, list1, afloat, bitset, modelblockrenderer$ambientocclusionface, p_234400_ -@@ -110,6 +_,7 @@ +@@ -108,6 +_,7 @@ } } @@ -104,12 +109,13 @@ public void tesselateWithoutAO( BlockAndTintGetter p_234402_, BakedModel p_234403_, -@@ -122,12 +_,28 @@ +@@ -120,15 +_,32 @@ long p_234410_, int p_234411_ ) { + tesselateWithoutAO(p_234402_, p_234403_, p_234404_, p_234405_, p_234406_, p_234407_, p_234408_, p_234409_, p_234410_, p_234411_, net.neoforged.neoforge.client.model.data.ModelData.EMPTY, null); + } ++ + public void tesselateWithoutAO( + BlockAndTintGetter p_234402_, + BakedModel p_234403_, @@ -133,8 +139,12 @@ + List list = p_234403_.getQuads(p_234404_, direction, p_234409_, modelData, renderType); if (!list.isEmpty()) { blockpos$mutableblockpos.setWithOffset(p_234405_, direction); - if (!p_234408_ || Block.shouldRenderFace(p_234404_, p_234402_, p_234405_, direction, blockpos$mutableblockpos)) { -@@ -138,7 +_,7 @@ +- if (!p_234408_ || Block.shouldRenderFace(p_234404_, p_234402_.getBlockState(blockpos$mutableblockpos), direction)) { ++ if (!p_234408_ || Block.shouldRenderFace(p_234402_, p_234405_, p_234404_, p_234402_.getBlockState(blockpos$mutableblockpos), direction)) { + int i = LevelRenderer.getLightColor(p_234402_, p_234404_, blockpos$mutableblockpos); + this.renderModelFaceFlat(p_234402_, p_234404_, p_234405_, i, p_234411_, false, p_234406_, p_234407_, list, bitset); + } +@@ -136,7 +_,7 @@ } p_234409_.setSeed(p_234410_); @@ -143,7 +153,7 @@ if (!list1.isEmpty()) { this.renderModelFaceFlat(p_234402_, p_234404_, p_234405_, -1, p_234411_, true, p_234406_, p_234407_, list1, bitset); } -@@ -158,6 +_,7 @@ +@@ -156,6 +_,7 @@ ) { for (BakedQuad bakedquad : p_111018_) { this.calculateShape(p_111013_, p_111014_, p_111015_, bakedquad.getVertices(), bakedquad.getDirection(), p_111019_, p_111020_); @@ -151,7 +161,7 @@ p_111021_.calculate(p_111013_, p_111014_, p_111015_, bakedquad.getDirection(), p_111019_, p_111020_, bakedquad.isShade()); this.putQuadData( p_111013_, -@@ -323,6 +_,7 @@ +@@ -321,6 +_,7 @@ } } @@ -159,7 +169,7 @@ public void renderModel( PoseStack.Pose p_111068_, VertexConsumer p_111069_, -@@ -334,16 +_,32 @@ +@@ -332,16 +_,32 @@ int p_111075_, int p_111076_ ) { @@ -194,30 +204,27 @@ } private static void renderQuadList( -@@ -724,22 +_,22 @@ +@@ -722,19 +_,19 @@ int l = modelblockrenderer$cache.getLightColor(blockstate3, p_111168_, blockpos$mutableblockpos); float f3 = modelblockrenderer$cache.getShadeBrightness(blockstate3, p_111168_, blockpos$mutableblockpos); BlockState blockstate4 = p_111168_.getBlockState( -- blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[0]).move(p_111171_) +- blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[0]).move(p_366875_) + blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[0]) // Neo: remove move() to avoid oversampling (MC-43968) ); - boolean flag = !blockstate4.isViewBlocking(p_111168_, blockpos$mutableblockpos) - || blockstate4.getLightBlock(p_111168_, blockpos$mutableblockpos) == 0; + boolean flag = !blockstate4.isViewBlocking(p_111168_, blockpos$mutableblockpos) || blockstate4.getLightBlock() == 0; BlockState blockstate5 = p_111168_.getBlockState( -- blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[1]).move(p_111171_) +- blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[1]).move(p_366875_) + blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[1]) // Neo: remove move() to avoid oversampling (MC-43968) ); - boolean flag1 = !blockstate5.isViewBlocking(p_111168_, blockpos$mutableblockpos) - || blockstate5.getLightBlock(p_111168_, blockpos$mutableblockpos) == 0; + boolean flag1 = !blockstate5.isViewBlocking(p_111168_, blockpos$mutableblockpos) || blockstate5.getLightBlock() == 0; BlockState blockstate6 = p_111168_.getBlockState( -- blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[2]).move(p_111171_) +- blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[2]).move(p_366875_) + blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[2]) // Neo: remove move() to avoid oversampling (MC-43968) ); - boolean flag2 = !blockstate6.isViewBlocking(p_111168_, blockpos$mutableblockpos) - || blockstate6.getLightBlock(p_111168_, blockpos$mutableblockpos) == 0; + boolean flag2 = !blockstate6.isViewBlocking(p_111168_, blockpos$mutableblockpos) || blockstate6.getLightBlock() == 0; BlockState blockstate7 = p_111168_.getBlockState( -- blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[3]).move(p_111171_) +- blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[3]).move(p_366875_) + blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[3]) // Neo: remove move() to avoid oversampling (MC-43968) ); - boolean flag3 = !blockstate7.isViewBlocking(p_111168_, blockpos$mutableblockpos) - || blockstate7.getLightBlock(p_111168_, blockpos$mutableblockpos) == 0; + boolean flag3 = !blockstate7.isViewBlocking(p_111168_, blockpos$mutableblockpos) || blockstate7.getLightBlock() == 0; + float f4; diff --git a/patches/net/minecraft/client/renderer/block/model/BakedOverrides.java.patch b/patches/net/minecraft/client/renderer/block/model/BakedOverrides.java.patch new file mode 100644 index 0000000000..60cb1a713d --- /dev/null +++ b/patches/net/minecraft/client/renderer/block/model/BakedOverrides.java.patch @@ -0,0 +1,38 @@ +--- a/net/minecraft/client/renderer/block/model/BakedOverrides.java ++++ b/net/minecraft/client/renderer/block/model/BakedOverrides.java +@@ -29,7 +_,15 @@ + this.properties = new ResourceLocation[0]; + } + ++ /** ++ * @deprecated Neo: Use {@link #BakedOverrides(ModelBaker, List, java.util.function.Function)} ++ */ ++ @Deprecated + public BakedOverrides(ModelBaker p_371950_, List p_371198_) { ++ this(p_371950_, p_371198_, p_371950_.getModelTextureGetter()); ++ } ++ ++ public BakedOverrides(ModelBaker p_371950_, List p_371198_, java.util.function.Function spriteGetter) { + this.properties = p_371198_.stream() + .flatMap(p_371945_ -> p_371945_.predicates().stream()) + .map(ItemOverride.Predicate::property) +@@ -45,7 +_,7 @@ + + for (int j = p_371198_.size() - 1; j >= 0; j--) { + ItemOverride itemoverride = p_371198_.get(j); +- BakedModel bakedmodel = p_371950_.bake(itemoverride.model(), BlockModelRotation.X0_Y0); ++ BakedModel bakedmodel = p_371950_.bake(itemoverride.model(), BlockModelRotation.X0_Y0, spriteGetter); + BakedOverrides.PropertyMatcher[] abakedoverrides$propertymatcher = itemoverride.predicates().stream().map(p_371644_ -> { + int k = object2intmap.getInt(p_371644_.property()); + return new BakedOverrides.PropertyMatcher(k, p_371644_.value()); +@@ -80,6 +_,10 @@ + } + + return null; ++ } ++ ++ public com.google.common.collect.ImmutableList getOverrides() { ++ return com.google.common.collect.ImmutableList.copyOf(overrides); + } + + @OnlyIn(Dist.CLIENT) diff --git a/patches/net/minecraft/client/renderer/block/model/BakedQuad.java.patch b/patches/net/minecraft/client/renderer/block/model/BakedQuad.java.patch index fb47f0c8ce..4c6541f542 100644 --- a/patches/net/minecraft/client/renderer/block/model/BakedQuad.java.patch +++ b/patches/net/minecraft/client/renderer/block/model/BakedQuad.java.patch @@ -1,29 +1,30 @@ --- a/net/minecraft/client/renderer/block/model/BakedQuad.java +++ b/net/minecraft/client/renderer/block/model/BakedQuad.java -@@ -12,13 +_,19 @@ - protected final Direction direction; +@@ -13,14 +_,20 @@ protected final TextureAtlasSprite sprite; private final boolean shade; + private final int lightEmission; + private final boolean hasAmbientOcclusion; - public BakedQuad(int[] p_111298_, int p_111299_, Direction p_111300_, TextureAtlasSprite p_111301_, boolean p_111302_) { -+ this(p_111298_, p_111299_, p_111300_, p_111301_, p_111302_, true); + public BakedQuad(int[] p_111298_, int p_111299_, Direction p_111300_, TextureAtlasSprite p_111301_, boolean p_111302_, int p_361140_) { ++ this(p_111298_, p_111299_, p_111300_, p_111301_, p_111302_, p_361140_, true); + } + -+ public BakedQuad(int[] p_111298_, int p_111299_, Direction p_111300_, TextureAtlasSprite p_111301_, boolean p_111302_, boolean hasAmbientOcclusion) { ++ public BakedQuad(int[] p_111298_, int p_111299_, Direction p_111300_, TextureAtlasSprite p_111301_, boolean p_111302_, int p_361140_, boolean hasAmbientOcclusion) { this.vertices = p_111298_; this.tintIndex = p_111299_; this.direction = p_111300_; this.sprite = p_111301_; this.shade = p_111302_; + this.lightEmission = p_361140_; + this.hasAmbientOcclusion = hasAmbientOcclusion; } public TextureAtlasSprite getSprite() { -@@ -43,5 +_,13 @@ +@@ -49,5 +_,13 @@ - public boolean isShade() { - return this.shade; + public int getLightEmission() { + return this.lightEmission; + } + + /** diff --git a/patches/net/minecraft/client/renderer/block/model/BlockElement.java.patch b/patches/net/minecraft/client/renderer/block/model/BlockElement.java.patch index eb9ddf9135..c19fb03a3e 100644 --- a/patches/net/minecraft/client/renderer/block/model/BlockElement.java.patch +++ b/patches/net/minecraft/client/renderer/block/model/BlockElement.java.patch @@ -1,41 +1,44 @@ --- a/net/minecraft/client/renderer/block/model/BlockElement.java +++ b/net/minecraft/client/renderer/block/model/BlockElement.java -@@ -29,16 +_,23 @@ - public final Map faces; +@@ -30,6 +_,7 @@ public final BlockElementRotation rotation; public final boolean shade; + public final int lightEmission; + private net.neoforged.neoforge.client.model.ExtraFaceData faceData; - public BlockElement( - Vector3f p_253626_, Vector3f p_254426_, Map p_254454_, @Nullable BlockElementRotation p_254229_, boolean p_253661_ + public BlockElement(Vector3f p_253626_, Vector3f p_254426_, Map p_254454_) { + this(p_253626_, p_254426_, p_254454_, null, true, 0); +@@ -43,6 +_,10 @@ + boolean p_361372_, + int p_361908_ ) { -+ this(p_253626_, p_254426_, p_254454_, p_254229_, p_253661_, net.neoforged.neoforge.client.model.ExtraFaceData.DEFAULT); ++ this(p_361324_, p_363867_, p_362722_, p_360926_, p_361372_, p_361908_, net.neoforged.neoforge.client.model.ExtraFaceData.DEFAULT); + } + -+ public BlockElement(Vector3f p_253626_, Vector3f p_254426_, Map p_254454_, @Nullable BlockElementRotation p_254229_, boolean p_253661_, net.neoforged.neoforge.client.model.ExtraFaceData faceData) { - this.from = p_253626_; - this.to = p_254426_; - this.faces = p_254454_; - this.rotation = p_254229_; - this.shade = p_253661_; ++ public BlockElement(Vector3f p_361324_, Vector3f p_363867_, Map p_362722_, @Nullable BlockElementRotation p_360926_, boolean p_361372_, int p_361908_, net.neoforged.neoforge.client.model.ExtraFaceData faceData) { + this.from = p_361324_; + this.to = p_363867_; + this.faces = p_362722_; +@@ -50,6 +_,8 @@ + this.shade = p_361372_; + this.lightEmission = p_361908_; this.fillUvs(); + this.setFaceData(faceData); + this.faces.values().forEach(face -> face.parent().setValue(this)); } private void fillUvs() { -@@ -80,7 +_,9 @@ - throw new JsonParseException("Expected shade to be a Boolean"); - } else { - boolean flag = GsonHelper.getAsBoolean(jsonobject, "shade", true); -- return new BlockElement(vector3f, vector3f1, map, blockelementrotation, flag); -+ if (jsonobject.has("forge_data")) throw new JsonParseException("forge_data should be replaced by neoforge_data"); // TODO 1.22: Remove +@@ -104,7 +_,8 @@ + } + } + +- return new BlockElement(vector3f, vector3f1, map, blockelementrotation, flag, i); + var faceData = net.neoforged.neoforge.client.model.ExtraFaceData.read(jsonobject.get("neoforge_data"), net.neoforged.neoforge.client.model.ExtraFaceData.DEFAULT); -+ return new BlockElement(vector3f, vector3f1, map, blockelementrotation, flag, faceData); ++ return new BlockElement(vector3f, vector3f1, map, blockelementrotation, flag, i, faceData); } } -@@ -191,5 +_,13 @@ +@@ -215,5 +_,13 @@ return new Vector3f(afloat[0], afloat[1], afloat[2]); } } diff --git a/patches/net/minecraft/client/renderer/block/model/BlockModel.java.patch b/patches/net/minecraft/client/renderer/block/model/BlockModel.java.patch index b587befb12..767bdb3611 100644 --- a/patches/net/minecraft/client/renderer/block/model/BlockModel.java.patch +++ b/patches/net/minecraft/client/renderer/block/model/BlockModel.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/block/model/BlockModel.java +++ b/net/minecraft/client/renderer/block/model/BlockModel.java -@@ -77,9 +_,10 @@ +@@ -72,9 +_,10 @@ public BlockModel parent; @Nullable protected ResourceLocation parentLocation; @@ -11,8 +11,8 @@ + return GsonHelper.fromJson(net.neoforged.neoforge.client.model.ExtendedBlockModelDeserializer.INSTANCE, p_111462_, BlockModel.class); } - public static BlockModel fromString(String p_111464_) { -@@ -104,10 +_,15 @@ + public BlockModel( +@@ -95,10 +_,15 @@ this.overrides = p_273099_; } @@ -28,42 +28,50 @@ public boolean hasAmbientOcclusion() { if (this.hasAmbientOcclusion != null) { return this.hasAmbientOcclusion; -@@ -136,6 +_,10 @@ - return this.overrides.isEmpty() ? ItemOverrides.EMPTY : new ItemOverrides(p_250138_, p_251800_, this.overrides); - } +@@ -132,10 +_,18 @@ -+ public ItemOverrides getOverrides(ModelBaker p_250138_, BlockModel p_251800_, Function spriteGetter) { -+ return this.overrides.isEmpty() ? ItemOverrides.EMPTY : new ItemOverrides(p_250138_, p_251800_, this.overrides, spriteGetter); -+ } -+ - @Override - public Collection getDependencies() { - Set set = Sets.newHashSet(); -@@ -184,6 +_,10 @@ - blockmodel.parent = (BlockModel)unbakedmodel; + this.parent = blockmodel; } - ++ + if (customData.hasCustomGeometry()) { -+ customData.getCustomGeometry().resolveParents(p_249059_, customData); ++ customData.getCustomGeometry().resolveDependencies(p_361203_, customData); + } -+ - this.overrides.forEach(p_247932_ -> { - UnbakedModel unbakedmodel1 = p_249059_.apply(p_247932_.getModel()); - if (!Objects.equals(unbakedmodel1, this)) { -@@ -198,6 +_,12 @@ } - public BakedModel bake( -+ ModelBaker p_249720_, BlockModel p_111451_, Function p_111452_, ModelState p_111453_, boolean p_111455_ -+ ) { -+ return net.neoforged.neoforge.client.model.geometry.UnbakedGeometryHelper.bake(this, p_249720_, p_111451_, p_111452_, p_111453_, p_111455_); -+ } + @Override + public BakedModel bake(ModelBaker p_252120_, Function p_250023_, ModelState p_251130_) { ++ var customGeometry = this.customData.getCustomGeometry(); ++ if (customGeometry != null) { ++ return customGeometry.bake(this.customData, p_252120_, p_250023_, p_251130_, this.overrides); ++ } + return this.bake(p_250023_, p_251130_, true); + } + +@@ -146,6 +_,10 @@ + } else { + SimpleBakedModel.Builder simplebakedmodel$builder = new SimpleBakedModel.Builder(this, p_111455_).particle(textureatlassprite); + ++ if (!this.customData.getRootTransform().isIdentity()) { ++ p_111453_ = net.neoforged.neoforge.client.model.geometry.UnbakedGeometryHelper.composeRootTransformIntoModelState(p_111453_, this.customData.getRootTransform()); ++ } + -+ public BakedModel bakeVanilla( - ModelBaker p_249720_, BlockModel p_111451_, Function p_111452_, ModelState p_111453_, boolean p_111455_ - ) { - TextureAtlasSprite textureatlassprite = p_111452_.apply(this.getMaterial("particle")); -@@ -288,7 +_,18 @@ + for (BlockElement blockelement : this.getElements()) { + for (Direction direction : blockelement.faces.keySet()) { + BlockElementFace blockelementface = blockelement.faces.get(direction); +@@ -161,7 +_,11 @@ + } + } + +- return simplebakedmodel$builder.build(); ++ var renderTypes = net.neoforged.neoforge.client.RenderTypeGroup.EMPTY; ++ if (this.customData.getRenderTypeHint() != null) { ++ renderTypes = this.customData.getRenderType(this.customData.getRenderTypeHint()); ++ } ++ return simplebakedmodel$builder.build(renderTypes); + } + } + +@@ -229,7 +_,18 @@ ItemTransform itemtransform5 = this.getTransform(ItemDisplayContext.GUI); ItemTransform itemtransform6 = this.getTransform(ItemDisplayContext.GROUND); ItemTransform itemtransform7 = this.getTransform(ItemDisplayContext.FIXED); @@ -83,12 +91,14 @@ } private ItemTransform getTransform(ItemDisplayContext p_270662_) { -@@ -407,6 +_,8 @@ +@@ -347,6 +_,10 @@ + public boolean lightLikeBlock() { return this == SIDE; - } ++ } + -+ public String getSerializedName() { return name; } ++ public String getSerializedName() { ++ return name; + } } - - @OnlyIn(Dist.CLIENT) + } diff --git a/patches/net/minecraft/client/renderer/block/model/FaceBakery.java.patch b/patches/net/minecraft/client/renderer/block/model/FaceBakery.java.patch index e24c70720e..71b9c9943e 100644 --- a/patches/net/minecraft/client/renderer/block/model/FaceBakery.java.patch +++ b/patches/net/minecraft/client/renderer/block/model/FaceBakery.java.patch @@ -1,13 +1,13 @@ --- a/net/minecraft/client/renderer/block/model/FaceBakery.java +++ b/net/minecraft/client/renderer/block/model/FaceBakery.java -@@ -57,7 +_,14 @@ +@@ -58,7 +_,14 @@ this.recalculateWinding(aint, direction); } -- return new BakedQuad(aint, p_111603_.tintIndex(), direction, p_111604_, p_111608_); +- return new BakedQuad(aint, p_111603_.tintIndex(), direction, p_111604_, p_111608_, p_364857_); + net.neoforged.neoforge.client.ClientHooks.fillNormal(aint, direction); + var data = p_111603_.faceData(); -+ var quad = new BakedQuad(aint, p_111603_.tintIndex(), direction, p_111604_, p_111608_, data.ambientOcclusion()); ++ var quad = new BakedQuad(aint, p_111603_.tintIndex(), direction, p_111604_, p_111608_, p_364857_, data.ambientOcclusion()); + if (!net.neoforged.neoforge.client.model.ExtraFaceData.DEFAULT.equals(data)) { + net.neoforged.neoforge.client.model.QuadTransformers.applyingLightmap(data.blockLight(), data.skyLight()).processInPlace(quad); + net.neoforged.neoforge.client.model.QuadTransformers.applyingColor(data.color()).processInPlace(quad); diff --git a/patches/net/minecraft/client/renderer/block/model/ItemOverrides.java.patch b/patches/net/minecraft/client/renderer/block/model/ItemOverrides.java.patch deleted file mode 100644 index 13a802c111..0000000000 --- a/patches/net/minecraft/client/renderer/block/model/ItemOverrides.java.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- a/net/minecraft/client/renderer/block/model/ItemOverrides.java -+++ b/net/minecraft/client/renderer/block/model/ItemOverrides.java -@@ -31,7 +_,15 @@ - this.properties = new ResourceLocation[0]; - } - -+ /** -+ * @deprecated Forge: Use {@link #ItemOverrides(ModelBaker, UnbakedModel, List, java.util.function.Function)} -+ */ -+ @Deprecated - public ItemOverrides(ModelBaker p_251211_, BlockModel p_111741_, List p_111743_) { -+ this(p_251211_, p_111741_, p_111743_, p_251211_.getModelTextureGetter()); -+ } -+ -+ public ItemOverrides(ModelBaker p_251211_, UnbakedModel p_111741_, List p_111743_, java.util.function.Function spriteGetter) { - this.properties = p_111743_.stream() - .flatMap(ItemOverride::getPredicates) - .map(ItemOverride.Predicate::getProperty) -@@ -47,7 +_,7 @@ - - for (int j = p_111743_.size() - 1; j >= 0; j--) { - ItemOverride itemoverride = p_111743_.get(j); -- BakedModel bakedmodel = this.bakeModel(p_251211_, p_111741_, itemoverride); -+ BakedModel bakedmodel = this.bakeModel(p_251211_, p_111741_, itemoverride, spriteGetter); - ItemOverrides.PropertyMatcher[] aitemoverrides$propertymatcher = itemoverride.getPredicates().map(p_173477_ -> { - int k = object2intmap.getInt(p_173477_.getProperty()); - return new ItemOverrides.PropertyMatcher(k, p_173477_.getValue()); -@@ -59,9 +_,9 @@ - } - - @Nullable -- private BakedModel bakeModel(ModelBaker p_249483_, BlockModel p_251965_, ItemOverride p_250816_) { -+ private BakedModel bakeModel(ModelBaker p_249483_, UnbakedModel p_251965_, ItemOverride p_250816_, java.util.function.Function spriteGetter) { - UnbakedModel unbakedmodel = p_249483_.getModel(p_250816_.getModel()); -- return Objects.equals(unbakedmodel, p_251965_) ? null : p_249483_.bake(p_250816_.getModel(), BlockModelRotation.X0_Y0); -+ return Objects.equals(unbakedmodel, p_251965_) ? null : p_249483_.bake(p_250816_.getModel(), BlockModelRotation.X0_Y0, spriteGetter); - } - - @Nullable -@@ -93,6 +_,10 @@ - } - - return p_173465_; -+ } -+ -+ public com.google.common.collect.ImmutableList getOverrides() { -+ return com.google.common.collect.ImmutableList.copyOf(overrides); - } - - @OnlyIn(Dist.CLIENT) diff --git a/patches/net/minecraft/client/renderer/block/model/MultiVariant.java.patch b/patches/net/minecraft/client/renderer/block/model/MultiVariant.java.patch index 438e617781..bd74eaf20d 100644 --- a/patches/net/minecraft/client/renderer/block/model/MultiVariant.java.patch +++ b/patches/net/minecraft/client/renderer/block/model/MultiVariant.java.patch @@ -1,11 +1,17 @@ --- a/net/minecraft/client/renderer/block/model/MultiVariant.java +++ b/net/minecraft/client/renderer/block/model/MultiVariant.java -@@ -68,7 +_,7 @@ - WeightedBakedModel.Builder weightedbakedmodel$builder = new WeightedBakedModel.Builder(); +@@ -45,12 +_,12 @@ + public BakedModel bake(ModelBaker p_249016_, Function p_111851_, ModelState p_111852_) { + if (this.variants.size() == 1) { + Variant variant1 = this.variants.getFirst(); +- return p_249016_.bake(variant1.getModelLocation(), variant1); ++ return p_249016_.bake(variant1.getModelLocation(), variant1, p_111851_); + } else { + SimpleWeightedRandomList.Builder builder = SimpleWeightedRandomList.builder(); - for (Variant variant : this.getVariants()) { + for (Variant variant : this.variants) { - BakedModel bakedmodel = p_249016_.bake(variant.getModelLocation(), variant); + BakedModel bakedmodel = p_249016_.bake(variant.getModelLocation(), variant, p_111851_); - weightedbakedmodel$builder.add(bakedmodel, variant.getWeight()); + builder.add(bakedmodel, variant.getWeight()); } diff --git a/patches/net/minecraft/client/renderer/blockentity/BannerRenderer.java.patch b/patches/net/minecraft/client/renderer/blockentity/BannerRenderer.java.patch index c526f18760..81cc3164d7 100644 --- a/patches/net/minecraft/client/renderer/blockentity/BannerRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/blockentity/BannerRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/blockentity/BannerRenderer.java +++ b/net/minecraft/client/renderer/blockentity/BannerRenderer.java -@@ -139,4 +_,11 @@ +@@ -141,4 +_,11 @@ int i = p_332728_.getTextureDiffuseColor(); p_332732_.render(p_332737_, p_332704_.buffer(p_332758_, RenderType::entityNoOutline), p_332821_, p_332828_, i); } diff --git a/patches/net/minecraft/client/renderer/blockentity/ChestRenderer.java.patch b/patches/net/minecraft/client/renderer/blockentity/ChestRenderer.java.patch index a79e270319..dc78f074c0 100644 --- a/patches/net/minecraft/client/renderer/blockentity/ChestRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/blockentity/ChestRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/blockentity/ChestRenderer.java +++ b/net/minecraft/client/renderer/blockentity/ChestRenderer.java -@@ -128,7 +_,7 @@ +@@ -66,7 +_,7 @@ f1 = 1.0F - f1; f1 = 1.0F - f1 * f1 * f1; int i = neighborcombineresult.apply(new BrightnessCombiner<>()).applyAsInt(p_112367_); @@ -9,10 +9,10 @@ VertexConsumer vertexconsumer = material.buffer(p_112366_, RenderType::entityCutout); if (flag1) { if (chesttype == ChestType.LEFT) { -@@ -159,5 +_,15 @@ - p_112372_.render(p_112370_, p_112371_, p_112376_, p_112377_); - p_112373_.render(p_112370_, p_112371_, p_112376_, p_112377_); - p_112374_.render(p_112370_, p_112371_, p_112376_, p_112377_); +@@ -85,5 +_,15 @@ + private void render(PoseStack p_112370_, VertexConsumer p_112371_, ChestModel p_364178_, float p_112375_, int p_112376_, int p_112377_) { + p_364178_.setupAnim(p_112375_); + p_364178_.renderToBuffer(p_112370_, p_112371_, p_112376_, p_112377_); + } + + protected Material getMaterial(T blockEntity, ChestType chestType) { diff --git a/patches/net/minecraft/client/renderer/blockentity/EnchantTableRenderer.java.patch b/patches/net/minecraft/client/renderer/blockentity/EnchantTableRenderer.java.patch index 35f7d56236..90b0eb6aad 100644 --- a/patches/net/minecraft/client/renderer/blockentity/EnchantTableRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/blockentity/EnchantTableRenderer.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/client/renderer/blockentity/EnchantTableRenderer.java +++ b/net/minecraft/client/renderer/blockentity/EnchantTableRenderer.java @@ -53,4 +_,10 @@ - this.bookModel.render(p_112420_, vertexconsumer, p_112422_, p_112423_, -1); + this.bookModel.renderToBuffer(p_112420_, vertexconsumer, p_112422_, p_112423_); p_112420_.popPose(); } + diff --git a/patches/net/minecraft/client/renderer/blockentity/ShulkerBoxRenderer.java.patch b/patches/net/minecraft/client/renderer/blockentity/ShulkerBoxRenderer.java.patch index 4bd585503f..b1bd51f952 100644 --- a/patches/net/minecraft/client/renderer/blockentity/ShulkerBoxRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/blockentity/ShulkerBoxRenderer.java.patch @@ -1,13 +1,15 @@ --- a/net/minecraft/client/renderer/blockentity/ShulkerBoxRenderer.java +++ b/net/minecraft/client/renderer/blockentity/ShulkerBoxRenderer.java -@@ -56,4 +_,10 @@ - this.model.renderToBuffer(p_112480_, vertexconsumer, p_112482_, p_112483_); +@@ -55,6 +_,12 @@ p_112480_.popPose(); } -+ + + @Override + public net.minecraft.world.phys.AABB getRenderBoundingBox(ShulkerBoxBlockEntity blockEntity) { + net.minecraft.core.BlockPos pos = blockEntity.getBlockPos(); + return new net.minecraft.world.phys.AABB(pos.getX() - 0.5, pos.getY() - 0.5, pos.getZ() - 0.5, pos.getX() + 1.5, pos.getY() + 1.5, pos.getZ() + 1.5); + } - } ++ + @OnlyIn(Dist.CLIENT) + static class ShulkerBoxModel extends Model { + private final ModelPart lid; diff --git a/patches/net/minecraft/client/renderer/blockentity/SignRenderer.java.patch b/patches/net/minecraft/client/renderer/blockentity/SignRenderer.java.patch index e4756dda94..23ffcf89c2 100644 --- a/patches/net/minecraft/client/renderer/blockentity/SignRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/blockentity/SignRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/blockentity/SignRenderer.java +++ b/net/minecraft/client/renderer/blockentity/SignRenderer.java -@@ -250,6 +_,15 @@ +@@ -251,6 +_,15 @@ return LayerDefinition.create(meshdefinition, 64, 32); } @@ -14,5 +14,5 @@ + } + @OnlyIn(Dist.CLIENT) - public static final class SignModel extends Model { - public final ModelPart root; + static record Models(Model standing, Model wall) { + } diff --git a/patches/net/minecraft/client/renderer/blockentity/SpawnerRenderer.java.patch b/patches/net/minecraft/client/renderer/blockentity/SpawnerRenderer.java.patch index 351d861b08..7a43c83c08 100644 --- a/patches/net/minecraft/client/renderer/blockentity/SpawnerRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/blockentity/SpawnerRenderer.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/client/renderer/blockentity/SpawnerRenderer.java +++ b/net/minecraft/client/renderer/blockentity/SpawnerRenderer.java @@ -57,4 +_,10 @@ - p_312703_.render(p_312223_, 0.0, 0.0, 0.0, 0.0F, p_311943_, p_312805_, p_312394_, p_311996_); + p_312703_.render(p_312223_, 0.0, 0.0, 0.0, p_311943_, p_312805_, p_312394_, p_311996_); p_312805_.popPose(); } + diff --git a/patches/net/minecraft/client/renderer/chunk/SectionRenderDispatcher.java.patch b/patches/net/minecraft/client/renderer/chunk/SectionRenderDispatcher.java.patch index 33e437bf17..83ea06baae 100644 --- a/patches/net/minecraft/client/renderer/chunk/SectionRenderDispatcher.java.patch +++ b/patches/net/minecraft/client/renderer/chunk/SectionRenderDispatcher.java.patch @@ -1,47 +1,42 @@ --- a/net/minecraft/client/renderer/chunk/SectionRenderDispatcher.java +++ b/net/minecraft/client/renderer/chunk/SectionRenderDispatcher.java -@@ -441,14 +_,15 @@ +@@ -393,9 +_,10 @@ public SectionRenderDispatcher.RenderSection.CompileTask createCompileTask(RenderRegionCache p_295324_) { - boolean flag = this.cancelTasks(); -- RenderChunkRegion renderchunkregion = p_295324_.createRegion(SectionRenderDispatcher.this.level, SectionPos.of(this.origin)); + this.cancelTasks(); +- RenderChunkRegion renderchunkregion = p_295324_.createRegion(SectionRenderDispatcher.this.level, SectionPos.of(this.sectionNode)); + var additionalRenderers = net.neoforged.neoforge.client.ClientHooks.gatherAdditionalRenderers(this.origin, SectionRenderDispatcher.this.level); -+ RenderChunkRegion renderchunkregion = p_295324_.createRegion(SectionRenderDispatcher.this.level, SectionPos.of(this.origin), additionalRenderers.isEmpty()); - boolean flag1 = this.compiled.get() == SectionRenderDispatcher.CompiledSection.UNCOMPILED; - if (flag1 && flag) { - this.initialCompilationCancelCount.incrementAndGet(); - } - - this.lastRebuildTask = new SectionRenderDispatcher.RenderSection.RebuildTask( -- this.getDistToPlayerSqr(), renderchunkregion, !flag1 || this.initialCompilationCancelCount.get() > 2 -+ this.getDistToPlayerSqr(), renderchunkregion, !flag1 || this.initialCompilationCancelCount.get() > 2, additionalRenderers - ); ++ RenderChunkRegion renderchunkregion = p_295324_.createRegion(SectionRenderDispatcher.this.level, SectionPos.of(this.sectionNode), additionalRenderers.isEmpty()); + boolean flag = this.compiled.get() != SectionRenderDispatcher.CompiledSection.UNCOMPILED; +- this.lastRebuildTask = new SectionRenderDispatcher.RenderSection.RebuildTask(renderchunkregion, flag); ++ this.lastRebuildTask = new SectionRenderDispatcher.RenderSection.RebuildTask(renderchunkregion, flag, additionalRenderers); return this.lastRebuildTask; } -@@ -523,10 +_,17 @@ + +@@ -464,10 +_,17 @@ class RebuildTask extends SectionRenderDispatcher.RenderSection.CompileTask { @Nullable - protected RenderChunkRegion region; + protected volatile RenderChunkRegion region; + private final List additionalRenderers; + @Deprecated - public RebuildTask(double p_294400_, @Nullable RenderChunkRegion p_294382_, boolean p_295207_) { -+ this(p_294400_, p_294382_, p_295207_, List.of()); + public RebuildTask(@Nullable RenderChunkRegion p_294382_, boolean p_295207_) { ++ this(p_294382_, p_295207_, List.of()); + } + -+ public RebuildTask(double p_294400_, @Nullable RenderChunkRegion p_294382_, boolean p_295207_, List additionalRenderers) { - super(p_294400_, p_295207_); ++ public RebuildTask(@Nullable RenderChunkRegion p_294382_, boolean p_295207_, List additionalRenderers) { + super(p_295207_); this.region = p_294382_; + this.additionalRenderers = additionalRenderers; } @Override -@@ -552,7 +_,7 @@ - } else { - SectionPos sectionpos = SectionPos.of(RenderSection.this.origin); - SectionCompiler.Results sectioncompiler$results = SectionRenderDispatcher.this.sectionCompiler -- .compile(sectionpos, renderchunkregion, RenderSection.this.createVertexSorting(), p_296138_); -+ .compile(sectionpos, renderchunkregion, RenderSection.this.createVertexSorting(), p_296138_, this.additionalRenderers); - RenderSection.this.updateGlobalBlockEntities(sectioncompiler$results.globalBlockEntities); - if (this.isCancelled.get()) { - sectioncompiler$results.release(); +@@ -498,7 +_,7 @@ + SectionCompiler.Results sectioncompiler$results; + try (Zone zone = Profiler.get().zone("Compile Section")) { + sectioncompiler$results = SectionRenderDispatcher.this.sectionCompiler +- .compile(sectionpos, renderchunkregion, RenderSection.this.createVertexSorting(), p_296138_); ++ .compile(sectionpos, renderchunkregion, RenderSection.this.createVertexSorting(), p_296138_, this.additionalRenderers); + } + + SectionRenderDispatcher.TranslucencyPointOfView sectionrenderdispatcher$translucencypointofview = SectionRenderDispatcher.TranslucencyPointOfView.of( diff --git a/patches/net/minecraft/client/renderer/culling/Frustum.java.patch b/patches/net/minecraft/client/renderer/culling/Frustum.java.patch index 92a6b521cb..9dc2e4adad 100644 --- a/patches/net/minecraft/client/renderer/culling/Frustum.java.patch +++ b/patches/net/minecraft/client/renderer/culling/Frustum.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/client/renderer/culling/Frustum.java +++ b/net/minecraft/client/renderer/culling/Frustum.java -@@ -70,6 +_,8 @@ +@@ -71,6 +_,8 @@ } public boolean isVisible(AABB p_113030_) { + // FORGE: exit early for infinite bounds, these would otherwise fail in the intersection test at certain camera angles (GH-9321) + if (p_113030_.isInfinite()) return true; - return this.cubeInFrustum(p_113030_.minX, p_113030_.minY, p_113030_.minZ, p_113030_.maxX, p_113030_.maxY, p_113030_.maxZ); + int i = this.cubeInFrustum(p_113030_.minX, p_113030_.minY, p_113030_.minZ, p_113030_.maxX, p_113030_.maxY, p_113030_.maxZ); + return i == -2 || i == -1; } - diff --git a/patches/net/minecraft/client/renderer/entity/BoatRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/BoatRenderer.java.patch deleted file mode 100644 index efa87185cc..0000000000 --- a/patches/net/minecraft/client/renderer/entity/BoatRenderer.java.patch +++ /dev/null @@ -1,45 +0,0 @@ ---- a/net/minecraft/client/renderer/entity/BoatRenderer.java -+++ b/net/minecraft/client/renderer/entity/BoatRenderer.java -@@ -45,7 +_,7 @@ - private ListModel createBoatModel(EntityRendererProvider.Context p_248834_, Boat.Type p_249317_, boolean p_250093_) { - ModelLayerLocation modellayerlocation = p_250093_ ? ModelLayers.createChestBoatModelName(p_249317_) : ModelLayers.createBoatModelName(p_249317_); - ModelPart modelpart = p_248834_.bakeLayer(modellayerlocation); -- if (p_249317_ == Boat.Type.BAMBOO) { -+ if (p_249317_.isRaft()) { - return (ListModel)(p_250093_ ? new ChestRaftModel(modelpart) : new RaftModel(modelpart)); - } else { - return (ListModel)(p_250093_ ? new ChestBoatModel(modelpart) : new BoatModel(modelpart)); -@@ -54,8 +_,8 @@ - - private static ResourceLocation getTextureLocation(Boat.Type p_234566_, boolean p_234567_) { - return p_234567_ -- ? ResourceLocation.withDefaultNamespace("textures/entity/chest_boat/" + p_234566_.getName() + ".png") -- : ResourceLocation.withDefaultNamespace("textures/entity/boat/" + p_234566_.getName() + ".png"); -+ ? ResourceLocation.parse(p_234566_.getName()).withPrefix("textures/entity/chest_boat/").withSuffix(".png") -+ : ResourceLocation.parse(p_234566_.getName()).withPrefix("textures/entity/boat/").withSuffix(".png"); - } - - public void render(Boat p_113929_, float p_113930_, float p_113931_, PoseStack p_113932_, MultiBufferSource p_113933_, int p_113934_) { -@@ -77,7 +_,7 @@ - p_113932_.mulPose(new Quaternionf().setAngleAxis(p_113929_.getBubbleAngle(p_113931_) * (float) (Math.PI / 180.0), 1.0F, 0.0F, 1.0F)); - } - -- Pair> pair = this.boatResources.get(p_113929_.getVariant()); -+ Pair> pair = getModelWithLocation(p_113929_); - ResourceLocation resourcelocation = pair.getFirst(); - ListModel listmodel = pair.getSecond(); - p_113932_.scale(-1.0F, -1.0F, 1.0F); -@@ -96,7 +_,12 @@ - super.render(p_113929_, p_113930_, p_113931_, p_113932_, p_113933_, p_113934_); - } - -+ @Deprecated // forge: override getModelWithLocation to change the texture / model - public ResourceLocation getTextureLocation(Boat p_113927_) { -- return this.boatResources.get(p_113927_.getVariant()).getFirst(); -+ return getModelWithLocation(p_113927_).getFirst(); -+ } -+ -+ public Pair> getModelWithLocation(Boat boat) { -+ return this.boatResources.get(boat.getVariant()); - } - } diff --git a/patches/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java.patch b/patches/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java.patch index d1dd832f9d..49c5906036 100644 --- a/patches/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java.patch +++ b/patches/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java +++ b/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java -@@ -222,12 +_,12 @@ +@@ -243,12 +_,12 @@ ) { AABB aabb = p_114444_.getBoundingBox().move(-p_114444_.getX(), -p_114444_.getY(), -p_114444_.getZ()); - LevelRenderer.renderLineBox(p_114442_, p_114443_, aabb, p_353064_, p_353059_, p_353042_, 1.0F); + ShapeRenderer.renderLineBox(p_114442_, p_114443_, aabb, p_353064_, p_353059_, p_353042_, 1.0F); - if (p_114444_ instanceof EnderDragon) { + if (p_114444_.isMultipartEntity()) { double d0 = -Mth.lerp((double)p_114445_, p_114444_.xOld, p_114444_.getX()); @@ -15,18 +15,18 @@ p_114442_.pushPose(); double d3 = d0 + Mth.lerp((double)p_114445_, enderdragonpart.xOld, enderdragonpart.getX()); double d4 = d1 + Mth.lerp((double)p_114445_, enderdragonpart.yOld, enderdragonpart.getY()); -@@ -467,6 +_,10 @@ +@@ -474,6 +_,10 @@ return this.itemInHandRenderer; } -+ public Map> getSkinMap() { ++ public Map> getSkinMap() { + return java.util.Collections.unmodifiableMap(playerRenderers); + } + @Override public void onResourceManagerReload(ResourceManager p_174004_) { EntityRendererProvider.Context entityrendererprovider$context = new EntityRendererProvider.Context( -@@ -474,5 +_,6 @@ +@@ -481,5 +_,6 @@ ); this.renderers = EntityRenderers.createEntityRenderers(entityrendererprovider$context); this.playerRenderers = EntityRenderers.createPlayerRenderers(entityrendererprovider$context); diff --git a/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch index 86142b3674..2e7b86b284 100644 --- a/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/EntityRenderer.java.patch @@ -1,25 +1,33 @@ --- a/net/minecraft/client/renderer/entity/EntityRenderer.java +++ b/net/minecraft/client/renderer/entity/EntityRenderer.java -@@ -94,8 +_,11 @@ - } +@@ -105,6 +_,8 @@ } -- if (this.shouldShowName(p_114485_)) { -- this.renderNameTag(p_114485_, p_114485_.getDisplayName(), p_114488_, p_114489_, p_114490_, p_114487_); -+ // Neo: Post the RenderNameTagEvent and conditionally wrap #renderNameTag based on the result. -+ var event = new net.neoforged.neoforge.client.event.RenderNameTagEvent(p_114485_, p_114485_.getDisplayName(), this, p_114488_, p_114489_, p_114490_, p_114487_); -+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(event); -+ if (event.canRender().isTrue() || event.canRender().isDefault() && this.shouldShowName(p_114485_)) { -+ this.renderNameTag(p_114485_, event.getContent(), p_114488_, p_114489_, p_114490_, p_114487_); + if (p_364816_.nameTag != null) { ++ var event = new net.neoforged.neoforge.client.event.RenderNameTagEvent.DoRender(p_364816_, p_364816_.nameTag, this, p_114488_, p_114489_, p_114490_, p_364816_.partialTick); ++ if (!net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(event).isCanceled()) + this.renderNameTag(p_364816_, p_364816_.nameTag, p_114488_, p_114489_, p_114490_); } } +@@ -270,7 +_,12 @@ + } -@@ -181,7 +_,7 @@ + p_361028_.distanceToCameraSq = this.entityRenderDispatcher.distanceToSqr(p_362104_); +- boolean flag = p_361028_.distanceToCameraSq < 4096.0 && this.shouldShowName(p_362104_, p_361028_.distanceToCameraSq); ++ boolean flag = p_361028_.distanceToCameraSq < 4096.0; ++ if (flag) { ++ var event = new net.neoforged.neoforge.client.event.RenderNameTagEvent.CanRender(p_362104_, p_361028_, p_362104_.getDisplayName(), this, p_362204_); ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(event); ++ flag = event.canRender().isTrue() || (event.canRender().isDefault() && this.shouldShowName(p_362104_, p_361028_.distanceToCameraSq)); ++ } + if (flag) { + p_361028_.nameTag = this.getNameTag(p_362104_); + p_361028_.nameTagAttachment = p_362104_.getAttachments().getNullable(EntityAttachment.NAME_TAG, 0, p_362104_.getYRot(p_362204_)); +@@ -302,5 +_,7 @@ + } - protected void renderNameTag(T p_114498_, Component p_114499_, PoseStack p_114500_, MultiBufferSource p_114501_, int p_114502_, float p_316698_) { - double d0 = this.entityRenderDispatcher.distanceToSqr(p_114498_); -- if (!(d0 > 4096.0)) { -+ if (net.neoforged.neoforge.client.ClientHooks.isNameplateInRenderDistance(p_114498_, d0)) { - Vec3 vec3 = p_114498_.getAttachments().getNullable(EntityAttachment.NAME_TAG, 0, p_114498_.getViewYRot(p_316698_)); - if (vec3 != null) { - boolean flag = !p_114498_.isDiscrete(); + p_361028_.displayFireAnimation = p_362104_.displayFireAnimation(); ++ ++ p_361028_.partialTick = p_362204_; + } + } diff --git a/patches/net/minecraft/client/renderer/entity/FallingBlockRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/FallingBlockRenderer.java.patch index 836cad28ab..0e7a50f641 100644 --- a/patches/net/minecraft/client/renderer/entity/FallingBlockRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/FallingBlockRenderer.java.patch @@ -1,27 +1,27 @@ --- a/net/minecraft/client/renderer/entity/FallingBlockRenderer.java +++ b/net/minecraft/client/renderer/entity/FallingBlockRenderer.java -@@ -34,6 +_,8 @@ - p_114637_.pushPose(); - BlockPos blockpos = BlockPos.containing(p_114634_.getX(), p_114634_.getBoundingBox().maxY, p_114634_.getZ()); - p_114637_.translate(-0.5, 0.0, -0.5); -+ var model = this.dispatcher.getBlockModel(blockstate); -+ for (var renderType : model.getRenderTypes(blockstate, RandomSource.create(blockstate.getSeed(p_114634_.getStartPos())), net.neoforged.neoforge.client.model.data.ModelData.EMPTY)) - this.dispatcher - .getModelRenderer() - .tesselateBlock( -@@ -42,11 +_,13 @@ - blockstate, - blockpos, - p_114637_, -- p_114638_.getBuffer(ItemBlockRenderTypes.getMovingBlockRenderType(blockstate)), -+ p_114638_.getBuffer(net.neoforged.neoforge.client.RenderTypeHelper.getMovingBlockRenderType(renderType)), - false, - RandomSource.create(), - blockstate.getSeed(p_114634_.getStartPos()), -- OverlayTexture.NO_OVERLAY -+ OverlayTexture.NO_OVERLAY, -+ net.neoforged.neoforge.client.model.data.ModelData.EMPTY, -+ renderType - ); - p_114637_.popPose(); - super.render(p_114634_, p_114635_, p_114636_, p_114637_, p_114638_, p_114639_); +@@ -36,6 +_,8 @@ + if (blockstate.getRenderShape() == RenderShape.MODEL) { + p_114637_.pushPose(); + p_114637_.translate(-0.5, 0.0, -0.5); ++ var model = this.dispatcher.getBlockModel(blockstate); ++ for (var renderType : model.getRenderTypes(blockstate, RandomSource.create(blockstate.getSeed(p_361300_.startBlockPos)), net.neoforged.neoforge.client.model.data.ModelData.EMPTY)) + this.dispatcher + .getModelRenderer() + .tesselateBlock( +@@ -44,11 +_,13 @@ + blockstate, + p_361300_.blockPos, + p_114637_, +- p_114638_.getBuffer(ItemBlockRenderTypes.getMovingBlockRenderType(blockstate)), ++ p_114638_.getBuffer(net.neoforged.neoforge.client.RenderTypeHelper.getMovingBlockRenderType(renderType)), + false, + RandomSource.create(), + blockstate.getSeed(p_361300_.startBlockPos), +- OverlayTexture.NO_OVERLAY ++ OverlayTexture.NO_OVERLAY, ++ net.neoforged.neoforge.client.model.data.ModelData.EMPTY, ++ renderType + ); + p_114637_.popPose(); + super.render(p_361300_, p_114637_, p_114638_, p_114639_); diff --git a/patches/net/minecraft/client/renderer/entity/FishingHookRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/FishingHookRenderer.java.patch index 77ce7e708d..6747d9fda7 100644 --- a/patches/net/minecraft/client/renderer/entity/FishingHookRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/FishingHookRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/entity/FishingHookRenderer.java +++ b/net/minecraft/client/renderer/entity/FishingHookRenderer.java -@@ -64,7 +_,7 @@ +@@ -63,7 +_,7 @@ private Vec3 getPlayerHandPos(Player p_340935_, float p_340872_, float p_341261_) { int i = p_340935_.getMainArm() == HumanoidArm.RIGHT ? 1 : -1; ItemStack itemstack = p_340935_.getMainHandItem(); diff --git a/patches/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java.patch new file mode 100644 index 0000000000..fa5624769b --- /dev/null +++ b/patches/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java ++++ b/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java +@@ -40,7 +_,7 @@ + p_362998_.isCrouching = p_365104_.isCrouching(); + p_362998_.isFallFlying = p_365104_.isFallFlying(); + p_362998_.isVisuallySwimming = p_365104_.isVisuallySwimming(); +- p_362998_.isPassenger = p_365104_.isPassenger(); ++ p_362998_.isPassenger = p_365104_.isPassenger() && (p_365104_.getVehicle() != null && p_365104_.getVehicle().shouldRiderSit()); + p_362998_.speedValue = 1.0F; + if (p_362998_.isFallFlying) { + p_362998_.speedValue = (float)p_365104_.getDeltaMovement().lengthSqr(); diff --git a/patches/net/minecraft/client/renderer/entity/ItemEntityRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/ItemEntityRenderer.java.patch index 7412c8c3ed..52951841f3 100644 --- a/patches/net/minecraft/client/renderer/entity/ItemEntityRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/ItemEntityRenderer.java.patch @@ -1,16 +1,16 @@ --- a/net/minecraft/client/renderer/entity/ItemEntityRenderer.java +++ b/net/minecraft/client/renderer/entity/ItemEntityRenderer.java -@@ -45,7 +_,8 @@ - BakedModel bakedmodel = this.itemRenderer.getModel(itemstack, p_115036_.level(), null, p_115036_.getId()); - boolean flag = bakedmodel.isGui3d(); - float f = 0.25F; -- float f1 = Mth.sin(((float)p_115036_.getAge() + p_115038_) / 10.0F + p_115036_.bobOffs) * 0.1F + 0.1F; -+ boolean shouldBob = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(itemstack).shouldBobAsEntity(itemstack); -+ float f1 = shouldBob ? Mth.sin(((float)p_115036_.getAge() + p_115038_) / 10.0F + p_115036_.bobOffs) * 0.1F + 0.1F : 0; - float f2 = bakedmodel.getTransforms().getTransform(ItemDisplayContext.GROUND).scale.y(); - p_115039_.translate(0.0F, f1 + 0.25F * f2, 0.0F); - float f3 = p_115036_.getSpin(p_115038_); -@@ -100,9 +_,10 @@ +@@ -54,7 +_,8 @@ + this.random.setSeed((long)getSeedForItemStack(itemstack)); + boolean flag = bakedmodel.isGui3d(); + float f = 0.25F; +- float f1 = Mth.sin(p_362172_.ageInTicks / 10.0F + p_362172_.bobOffset) * 0.1F + 0.1F; ++ boolean shouldBob = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(itemstack).shouldBobAsEntity(itemstack); ++ float f1 = shouldBob ? Mth.sin(p_362172_.ageInTicks / 10.0F + p_362172_.bobOffset) * 0.1F + 0.1F : 0; + float f2 = bakedmodel.getTransforms().getTransform(ItemDisplayContext.GROUND).scale.y(); + p_115030_.translate(0.0F, f1 + 0.25F * f2, 0.0F); + float f3 = ItemEntity.getSpin(p_362172_.ageInTicks, p_362172_.bobOffset); +@@ -110,9 +_,10 @@ p_323733_.translate(f3, f4, f5); } diff --git a/patches/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch index d2db3be4a8..7fe0bf497d 100644 --- a/patches/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch @@ -1,50 +1,27 @@ --- a/net/minecraft/client/renderer/entity/ItemFrameRenderer.java +++ b/net/minecraft/client/renderer/entity/ItemFrameRenderer.java -@@ -84,25 +_,25 @@ - } - - if (!itemstack.isEmpty()) { -- MapId mapid = p_115076_.getFramedMapId(itemstack); -+ MapItemSavedData mapitemsaveddata = MapItem.getSavedData(itemstack, p_115076_.level()); - if (flag) { - p_115079_.translate(0.0F, 0.0F, 0.5F); - } else { - p_115079_.translate(0.0F, 0.0F, 0.4375F); - } +@@ -100,6 +_,7 @@ -- int j = mapid != null ? p_115076_.getRotation() % 4 * 2 : p_115076_.getRotation(); -+ int j = mapitemsaveddata != null ? p_115076_.getRotation() % 4 * 2 : p_115076_.getRotation(); + int j = mapid != null ? p_364723_.rotation % 4 * 2 : p_364723_.rotation; p_115079_.mulPose(Axis.ZP.rotationDegrees((float)j * 360.0F / 8.0F)); -- if (mapid != null) { -+ if (!net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderItemInFrameEvent(p_115076_, this, p_115079_, p_115080_, p_115081_)).isCanceled()) { -+ if (mapitemsaveddata != null) { ++ if (!net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderItemInFrameEvent(p_364723_, this, p_115079_, p_115080_, p_115081_)).isCanceled()) { + if (mapid != null) { p_115079_.mulPose(Axis.ZP.rotationDegrees(180.0F)); - float f = 0.0078125F; - p_115079_.scale(0.0078125F, 0.0078125F, 0.0078125F); - p_115079_.translate(-64.0F, -64.0F, 0.0F); -- MapItemSavedData mapitemsaveddata = MapItem.getSavedData(mapid, p_115076_.level()); - p_115079_.translate(0.0F, 0.0F, -1.0F); - if (mapitemsaveddata != null) { - int i = this.getLightVal(p_115076_, 15728850, p_115081_); -- Minecraft.getInstance().gameRenderer.getMapRenderer().render(p_115079_, p_115080_, mapid, mapitemsaveddata, true, i); -+ Minecraft.getInstance().gameRenderer.getMapRenderer().render(p_115079_, p_115080_, p_115076_.getFramedMapId(itemstack), mapitemsaveddata, true, i); - } - } else { - int k = this.getLightVal(p_115076_, 15728880, p_115081_); -@@ -110,6 +_,7 @@ - this.itemRenderer - .renderStatic(itemstack, ItemDisplayContext.FIXED, k, OverlayTexture.NO_OVERLAY, p_115079_, p_115080_, p_115076_.level(), p_115076_.getId()); + float f2 = 0.0078125F; +@@ -113,6 +_,7 @@ + p_115079_.scale(0.5F, 0.5F, 0.5F); + this.itemRenderer.render(itemstack, ItemDisplayContext.FIXED, false, p_115079_, p_115080_, k, OverlayTexture.NO_OVERLAY, p_364723_.itemModel); } + } } p_115079_.popPose(); -@@ -121,7 +_,7 @@ - - private ModelResourceLocation getFrameModelResourceLoc(T p_174213_, ItemStack p_174214_) { - boolean flag = p_174213_.getType() == EntityType.GLOW_ITEM_FRAME; -- if (p_174214_.is(Items.FILLED_MAP)) { -+ if (p_174214_.getItem() instanceof MapItem) { - return flag ? GLOW_MAP_FRAME_LOCATION : MAP_FRAME_LOCATION; - } else { - return flag ? GLOW_FRAME_LOCATION : FRAME_LOCATION; +@@ -161,7 +_,7 @@ + if (!p_362907_.itemStack.isEmpty()) { + MapId mapid = p_363125_.getFramedMapId(itemstack); + if (mapid != null) { +- MapItemSavedData mapitemsaveddata = p_363125_.level().getMapData(mapid); ++ MapItemSavedData mapitemsaveddata = net.minecraft.world.item.MapItem.getSavedData(itemstack, p_363125_.level()); + if (mapitemsaveddata != null) { + this.mapRenderer.extractRenderState(mapid, mapitemsaveddata, p_362907_.mapRenderState); + p_362907_.mapId = mapid; diff --git a/patches/net/minecraft/client/renderer/entity/ItemRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/ItemRenderer.java.patch index 67b1f7c54f..a53ce7e08e 100644 --- a/patches/net/minecraft/client/renderer/entity/ItemRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/ItemRenderer.java.patch @@ -1,63 +1,54 @@ --- a/net/minecraft/client/renderer/entity/ItemRenderer.java +++ b/net/minecraft/client/renderer/entity/ItemRenderer.java -@@ -70,7 +_,7 @@ - public ItemRenderer(Minecraft p_266926_, TextureManager p_266774_, ModelManager p_266850_, ItemColors p_267016_, BlockEntityWithoutLevelRenderer p_267049_) { - this.minecraft = p_266926_; - this.textureManager = p_266774_; -- this.itemModelShaper = new ItemModelShaper(p_266850_); -+ this.itemModelShaper = new net.neoforged.neoforge.client.model.RegistryAwareItemModelShaper(p_266850_); - this.blockEntityRenderer = p_267049_; - - for (Item item : BuiltInRegistries.ITEM) { -@@ -120,7 +_,7 @@ - } +@@ -156,7 +_,7 @@ + float p_371782_ + ) { + p_371635_.pushPose(); +- p_371384_.getTransforms().getTransform(p_371250_).apply(p_371248_, p_371635_); ++ p_371384_ = net.neoforged.neoforge.client.ClientHooks.handleCameraTransforms(p_371635_, p_371384_, p_371250_, p_371248_); + p_371635_.translate(-0.5F, -0.5F, p_371782_); + this.renderItem(p_371318_, p_371250_, p_371635_, p_371946_, p_371752_, p_371508_, p_371384_, p_371718_); + p_371635_.popPose(); +@@ -173,7 +_,8 @@ + boolean p_364829_ + ) { + if (!p_363970_.isCustomRenderer() && (!p_361397_.is(Items.TRIDENT) || p_364829_)) { +- RenderType rendertype = ItemBlockRenderTypes.getRenderType(p_361397_); ++ for (var model : p_363970_.getRenderPasses(p_361397_)) { ++ for (var rendertype : model.getRenderTypes(p_361397_)) { + VertexConsumer vertexconsumer; + if (hasAnimatedTexture(p_361397_) && p_361397_.hasFoil()) { + PoseStack.Pose posestack$pose = p_360423_.last().copy(); +@@ -188,9 +_,11 @@ + vertexconsumer = getFoilBuffer(p_360415_, rendertype, true, p_361397_.hasFoil()); } -- p_115151_.getTransforms().getTransform(p_270188_).apply(p_115146_, p_115147_); -+ p_115151_ = net.neoforged.neoforge.client.ClientHooks.handleCameraTransforms(p_115147_, p_115151_, p_270188_, p_115146_); - p_115147_.translate(-0.5F, -0.5F, -0.5F); - if (!p_115151_.isCustomRenderer() && (!p_115144_.is(Items.TRIDENT) || flag)) { - boolean flag1; -@@ -131,7 +_,8 @@ - flag1 = true; - } - -- RenderType rendertype = ItemBlockRenderTypes.getRenderType(p_115144_, flag1); -+ for (var model : p_115151_.getRenderPasses(p_115144_, flag1)) { -+ for (var rendertype : model.getRenderTypes(p_115144_, flag1)) { - VertexConsumer vertexconsumer; - if (hasAnimatedTexture(p_115144_) && p_115144_.hasFoil()) { - PoseStack.Pose posestack$pose = p_115147_.last().copy(); -@@ -148,9 +_,11 @@ - vertexconsumer = getFoilBuffer(p_115148_, rendertype, true, p_115144_.hasFoil()); - } - -- this.renderModelLists(p_115151_, p_115144_, p_115149_, p_115150_, p_115147_, vertexconsumer); -+ this.renderModelLists(model, p_115144_, p_115149_, p_115150_, p_115147_, vertexconsumer); -+ } -+ } - } else { -- this.blockEntityRenderer.renderByItem(p_115144_, p_270188_, p_115147_, p_115148_, p_115149_, p_115150_); -+ net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(p_115144_).getCustomRenderer().renderByItem(p_115144_, p_270188_, p_115147_, p_115148_, p_115149_, p_115150_); - } +- this.renderModelLists(p_363970_, p_361397_, p_361265_, p_364771_, p_360423_, vertexconsumer); ++ this.renderModelLists(model, p_361397_, p_361265_, p_364771_, p_360423_, vertexconsumer); ++ } ++ } + } else { +- this.blockEntityRenderer.renderByItem(p_361397_, p_361627_, p_360423_, p_360415_, p_361265_, p_364771_); ++ net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(p_361397_).getCustomRenderer().renderByItem(p_361397_, p_361627_, p_360423_, p_360415_, p_361265_, p_364771_); + } + } - p_115147_.popPose(); -@@ -203,7 +_,7 @@ - float f1 = (float)FastColor.ARGB32.red(i) / 255.0F; - float f2 = (float)FastColor.ARGB32.green(i) / 255.0F; - float f3 = (float)FastColor.ARGB32.blue(i) / 255.0F; +@@ -238,7 +_,7 @@ + float f1 = (float)ARGB.red(i) / 255.0F; + float f2 = (float)ARGB.green(i) / 255.0F; + float f3 = (float)ARGB.blue(i) / 255.0F; - p_115164_.putBulkData(posestack$pose, bakedquad, f1, f2, f3, f, p_115167_, p_115168_); + p_115164_.putBulkData(posestack$pose, bakedquad, f1, f2, f3, f, p_115167_, p_115168_, true); // Neo: pass readExistingColor=true } } -@@ -256,5 +_,9 @@ - @Override - public void onResourceManagerReload(ResourceManager p_115105_) { - this.itemModelShaper.rebuildCache(); +@@ -294,5 +_,9 @@ + ClientLevel clientlevel = p_372942_ instanceof ClientLevel ? (ClientLevel)p_372942_ : null; + BakedModel bakedmodel = p_373094_.overrides().findOverride(p_372923_, clientlevel, p_373099_, p_372933_); + return bakedmodel == null ? p_373094_ : bakedmodel; + } + + public BlockEntityWithoutLevelRenderer getBlockEntityRenderer() { -+ return blockEntityRenderer; ++ return blockEntityRenderer; } } diff --git a/patches/net/minecraft/client/renderer/entity/LivingEntityRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/LivingEntityRenderer.java.patch index 77ec112179..8322d59b63 100644 --- a/patches/net/minecraft/client/renderer/entity/LivingEntityRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/LivingEntityRenderer.java.patch @@ -1,38 +1,36 @@ --- a/net/minecraft/client/renderer/entity/LivingEntityRenderer.java +++ b/net/minecraft/client/renderer/entity/LivingEntityRenderer.java -@@ -50,14 +_,16 @@ +@@ -69,6 +_,7 @@ } - public void render(T p_115308_, float p_115309_, float p_115310_, PoseStack p_115311_, MultiBufferSource p_115312_, int p_115313_) { -+ if (net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderLivingEvent.Pre(p_115308_, this, p_115310_, p_115311_, p_115312_, p_115313_)).isCanceled()) return; + public void render(S p_361886_, PoseStack p_115311_, MultiBufferSource p_115312_, int p_115313_) { ++ if (net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderLivingEvent.Pre(p_361886_, this, p_361886_.partialTick, p_115311_, p_115312_, p_115313_)).isCanceled()) return; p_115311_.pushPose(); - this.model.attackTime = this.getAttackAnim(p_115308_, p_115310_); -- this.model.riding = p_115308_.isPassenger(); -+ boolean shouldSit = p_115308_.isPassenger() && (p_115308_.getVehicle() != null && p_115308_.getVehicle().shouldRiderSit()); -+ this.model.riding = shouldSit; - this.model.young = p_115308_.isBaby(); - float f = Mth.rotLerp(p_115310_, p_115308_.yBodyRotO, p_115308_.yBodyRot); - float f1 = Mth.rotLerp(p_115310_, p_115308_.yHeadRotO, p_115308_.yHeadRot); - float f2 = f1 - f; -- if (p_115308_.isPassenger() && p_115308_.getVehicle() instanceof LivingEntity livingentity) { -+ if (shouldSit && p_115308_.getVehicle() instanceof LivingEntity livingentity) { - f = Mth.rotLerp(p_115310_, livingentity.yBodyRotO, livingentity.yBodyRot); - f2 = f1 - f; - float f7 = Mth.wrapDegrees(f2); -@@ -101,7 +_,7 @@ - p_115311_.translate(0.0F, -1.501F, 0.0F); - float f4 = 0.0F; - float f5 = 0.0F; -- if (!p_115308_.isPassenger() && p_115308_.isAlive()) { -+ if (!shouldSit && p_115308_.isAlive()) { - f4 = p_115308_.walkAnimation.speed(p_115310_); - f5 = p_115308_.walkAnimation.position(p_115310_); - if (p_115308_.isBaby()) { -@@ -134,6 +_,7 @@ + if (p_361886_.hasPose(Pose.SLEEPING)) { + Direction direction = p_361886_.bedOrientation; +@@ -104,6 +_,7 @@ p_115311_.popPose(); - super.render(p_115308_, p_115309_, p_115310_, p_115311_, p_115312_, p_115313_); -+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderLivingEvent.Post(p_115308_, this, p_115310_, p_115311_, p_115312_, p_115313_)); + super.render(p_361886_, p_115311_, p_115312_, p_115313_); ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderLivingEvent.Post(p_361886_, this, p_361886_.partialTick, p_115311_, p_115312_, p_115313_)); } - @Nullable + protected boolean shouldRenderLayers(S p_364697_) { +@@ -201,7 +_,7 @@ + protected boolean shouldShowName(T p_363517_, double p_365448_) { + if (p_363517_.isDiscrete()) { + float f = 32.0F; +- if (p_365448_ >= 1024.0) { ++ if (!net.neoforged.neoforge.client.ClientHooks.isNameplateInRenderDistance(p_363517_, p_365448_)) { + return false; + } + } +@@ -284,7 +_,7 @@ + + p_360515_.isFullyFrozen = p_362733_.isFullyFrozen(); + p_360515_.isBaby = p_362733_.isBaby(); +- p_360515_.isInWater = p_362733_.isInWater(); ++ p_360515_.isInWater = p_362733_.isInWater() || p_362733_.isInFluidType((fluidType, height) -> p_362733_.canSwimInFluidType(fluidType)); + p_360515_.isAutoSpinAttack = p_362733_.isAutoSpinAttack(); + p_360515_.hasRedOverlay = p_362733_.hurtTime > 0 || p_362733_.deathTime > 0; + ItemStack itemstack1 = p_362733_.getItemBySlot(EquipmentSlot.HEAD); diff --git a/patches/net/minecraft/client/renderer/entity/layers/ElytraLayer.java.patch b/patches/net/minecraft/client/renderer/entity/layers/ElytraLayer.java.patch deleted file mode 100644 index d64f1997de..0000000000 --- a/patches/net/minecraft/client/renderer/entity/layers/ElytraLayer.java.patch +++ /dev/null @@ -1,55 +0,0 @@ ---- a/net/minecraft/client/renderer/entity/layers/ElytraLayer.java -+++ b/net/minecraft/client/renderer/entity/layers/ElytraLayer.java -@@ -45,7 +_,7 @@ - float p_116960_ - ) { - ItemStack itemstack = p_116954_.getItemBySlot(EquipmentSlot.CHEST); -- if (itemstack.is(Items.ELYTRA)) { -+ if (shouldRender(itemstack, p_116954_)) { - ResourceLocation resourcelocation; - if (p_116954_ instanceof AbstractClientPlayer abstractclientplayer) { - PlayerSkin playerskin = abstractclientplayer.getSkin(); -@@ -54,10 +_,10 @@ - } else if (playerskin.capeTexture() != null && abstractclientplayer.isModelPartShown(PlayerModelPart.CAPE)) { - resourcelocation = playerskin.capeTexture(); - } else { -- resourcelocation = WINGS_LOCATION; -+ resourcelocation = getElytraTexture(itemstack, p_116954_); - } - } else { -- resourcelocation = WINGS_LOCATION; -+ resourcelocation = getElytraTexture(itemstack, p_116954_); - } - - p_116951_.pushPose(); -@@ -68,5 +_,30 @@ - this.elytraModel.renderToBuffer(p_116951_, vertexconsumer, p_116953_, OverlayTexture.NO_OVERLAY); - p_116951_.popPose(); - } -+ } -+ -+ /** -+ * Determines if the ElytraLayer should render. -+ * ItemStack and Entity are provided for modder convenience, -+ * For example, using the same ElytraLayer for multiple custom Elytra. -+ * -+ * @param stack The Elytra ItemStack -+ * @param entity The entity being rendered. -+ * @return If the ElytraLayer should render. -+ */ -+ public boolean shouldRender(ItemStack stack, T entity) { -+ return stack.getItem() == Items.ELYTRA; -+ } -+ -+ /** -+ * Gets the texture to use with this ElytraLayer. -+ * This assumes the vanilla Elytra model. -+ * -+ * @param stack The Elytra ItemStack. -+ * @param entity The entity being rendered. -+ * @return The texture. -+ */ -+ public ResourceLocation getElytraTexture(ItemStack stack, T entity) { -+ return WINGS_LOCATION; - } - } diff --git a/patches/net/minecraft/client/renderer/entity/layers/EquipmentLayerRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/layers/EquipmentLayerRenderer.java.patch new file mode 100644 index 0000000000..d9bc50306b --- /dev/null +++ b/patches/net/minecraft/client/renderer/entity/layers/EquipmentLayerRenderer.java.patch @@ -0,0 +1,45 @@ +--- a/net/minecraft/client/renderer/entity/layers/EquipmentLayerRenderer.java ++++ b/net/minecraft/client/renderer/entity/layers/EquipmentLayerRenderer.java +@@ -65,21 +_,26 @@ + int p_371309_, + @Nullable ResourceLocation p_371587_ + ) { ++ p_371731_ = getArmorModelHook(p_371670_, p_371854_, p_371731_); + List list = this.equipmentModels.get(p_371639_).getLayers(p_371854_); + if (!list.isEmpty()) { +- int i = p_371670_.is(ItemTags.DYEABLE) ? DyedItemColor.getOrDefault(p_371670_, 0) : 0; ++ net.neoforged.neoforge.client.extensions.common.IClientItemExtensions extensions = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(p_371670_); ++ int i = extensions.getDefaultDyeColor(p_371670_); + boolean flag = p_371670_.hasFoil(); + ++ int idx = 0; + for (EquipmentModel.Layer equipmentmodel$layer : list) { +- int j = getColorForLayer(equipmentmodel$layer, i); ++ int j = extensions.getArmorLayerTintColor(p_371670_, equipmentmodel$layer, idx, i); + if (j != 0) { + ResourceLocation resourcelocation = equipmentmodel$layer.usePlayerTexture() && p_371587_ != null + ? p_371587_ + : this.layerTextureLookup.apply(new EquipmentLayerRenderer.LayerTextureKey(p_371854_, equipmentmodel$layer)); ++ resourcelocation = net.neoforged.neoforge.client.ClientHooks.getArmorTexture(p_371670_, p_371854_, equipmentmodel$layer, resourcelocation); + VertexConsumer vertexconsumer = ItemRenderer.getArmorFoilBuffer(p_371286_, RenderType.armorCutoutNoCull(resourcelocation), flag); + p_371731_.renderToBuffer(p_371767_, vertexconsumer, p_371309_, OverlayTexture.NO_OVERLAY, j); + flag = false; + } ++ idx++; + } + + ArmorTrim armortrim = p_371670_.get(DataComponents.TRIM); +@@ -99,6 +_,13 @@ + } else { + return -1; + } ++ } ++ ++ /** ++ * Hook to allow item-sensitive armor model. for HumanoidArmorLayer. ++ */ ++ protected net.minecraft.client.model.Model getArmorModelHook(ItemStack itemStack, EquipmentModel.LayerType layerType, Model model) { ++ return net.neoforged.neoforge.client.ClientHooks.getArmorModel(itemStack, layerType, model); + } + + @OnlyIn(Dist.CLIENT) diff --git a/patches/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java.patch b/patches/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java.patch deleted file mode 100644 index b6db566e31..0000000000 --- a/patches/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java.patch +++ /dev/null @@ -1,105 +0,0 @@ ---- a/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java -+++ b/net/minecraft/client/renderer/entity/layers/HumanoidArmorLayer.java -@@ -54,34 +_,47 @@ - float p_117104_, - float p_117105_ - ) { -- this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.CHEST, p_117098_, this.getArmorModel(EquipmentSlot.CHEST)); -- this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.LEGS, p_117098_, this.getArmorModel(EquipmentSlot.LEGS)); -- this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.FEET, p_117098_, this.getArmorModel(EquipmentSlot.FEET)); -- this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.HEAD, p_117098_, this.getArmorModel(EquipmentSlot.HEAD)); -+ this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.CHEST, p_117098_, this.getArmorModel(EquipmentSlot.CHEST), p_117100_, p_117101_, p_117102_, p_117103_, p_117104_, p_117105_); -+ this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.LEGS, p_117098_, this.getArmorModel(EquipmentSlot.LEGS), p_117100_, p_117101_, p_117102_, p_117103_, p_117104_, p_117105_); -+ this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.FEET, p_117098_, this.getArmorModel(EquipmentSlot.FEET), p_117100_, p_117101_, p_117102_, p_117103_, p_117104_, p_117105_); -+ this.renderArmorPiece(p_117096_, p_117097_, p_117099_, EquipmentSlot.HEAD, p_117098_, this.getArmorModel(EquipmentSlot.HEAD), p_117100_, p_117101_, p_117102_, p_117103_, p_117104_, p_117105_); - } - -+ /** @deprecated Neo: use {@link #renderArmorPiece(PoseStack, MultiBufferSource, LivingEntity, EquipmentSlot, int, HumanoidModel, float, float, float, float, float, float)} instead. */ -+ @Deprecated - private void renderArmorPiece(PoseStack p_117119_, MultiBufferSource p_117120_, T p_117121_, EquipmentSlot p_117122_, int p_117123_, A p_117124_) { -+ this.renderArmorPiece(p_117119_, p_117120_, p_117121_, p_117122_, p_117123_, p_117124_, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F); -+ } -+ -+ private void renderArmorPiece(PoseStack p_117119_, MultiBufferSource p_117120_, T p_117121_, EquipmentSlot p_117122_, int p_117123_, A p_117124_, float limbSwing, float limbSwingAmount, float partialTick, float ageInTicks, float netHeadYaw, float headPitch) { - ItemStack itemstack = p_117121_.getItemBySlot(p_117122_); - if (itemstack.getItem() instanceof ArmorItem armoritem) { - if (armoritem.getEquipmentSlot() == p_117122_) { - this.getParentModel().copyPropertiesTo(p_117124_); - this.setPartVisibility(p_117124_, p_117122_); -+ net.minecraft.client.model.Model model = getArmorModelHook(p_117121_, itemstack, p_117122_, p_117124_); - boolean flag = this.usesInnerModel(p_117122_); - ArmorMaterial armormaterial = armoritem.getMaterial().value(); -- int i = itemstack.is(ItemTags.DYEABLE) ? FastColor.ARGB32.opaque(DyedItemColor.getOrDefault(itemstack, -6265536)) : -1; - -- for (ArmorMaterial.Layer armormaterial$layer : armormaterial.layers()) { -- int j = armormaterial$layer.dyeable() ? i : -1; -- this.renderModel(p_117119_, p_117120_, p_117123_, p_117124_, j, armormaterial$layer.texture(flag)); -+ net.neoforged.neoforge.client.extensions.common.IClientItemExtensions extensions = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(itemstack); -+ extensions.setupModelAnimations(p_117121_, itemstack, p_117122_, model, limbSwing, limbSwingAmount, partialTick, ageInTicks, netHeadYaw, headPitch); -+ int fallbackColor = extensions.getDefaultDyeColor(itemstack); -+ for (int layerIdx = 0; layerIdx < armormaterial.layers().size(); layerIdx++) { -+ ArmorMaterial.Layer armormaterial$layer = armormaterial.layers().get(layerIdx); -+ int j = extensions.getArmorLayerTintColor(itemstack, p_117121_, armormaterial$layer, layerIdx, fallbackColor); -+ if (j != 0) { -+ var texture = net.neoforged.neoforge.client.ClientHooks.getArmorTexture(p_117121_, itemstack, armormaterial$layer, flag, p_117122_); -+ this.renderModel(p_117119_, p_117120_, p_117123_, model, j, texture); -+ } - } - - ArmorTrim armortrim = itemstack.get(DataComponents.TRIM); - if (armortrim != null) { -- this.renderTrim(armoritem.getMaterial(), p_117119_, p_117120_, p_117123_, armortrim, p_117124_, flag); -+ this.renderTrim(armoritem.getMaterial(), p_117119_, p_117120_, p_117123_, armortrim, model, flag); - } - - if (itemstack.hasFoil()) { -- this.renderGlint(p_117119_, p_117120_, p_117123_, p_117124_); -+ this.renderGlint(p_117119_, p_117120_, p_117123_, model); - } - } - } -@@ -111,6 +_,9 @@ - } - - private void renderModel(PoseStack p_289664_, MultiBufferSource p_289689_, int p_289681_, A p_289658_, int p_350798_, ResourceLocation p_324344_) { -+ renderModel(p_289664_, p_289689_, p_289681_, (net.minecraft.client.model.Model) p_289658_, p_350798_, p_324344_); -+ } -+ private void renderModel(PoseStack p_289664_, MultiBufferSource p_289689_, int p_289681_, net.minecraft.client.model.Model p_289658_, int p_350798_, ResourceLocation p_324344_) { - VertexConsumer vertexconsumer = p_289689_.getBuffer(RenderType.armorCutoutNoCull(p_324344_)); - p_289658_.renderToBuffer(p_289664_, vertexconsumer, p_289681_, OverlayTexture.NO_OVERLAY, p_350798_); - } -@@ -118,6 +_,11 @@ - private void renderTrim( - Holder p_323506_, PoseStack p_289687_, MultiBufferSource p_289643_, int p_289683_, ArmorTrim p_289692_, A p_289663_, boolean p_289651_ - ) { -+ renderTrim(p_323506_, p_289687_, p_289643_, p_289683_, p_289692_, (net.minecraft.client.model.Model) p_289663_, p_289651_); -+ } -+ private void renderTrim( -+ Holder p_323506_, PoseStack p_289687_, MultiBufferSource p_289643_, int p_289683_, ArmorTrim p_289692_, net.minecraft.client.model.Model p_289663_, boolean p_289651_ -+ ) { - TextureAtlasSprite textureatlassprite = this.armorTrimAtlas - .getSprite(p_289651_ ? p_289692_.innerTexture(p_323506_) : p_289692_.outerTexture(p_323506_)); - VertexConsumer vertexconsumer = textureatlassprite.wrap(p_289643_.getBuffer(Sheets.armorTrimsSheet(p_289692_.pattern().value().decal()))); -@@ -125,6 +_,9 @@ - } - - private void renderGlint(PoseStack p_289673_, MultiBufferSource p_289654_, int p_289649_, A p_289659_) { -+ renderGlint(p_289673_, p_289654_, p_289649_, (net.minecraft.client.model.Model) p_289659_); -+ } -+ private void renderGlint(PoseStack p_289673_, MultiBufferSource p_289654_, int p_289649_, net.minecraft.client.model.Model p_289659_) { - p_289659_.renderToBuffer(p_289673_, p_289654_.getBuffer(RenderType.armorEntityGlint()), p_289649_, OverlayTexture.NO_OVERLAY); - } - -@@ -134,5 +_,12 @@ - - private boolean usesInnerModel(EquipmentSlot p_117129_) { - return p_117129_ == EquipmentSlot.LEGS; -+ } -+ -+ /** -+ * Hook to allow item-sensitive armor model. for HumanoidArmorLayer. -+ */ -+ protected net.minecraft.client.model.Model getArmorModelHook(T entity, ItemStack itemStack, EquipmentSlot slot, A model) { -+ return net.neoforged.neoforge.client.ClientHooks.getArmorModel(entity, itemStack, slot, model); - } - } diff --git a/patches/net/minecraft/client/renderer/entity/player/PlayerRenderer.java.patch b/patches/net/minecraft/client/renderer/entity/player/PlayerRenderer.java.patch index 7f8084039e..d2fb4f4901 100644 --- a/patches/net/minecraft/client/renderer/entity/player/PlayerRenderer.java.patch +++ b/patches/net/minecraft/client/renderer/entity/player/PlayerRenderer.java.patch @@ -1,47 +1,66 @@ --- a/net/minecraft/client/renderer/entity/player/PlayerRenderer.java +++ b/net/minecraft/client/renderer/entity/player/PlayerRenderer.java -@@ -68,7 +_,9 @@ - - public void render(AbstractClientPlayer p_117788_, float p_117789_, float p_117790_, PoseStack p_117791_, MultiBufferSource p_117792_, int p_117793_) { - this.setModelProperties(p_117788_); -+ if (net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderPlayerEvent.Pre(p_117788_, this, p_117790_, p_117791_, p_117792_, p_117793_)).isCanceled()) return; - super.render(p_117788_, p_117789_, p_117790_, p_117791_, p_117792_, p_117793_); -+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderPlayerEvent.Post(p_117788_, this, p_117790_, p_117791_, p_117792_, p_117793_)); - } - - public Vec3 getRenderOffset(AbstractClientPlayer p_117785_, float p_117786_) { -@@ -140,9 +_,11 @@ - if (useanim == UseAnim.BRUSH) { - return HumanoidModel.ArmPose.BRUSH; - } -- } else if (!p_117795_.swinging && itemstack.is(Items.CROSSBOW) && CrossbowItem.isCharged(itemstack)) { -+ } else if (!p_117795_.swinging && itemstack.getItem() instanceof CrossbowItem && CrossbowItem.isCharged(itemstack)) { +@@ -127,6 +_,9 @@ + } else if (!p_363098_.swinging && p_364742_.holdsChargedCrossbow) { return HumanoidModel.ArmPose.CROSSBOW_HOLD; } -+ HumanoidModel.ArmPose forgeArmPose = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(itemstack).getArmPose(p_117795_, p_117796_, itemstack); -+ if (forgeArmPose != null) return forgeArmPose; ++ if (p_364742_.customArmPose != null) { ++ return p_364742_.customArmPose; ++ } return HumanoidModel.ArmPose.ITEM; } -@@ -185,10 +_,12 @@ +@@ -141,6 +_,13 @@ + p_117799_.scale(0.9375F, 0.9375F, 0.9375F); } - public void renderRightHand(PoseStack p_117771_, MultiBufferSource p_117772_, int p_117773_, AbstractClientPlayer p_117774_) { -+ if(!net.neoforged.neoforge.client.ClientHooks.renderSpecificFirstPersonArm(p_117771_, p_117772_, p_117773_, p_117774_, HumanoidArm.RIGHT)) - this.renderHand(p_117771_, p_117772_, p_117773_, p_117774_, this.model.rightArm, this.model.rightSleeve); ++ @Override ++ public void render(PlayerRenderState p_361886_, PoseStack p_115311_, MultiBufferSource p_115312_, int p_115313_) { ++ if (net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderPlayerEvent.Pre(p_361886_, this, p_361886_.partialTick, p_115311_, p_115312_, p_115313_)).isCanceled()) return; ++ super.render(p_361886_, p_115311_, p_115312_, p_115313_); ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.client.event.RenderPlayerEvent.Post(p_361886_, this, p_361886_.partialTick, p_115311_, p_115312_, p_115313_)); ++ } ++ + protected void renderNameTag(PlayerRenderState p_363185_, Component p_117809_, PoseStack p_117810_, MultiBufferSource p_117811_, int p_117812_) { + p_117810_.pushPose(); + if (p_363185_.scoreText != null) { +@@ -217,7 +_,8 @@ + ItemStack itemstack = p_364516_.getItemInHand(p_364304_); + p_360817_.isEmpty = itemstack.isEmpty(); + p_360817_.useAnimation = !itemstack.isEmpty() ? itemstack.getUseAnimation() : null; +- p_360817_.holdsChargedCrossbow = itemstack.is(Items.CROSSBOW) && CrossbowItem.isCharged(itemstack); ++ p_360817_.holdsChargedCrossbow = itemstack.getItem() instanceof CrossbowItem && CrossbowItem.isCharged(itemstack); ++ p_360817_.customArmPose = net.neoforged.neoforge.client.extensions.common.IClientItemExtensions.of(itemstack).getArmPose(p_364516_, p_364304_, itemstack); } - public void renderLeftHand(PoseStack p_117814_, MultiBufferSource p_117815_, int p_117816_, AbstractClientPlayer p_117817_) { -+ if(!net.neoforged.neoforge.client.ClientHooks.renderSpecificFirstPersonArm(p_117814_, p_117815_, p_117816_, p_117817_, HumanoidArm.LEFT)) - this.renderHand(p_117814_, p_117815_, p_117816_, p_117817_, this.model.leftArm, this.model.leftSleeve); + private static void extractCapeState(AbstractClientPlayer p_364691_, PlayerRenderState p_360814_, float p_364460_) { +@@ -247,11 +_,29 @@ + : null; + } + ++ /** ++ * @deprecated Neo: use {@link #renderRightHand(PoseStack, MultiBufferSource, int, ResourceLocation, boolean, AbstractClientPlayer)} instead ++ */ ++ @Deprecated + public void renderRightHand(PoseStack p_117771_, MultiBufferSource p_117772_, int p_117773_, ResourceLocation p_363694_, boolean p_366898_) { ++ this.renderRightHand(p_117771_, p_117772_, p_117773_, p_363694_, p_366898_, net.minecraft.client.Minecraft.getInstance().player); ++ } ++ ++ public void renderRightHand(PoseStack p_117771_, MultiBufferSource p_117772_, int p_117773_, ResourceLocation p_363694_, boolean p_366898_, AbstractClientPlayer player) { ++ if(!net.neoforged.neoforge.client.ClientHooks.renderSpecificFirstPersonArm(p_117771_, p_117772_, p_117773_, player, HumanoidArm.RIGHT)) + this.renderHand(p_117771_, p_117772_, p_117773_, p_363694_, this.model.rightArm, p_366898_); + } + ++ /** ++ * @deprecated Neo: use {@link #renderLeftHand(PoseStack, MultiBufferSource, int, ResourceLocation, boolean, AbstractClientPlayer)} instead ++ */ ++ @Deprecated + public void renderLeftHand(PoseStack p_117814_, MultiBufferSource p_117815_, int p_117816_, ResourceLocation p_361745_, boolean p_366730_) { ++ this.renderLeftHand(p_117814_, p_117815_, p_117816_, p_361745_, p_366730_, net.minecraft.client.Minecraft.getInstance().player); ++ } ++ ++ public void renderLeftHand(PoseStack p_117814_, MultiBufferSource p_117815_, int p_117816_, ResourceLocation p_361745_, boolean p_366730_, AbstractClientPlayer player) { ++ if(!net.neoforged.neoforge.client.ClientHooks.renderSpecificFirstPersonArm(p_117814_, p_117815_, p_117816_, player, HumanoidArm.LEFT)) + this.renderHand(p_117814_, p_117815_, p_117816_, p_361745_, this.model.leftArm, p_366730_); } -@@ -230,7 +_,7 @@ - } - } else if (f > 0.0F) { - super.setupRotations(p_117802_, p_117803_, p_117804_, p_117805_, p_117806_, p_320048_); -- float f4 = p_117802_.isInWater() ? -90.0F - f1 : -90.0F; -+ float f4 = p_117802_.isInWater() || p_117802_.isInFluidType((fluidType, height) -> p_117802_.canSwimInFluidType(fluidType)) ? -90.0F - p_117802_.getXRot() : -90.0F; - float f5 = Mth.lerp(f, 0.0F, f4); - p_117803_.mulPose(Axis.XP.rotationDegrees(f5)); - if (p_117802_.isVisuallySwimming()) { diff --git a/patches/net/minecraft/client/renderer/entity/state/EntityRenderState.java.patch b/patches/net/minecraft/client/renderer/entity/state/EntityRenderState.java.patch new file mode 100644 index 0000000000..a9fd80707c --- /dev/null +++ b/patches/net/minecraft/client/renderer/entity/state/EntityRenderState.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/client/renderer/entity/state/EntityRenderState.java ++++ b/net/minecraft/client/renderer/entity/state/EntityRenderState.java +@@ -27,6 +_,7 @@ + public Vec3 nameTagAttachment; + @Nullable + public EntityRenderState.LeashState leashState; ++ public float partialTick; + + @OnlyIn(Dist.CLIENT) + public static class LeashState { diff --git a/patches/net/minecraft/client/renderer/entity/state/PlayerRenderState.java.patch b/patches/net/minecraft/client/renderer/entity/state/PlayerRenderState.java.patch new file mode 100644 index 0000000000..870f5bd850 --- /dev/null +++ b/patches/net/minecraft/client/renderer/entity/state/PlayerRenderState.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/client/renderer/entity/state/PlayerRenderState.java ++++ b/net/minecraft/client/renderer/entity/state/PlayerRenderState.java +@@ -52,5 +_,7 @@ + @Nullable + public ItemUseAnimation useAnimation; + public boolean holdsChargedCrossbow; ++ @Nullable ++ public net.minecraft.client.model.HumanoidModel.ArmPose customArmPose; + } + } diff --git a/patches/net/minecraft/client/renderer/state/MapRenderState.java.patch b/patches/net/minecraft/client/renderer/state/MapRenderState.java.patch new file mode 100644 index 0000000000..2ac034ae3d --- /dev/null +++ b/patches/net/minecraft/client/renderer/state/MapRenderState.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/client/renderer/state/MapRenderState.java ++++ b/net/minecraft/client/renderer/state/MapRenderState.java +@@ -17,6 +_,7 @@ + + @OnlyIn(Dist.CLIENT) + public static class MapDecorationRenderState { ++ public net.minecraft.core.Holder type; + @Nullable + public TextureAtlasSprite atlasSprite; + public byte x; diff --git a/patches/net/minecraft/client/renderer/texture/AbstractTexture.java.patch b/patches/net/minecraft/client/renderer/texture/AbstractTexture.java.patch index 8990e16bac..ce14e13dcf 100644 --- a/patches/net/minecraft/client/renderer/texture/AbstractTexture.java.patch +++ b/patches/net/minecraft/client/renderer/texture/AbstractTexture.java.patch @@ -1,9 +1,25 @@ --- a/net/minecraft/client/renderer/texture/AbstractTexture.java +++ b/net/minecraft/client/renderer/texture/AbstractTexture.java -@@ -36,6 +_,20 @@ - GlStateManager._texParameter(3553, 10240, j); - } +@@ -15,9 +_,13 @@ + public static final int NOT_ASSIGNED = -1; + protected int id = -1; + protected boolean defaultBlur; ++ protected boolean blur; ++ protected boolean mipmap; + public void setFilter(boolean p_117961_, boolean p_117962_) { + RenderSystem.assertOnRenderThreadOrInit(); ++ this.blur = p_117961_; ++ this.mipmap = p_117962_; + int i; + int j; + if (p_117961_) { +@@ -31,6 +_,20 @@ + this.bind(); + GlStateManager._texParameter(3553, 10241, i); + GlStateManager._texParameter(3553, 10240, j); ++ } ++ + // FORGE: This seems to have been stripped out, but we need it + private boolean lastBlur; + private boolean lastMipmap; @@ -16,8 +32,6 @@ + + public void restoreLastBlurMipmap() { + setFilter(this.lastBlur, this.lastMipmap); -+ } -+ + } + public int getId() { - RenderSystem.assertOnRenderThreadOrInit(); - if (this.id == -1) { diff --git a/patches/net/minecraft/client/renderer/texture/MipmapGenerator.java.patch b/patches/net/minecraft/client/renderer/texture/MipmapGenerator.java.patch index 5835dfec53..c6a51c60f1 100644 --- a/patches/net/minecraft/client/renderer/texture/MipmapGenerator.java.patch +++ b/patches/net/minecraft/client/renderer/texture/MipmapGenerator.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/texture/MipmapGenerator.java +++ b/net/minecraft/client/renderer/texture/MipmapGenerator.java -@@ -25,12 +_,15 @@ +@@ -26,12 +_,15 @@ anativeimage[0] = p_251300_[0]; boolean flag = hasTransparentPixel(anativeimage[0]); @@ -17,7 +17,7 @@ int j = nativeimage1.getWidth(); int k = nativeimage1.getHeight(); -@@ -48,6 +_,7 @@ +@@ -49,6 +_,7 @@ ) ); } diff --git a/patches/net/minecraft/client/renderer/texture/TextureAtlas.java.patch b/patches/net/minecraft/client/renderer/texture/TextureAtlas.java.patch index 6fe9f37fe1..ffc654c26a 100644 --- a/patches/net/minecraft/client/renderer/texture/TextureAtlas.java.patch +++ b/patches/net/minecraft/client/renderer/texture/TextureAtlas.java.patch @@ -9,7 +9,7 @@ } @Override -@@ -172,5 +_,9 @@ +@@ -168,5 +_,9 @@ public void updateFilter(SpriteLoader.Preparations p_251993_) { this.setFilter(false, p_251993_.mipLevel() > 0); diff --git a/patches/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch b/patches/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch index 3c47d4cccc..3dbb3049e4 100644 --- a/patches/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch +++ b/patches/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch @@ -12,6 +12,6 @@ + y += this.contents.animatedTexture.getFrameY(frameIndex) * this.contents.height; + } + -+ return this.contents.getOriginalImage().getPixelRGBA(x, y); ++ return this.contents.getOriginalImage().getPixel(x, y); + } } diff --git a/patches/net/minecraft/client/resources/language/ClientLanguage.java.patch b/patches/net/minecraft/client/resources/language/ClientLanguage.java.patch index 86f9a1dabe..22eb7edb6f 100644 --- a/patches/net/minecraft/client/resources/language/ClientLanguage.java.patch +++ b/patches/net/minecraft/client/resources/language/ClientLanguage.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/resources/language/ClientLanguage.java +++ b/net/minecraft/client/resources/language/ClientLanguage.java -@@ -22,36 +_,50 @@ +@@ -22,23 +_,32 @@ public class ClientLanguage extends Language { private static final Logger LOGGER = LogUtils.getLogger(); private final Map storage; @@ -19,8 +19,8 @@ } public static ClientLanguage loadFrom(ResourceManager p_265765_, List p_265743_, boolean p_265470_) { - Map map = Maps.newHashMap(); -+ Map componentMap = Maps.newHashMap(); + Map map = new HashMap<>(); ++ Map componentMap = new HashMap<>(); for (String s : p_265743_) { String s1 = String.format(Locale.ROOT, "lang/%s.json", s); @@ -34,11 +34,12 @@ } catch (Exception exception) { LOGGER.warn("Skipped language file: {}:{} ({})", s2, s1, exception.toString()); } - } +@@ -46,13 +_,18 @@ } -- return new ClientLanguage(ImmutableMap.copyOf(map), p_265470_); -+ return new ClientLanguage(ImmutableMap.copyOf(map), p_265470_, ImmutableMap.copyOf(componentMap)); + DeprecatedTranslationsInfo.loadFromDefaultResource().applyToMap(map); +- return new ClientLanguage(Map.copyOf(map), p_265470_); ++ return new ClientLanguage(Map.copyOf(map), p_265470_, Map.copyOf(componentMap)); } + @Deprecated @@ -54,7 +55,7 @@ } catch (IOException ioexception) { LOGGER.warn("Failed to load translations for {} from pack {}", p_235036_, resource.sourcePackId(), ioexception); } -@@ -76,5 +_,15 @@ +@@ -77,5 +_,15 @@ @Override public FormattedCharSequence getVisualOrder(FormattedText p_118925_) { return FormattedBidiReorder.reorder(p_118925_, this.defaultRightToLeft); diff --git a/patches/net/minecraft/client/resources/model/BakedModel.java.patch b/patches/net/minecraft/client/resources/model/BakedModel.java.patch index 6f162f2274..15490942f9 100644 --- a/patches/net/minecraft/client/resources/model/BakedModel.java.patch +++ b/patches/net/minecraft/client/resources/model/BakedModel.java.patch @@ -24,5 +24,5 @@ + @Deprecated + default ItemTransforms getTransforms() { return ItemTransforms.NO_TRANSFORMS; } - ItemOverrides getOverrides(); - } + default BakedOverrides overrides() { + return BakedOverrides.EMPTY; diff --git a/patches/net/minecraft/client/resources/model/DelegateBakedModel.java.patch b/patches/net/minecraft/client/resources/model/DelegateBakedModel.java.patch new file mode 100644 index 0000000000..5c8eacbbe9 --- /dev/null +++ b/patches/net/minecraft/client/resources/model/DelegateBakedModel.java.patch @@ -0,0 +1,75 @@ +--- a/net/minecraft/client/resources/model/DelegateBakedModel.java ++++ b/net/minecraft/client/resources/model/DelegateBakedModel.java +@@ -20,16 +_,27 @@ + } + + @Override ++ @Deprecated + public List getQuads(@Nullable BlockState p_371320_, @Nullable Direction p_371369_, RandomSource p_371947_) { + return this.parent.getQuads(p_371320_, p_371369_, p_371947_); + } + + @Override ++ public List getQuads(@Nullable BlockState p_371320_, @Nullable Direction p_371369_, RandomSource p_371947_, net.neoforged.neoforge.client.model.data.ModelData modelData, @org.jetbrains.annotations.Nullable net.minecraft.client.renderer.RenderType renderType) { ++ return this.parent.getQuads(p_371320_, p_371369_, p_371947_, modelData, renderType); ++ } ++ ++ @Override + public boolean useAmbientOcclusion() { + return this.parent.useAmbientOcclusion(); + } + + @Override ++ public net.neoforged.neoforge.common.util.TriState useAmbientOcclusion(BlockState state, net.neoforged.neoforge.client.model.data.ModelData modelData, net.minecraft.client.renderer.RenderType renderType) { ++ return this.parent.useAmbientOcclusion(state, modelData, renderType); ++ } ++ ++ @Override + public boolean isGui3d() { + return this.parent.isGui3d(); + } +@@ -45,12 +_,44 @@ + } + + @Override ++ @Deprecated + public TextureAtlasSprite getParticleIcon() { + return this.parent.getParticleIcon(); + } + + @Override ++ public TextureAtlasSprite getParticleIcon(net.neoforged.neoforge.client.model.data.ModelData modelData) { ++ return this.parent.getParticleIcon(modelData); ++ } ++ ++ @Override ++ @Deprecated + public ItemTransforms getTransforms() { + return this.parent.getTransforms(); ++ } ++ ++ @Override ++ public BakedModel applyTransform(net.minecraft.world.item.ItemDisplayContext transformType, com.mojang.blaze3d.vertex.PoseStack poseStack, boolean applyLeftHandTransform) { ++ return this.parent.applyTransform(transformType, poseStack, applyLeftHandTransform); ++ } ++ ++ @Override ++ public net.neoforged.neoforge.client.model.data.ModelData getModelData(net.minecraft.world.level.BlockAndTintGetter level, net.minecraft.core.BlockPos pos, BlockState state, net.neoforged.neoforge.client.model.data.ModelData modelData) { ++ return this.parent.getModelData(level, pos, state, modelData); ++ } ++ ++ @Override ++ public net.neoforged.neoforge.client.ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, net.neoforged.neoforge.client.model.data.ModelData data) { ++ return this.parent.getRenderTypes(state, rand, data); ++ } ++ ++ @Override ++ public List getRenderTypes(net.minecraft.world.item.ItemStack itemStack) { ++ return this.parent.getRenderTypes(itemStack); ++ } ++ ++ @Override ++ public List getRenderPasses(net.minecraft.world.item.ItemStack itemStack) { ++ return this.parent.getRenderPasses(itemStack); + } + } diff --git a/patches/net/minecraft/client/resources/model/ItemModel.java.patch b/patches/net/minecraft/client/resources/model/ItemModel.java.patch new file mode 100644 index 0000000000..10d96b4e0a --- /dev/null +++ b/patches/net/minecraft/client/resources/model/ItemModel.java.patch @@ -0,0 +1,16 @@ +--- a/net/minecraft/client/resources/model/ItemModel.java ++++ b/net/minecraft/client/resources/model/ItemModel.java +@@ -29,11 +_,11 @@ + + @Override + public BakedModel bake(ModelBaker p_371426_, Function p_371750_, ModelState p_371674_) { +- BakedModel bakedmodel = p_371426_.bake(this.id, p_371674_); ++ BakedModel bakedmodel = p_371426_.bake(this.id, p_371674_, p_371750_); + if (this.overrides.isEmpty()) { + return bakedmodel; + } else { +- BakedOverrides bakedoverrides = new BakedOverrides(p_371426_, this.overrides); ++ BakedOverrides bakedoverrides = new BakedOverrides(p_371426_, this.overrides, p_371750_); + return new ItemModel.BakedModelWithOverrides(bakedmodel, bakedoverrides); + } + } diff --git a/patches/net/minecraft/client/resources/model/ModelBaker.java.patch b/patches/net/minecraft/client/resources/model/ModelBaker.java.patch index 7535b116b1..36016793f0 100644 --- a/patches/net/minecraft/client/resources/model/ModelBaker.java.patch +++ b/patches/net/minecraft/client/resources/model/ModelBaker.java.patch @@ -1,17 +1,14 @@ --- a/net/minecraft/client/resources/model/ModelBaker.java +++ b/net/minecraft/client/resources/model/ModelBaker.java -@@ -6,9 +_,13 @@ +@@ -5,6 +_,10 @@ import net.neoforged.api.distmarker.OnlyIn; @OnlyIn(Dist.CLIENT) -public interface ModelBaker { +public interface ModelBaker extends net.neoforged.neoforge.client.extensions.IModelBakerExtension { - UnbakedModel getModel(ResourceLocation p_252194_); - + /** + * @deprecated Forge: Use {@link #bake(ResourceLocation, ModelState, java.util.function.Function)} instead. + */ + @Deprecated - @Nullable BakedModel bake(ResourceLocation p_250776_, ModelState p_251280_); } diff --git a/patches/net/minecraft/client/resources/model/ModelBakery.java.patch b/patches/net/minecraft/client/resources/model/ModelBakery.java.patch index cf11be4790..ed116d3ffe 100644 --- a/patches/net/minecraft/client/resources/model/ModelBakery.java.patch +++ b/patches/net/minecraft/client/resources/model/ModelBakery.java.patch @@ -1,25 +1,12 @@ --- a/net/minecraft/client/resources/model/ModelBakery.java +++ b/net/minecraft/client/resources/model/ModelBakery.java -@@ -117,6 +_,12 @@ - p_252014_.popPush("special"); - this.loadSpecialItemModelAndDependencies(ItemRenderer.TRIDENT_IN_HAND_MODEL); - this.loadSpecialItemModelAndDependencies(ItemRenderer.SPYGLASS_IN_HAND_MODEL); -+ Set additionalModels = new HashSet<>(); -+ net.neoforged.neoforge.client.ClientHooks.onRegisterAdditionalModels(additionalModels); -+ for (ModelResourceLocation rl : additionalModels) { -+ UnbakedModel unbakedmodel = this.getModel(rl.id()); -+ this.registerModelAndLoadDependencies(rl, unbakedmodel); -+ } - this.topLevelModels.values().forEach(p_247954_ -> p_247954_.resolveParents(this::getModel)); - p_252014_.pop(); - } -@@ -246,14 +_,30 @@ +@@ -94,25 +_,46 @@ } @Override -+ @Nullable ++ @org.jetbrains.annotations.Nullable + public UnbakedModel getTopLevelModel(ModelResourceLocation location) { -+ return topLevelModels.get(location); ++ return topModels.get(location); + } + + @Override @@ -45,22 +32,17 @@ ModelBakery.this.bakedCache.put(modelbakery$bakedcachekey, bakedmodel1); return bakedmodel1; } -@@ -261,13 +_,19 @@ + } - @Nullable BakedModel bakeUncached(UnbakedModel p_352386_, ModelState p_352194_) { + return bakeUncached(p_352386_, p_352194_, this.modelTextureGetter); + } + + @Override -+ @Nullable + public BakedModel bakeUncached(UnbakedModel p_352386_, ModelState p_352194_, Function sprites) { - if (p_352386_ instanceof BlockModel blockmodel && blockmodel.getRootModel() == ModelBakery.GENERATION_MARKER) { - return ModelBakery.ITEM_MODEL_GENERATOR -- .generateBlockModel(this.modelTextureGetter, blockmodel) -- .bake(this, blockmodel, this.modelTextureGetter, p_352194_, false); -+ .generateBlockModel(sprites, blockmodel) -+ .bake(this, blockmodel, sprites, p_352194_, false); + if (p_352386_ instanceof BlockModel blockmodel && blockmodel.getRootModel() == SpecialModels.GENERATED_MARKER) { +- return ModelBakery.ITEM_MODEL_GENERATOR.generateBlockModel(this.modelTextureGetter, blockmodel).bake(this.modelTextureGetter, p_352194_, false); ++ return ModelBakery.ITEM_MODEL_GENERATOR.generateBlockModel(sprites, blockmodel).bake(sprites, p_352194_, false); } - return p_352386_.bake(this, this.modelTextureGetter, p_352194_); diff --git a/patches/net/minecraft/client/resources/model/ModelDiscovery.java.patch b/patches/net/minecraft/client/resources/model/ModelDiscovery.java.patch new file mode 100644 index 0000000000..7c9de8482a --- /dev/null +++ b/patches/net/minecraft/client/resources/model/ModelDiscovery.java.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/client/resources/model/ModelDiscovery.java ++++ b/net/minecraft/client/resources/model/ModelDiscovery.java +@@ -49,6 +_,7 @@ + }); + set.add(ItemRenderer.TRIDENT_MODEL); + set.add(ItemRenderer.SPYGLASS_MODEL); ++ net.neoforged.neoforge.client.ClientHooks.onRegisterAdditionalModels(set); + return set; + } + +@@ -77,6 +_,15 @@ + } + } + ); ++ // Neo: ensure standalone models registered in ModelEvent.RegisterAdditional are loaded ++ var it = set.iterator(); ++ while (it.hasNext()) { ++ ModelResourceLocation mrl = it.next(); ++ if (mrl.getVariant().equals(ModelResourceLocation.STANDALONE_VARIANT)) { ++ registerTopModel(mrl, getBlockModel(mrl.id())); ++ it.remove(); ++ } ++ } + if (!set.isEmpty()) { + LOGGER.warn("Missing mandatory models: {}", set.stream().map(p_370354_ -> "\n\t" + p_370354_).collect(Collectors.joining())); + } diff --git a/patches/net/minecraft/client/resources/model/ModelManager.java.patch b/patches/net/minecraft/client/resources/model/ModelManager.java.patch index dd6edb6544..2795dad254 100644 --- a/patches/net/minecraft/client/resources/model/ModelManager.java.patch +++ b/patches/net/minecraft/client/resources/model/ModelManager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/resources/model/ModelManager.java +++ b/net/minecraft/client/resources/model/ModelManager.java -@@ -63,13 +_,14 @@ +@@ -71,13 +_,14 @@ TextureAtlas.LOCATION_BLOCKS, ResourceLocation.withDefaultNamespace("blocks") ); @@ -16,15 +16,15 @@ public ModelManager(TextureManager p_119406_, BlockColors p_119407_, int p_119408_) { this.blockColors = p_119407_; -@@ -100,6 +_,7 @@ - Executor p_249221_ +@@ -102,6 +_,7 @@ + public final CompletableFuture reload( + PreparableReloadListener.PreparationBarrier p_249079_, ResourceManager p_251134_, Executor p_250550_, Executor p_249221_ ) { - p_250336_.startTick(); + net.neoforged.neoforge.client.model.geometry.GeometryLoaderManager.init(); - CompletableFuture> completablefuture = loadBlockModels(p_251134_, p_250550_); - CompletableFuture>> completablefuture1 = loadBlockStates(p_251134_, p_250550_); - CompletableFuture completablefuture2 = completablefuture.thenCombineAsync( -@@ -218,6 +_,8 @@ + UnbakedModel unbakedmodel = MissingBlockModel.missingModel(); + BlockStateModelLoader blockstatemodelloader = new BlockStateModelLoader(unbakedmodel); + CompletableFuture> completablefuture = loadBlockModels(p_251134_, p_250550_); +@@ -258,6 +_,8 @@ .collect(Collectors.joining("\n")) ) ); @@ -32,17 +32,17 @@ + net.neoforged.neoforge.client.ClientHooks.onModifyBakingResult(p_248945_.getBakedTopLevelModels(), p_250646_, p_248945_); p_252136_.popPush("dispatch"); Map map = p_248945_.getBakedTopLevelModels(); - BakedModel bakedmodel = map.get(ModelBakery.MISSING_MODEL_VARIANT); -@@ -247,6 +_,8 @@ + BakedModel bakedmodel = map.get(MissingBlockModel.VARIANT); +@@ -289,6 +_,8 @@ this.bakedRegistry = modelbakery.getBakedTopLevelModels(); - this.modelGroups = modelbakery.getModelGroups(); + this.modelGroups = p_248996_.modelGroups; this.missingModel = p_248996_.missingModel; + this.modelBakery = modelbakery; + net.neoforged.neoforge.client.ClientHooks.onModelBake(this, this.bakedRegistry, modelbakery); p_251960_.popPush("cache"); this.blockModelShaper.replaceCache(p_248996_.modelCache); p_251960_.pop(); -@@ -272,6 +_,7 @@ +@@ -313,6 +_,7 @@ } public TextureAtlas getAtlas(ResourceLocation p_119429_) { @@ -50,7 +50,7 @@ return this.atlases.getAtlas(p_119429_); } -@@ -282,6 +_,10 @@ +@@ -323,6 +_,10 @@ public void updateMaxMipLevel(int p_119411_) { this.maxMipmapLevels = p_119411_; diff --git a/patches/net/minecraft/client/resources/model/ModelResourceLocation.java.patch b/patches/net/minecraft/client/resources/model/ModelResourceLocation.java.patch index ff24a3eafd..85d4fc00bc 100644 --- a/patches/net/minecraft/client/resources/model/ModelResourceLocation.java.patch +++ b/patches/net/minecraft/client/resources/model/ModelResourceLocation.java.patch @@ -8,7 +8,7 @@ public ModelResourceLocation(ResourceLocation id, String variant) { variant = lowercaseVariant(variant); -@@ -21,6 +_,14 @@ +@@ -17,6 +_,14 @@ public static ModelResourceLocation inventory(ResourceLocation p_352141_) { return new ModelResourceLocation(p_352141_, "inventory"); diff --git a/patches/net/minecraft/client/resources/model/MultiPartBakedModel.java.patch b/patches/net/minecraft/client/resources/model/MultiPartBakedModel.java.patch index 8404abbec3..b91323bf9d 100644 --- a/patches/net/minecraft/client/resources/model/MultiPartBakedModel.java.patch +++ b/patches/net/minecraft/client/resources/model/MultiPartBakedModel.java.patch @@ -1,29 +1,16 @@ --- a/net/minecraft/client/resources/model/MultiPartBakedModel.java +++ b/net/minecraft/client/resources/model/MultiPartBakedModel.java -@@ -20,7 +_,7 @@ - import org.apache.commons.lang3.tuple.Pair; +@@ -16,7 +_,7 @@ + import net.neoforged.api.distmarker.OnlyIn; @OnlyIn(Dist.CLIENT) --public class MultiPartBakedModel implements BakedModel { -+public class MultiPartBakedModel implements BakedModel, net.neoforged.neoforge.client.model.IDynamicBakedModel { - private final List, BakedModel>> selectors; - protected final boolean hasAmbientOcclusion; - protected final boolean isGui3d; -@@ -29,10 +_,12 @@ - protected final ItemTransforms transforms; - protected final ItemOverrides overrides; +-public class MultiPartBakedModel extends DelegateBakedModel { ++public class MultiPartBakedModel extends DelegateBakedModel implements net.neoforged.neoforge.client.model.IDynamicBakedModel { + private final List selectors; private final Map selectorCache = new Reference2ObjectOpenHashMap<>(); -+ private final BakedModel defaultModel; - public MultiPartBakedModel(List, BakedModel>> p_119462_) { +@@ -33,11 +_,7 @@ this.selectors = p_119462_; - BakedModel bakedmodel = p_119462_.iterator().next().getRight(); -+ this.defaultModel = bakedmodel; - this.hasAmbientOcclusion = bakedmodel.useAmbientOcclusion(); - this.isGui3d = bakedmodel.isGui3d(); - this.usesBlockLight = bakedmodel.usesBlockLight(); -@@ -41,11 +_,7 @@ - this.overrides = bakedmodel.getOverrides(); } - @Override @@ -35,14 +22,14 @@ BitSet bitset = this.selectorCache.get(p_235050_); if (bitset == null) { bitset = new BitSet(); -@@ -59,17 +_,28 @@ +@@ -50,19 +_,47 @@ this.selectorCache.put(p_235050_, bitset); } + return bitset; + } -- List list = Lists.newArrayList(); +- List list = new ArrayList<>(); + // FORGE: Implement our overloads (here and below) so child models can have custom logic + @Override + public List getQuads(@Nullable BlockState p_235050_, @Nullable Direction p_235051_, RandomSource p_235052_, net.neoforged.neoforge.client.model.data.ModelData modelData, @org.jetbrains.annotations.Nullable net.minecraft.client.renderer.RenderType renderType) { @@ -50,29 +37,25 @@ + return Collections.emptyList(); + } else { + BitSet bitset = getSelectors(p_235050_); -+ List> list = Lists.newArrayList(); - long k = p_235052_.nextLong(); ++ List> list = new ArrayList<>(); + long j = p_235052_.nextLong(); - for (int j = 0; j < bitset.length(); j++) { - if (bitset.get(j)) { -- list.addAll(this.selectors.get(j).getRight().getQuads(p_235050_, p_235051_, RandomSource.create(k))); -+ var model = this.selectors.get(j).getRight(); -+ if (renderType == null || model.getRenderTypes(p_235050_, p_235052_, modelData).contains(renderType)) // FORGE: Only put quad data if the model is using the render type passed -+ list.add(model.getQuads(p_235050_, p_235051_, RandomSource.create(k), net.neoforged.neoforge.client.model.data.MultipartModelData.resolve(modelData, model), renderType)); + for (int k = 0; k < bitset.length(); k++) { + if (bitset.get(k)) { +- p_235052_.setSeed(j); +- list.addAll(this.selectors.get(k).model.getQuads(p_235050_, p_235051_, p_235052_)); ++ ++ var model = this.selectors.get(k).model; ++ if (renderType == null || model.getRenderTypes(p_235050_, p_235052_, modelData).contains(renderType)) { // FORGE: Only put quad data if the model is using the render type passed ++ p_235052_.setSeed(j); ++ list.add(model.getQuads(p_235050_, p_235051_, RandomSource.create(k), net.neoforged.neoforge.client.model.data.MultipartModelData.resolve(modelData, model), renderType)); ++ } } } - return list; + return net.neoforged.neoforge.common.util.ConcatenatedListView.of(list); } - } - -@@ -79,6 +_,16 @@ - } - - @Override -+ public net.neoforged.neoforge.common.util.TriState useAmbientOcclusion(BlockState state, net.neoforged.neoforge.client.model.data.ModelData modelData, net.minecraft.client.renderer.RenderType renderType) { -+ return this.defaultModel.useAmbientOcclusion(state, modelData, renderType); + } + + @Override @@ -80,43 +63,14 @@ + return net.neoforged.neoforge.client.model.data.MultipartModelData.create(selectors, getSelectors(state), level, pos, state, modelData); + } + -+ @Override - public boolean isGui3d() { - return this.isGui3d; - } -@@ -94,13 +_,35 @@ - } - - @Override -+ @Deprecated - public TextureAtlasSprite getParticleIcon() { - return this.particleIcon; - } - - @Override -+ public TextureAtlasSprite getParticleIcon(net.neoforged.neoforge.client.model.data.ModelData modelData) { -+ return this.defaultModel.getParticleIcon(modelData); -+ } -+ -+ @Deprecated -+ @Override - public ItemTransforms getTransforms() { - return this.transforms; -+ } -+ -+ @Override -+ public BakedModel applyTransform(net.minecraft.world.item.ItemDisplayContext transformType, com.mojang.blaze3d.vertex.PoseStack poseStack, boolean applyLeftHandTransform) { -+ return this.defaultModel.applyTransform(transformType, poseStack, applyLeftHandTransform); -+ } -+ + @Override // FORGE: Get render types based on the selectors matched by the given block state + public net.neoforged.neoforge.client.ChunkRenderTypeSet getRenderTypes(@org.jetbrains.annotations.NotNull BlockState state, @org.jetbrains.annotations.NotNull RandomSource rand, @org.jetbrains.annotations.NotNull net.neoforged.neoforge.client.model.data.ModelData data) { + var renderTypeSets = new java.util.LinkedList(); + var selectors = getSelectors(state); + for (int i = 0; i < selectors.length(); i++) + if (selectors.get(i)) -+ renderTypeSets.add(this.selectors.get(i).getRight().getRenderTypes(state, rand, data)); ++ renderTypeSets.add(this.selectors.get(i).model.getRenderTypes(state, rand, data)); + return net.neoforged.neoforge.client.ChunkRenderTypeSet.union(renderTypeSets); } - @Override + @OnlyIn(Dist.CLIENT) diff --git a/patches/net/minecraft/client/resources/model/SimpleBakedModel.java.patch b/patches/net/minecraft/client/resources/model/SimpleBakedModel.java.patch index b477646b9c..41044226e2 100644 --- a/patches/net/minecraft/client/resources/model/SimpleBakedModel.java.patch +++ b/patches/net/minecraft/client/resources/model/SimpleBakedModel.java.patch @@ -1,76 +1,68 @@ --- a/net/minecraft/client/resources/model/SimpleBakedModel.java +++ b/net/minecraft/client/resources/model/SimpleBakedModel.java -@@ -26,7 +_,12 @@ +@@ -25,7 +_,11 @@ + protected final boolean usesBlockLight; protected final TextureAtlasSprite particleIcon; protected final ItemTransforms transforms; - protected final ItemOverrides overrides; -+ protected final net.neoforged.neoforge.client.ChunkRenderTypeSet blockRenderTypes; -+ protected final List itemRenderTypes; -+ protected final List fabulousItemRenderTypes; ++ @Nullable protected final net.neoforged.neoforge.client.ChunkRenderTypeSet blockRenderTypes; ++ @Nullable protected final List itemRenderTypes; -+ /** @deprecated Forge: Use {@linkplain #SimpleBakedModel(List, Map, boolean, boolean, boolean, TextureAtlasSprite, ItemTransforms, ItemOverrides, net.neoforged.neoforge.client.RenderTypeGroup) variant with RenderTypeGroup} **/ ++ /** @deprecated Forge: Use {@linkplain #SimpleBakedModel(List, Map, boolean, boolean, boolean, TextureAtlasSprite, ItemTransforms, net.neoforged.neoforge.client.RenderTypeGroup) variant with RenderTypeGroup} **/ + @Deprecated public SimpleBakedModel( List p_119489_, Map> p_119490_, -@@ -37,6 +_,20 @@ - ItemTransforms p_119495_, - ItemOverrides p_119496_ +@@ -35,6 +_,19 @@ + TextureAtlasSprite p_119494_, + ItemTransforms p_119495_ ) { -+ this(p_119489_, p_119490_, p_119491_, p_119492_, p_119493_, p_119494_, p_119495_, p_119496_, net.neoforged.neoforge.client.RenderTypeGroup.EMPTY); ++ this(p_119489_, p_119490_, p_119491_, p_119492_, p_119493_, p_119494_, p_119495_, net.neoforged.neoforge.client.RenderTypeGroup.EMPTY); + } + + public SimpleBakedModel( -+ List p_119489_, -+ Map> p_119490_, -+ boolean p_119491_, -+ boolean p_119492_, -+ boolean p_119493_, -+ TextureAtlasSprite p_119494_, -+ ItemTransforms p_119495_, -+ ItemOverrides p_119496_, -+ net.neoforged.neoforge.client.RenderTypeGroup renderTypes ++ List p_119489_, ++ Map> p_119490_, ++ boolean p_119491_, ++ boolean p_119492_, ++ boolean p_119493_, ++ TextureAtlasSprite p_119494_, ++ ItemTransforms p_119495_, ++ net.neoforged.neoforge.client.RenderTypeGroup renderTypes + ) { this.unculledFaces = p_119489_; this.culledFaces = p_119490_; this.hasAmbientOcclusion = p_119491_; -@@ -45,6 +_,9 @@ +@@ -42,6 +_,8 @@ + this.usesBlockLight = p_119492_; this.particleIcon = p_119494_; this.transforms = p_119495_; - this.overrides = p_119496_; + this.blockRenderTypes = !renderTypes.isEmpty() ? net.neoforged.neoforge.client.ChunkRenderTypeSet.of(renderTypes.block()) : null; + this.itemRenderTypes = !renderTypes.isEmpty() ? List.of(renderTypes.entity()) : null; -+ this.fabulousItemRenderTypes = !renderTypes.isEmpty() ? List.of(renderTypes.entityFabulous()) : null; } @Override -@@ -87,6 +_,25 @@ - return this.overrides; +@@ -79,6 +_,20 @@ + return this.transforms; } + @Override -+ public net.neoforged.neoforge.client.ChunkRenderTypeSet getRenderTypes(@org.jetbrains.annotations.NotNull BlockState state, @org.jetbrains.annotations.NotNull RandomSource rand, @org.jetbrains.annotations.NotNull net.neoforged.neoforge.client.model.data.ModelData data) { ++ public net.neoforged.neoforge.client.ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, net.neoforged.neoforge.client.model.data.ModelData data) { + if (blockRenderTypes != null) + return blockRenderTypes; + return BakedModel.super.getRenderTypes(state, rand, data); + } + + @Override -+ public List getRenderTypes(net.minecraft.world.item.ItemStack itemStack, boolean fabulous) { -+ if (!fabulous) { -+ if (itemRenderTypes != null) -+ return itemRenderTypes; -+ } else { -+ if (fabulousItemRenderTypes != null) -+ return fabulousItemRenderTypes; -+ } -+ return BakedModel.super.getRenderTypes(itemStack, fabulous); ++ public List getRenderTypes(net.minecraft.world.item.ItemStack itemStack) { ++ if (itemRenderTypes != null) ++ return itemRenderTypes; ++ return BakedModel.super.getRenderTypes(itemStack); + } + @OnlyIn(Dist.CLIENT) public static class Builder { - private final List unculledFaces = Lists.newArrayList(); -@@ -133,7 +_,13 @@ + private final ImmutableList.Builder unculledFaces = ImmutableList.builder(); +@@ -124,7 +_,13 @@ return this; } @@ -84,12 +76,12 @@ if (this.particleIcon == null) { throw new RuntimeException("Missing particle!"); } else { -@@ -145,7 +_,8 @@ +@@ -136,7 +_,8 @@ + this.usesBlockLight, this.isGui3d, this.particleIcon, - this.transforms, -- this.overrides -+ this.overrides, +- this.transforms ++ this.transforms, + renderTypes ); } diff --git a/patches/net/minecraft/client/resources/model/WeightedBakedModel.java.patch b/patches/net/minecraft/client/resources/model/WeightedBakedModel.java.patch index 3483772f34..ecca5f2753 100644 --- a/patches/net/minecraft/client/resources/model/WeightedBakedModel.java.patch +++ b/patches/net/minecraft/client/resources/model/WeightedBakedModel.java.patch @@ -1,67 +1,30 @@ --- a/net/minecraft/client/resources/model/WeightedBakedModel.java +++ b/net/minecraft/client/resources/model/WeightedBakedModel.java -@@ -17,7 +_,7 @@ +@@ -12,7 +_,7 @@ import net.neoforged.api.distmarker.OnlyIn; @OnlyIn(Dist.CLIENT) --public class WeightedBakedModel implements BakedModel { -+public class WeightedBakedModel implements BakedModel, net.neoforged.neoforge.client.model.IDynamicBakedModel { - private final int totalWeight; - private final List> list; - private final BakedModel wrapped; -@@ -29,9 +_,10 @@ +-public class WeightedBakedModel extends DelegateBakedModel { ++public class WeightedBakedModel extends DelegateBakedModel implements net.neoforged.neoforge.client.model.IDynamicBakedModel { + private final SimpleWeightedRandomList list; + + public WeightedBakedModel(SimpleWeightedRandomList p_371780_) { +@@ -20,8 +_,15 @@ + this.list = p_371780_; } - @Override +- @Override - public List getQuads(@Nullable BlockState p_235058_, @Nullable Direction p_235059_, RandomSource p_235060_) { -+ // FORGE: Implement our overloads (here and below) so child models can have custom logic +- return this.list.getRandomValue(p_235060_).map(p_370367_ -> p_370367_.getQuads(p_235058_, p_235059_, p_235060_)).orElse(Collections.emptyList()); ++ @Override // FORGE: Implement our overload so child models can have custom logic + public List getQuads(@Nullable BlockState p_235058_, @Nullable Direction p_235059_, RandomSource p_235060_, net.neoforged.neoforge.client.model.data.ModelData modelData, @org.jetbrains.annotations.Nullable net.minecraft.client.renderer.RenderType renderType) { - return WeightedRandom.getWeightedItem(this.list, Math.abs((int)p_235060_.nextLong()) % this.totalWeight) -- .map(p_337442_ -> p_337442_.data().getQuads(p_235058_, p_235059_, p_235060_)) -+ .map(p_235065_ -> p_235065_.data().getQuads(p_235058_, p_235059_, p_235060_, modelData, renderType)) - .orElse(Collections.emptyList()); - } - -@@ -41,6 +_,11 @@ - } - - @Override -+ public net.neoforged.neoforge.common.util.TriState useAmbientOcclusion(BlockState state, net.neoforged.neoforge.client.model.data.ModelData modelData, net.minecraft.client.renderer.RenderType renderType) { -+ return this.wrapped.useAmbientOcclusion(state, modelData, renderType); -+ } -+ -+ @Override - public boolean isGui3d() { - return this.wrapped.isGui3d(); - } -@@ -61,8 +_,30 @@ - } - - @Override -+ public TextureAtlasSprite getParticleIcon(net.neoforged.neoforge.client.model.data.ModelData modelData) { -+ return this.wrapped.getParticleIcon(modelData); -+ } -+ -+ @Override - public ItemTransforms getTransforms() { - return this.wrapped.getTransforms(); -+ } -+ -+ @Override -+ public BakedModel applyTransform(net.minecraft.world.item.ItemDisplayContext transformType, com.mojang.blaze3d.vertex.PoseStack poseStack, boolean applyLeftHandTransform) { -+ return this.wrapped.applyTransform(transformType, poseStack, applyLeftHandTransform); ++ return this.list.getRandomValue(p_235060_).map(p_370367_ -> p_370367_.getQuads(p_235058_, p_235059_, p_235060_, modelData, renderType)).orElse(Collections.emptyList()); + } + + @Override // FORGE: Get render types based on the active weighted model -+ public net.neoforged.neoforge.client.ChunkRenderTypeSet getRenderTypes(@org.jetbrains.annotations.NotNull BlockState state, @org.jetbrains.annotations.NotNull RandomSource rand, @org.jetbrains.annotations.NotNull net.neoforged.neoforge.client.model.data.ModelData data) { -+ return WeightedRandom.getWeightedItem(this.list, Math.abs((int)rand.nextLong()) % this.totalWeight) -+ .map((p_235065_) -> p_235065_.data().getRenderTypes(state, rand, data)) -+ .orElse(net.neoforged.neoforge.client.ChunkRenderTypeSet.none()); -+ } -+ -+ @Override -+ public net.neoforged.neoforge.client.model.data.ModelData getModelData(net.minecraft.world.level.BlockAndTintGetter level, net.minecraft.core.BlockPos pos, BlockState state, net.neoforged.neoforge.client.model.data.ModelData modelData) { -+ return this.wrapped.getModelData(level, pos, state, modelData); ++ public net.neoforged.neoforge.client.ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, net.neoforged.neoforge.client.model.data.ModelData data) { ++ return list.getRandomValue(rand) ++ .map(model -> model.getRenderTypes(state, rand, data)) ++ .orElse(net.neoforged.neoforge.client.ChunkRenderTypeSet.none()); } - - @Override + } diff --git a/patches/net/minecraft/client/server/IntegratedServer.java.patch b/patches/net/minecraft/client/server/IntegratedServer.java.patch index 2c8e4f62cc..8d9e76bd8e 100644 --- a/patches/net/minecraft/client/server/IntegratedServer.java.patch +++ b/patches/net/minecraft/client/server/IntegratedServer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/server/IntegratedServer.java +++ b/net/minecraft/client/server/IntegratedServer.java -@@ -73,10 +_,12 @@ +@@ -71,10 +_,12 @@ this.setPvpAllowed(true); this.setFlightAllowed(true); this.initializeKeyPair(); @@ -13,7 +13,7 @@ return true; } -@@ -225,6 +_,7 @@ +@@ -218,6 +_,7 @@ @Override public void halt(boolean p_120053_) { diff --git a/patches/net/minecraft/client/sounds/MusicManager.java.patch b/patches/net/minecraft/client/sounds/MusicManager.java.patch index 9772e14aed..578bcd60a4 100644 --- a/patches/net/minecraft/client/sounds/MusicManager.java.patch +++ b/patches/net/minecraft/client/sounds/MusicManager.java.patch @@ -15,5 +15,5 @@ + } + if (this.currentMusic != null) { - if (!music.getEvent().value().getLocation().equals(this.currentMusic.getLocation()) && music.replaceCurrentMusic()) { + if (!music.getEvent().value().location().equals(this.currentMusic.getLocation()) && music.replaceCurrentMusic()) { this.minecraft.getSoundManager().stop(this.currentMusic); diff --git a/patches/net/minecraft/commands/CommandSourceStack.java.patch b/patches/net/minecraft/commands/CommandSourceStack.java.patch index 6065370948..09ebb7cb46 100644 --- a/patches/net/minecraft/commands/CommandSourceStack.java.patch +++ b/patches/net/minecraft/commands/CommandSourceStack.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/commands/CommandSourceStack.java +++ b/net/minecraft/commands/CommandSourceStack.java -@@ -43,7 +_,7 @@ +@@ -46,7 +_,7 @@ import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; diff --git a/patches/net/minecraft/commands/Commands.java.patch b/patches/net/minecraft/commands/Commands.java.patch index e345615137..17ef4a8463 100644 --- a/patches/net/minecraft/commands/Commands.java.patch +++ b/patches/net/minecraft/commands/Commands.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/commands/Commands.java +++ b/net/minecraft/commands/Commands.java -@@ -214,7 +_,7 @@ +@@ -219,7 +_,7 @@ JfrCommand.register(this.dispatcher); } @@ -9,7 +9,7 @@ TestCommand.register(this.dispatcher); RaidCommand.register(this.dispatcher, p_230944_); DebugPathCommand.register(this.dispatcher); -@@ -248,6 +_,7 @@ +@@ -253,6 +_,7 @@ if (p_230943_.includeIntegrated) { PublishCommand.register(this.dispatcher); } @@ -17,7 +17,7 @@ this.dispatcher.setConsumer(ExecutionCommandSource.resultConsumer()); } -@@ -265,6 +_,16 @@ +@@ -270,6 +_,16 @@ public void performCommand(ParseResults p_242844_, String p_242841_) { CommandSourceStack commandsourcestack = p_242844_.getContext().getSource(); @@ -31,10 +31,10 @@ + } + p_242844_ = event.getParseResults(); + - commandsourcestack.getServer().getProfiler().push(() -> "/" + p_242841_); + Profiler.get().push(() -> "/" + p_242841_); ContextChain contextchain = finishParsing(p_242844_, p_242841_, commandsourcestack); -@@ -362,7 +_,8 @@ +@@ -367,7 +_,8 @@ Map, CommandNode> map = Maps.newHashMap(); RootCommandNode rootcommandnode = new RootCommandNode<>(); map.put(this.dispatcher.getRoot(), rootcommandnode); diff --git a/patches/net/minecraft/commands/arguments/ResourceKeyArgument.java.patch b/patches/net/minecraft/commands/arguments/ResourceKeyArgument.java.patch new file mode 100644 index 0000000000..6fa16e9d47 --- /dev/null +++ b/patches/net/minecraft/commands/arguments/ResourceKeyArgument.java.patch @@ -0,0 +1,31 @@ +--- a/net/minecraft/commands/arguments/ResourceKeyArgument.java ++++ b/net/minecraft/commands/arguments/ResourceKeyArgument.java +@@ -49,6 +_,9 @@ + private static final DynamicCommandExceptionType ERROR_INVALID_ADVANCEMENT = new DynamicCommandExceptionType( + p_378835_ -> Component.translatableEscape("advancement.advancementNotFound", p_378835_) + ); ++ private static final com.mojang.brigadier.exceptions.SimpleCommandExceptionType ERROR_NO_RECIPES_ON_CLIENT = new com.mojang.brigadier.exceptions.SimpleCommandExceptionType( ++ Component.translatable("commands.neoforge.vanilla.resource_key.no_recipes_on_client") ++ ); + final ResourceKey> registryKey; + + public ResourceKeyArgument(ResourceKey> p_212367_) { +@@ -91,6 +_,9 @@ + } + + public static RecipeHolder getRecipe(CommandContext p_380134_, String p_379840_) throws CommandSyntaxException { ++ if (p_380134_.getSource().getUnsidedLevel().isClientSide()) { ++ throw ERROR_NO_RECIPES_ON_CLIENT.create(); ++ } + RecipeManager recipemanager = p_380134_.getSource().getServer().getRecipeManager(); + ResourceKey> resourcekey = getRegistryKey(p_380134_, p_379840_, Registries.RECIPE, ERROR_INVALID_RECIPE); + return recipemanager.byKey(resourcekey).orElseThrow(() -> ERROR_INVALID_RECIPE.create(resourcekey.location())); +@@ -98,7 +_,7 @@ + + public static AdvancementHolder getAdvancement(CommandContext p_379729_, String p_379326_) throws CommandSyntaxException { + ResourceKey resourcekey = getRegistryKey(p_379729_, p_379326_, Registries.ADVANCEMENT, ERROR_INVALID_ADVANCEMENT); +- AdvancementHolder advancementholder = p_379729_.getSource().getServer().getAdvancements().get(resourcekey.location()); ++ AdvancementHolder advancementholder = p_379729_.getSource().getAdvancement(resourcekey.location()); + if (advancementholder == null) { + throw ERROR_INVALID_ADVANCEMENT.create(resourcekey.location()); + } else { diff --git a/patches/net/minecraft/commands/arguments/ResourceLocationArgument.java.patch b/patches/net/minecraft/commands/arguments/ResourceLocationArgument.java.patch deleted file mode 100644 index 676795818b..0000000000 --- a/patches/net/minecraft/commands/arguments/ResourceLocationArgument.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/net/minecraft/commands/arguments/ResourceLocationArgument.java -+++ b/net/minecraft/commands/arguments/ResourceLocationArgument.java -@@ -29,7 +_,7 @@ - - public static AdvancementHolder getAdvancement(CommandContext p_106988_, String p_106989_) throws CommandSyntaxException { - ResourceLocation resourcelocation = getId(p_106988_, p_106989_); -- AdvancementHolder advancementholder = p_106988_.getSource().getServer().getAdvancements().get(resourcelocation); -+ AdvancementHolder advancementholder = p_106988_.getSource().getAdvancement(resourcelocation); - if (advancementholder == null) { - throw ERROR_UNKNOWN_ADVANCEMENT.create(resourcelocation); - } else { -@@ -38,7 +_,7 @@ - } - - public static RecipeHolder getRecipe(CommandContext p_106995_, String p_106996_) throws CommandSyntaxException { -- RecipeManager recipemanager = p_106995_.getSource().getServer().getRecipeManager(); -+ RecipeManager recipemanager = p_106995_.getSource().getRecipeManager(); - ResourceLocation resourcelocation = getId(p_106995_, p_106996_); - return recipemanager.byKey(resourcelocation).orElseThrow(() -> ERROR_UNKNOWN_RECIPE.create(resourcelocation)); - } diff --git a/patches/net/minecraft/core/Holder.java.patch b/patches/net/minecraft/core/Holder.java.patch index f4b396b691..4cb8ce7c06 100644 --- a/patches/net/minecraft/core/Holder.java.patch +++ b/patches/net/minecraft/core/Holder.java.patch @@ -9,7 +9,7 @@ T value(); boolean isBound(); -@@ -220,6 +_,14 @@ +@@ -229,6 +_,14 @@ } } @@ -24,7 +24,7 @@ void bindTags(Collection> p_205770_) { this.tags = Set.copyOf(p_205770_); } -@@ -232,6 +_,33 @@ +@@ -241,6 +_,33 @@ @Override public String toString() { return "Reference{" + this.key + "=" + this.value + "}"; diff --git a/patches/net/minecraft/core/HolderLookup.java.patch b/patches/net/minecraft/core/HolderLookup.java.patch index d954817172..aa44414fdb 100644 --- a/patches/net/minecraft/core/HolderLookup.java.patch +++ b/patches/net/minecraft/core/HolderLookup.java.patch @@ -4,17 +4,24 @@ return this.listTags().map(HolderSet.Named::key); } -- public interface Provider { -+ public interface Provider extends net.neoforged.neoforge.common.extensions.IHolderLookupProviderExtension { - Stream>> listRegistries(); +- public interface Provider extends HolderGetter.Provider { ++ public interface Provider extends HolderGetter.Provider, net.neoforged.neoforge.common.extensions.IHolderLookupProviderExtension { + Stream>> listRegistryKeys(); - Optional> lookup(ResourceKey> p_256285_); -@@ -96,6 +_,11 @@ + default Stream> listRegistries() { +@@ -96,6 +_,18 @@ }; } ++ /** ++ * {@return the data map value attached with the object with the key, or {@code null} if there's no attached value} ++ * ++ * @param type the type of the data map ++ * @param key the object to get the value for ++ * @param the data type ++ */ + @org.jetbrains.annotations.Nullable -+ default A getData(net.neoforged.neoforge.registries.datamaps.DataMapType attachment, ResourceKey key) { ++ default A getData(net.neoforged.neoforge.registries.datamaps.DataMapType type, ResourceKey key) { + return null; + } + diff --git a/patches/net/minecraft/core/HolderSet.java.patch b/patches/net/minecraft/core/HolderSet.java.patch index a557fdb28d..6c2a44d7f0 100644 --- a/patches/net/minecraft/core/HolderSet.java.patch +++ b/patches/net/minecraft/core/HolderSet.java.patch @@ -9,7 +9,7 @@ Stream> stream(); int size(); -@@ -174,6 +_,9 @@ +@@ -182,6 +_,9 @@ void bind(List> p_205836_) { this.contents = List.copyOf(p_205836_); @@ -19,7 +19,7 @@ } public TagKey key() { -@@ -208,6 +_,11 @@ +@@ -225,6 +_,11 @@ @Override public boolean canSerializeIn(HolderOwner p_256542_) { return this.owner.canSerializeIn(p_256542_); diff --git a/patches/net/minecraft/core/MappedRegistry.java.patch b/patches/net/minecraft/core/MappedRegistry.java.patch index e7f390bb75..08874566bd 100644 --- a/patches/net/minecraft/core/MappedRegistry.java.patch +++ b/patches/net/minecraft/core/MappedRegistry.java.patch @@ -1,28 +1,15 @@ --- a/net/minecraft/core/MappedRegistry.java +++ b/net/minecraft/core/MappedRegistry.java -@@ -31,7 +_,7 @@ +@@ -30,7 +_,7 @@ + import net.minecraft.tags.TagLoader; import net.minecraft.util.RandomSource; - import org.slf4j.Logger; -public class MappedRegistry implements WritableRegistry { +public class MappedRegistry extends net.neoforged.neoforge.registries.BaseMappedRegistry implements WritableRegistry { - private static final Logger LOGGER = LogUtils.getLogger(); - final ResourceKey> key; + private final ResourceKey> key; private final ObjectList> byId = new ObjectArrayList<>(256); -@@ -75,6 +_,12 @@ - public Stream> listTags() { - return MappedRegistry.this.getTags().map(Pair::getSecond); - } -+ -+ @Override -+ @org.jetbrains.annotations.Nullable -+ public A getData(net.neoforged.neoforge.registries.datamaps.DataMapType type, ResourceKey key) { -+ return MappedRegistry.this.getData(type, key); -+ } - }; - private final Object tagAdditionLock = new Object(); - -@@ -114,9 +_,17 @@ + private final Reference2IntMap toId = Util.make(new Reference2IntOpenHashMap<>(), p_304142_ -> p_304142_.defaultReturnValue(-1)); +@@ -86,9 +_,17 @@ @Override public Holder.Reference register(ResourceKey p_256252_, T p_256591_, RegistrationInfo p_326235_) { @@ -38,77 +25,89 @@ + throw new IllegalStateException(String.format(java.util.Locale.ENGLISH, "Invalid id %d - maximum id range of %d exceeded.", i, this.getMaxId())); + if (this.byLocation.containsKey(p_256252_.location())) { - Util.pauseInIde(new IllegalStateException("Adding duplicate key '" + p_256252_ + "' to registry")); - } -@@ -135,16 +_,18 @@ - reference.bindKey(p_256252_); - } else { - reference = this.byKey.computeIfAbsent(p_256252_, p_258168_ -> Holder.Reference.createStandAlone(this.holderOwner(), (ResourceKey)p_258168_)); -+ // Forge: Bind the value immediately so it can be queried while the registry is not frozen -+ reference.bindValue(p_256591_); - } + throw (IllegalStateException)Util.pauseInIde(new IllegalStateException("Adding duplicate key '" + p_256252_ + "' to registry")); + } else if (this.byValue.containsKey(p_256591_)) { +@@ -104,16 +_,18 @@ + reference.bindKey(p_256252_); + } else { + reference = this.byKey.computeIfAbsent(p_256252_, p_367800_ -> Holder.Reference.createStandAlone(this, (ResourceKey)p_367800_)); ++ // Forge: Bind the value immediately so it can be queried while the registry is not frozen ++ reference.bindValue(p_256591_); + } - this.byKey.put(p_256252_, reference); - this.byLocation.put(p_256252_.location(), reference); - this.byValue.put(p_256591_, reference); -- int i = this.byId.size(); - this.byId.add(reference); - this.toId.put(p_256591_, i); - this.registrationInfos.put(p_256252_, p_326235_); - this.registryLifecycle = this.registryLifecycle.add(p_326235_.lifecycle()); -+ this.addCallbacks.forEach(addCallback -> addCallback.onAdd(this, i, p_256252_, p_256591_)); - return reference; + this.byKey.put(p_256252_, reference); + this.byLocation.put(p_256252_.location(), reference); + this.byValue.put(p_256591_, reference); +- int i = this.byId.size(); + this.byId.add(reference); + this.toId.put(p_256591_, i); + this.registrationInfos.put(p_256252_, p_326235_); + this.registryLifecycle = this.registryLifecycle.add(p_326235_.lifecycle()); ++ this.addCallbacks.forEach(addCallback -> addCallback.onAdd(this, i, p_256252_, p_256591_)); + return reference; + } } - -@@ -168,7 +_,7 @@ +@@ -138,7 +_,7 @@ @Nullable @Override - public T get(@Nullable ResourceKey p_122714_) { + public T getValue(@Nullable ResourceKey p_122714_) { - return getValueFromNullable(this.byKey.get(p_122714_)); + return getValueFromNullable(this.byKey.get(resolve(p_122714_))); } @Nullable -@@ -184,12 +_,12 @@ +@@ -154,12 +_,12 @@ @Override - public Optional> getHolder(ResourceLocation p_316743_) { + public Optional> get(ResourceLocation p_316743_) { - return Optional.ofNullable(this.byLocation.get(p_316743_)); + return Optional.ofNullable(this.byLocation.get(resolve(p_316743_))); } @Override - public Optional> getHolder(ResourceKey p_205905_) { + public Optional> get(ResourceKey p_205905_) { - return Optional.ofNullable(this.byKey.get(p_205905_)); + return Optional.ofNullable(this.byKey.get(resolve(p_205905_))); } @Override -@@ -204,7 +_,7 @@ +@@ -174,12 +_,12 @@ } Holder.Reference getOrCreateHolderOrThrow(ResourceKey p_248831_) { -- return this.byKey.computeIfAbsent(p_248831_, p_258169_ -> { +- return this.byKey.computeIfAbsent(p_248831_, p_367801_ -> { + return this.byKey.computeIfAbsent(resolve(p_248831_), p_258169_ -> { if (this.unregisteredIntrusiveHolders != null) { throw new IllegalStateException("This registry can't create new holders without value"); } else { -@@ -237,7 +_,7 @@ +- this.validateWrite((ResourceKey)p_367801_); +- return Holder.Reference.createStandAlone(this, (ResourceKey)p_367801_); ++ this.validateWrite((ResourceKey)p_258169_); ++ return Holder.Reference.createStandAlone(this, (ResourceKey)p_258169_); + } + }); + } +@@ -207,7 +_,7 @@ @Nullable @Override - public T get(@Nullable ResourceLocation p_122739_) { + public T getValue(@Nullable ResourceLocation p_122739_) { - Holder.Reference reference = this.byLocation.get(p_122739_); + Holder.Reference reference = this.byLocation.get(p_122739_ != null ? resolve(p_122739_) : null); return getValueFromNullable(reference); } -@@ -321,13 +_,18 @@ +@@ -269,13 +_,23 @@ return this.byKey.containsKey(p_175392_); } + /** @deprecated Forge: For internal use only. Use the Register events when registering values. */ + @Deprecated -+ public void unfreeze() { ++ @Override ++ public void unfreeze(boolean clearTags) { ++ if (clearTags) { ++ // unbind tags which were bound by the previous freeze ++ this.allTags = MappedRegistry.TagSet.unbound(); ++ } + this.frozen = false; + } + @@ -122,7 +121,7 @@ List list = this.byKey .entrySet() .stream() -@@ -343,8 +_,10 @@ +@@ -291,11 +_,15 @@ throw new IllegalStateException("Some intrusive holders were not registered: " + this.unregisteredIntrusiveHolders.values()); } @@ -132,12 +131,18 @@ } + this.bakeCallbacks.forEach(bakeCallback -> bakeCallback.onBake(this)); - return this; - } -@@ -440,5 +_,53 @@ - @Override - public HolderLookup.RegistryLookup asLookup() { - return this.lookup; + if (this.allTags.isBound()) { +- throw new IllegalStateException("Tags already present before freezing"); ++ // Neo: we freeze/unfreeze the registry to apply snapshots and tags need to be preserved in those cases ++ //throw new IllegalStateException("Tags already present before freezing"); ++ return this; + } else { + List list1 = this.frozenTags + .entrySet() +@@ -450,6 +_,54 @@ + } + }; + } + } + + @Override @@ -151,7 +156,7 @@ + this.byLocation.clear(); + this.byKey.clear(); + this.byValue.clear(); -+ this.tags.clear(); ++ this.allTags = MappedRegistry.TagSet.unbound(); + if (unregisteredIntrusiveHolders != null) { + unregisteredIntrusiveHolders.clear(); + unregisteredIntrusiveHolders = null; @@ -175,16 +180,17 @@ + + @Override + public int getId(ResourceLocation name) { -+ return getId(get(name)); ++ return getId(getValue(name)); + } + + @Override + public int getId(ResourceKey key) { -+ return getId(get(key)); ++ return getId(getValue(key)); + } + + @Override + public boolean containsValue(T value) { + return byValue.containsKey(value); } - } + + interface TagSet { diff --git a/patches/net/minecraft/core/Registry.java.patch b/patches/net/minecraft/core/Registry.java.patch index 7276d4d687..b12790d266 100644 --- a/patches/net/minecraft/core/Registry.java.patch +++ b/patches/net/minecraft/core/Registry.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/core/Registry.java +++ b/net/minecraft/core/Registry.java -@@ -22,7 +_,7 @@ +@@ -21,7 +_,7 @@ import net.minecraft.util.ExtraCodecs; import net.minecraft.util.RandomSource; --public interface Registry extends Keyable, IdMap { -+public interface Registry extends Keyable, IdMap, net.neoforged.neoforge.registries.IRegistryExtension { +-public interface Registry extends Keyable, HolderLookup.RegistryLookup, IdMap { ++public interface Registry extends Keyable, HolderLookup.RegistryLookup, IdMap, net.neoforged.neoforge.registries.IRegistryExtension { + @Override ResourceKey> key(); - default Codec byNameCodec() { @@ -48,7 +_,7 @@ } diff --git a/patches/net/minecraft/core/RegistrySetBuilder.java.patch b/patches/net/minecraft/core/RegistrySetBuilder.java.patch index 163a1531b2..0acf4974e8 100644 --- a/patches/net/minecraft/core/RegistrySetBuilder.java.patch +++ b/patches/net/minecraft/core/RegistrySetBuilder.java.patch @@ -22,7 +22,7 @@ - RegistrySetBuilder.LazyHolder lazyholder = new RegistrySetBuilder.LazyHolder<>(p_312323_, resourcekey); - lazyholder.supplier = () -> cloner.clone((T)p_311506_.value(), p_312725_, p_311797_.getValue()); - return lazyholder; -+ Optional> lookup = p_312725_.lookup(p_311836_); ++ Optional> lookup = p_312725_.lookup(p_311836_); + Lifecycle lifecycle; + if (lookup.isPresent()) { + HolderLookup.RegistryLookup registrylookup1 = lookup.get(); @@ -43,16 +43,16 @@ return lookupFromMap(p_311836_, lifecycle, p_312323_, map); } } -@@ -236,7 +_,7 @@ +@@ -235,7 +_,7 @@ + List list = new ArrayList<>(); RegistrySetBuilder.UniversalLookup registrysetbuilder$universallookup = new RegistrySetBuilder.UniversalLookup(registrysetbuilder$universalowner); Builder> builder = ImmutableMap.builder(); - p_255995_.registries() -- .forEach(p_258197_ -> builder.put(p_258197_.key().location(), RegistrySetBuilder.wrapContextLookup(p_258197_.value().asLookup()))); -+ .forEach(p_258197_ -> builder.put(p_258197_.key().location(), net.neoforged.neoforge.common.CommonHooks.wrapRegistryLookup(p_258197_.value().asLookup()))); +- p_255995_.registries().forEach(p_367807_ -> builder.put(p_367807_.key().location(), RegistrySetBuilder.wrapContextLookup(p_367807_.value()))); ++ p_255995_.registries().forEach(p_367807_ -> builder.put(p_367807_.key().location(), net.neoforged.neoforge.common.CommonHooks.wrapRegistryLookup(p_367807_.value()))); p_256495_.forEach(p_256603_ -> builder.put(p_256603_.location(), registrysetbuilder$universallookup)); return new RegistrySetBuilder.BuildState( registrysetbuilder$universalowner, registrysetbuilder$universallookup, builder.build(), new HashMap<>(), list -@@ -260,6 +_,11 @@ +@@ -259,6 +_,11 @@ @Override public HolderGetter lookup(ResourceKey> p_255961_) { return (HolderGetter)BuildState.this.registries.getOrDefault(p_255961_.location(), BuildState.this.lookup); diff --git a/patches/net/minecraft/core/component/DataComponentHolder.java.patch b/patches/net/minecraft/core/component/DataComponentHolder.java.patch index c1264738ba..d8a88115de 100644 --- a/patches/net/minecraft/core/component/DataComponentHolder.java.patch +++ b/patches/net/minecraft/core/component/DataComponentHolder.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/core/component/DataComponentHolder.java +++ b/net/minecraft/core/component/DataComponentHolder.java -@@ -2,7 +_,7 @@ - +@@ -3,7 +_,7 @@ + import java.util.stream.Stream; import javax.annotation.Nullable; -public interface DataComponentHolder { diff --git a/patches/net/minecraft/core/component/PatchedDataComponentMap.java.patch b/patches/net/minecraft/core/component/PatchedDataComponentMap.java.patch index 041019ddac..dfea9ede8a 100644 --- a/patches/net/minecraft/core/component/PatchedDataComponentMap.java.patch +++ b/patches/net/minecraft/core/component/PatchedDataComponentMap.java.patch @@ -8,7 +8,7 @@ this.ensureMapOwnership(); T t = this.prototype.get((DataComponentType)p_330791_); Optional optional; -@@ -192,6 +_,10 @@ +@@ -197,6 +_,10 @@ } return i; diff --git a/patches/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java.patch b/patches/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java.patch index f2a00c2abf..df2a666f9c 100644 --- a/patches/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java.patch +++ b/patches/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java.patch @@ -1,31 +1,42 @@ --- a/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java +++ b/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java -@@ -35,21 +_,22 @@ +@@ -29,27 +_,33 @@ double d2 = vec3.y() + (double)((float)direction.getStepY() * 1.125F); double d3 = vec3.z() + (double)direction.getStepZ() * d0; BlockPos blockpos = p_302460_.pos().relative(direction); -+ Boat boat = (Boat)(this.isChestBoat ? new ChestBoat(serverlevel, d1, d2, d3) : new Boat(serverlevel, d1, d2, d3)); -+ EntityType.createDefaultStackConfig(serverlevel, p_123376_, null).accept(boat); -+ boat.setVariant(this.type); -+ boat.setYRot(direction.toYRot()); ++ AbstractBoat abstractboat = this.type.create(serverlevel, EntitySpawnReason.DISPENSER); ++ if (abstractboat != null) { ++ EntityType.createDefaultStackConfig(serverlevel, p_123376_, null).accept(abstractboat); ++ abstractboat.setYRot(direction.toYRot()); ++ serverlevel.addFreshEntity(abstractboat); ++ } double d4; - if (serverlevel.getFluidState(blockpos).is(FluidTags.WATER)) { -+ if (boat.canBoatInFluid(serverlevel.getFluidState(blockpos))) { ++ if (canBoatInFluid(abstractboat, serverlevel.getFluidState(blockpos))) { d4 = 1.0; } else { - if (!serverlevel.getBlockState(blockpos).isAir() || !serverlevel.getFluidState(blockpos.below()).is(FluidTags.WATER)) { -+ if (!serverlevel.getBlockState(blockpos).isAir() || !boat.canBoatInFluid(serverlevel.getFluidState(blockpos.below()))) { ++ if (!serverlevel.getBlockState(blockpos).isAir() || !canBoatInFluid(abstractboat, serverlevel.getFluidState(blockpos.below()))) { return this.defaultDispenseItemBehavior.dispense(p_302460_, p_123376_); } d4 = 0.0; } -- Boat boat = (Boat)(this.isChestBoat ? new ChestBoat(serverlevel, d1, d2 + d4, d3) : new Boat(serverlevel, d1, d2 + d4, d3)); -- EntityType.createDefaultStackConfig(serverlevel, p_123376_, null).accept(boat); -- boat.setVariant(this.type); -- boat.setYRot(direction.toYRot()); -+ boat.setPos(d1, d2 + d4, d3); - serverlevel.addFreshEntity(boat); - p_123376_.shrink(1); +- AbstractBoat abstractboat = this.type.create(serverlevel, EntitySpawnReason.DISPENSER); + if (abstractboat != null) { + abstractboat.setInitialPos(d1, d2 + d4, d3); +- EntityType.createDefaultStackConfig(serverlevel, p_123376_, null).accept(abstractboat); +- abstractboat.setYRot(direction.toYRot()); +- serverlevel.addFreshEntity(abstractboat); + p_123376_.shrink(1); + } + return p_123376_; ++ } ++ ++ private static boolean canBoatInFluid(@org.jetbrains.annotations.Nullable AbstractBoat boat, net.minecraft.world.level.material.FluidState fluid) { ++ return boat != null ? boat.canBoatInFluid(fluid) : fluid.is(FluidTags.WATER); + } + + @Override diff --git a/patches/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch b/patches/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch index 9f0b115a25..e65ba52405 100644 --- a/patches/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch +++ b/patches/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch @@ -1,28 +1,28 @@ --- a/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -231,7 +_,7 @@ - DispensibleContainerItem dispensiblecontaineritem = (DispensibleContainerItem)p_338251_.getItem(); - BlockPos blockpos = p_338850_.pos().relative(p_338850_.state().getValue(DispenserBlock.FACING)); - Level level = p_338850_.level(); +@@ -192,7 +_,7 @@ + DispensibleContainerItem dispensiblecontaineritem = (DispensibleContainerItem)p_338735_.getItem(); + BlockPos blockpos = p_338297_.pos().relative(p_338297_.state().getValue(DispenserBlock.FACING)); + Level level = p_338297_.level(); - if (dispensiblecontaineritem.emptyContents(null, level, blockpos, null)) { -+ if (dispensiblecontaineritem.emptyContents(null, level, blockpos, null, p_338251_)) { - dispensiblecontaineritem.checkExtraContent(null, level, p_338251_, blockpos); - return this.consumeWithRemainder(p_338850_, p_338251_, new ItemStack(Items.BUCKET)); ++ if (dispensiblecontaineritem.emptyContents(null, level, blockpos, null, p_338735_)) { + dispensiblecontaineritem.checkExtraContent(null, level, p_338735_, blockpos); + return this.consumeWithRemainder(p_338297_, p_338735_, new ItemStack(Items.BUCKET)); } else { -@@ -279,12 +_,13 @@ +@@ -240,12 +_,13 @@ if (BaseFireBlock.canBePlacedAt(serverlevel, blockpos, direction)) { serverlevel.setBlockAndUpdate(blockpos, BaseFireBlock.getState(serverlevel, blockpos)); serverlevel.gameEvent(null, GameEvent.BLOCK_PLACE, blockpos); - } else if (CampfireBlock.canLight(blockstate) || CandleBlock.canLight(blockstate) || CandleCakeBlock.canLight(blockstate)) { - serverlevel.setBlockAndUpdate(blockpos, blockstate.setValue(BlockStateProperties.LIT, Boolean.valueOf(true))); -+ } else if (blockstate.getToolModifiedState(new net.minecraft.world.item.context.UseOnContext(p_338494_.level(), null, net.minecraft.world.InteractionHand.MAIN_HAND, p_338444_, new net.minecraft.world.phys.BlockHitResult(blockpos.getCenter(), direction.getOpposite(), blockpos, false)), net.neoforged.neoforge.common.ItemAbilities.FIRESTARTER_LIGHT, false) instanceof BlockState blockstate2) { ++ } else if (blockstate.getToolModifiedState(new net.minecraft.world.item.context.UseOnContext(serverlevel, null, net.minecraft.world.InteractionHand.MAIN_HAND, p_338526_, new net.minecraft.world.phys.BlockHitResult(blockpos.getCenter(), direction.getOpposite(), blockpos, false)), net.neoforged.neoforge.common.ItemAbilities.FIRESTARTER_LIGHT, false) instanceof BlockState blockstate2) { + serverlevel.setBlockAndUpdate(blockpos, blockstate2); serverlevel.gameEvent(null, GameEvent.BLOCK_CHANGE, blockpos); - } else if (blockstate.getBlock() instanceof TntBlock) { - TntBlock.explode(serverlevel, blockpos); - serverlevel.removeBlock(blockpos, false); -+ } else if (blockstate.isFlammable(serverlevel, blockpos, p_338494_.state().getValue(DispenserBlock.FACING).getOpposite())) { -+ blockstate.onCaughtFire(serverlevel, blockpos, p_338494_.state().getValue(DispenserBlock.FACING).getOpposite(), null); ++ } else if (blockstate.isFlammable(serverlevel, blockpos, p_338386_.state().getValue(DispenserBlock.FACING).getOpposite())) { ++ blockstate.onCaughtFire(serverlevel, blockpos, p_338386_.state().getValue(DispenserBlock.FACING).getOpposite(), null); + if (blockstate.getBlock() instanceof TntBlock) + serverlevel.removeBlock(blockpos, false); } else { diff --git a/patches/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java.patch b/patches/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java.patch new file mode 100644 index 0000000000..0959113dde --- /dev/null +++ b/patches/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java ++++ b/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java +@@ -26,6 +_,8 @@ + } else { + LivingEntity livingentity = list.getFirst(); + EquipmentSlot equipmentslot = livingentity.getEquipmentSlotForItem(p_371227_); ++ // Neo: Respect IItemExtension#canEquip in dispenseArmor ++ if (!p_371227_.canEquip(equipmentslot, livingentity)) return false; + ItemStack itemstack = p_371227_.split(1); + livingentity.setItemSlot(equipmentslot, itemstack); + if (livingentity instanceof Mob mob) { diff --git a/patches/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java.patch b/patches/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java.patch new file mode 100644 index 0000000000..866bbb8217 --- /dev/null +++ b/patches/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java.patch @@ -0,0 +1,31 @@ +--- a/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java ++++ b/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java +@@ -34,7 +_,7 @@ + BlockState blockstate = serverlevel.getBlockState(blockpos); + double d3; + if (blockstate.is(BlockTags.RAILS)) { +- if (getRailShape(blockstate).isSlope()) { ++ if (getRailShape(blockstate, serverlevel, blockpos).isSlope()) { + d3 = 0.6; + } else { + d3 = 0.1; +@@ -49,7 +_,7 @@ + return this.defaultDispenseItemBehavior.dispense(p_374045_, p_374580_); + } + +- if (direction != Direction.DOWN && getRailShape(blockstate1).isSlope()) { ++ if (direction != Direction.DOWN && getRailShape(blockstate1, serverlevel, blockpos.below()).isSlope()) { + d3 = -0.4; + } else { + d3 = -0.9; +@@ -68,8 +_,8 @@ + return p_374580_; + } + +- private static RailShape getRailShape(BlockState p_374571_) { +- return p_374571_.getBlock() instanceof BaseRailBlock baserailblock ? p_374571_.getValue(baserailblock.getShapeProperty()) : RailShape.NORTH_SOUTH; ++ private static RailShape getRailShape(BlockState p_374571_, ServerLevel level, BlockPos pos) { ++ return p_374571_.getBlock() instanceof BaseRailBlock baserailblock ? baserailblock.getRailDirection(p_374571_, level, pos, null) : RailShape.NORTH_SOUTH; + } + + @Override diff --git a/patches/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java.patch b/patches/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java.patch index 0ab8226972..1e9b2b01cd 100644 --- a/patches/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java.patch +++ b/patches/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java.patch @@ -4,22 +4,19 @@ ServerLevel serverlevel = p_302443_.level(); if (!serverlevel.isClientSide()) { BlockPos blockpos = p_302443_.pos().relative(p_302443_.state().getValue(DispenserBlock.FACING)); -- this.setSuccess(tryShearBeehive(serverlevel, blockpos) || tryShearLivingEntity(serverlevel, blockpos)); +- this.setSuccess(tryShearBeehive(serverlevel, blockpos) || tryShearLivingEntity(serverlevel, blockpos, p_123581_)); + this.setSuccess(net.neoforged.neoforge.common.CommonHooks.tryDispenseShearsHarvestBlock(p_302443_, p_123581_, serverlevel, blockpos) || tryShearBeehive(serverlevel, blockpos) || tryShearLivingEntity(serverlevel, blockpos, p_123581_)); if (this.isSuccess()) { p_123581_.hurtAndBreak(1, serverlevel, null, p_348118_ -> { }); -@@ -51,10 +_,11 @@ - return false; - } +@@ -53,8 +_,9 @@ -- private static boolean tryShearLivingEntity(ServerLevel p_123583_, BlockPos p_123584_) { -+ private static boolean tryShearLivingEntity(ServerLevel p_123583_, BlockPos p_123584_, ItemStack stack) { + private static boolean tryShearLivingEntity(ServerLevel p_123583_, BlockPos p_123584_, ItemStack p_372883_) { for (LivingEntity livingentity : p_123583_.getEntitiesOfClass(LivingEntity.class, new AABB(p_123584_), EntitySelector.NO_SPECTATORS)) { - if (livingentity instanceof Shearable shearable && shearable.readyForShearing()) { -- shearable.shear(SoundSource.BLOCKS); -+ if (livingentity instanceof net.neoforged.neoforge.common.IShearable shearable && shearable.isShearable(null, stack, p_123583_, p_123584_)) { -+ shearable.onSheared(null, stack, p_123583_, p_123584_) +- shearable.shear(p_123583_, SoundSource.BLOCKS, p_372883_); ++ if (livingentity instanceof net.neoforged.neoforge.common.IShearable shearable && shearable.isShearable(null, p_372883_, p_123583_, p_123584_)) { ++ shearable.onSheared(null, p_372883_, p_123583_, p_123584_) + .forEach(drop -> shearable.spawnShearedDrop(p_123583_, p_123584_, drop)); p_123583_.gameEvent(null, GameEvent.SHEAR, p_123584_); return true; diff --git a/patches/net/minecraft/core/particles/ItemParticleOption.java.patch b/patches/net/minecraft/core/particles/ItemParticleOption.java.patch index ba30506ce6..33a8473c99 100644 --- a/patches/net/minecraft/core/particles/ItemParticleOption.java.patch +++ b/patches/net/minecraft/core/particles/ItemParticleOption.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/particles/ItemParticleOption.java +++ b/net/minecraft/core/particles/ItemParticleOption.java -@@ -24,7 +_,7 @@ +@@ -25,7 +_,7 @@ throw new IllegalArgumentException("Empty stacks are not allowed"); } else { this.type = p_123705_; diff --git a/patches/net/minecraft/core/registries/BuiltInRegistries.java.patch b/patches/net/minecraft/core/registries/BuiltInRegistries.java.patch index e693d8f2a9..d6ad5ccf02 100644 --- a/patches/net/minecraft/core/registries/BuiltInRegistries.java.patch +++ b/patches/net/minecraft/core/registries/BuiltInRegistries.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/core/registries/BuiltInRegistries.java +++ b/net/minecraft/core/registries/BuiltInRegistries.java -@@ -356,6 +_,10 @@ - }); +@@ -373,6 +_,10 @@ + ((MappedRegistry)p_365443_).bindAllTagsToEmpty(); } + public static java.util.Set getVanillaRegistrationOrder() { diff --git a/patches/net/minecraft/core/registries/Registries.java.patch b/patches/net/minecraft/core/registries/Registries.java.patch index 1d5ce37612..6e9682548e 100644 --- a/patches/net/minecraft/core/registries/Registries.java.patch +++ b/patches/net/minecraft/core/registries/Registries.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/registries/Registries.java +++ b/net/minecraft/core/registries/Registries.java -@@ -249,10 +_,10 @@ +@@ -257,10 +_,10 @@ } public static String elementsDirPath(ResourceKey> p_350960_) { diff --git a/patches/net/minecraft/data/DataProvider.java.patch b/patches/net/minecraft/data/DataProvider.java.patch index 24c9736040..07f5c14860 100644 --- a/patches/net/minecraft/data/DataProvider.java.patch +++ b/patches/net/minecraft/data/DataProvider.java.patch @@ -1,11 +1,12 @@ --- a/net/minecraft/data/DataProvider.java +++ b/net/minecraft/data/DataProvider.java -@@ -24,6 +_,8 @@ +@@ -28,6 +_,9 @@ public interface DataProvider { ToIntFunction FIXED_ORDER_FIELDS = Util.make(new Object2IntOpenHashMap<>(), p_236070_ -> { + // Neo: conditions go first + p_236070_.put("neoforge:conditions", -1); ++ p_236070_.put("neoforge:ingredient_type", 0); p_236070_.put("type", 0); p_236070_.put("parent", 1); p_236070_.defaultReturnValue(2); diff --git a/patches/net/minecraft/data/Main.java.patch b/patches/net/minecraft/data/Main.java.patch index 4f188c8e33..4e6c37a6e7 100644 --- a/patches/net/minecraft/data/Main.java.patch +++ b/patches/net/minecraft/data/Main.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/data/Main.java +++ b/net/minecraft/data/Main.java -@@ -77,8 +_,15 @@ +@@ -86,8 +_,15 @@ OptionSpec optionspec6 = optionparser.accepts("all", "Include all generators"); OptionSpec optionspec7 = optionparser.accepts("output", "Output folder").withRequiredArg().defaultsTo("generated"); OptionSpec optionspec8 = optionparser.accepts("input", "Input folder").withRequiredArg(); @@ -17,7 +17,7 @@ Path path = Paths.get(optionspec7.value(optionset)); boolean flag = optionset.has(optionspec6); boolean flag1 = flag || optionset.has(optionspec2); -@@ -86,9 +_,16 @@ +@@ -95,9 +_,16 @@ boolean flag3 = flag || optionset.has(optionspec3); boolean flag4 = flag || optionset.has(optionspec4); boolean flag5 = flag || optionset.has(optionspec5); @@ -36,7 +36,7 @@ flag1, flag2, flag3, -@@ -98,6 +_,7 @@ +@@ -107,6 +_,7 @@ true ); datagenerator.run(); diff --git a/patches/net/minecraft/data/loot/BlockLootSubProvider.java.patch b/patches/net/minecraft/data/loot/BlockLootSubProvider.java.patch index 95cf157be3..2bd05fb51a 100644 --- a/patches/net/minecraft/data/loot/BlockLootSubProvider.java.patch +++ b/patches/net/minecraft/data/loot/BlockLootSubProvider.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/data/loot/BlockLootSubProvider.java +++ b/net/minecraft/data/loot/BlockLootSubProvider.java -@@ -655,12 +_,16 @@ +@@ -684,12 +_,16 @@ protected abstract void generate(); @@ -14,7 +14,7 @@ Set> set = new HashSet<>(); - for (Block block : BuiltInRegistries.BLOCK) { -+ for(Block block : getKnownBlocks()) { ++ for (Block block : getKnownBlocks()) { if (block.isEnabled(this.enabledFeatures)) { - ResourceKey resourcekey = block.getLootTable(); - if (resourcekey != BuiltInLootTables.EMPTY && set.add(resourcekey)) { + block.getLootTable() + .ifPresent( diff --git a/patches/net/minecraft/data/loot/EntityLootSubProvider.java.patch b/patches/net/minecraft/data/loot/EntityLootSubProvider.java.patch index 0513593438..6ec12bdeab 100644 --- a/patches/net/minecraft/data/loot/EntityLootSubProvider.java.patch +++ b/patches/net/minecraft/data/loot/EntityLootSubProvider.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/data/loot/EntityLootSubProvider.java +++ b/net/minecraft/data/loot/EntityLootSubProvider.java -@@ -96,12 +_,16 @@ +@@ -104,12 +_,16 @@ public abstract void generate(); @@ -13,18 +13,9 @@ this.generate(); Set> set = new HashSet<>(); - BuiltInRegistries.ENTITY_TYPE -- .holders() +- .listElements() + this.getKnownEntityTypes() + .map(EntityType::builtInRegistryHolder) .forEach( - p_266624_ -> { - EntityType entitytype = p_266624_.value(); -@@ -151,7 +_,7 @@ - } - } - -- protected static boolean canHaveLootTable(EntityType p_249029_) { -+ protected boolean canHaveLootTable(EntityType p_249029_) { - return SPECIAL_LOOT_TABLE_TYPES.contains(p_249029_) || p_249029_.getCategory() != MobCategory.MISC; - } - + p_367828_ -> { + EntityType entitytype = p_367828_.value(); diff --git a/patches/net/minecraft/data/loot/LootTableProvider.java.patch b/patches/net/minecraft/data/loot/LootTableProvider.java.patch index 8a8f1bc25a..d68c2594ba 100644 --- a/patches/net/minecraft/data/loot/LootTableProvider.java.patch +++ b/patches/net/minecraft/data/loot/LootTableProvider.java.patch @@ -1,29 +1,29 @@ --- a/net/minecraft/data/loot/LootTableProvider.java +++ b/net/minecraft/data/loot/LootTableProvider.java -@@ -62,33 +_,24 @@ +@@ -62,34 +_,24 @@ private CompletableFuture run(CachedOutput p_324447_, HolderLookup.Provider p_323978_) { WritableRegistry writableregistry = new MappedRegistry<>(Registries.LOOT_TABLE, Lifecycle.experimental()); Map map = new Object2ObjectOpenHashMap<>(); -- this.subProviders.forEach(p_344197_ -> p_344197_.provider().apply(p_323978_).generate((p_339366_, p_339367_) -> { -- ResourceLocation resourcelocation = sequenceIdForLootTable(p_339366_); +- this.subProviders.forEach(p_344197_ -> p_344197_.provider().apply(p_323978_).generate((p_380827_, p_380828_) -> { +- ResourceLocation resourcelocation = sequenceIdForLootTable(p_380827_); + getTables().forEach(p_329847_ -> p_329847_.provider().apply(p_323978_).generate((p_335199_, p_335200_) -> { + ResourceLocation resourcelocation = sequenceIdForLootTable(p_335199_); ResourceLocation resourcelocation1 = map.put(RandomSequence.seedForKey(resourcelocation), resourcelocation); if (resourcelocation1 != null) { -- Util.logAndPauseIfInIde("Loot table random sequence seed collision on " + resourcelocation1 + " and " + p_339366_.location()); +- Util.logAndPauseIfInIde("Loot table random sequence seed collision on " + resourcelocation1 + " and " + p_380827_.location()); + Util.logAndPauseIfInIde("Loot table random sequence seed collision on " + resourcelocation1 + " and " + p_335199_.location()); } -- p_339367_.setRandomSequence(resourcelocation); -- LootTable loottable = p_339367_.setParamSet(p_344197_.paramSet).build(); -- writableregistry.register(p_339366_, loottable, RegistrationInfo.BUILT_IN); +- p_380828_.setRandomSequence(resourcelocation); +- LootTable loottable = p_380828_.setParamSet(p_344197_.paramSet).build(); +- writableregistry.register(p_380827_, loottable, RegistrationInfo.BUILT_IN); + p_335200_.setRandomSequence(resourcelocation); + LootTable loottable = p_335200_.setParamSet(p_329847_.paramSet).build(); + writableregistry.register(p_335199_, loottable, RegistrationInfo.BUILT_IN); })); writableregistry.freeze(); ProblemReporter.Collector problemreporter$collector = new ProblemReporter.Collector(); - HolderGetter.Provider holdergetter$provider = new RegistryAccess.ImmutableRegistryAccess(List.of(writableregistry)).freeze().asGetterLookup(); + HolderGetter.Provider holdergetter$provider = new RegistryAccess.ImmutableRegistryAccess(List.of(writableregistry)).freeze(); ValidationContext validationcontext = new ValidationContext(problemreporter$collector, LootContextParamSets.ALL_PARAMS, holdergetter$provider); - for (ResourceKey resourcekey : Sets.difference(this.requiredTables, writableregistry.registryKeySet())) { @@ -31,17 +31,18 @@ - } + validate(writableregistry, validationcontext, problemreporter$collector); -- writableregistry.holders() +- writableregistry.listElements() - .forEach( -- p_339369_ -> p_339369_.value() +- p_380823_ -> p_380823_.value() - .validate( -- validationcontext.setParams(p_339369_.value().getParamSet()).enterElement("{" + p_339369_.key().location() + "}", p_339369_.key()) +- validationcontext.setContextKeySet(p_380823_.value().getParamSet()) +- .enterElement("{" + p_380823_.key().location() + "}", p_380823_.key()) - ) - ); Multimap multimap = problemreporter$collector.get(); if (!multimap.isEmpty()) { multimap.forEach((p_124446_, p_124447_) -> LOGGER.warn("Found validation problem in {}: {}", p_124446_, p_124447_)); -@@ -101,6 +_,20 @@ +@@ -102,6 +_,20 @@ return DataProvider.saveStable(p_324447_, p_323978_, LootTable.DIRECT_CODEC, loottable, path); }).toArray(CompletableFuture[]::new)); } @@ -56,8 +57,8 @@ + problemreporter$collector.report("Missing built-in table: " + resourcekey.location()); + } + -+ writableregistry.holders().forEach(p_335195_ -> { -+ p_335195_.value().validate(validationcontext.setParams(p_335195_.value().getParamSet()).enterElement("{" + p_335195_.key().location() + "}", p_335195_.key())); ++ writableregistry.listElements().forEach(p_335195_ -> { ++ p_335195_.value().validate(validationcontext.setContextKeySet(p_335195_.value().getParamSet()).enterElement("{" + p_335195_.key().location() + "}", p_335195_.key())); + }); } diff --git a/patches/net/minecraft/data/recipes/RecipeOutput.java.patch b/patches/net/minecraft/data/recipes/RecipeOutput.java.patch index 17b3c42df4..18206b3385 100644 --- a/patches/net/minecraft/data/recipes/RecipeOutput.java.patch +++ b/patches/net/minecraft/data/recipes/RecipeOutput.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/data/recipes/RecipeOutput.java +++ b/net/minecraft/data/recipes/RecipeOutput.java @@ -6,8 +_,10 @@ - import net.minecraft.resources.ResourceLocation; + import net.minecraft.resources.ResourceKey; import net.minecraft.world.item.crafting.Recipe; -public interface RecipeOutput { -- void accept(ResourceLocation p_312249_, Recipe p_312328_, @Nullable AdvancementHolder p_312176_); +- void accept(ResourceKey> p_380042_, Recipe p_312328_, @Nullable AdvancementHolder p_312176_); +public interface RecipeOutput extends net.neoforged.neoforge.common.extensions.IRecipeOutputExtension { -+ default void accept(ResourceLocation p_312249_, Recipe p_312328_, @Nullable AdvancementHolder p_312176_) { ++ default void accept(ResourceKey> p_312249_, Recipe p_312328_, @Nullable AdvancementHolder p_312176_) { + accept(p_312249_, p_312328_, p_312176_, new net.neoforged.neoforge.common.conditions.ICondition[0]); + } Advancement.Builder advancement(); - } + diff --git a/patches/net/minecraft/data/recipes/RecipeProvider.java.patch b/patches/net/minecraft/data/recipes/RecipeProvider.java.patch index ec1d44e063..27eb2f31a7 100644 --- a/patches/net/minecraft/data/recipes/RecipeProvider.java.patch +++ b/patches/net/minecraft/data/recipes/RecipeProvider.java.patch @@ -1,69 +1,53 @@ --- a/net/minecraft/data/recipes/RecipeProvider.java +++ b/net/minecraft/data/recipes/RecipeProvider.java -@@ -84,18 +_,18 @@ - this.buildRecipes( - new RecipeOutput() { - @Override -- public void accept(ResourceLocation p_312039_, Recipe p_312254_, @Nullable AdvancementHolder p_311794_) { -+ public void accept(ResourceLocation p_312039_, Recipe p_312254_, @Nullable AdvancementHolder p_311794_, net.neoforged.neoforge.common.conditions.ICondition... conditions) { - if (!set.add(p_312039_)) { - throw new IllegalStateException("Duplicate recipe " + p_312039_); - } else { -- list.add(DataProvider.saveStable(p_324494_, p_324248_, Recipe.CODEC, p_312254_, RecipeProvider.this.recipePathProvider.json(p_312039_))); -+ list.add(DataProvider.saveStable(p_324494_, p_324248_, Recipe.CONDITIONAL_CODEC, Optional.of(new net.neoforged.neoforge.common.conditions.WithConditions<>(p_312254_, conditions)), RecipeProvider.this.recipePathProvider.json(p_312039_))); - if (p_311794_ != null) { - list.add( - DataProvider.saveStable( - p_324494_, - p_324248_, -- Advancement.CODEC, -- p_311794_.value(), -+ Advancement.CONDITIONAL_CODEC, -+ Optional.of(new net.neoforged.neoforge.common.conditions.WithConditions<>(p_311794_.value(), conditions)), - RecipeProvider.this.advancementPathProvider.json(p_311794_.id()) - ) - ); -@@ -107,18 +_,26 @@ - public Advancement.Builder advancement() { - return Advancement.Builder.recipeAdvancement().parent(RecipeBuilder.ROOT_RECIPE_ADVANCEMENT); - } -- } -+ }, p_324248_ - ); - return CompletableFuture.allOf(list.toArray(CompletableFuture[]::new)); +@@ -566,8 +_,7 @@ } - protected CompletableFuture buildAdvancement(CachedOutput p_253674_, HolderLookup.Provider p_323646_, AdvancementHolder p_301116_) { -- return DataProvider.saveStable(p_253674_, p_323646_, Advancement.CODEC, p_301116_.value(), this.advancementPathProvider.json(p_301116_.id())); -- } -- -- protected abstract void buildRecipes(RecipeOutput p_301172_); -- -- protected static void generateForEnabledBlockFamilies(RecipeOutput p_301146_, FeatureFlagSet p_251836_) { -+ return buildAdvancement(p_253674_, p_323646_, p_301116_, new net.neoforged.neoforge.common.conditions.ICondition[0]); -+ } -+ -+ protected CompletableFuture buildAdvancement(CachedOutput p_253674_, HolderLookup.Provider p_323646_, AdvancementHolder p_301116_, net.neoforged.neoforge.common.conditions.ICondition... conditions) { -+ return DataProvider.saveStable(p_253674_, p_323646_, Advancement.CONDITIONAL_CODEC, Optional.of(new net.neoforged.neoforge.common.conditions.WithConditions<>(p_301116_.value(), conditions)), this.advancementPathProvider.json(p_301116_.id())); -+ } -+ -+ protected void buildRecipes(RecipeOutput recipeOutput, HolderLookup.Provider holderLookup) { -+ buildRecipes(recipeOutput); -+ } -+ -+ protected void buildRecipes(RecipeOutput p_301172_) {} -+ -+ protected void generateForEnabledBlockFamilies(RecipeOutput p_301146_, FeatureFlagSet p_251836_) { - BlockFamilies.getAllFamilies().filter(BlockFamily::shouldGenerateRecipe).forEach(p_313461_ -> generateRecipes(p_301146_, p_313461_, p_251836_)); - } - -@@ -611,8 +_,7 @@ - } - - protected static void waxRecipes(RecipeOutput p_301254_, FeatureFlagSet p_313879_) { + protected void waxRecipes(FeatureFlagSet p_313879_) { - HoneycombItem.WAXABLES - .get() + net.neoforged.neoforge.common.DataMapHooks.INVERSE_WAXABLES_DATAMAP .forEach( - (p_337490_, p_337491_) -> { - if (p_337491_.requiredFeatures().isSubsetOf(p_313879_)) { + (p_359424_, p_359425_) -> { + if (p_359425_.requiredFeatures().isSubsetOf(p_313879_)) { +@@ -756,13 +_,13 @@ + final List> list = new ArrayList<>(); + RecipeOutput recipeoutput = new RecipeOutput() { + @Override +- public void accept(ResourceKey> p_380360_, Recipe p_362882_, @Nullable AdvancementHolder p_364507_) { ++ public void accept(ResourceKey> p_380360_, Recipe p_362882_, @Nullable AdvancementHolder p_364507_, net.neoforged.neoforge.common.conditions.ICondition... conditions) { + if (!set.add(p_380360_)) { + throw new IllegalStateException("Duplicate recipe " + p_380360_.location()); + } else { +- this.saveRecipe(p_380360_, p_362882_); ++ this.saveRecipe(p_380360_, p_362882_, conditions); + if (p_364507_ != null) { +- this.saveAdvancement(p_364507_); ++ this.saveAdvancement(p_364507_, conditions); + } + } + } +@@ -781,15 +_,21 @@ + } + + private void saveRecipe(ResourceKey> p_380099_, Recipe p_364792_) { ++ saveRecipe(p_380099_, p_364792_, new net.neoforged.neoforge.common.conditions.ICondition[0]); ++ } ++ private void saveRecipe(ResourceKey> p_380099_, Recipe p_364792_, net.neoforged.neoforge.common.conditions.ICondition... conditions) { + list.add( +- DataProvider.saveStable(p_364823_, p_364211_, Recipe.CODEC, p_364792_, packoutput$pathprovider.json(p_380099_.location())) ++ DataProvider.saveStable(p_364823_, p_364211_, Recipe.CONDITIONAL_CODEC, Optional.of(new net.neoforged.neoforge.common.conditions.WithConditions<>(p_364792_, conditions)), packoutput$pathprovider.json(p_380099_.location())) + ); + } + + private void saveAdvancement(AdvancementHolder p_363148_) { ++ saveAdvancement(p_363148_, new net.neoforged.neoforge.common.conditions.ICondition[0]); ++ } ++ private void saveAdvancement(AdvancementHolder p_363148_, net.neoforged.neoforge.common.conditions.ICondition... conditions) { + list.add( + DataProvider.saveStable( +- p_364823_, p_364211_, Advancement.CODEC, p_363148_.value(), packoutput$pathprovider1.json(p_363148_.id()) ++ p_364823_, p_364211_, Advancement.CONDITIONAL_CODEC, Optional.of(new net.neoforged.neoforge.common.conditions.WithConditions<>(p_363148_.value(), conditions)), packoutput$pathprovider1.json(p_363148_.id()) + ) + ); + } diff --git a/patches/net/minecraft/data/recipes/ShapedRecipeBuilder.java.patch b/patches/net/minecraft/data/recipes/ShapedRecipeBuilder.java.patch index 2d994e43aa..e14eb5413d 100644 --- a/patches/net/minecraft/data/recipes/ShapedRecipeBuilder.java.patch +++ b/patches/net/minecraft/data/recipes/ShapedRecipeBuilder.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/data/recipes/ShapedRecipeBuilder.java +++ b/net/minecraft/data/recipes/ShapedRecipeBuilder.java -@@ -25,6 +_,7 @@ +@@ -28,6 +_,7 @@ private final RecipeCategory category; private final Item result; private final int count; @@ -8,14 +8,15 @@ private final List rows = Lists.newArrayList(); private final Map key = Maps.newLinkedHashMap(); private final Map> criteria = new LinkedHashMap<>(); -@@ -33,9 +_,14 @@ +@@ -36,10 +_,15 @@ private boolean showNotification = true; - public ShapedRecipeBuilder(RecipeCategory p_249996_, ItemLike p_251475_, int p_248948_) { -+ this(p_249996_, new ItemStack(p_251475_, p_248948_)); + private ShapedRecipeBuilder(HolderGetter p_365072_, RecipeCategory p_249996_, ItemLike p_251475_, int p_248948_) { ++ this(p_365072_, p_249996_, new ItemStack(p_251475_, p_248948_)); + } + -+ public ShapedRecipeBuilder(RecipeCategory p_249996_, ItemStack result) { ++ private ShapedRecipeBuilder(HolderGetter p_365072_, RecipeCategory p_249996_, ItemStack result) { + this.items = p_365072_; this.category = p_249996_; - this.result = p_251475_.asItem(); - this.count = p_248948_; @@ -24,19 +25,19 @@ + this.resultStack = result; } - public static ShapedRecipeBuilder shaped(RecipeCategory p_250853_, ItemLike p_249747_) { -@@ -46,6 +_,10 @@ - return new ShapedRecipeBuilder(p_251325_, p_250636_, p_249081_); + public static ShapedRecipeBuilder shaped(HolderGetter p_364036_, RecipeCategory p_250853_, ItemLike p_249747_) { +@@ -50,6 +_,10 @@ + return new ShapedRecipeBuilder(p_365019_, p_251325_, p_250636_, p_249081_); } -+ public static ShapedRecipeBuilder shaped(RecipeCategory p_251325_, ItemStack result) { -+ return new ShapedRecipeBuilder(p_251325_, result); ++ public static ShapedRecipeBuilder shaped(HolderGetter p_365019_, RecipeCategory p_251325_, ItemStack result) { ++ return new ShapedRecipeBuilder(p_365019_, p_251325_, result); + } + public ShapedRecipeBuilder define(Character p_206417_, TagKey p_206418_) { - return this.define(p_206417_, Ingredient.of(p_206418_)); + return this.define(p_206417_, Ingredient.of(this.items.getOrThrow(p_206418_))); } -@@ -106,7 +_,7 @@ +@@ -110,7 +_,7 @@ Objects.requireNonNullElse(this.group, ""), RecipeBuilder.determineBookCategory(this.category), shapedrecipepattern, @@ -44,4 +45,4 @@ + this.resultStack, this.showNotification ); - p_301098_.accept(p_126142_, shapedrecipe, advancement$builder.build(p_126142_.withPrefix("recipes/" + this.category.getFolderName() + "/"))); + p_301098_.accept(p_380072_, shapedrecipe, advancement$builder.build(p_380072_.location().withPrefix("recipes/" + this.category.getFolderName() + "/"))); diff --git a/patches/net/minecraft/data/recipes/ShapelessRecipeBuilder.java.patch b/patches/net/minecraft/data/recipes/ShapelessRecipeBuilder.java.patch deleted file mode 100644 index 27ab5b58ad..0000000000 --- a/patches/net/minecraft/data/recipes/ShapelessRecipeBuilder.java.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- a/net/minecraft/data/recipes/ShapelessRecipeBuilder.java -+++ b/net/minecraft/data/recipes/ShapelessRecipeBuilder.java -@@ -22,15 +_,21 @@ - private final RecipeCategory category; - private final Item result; - private final int count; -+ private final ItemStack resultStack; // Neo: add stack result support - private final NonNullList ingredients = NonNullList.create(); - private final Map> criteria = new LinkedHashMap<>(); - @Nullable - private String group; - - public ShapelessRecipeBuilder(RecipeCategory p_250837_, ItemLike p_251897_, int p_252227_) { -+ this(p_250837_, new ItemStack(p_251897_, p_252227_)); -+ } -+ -+ public ShapelessRecipeBuilder(RecipeCategory p_250837_, ItemStack result) { - this.category = p_250837_; -- this.result = p_251897_.asItem(); -- this.count = p_252227_; -+ this.result = result.getItem(); -+ this.count = result.getCount(); -+ this.resultStack = result; - } - - public static ShapelessRecipeBuilder shapeless(RecipeCategory p_250714_, ItemLike p_249659_) { -@@ -41,6 +_,10 @@ - return new ShapelessRecipeBuilder(p_252339_, p_250836_, p_249928_); - } - -+ public static ShapelessRecipeBuilder shapeless(RecipeCategory p_252339_, ItemStack result) { -+ return new ShapelessRecipeBuilder(p_252339_, result); -+ } -+ - public ShapelessRecipeBuilder requires(TagKey p_206420_) { - return this.requires(Ingredient.of(p_206420_)); - } -@@ -95,7 +_,7 @@ - ShapelessRecipe shapelessrecipe = new ShapelessRecipe( - Objects.requireNonNullElse(this.group, ""), - RecipeBuilder.determineBookCategory(this.category), -- new ItemStack(this.result, this.count), -+ this.resultStack, - this.ingredients - ); - p_301215_.accept(p_126206_, shapelessrecipe, advancement$builder.build(p_126206_.withPrefix("recipes/" + this.category.getFolderName() + "/"))); diff --git a/patches/net/minecraft/data/recipes/SimpleCookingRecipeBuilder.java.patch b/patches/net/minecraft/data/recipes/SimpleCookingRecipeBuilder.java.patch index fb0bc660cf..38432d6166 100644 --- a/patches/net/minecraft/data/recipes/SimpleCookingRecipeBuilder.java.patch +++ b/patches/net/minecraft/data/recipes/SimpleCookingRecipeBuilder.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/data/recipes/SimpleCookingRecipeBuilder.java +++ b/net/minecraft/data/recipes/SimpleCookingRecipeBuilder.java -@@ -28,6 +_,7 @@ +@@ -29,6 +_,7 @@ private final RecipeCategory category; private final CookingBookCategory bookCategory; private final Item result; @@ -8,7 +8,7 @@ private final Ingredient ingredient; private final float experience; private final int cookingTime; -@@ -45,9 +_,22 @@ +@@ -46,9 +_,22 @@ int p_250189_, AbstractCookingRecipe.Factory p_311960_ ) { @@ -32,7 +32,7 @@ this.ingredient = p_250362_; this.experience = p_251204_; this.cookingTime = p_250189_; -@@ -86,6 +_,38 @@ +@@ -87,6 +_,38 @@ return new SimpleCookingRecipeBuilder(p_250319_, CookingBookCategory.FOOD, p_250377_, p_248930_, p_252329_, p_250482_, SmokingRecipe::new); } @@ -71,12 +71,12 @@ public SimpleCookingRecipeBuilder unlockedBy(String p_176792_, Criterion p_300970_) { this.criteria.put(p_176792_, p_300970_); return this; -@@ -111,7 +_,7 @@ +@@ -112,7 +_,7 @@ this.criteria.forEach(advancement$builder::addCriterion); AbstractCookingRecipe abstractcookingrecipe = this.factory .create( - Objects.requireNonNullElse(this.group, ""), this.bookCategory, this.ingredient, new ItemStack(this.result), this.experience, this.cookingTime + Objects.requireNonNullElse(this.group, ""), this.bookCategory, this.ingredient, this.stackResult, this.experience, this.cookingTime ); - p_301266_.accept(p_126264_, abstractcookingrecipe, advancement$builder.build(p_126264_.withPrefix("recipes/" + this.category.getFolderName() + "/"))); - } + p_301266_.accept( + p_380371_, abstractcookingrecipe, advancement$builder.build(p_380371_.location().withPrefix("recipes/" + this.category.getFolderName() + "/")) diff --git a/patches/net/minecraft/data/registries/RegistriesDatapackGenerator.java.patch b/patches/net/minecraft/data/registries/RegistriesDatapackGenerator.java.patch index 53007c8fe3..6619051d3d 100644 --- a/patches/net/minecraft/data/registries/RegistriesDatapackGenerator.java.patch +++ b/patches/net/minecraft/data/registries/RegistriesDatapackGenerator.java.patch @@ -48,10 +48,10 @@ + var conditionalCodec = net.neoforged.neoforge.common.conditions.ConditionalOps.createConditionalCodecWithConditions(p_256449_.elementCodec()); return p_256492_.lookup(resourcekey) .map( - p_349921_ -> { + p_367836_ -> { PackOutput.PathProvider packoutput$pathprovider = this.output.createRegistryElementsPathProvider(resourcekey); return CompletableFuture.allOf( - p_349921_.listElements() + p_367836_.listElements() + .filter(holder -> this.namespacePredicate.test(holder.key().location().getNamespace())) .map( p_256105_ -> dumpValue( diff --git a/patches/net/minecraft/data/registries/RegistryPatchGenerator.java.patch b/patches/net/minecraft/data/registries/RegistryPatchGenerator.java.patch index 29eceb38e7..d7b34a0cb0 100644 --- a/patches/net/minecraft/data/registries/RegistryPatchGenerator.java.patch +++ b/patches/net/minecraft/data/registries/RegistryPatchGenerator.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/data/registries/RegistryPatchGenerator.java +++ b/net/minecraft/data/registries/RegistryPatchGenerator.java -@@ -20,7 +_,7 @@ +@@ -21,7 +_,7 @@ p_311522_ -> { RegistryAccess.Frozen registryaccess$frozen = RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY); Cloner.Factory cloner$factory = new Cloner.Factory(); diff --git a/patches/net/minecraft/data/registries/VanillaRegistries.java.patch b/patches/net/minecraft/data/registries/VanillaRegistries.java.patch index 94e1887dfc..2831c7f25b 100644 --- a/patches/net/minecraft/data/registries/VanillaRegistries.java.patch +++ b/patches/net/minecraft/data/registries/VanillaRegistries.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/data/registries/VanillaRegistries.java +++ b/net/minecraft/data/registries/VanillaRegistries.java -@@ -68,6 +_,7 @@ - .add(Registries.ENCHANTMENT, Enchantments::bootstrap) +@@ -72,6 +_,7 @@ .add(Registries.ENCHANTMENT_PROVIDER, VanillaEnchantmentProviders::bootstrap) - .add(Registries.JUKEBOX_SONG, JukeboxSongs::bootstrap); + .add(Registries.JUKEBOX_SONG, JukeboxSongs::bootstrap) + .add(Registries.INSTRUMENT, Instruments::bootstrap); + public static final List>> DATAPACK_REGISTRY_KEYS = BUILDER.getEntryKeys(); private static void validateThatAllBiomeFeaturesHaveBiomeFilter(HolderLookup.Provider p_256242_) { diff --git a/patches/net/minecraft/gametest/framework/GameTestInfo.java.patch b/patches/net/minecraft/gametest/framework/GameTestInfo.java.patch index 6d77cc9d23..2081e074ab 100644 --- a/patches/net/minecraft/gametest/framework/GameTestInfo.java.patch +++ b/patches/net/minecraft/gametest/framework/GameTestInfo.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/gametest/framework/GameTestInfo.java +++ b/net/minecraft/gametest/framework/GameTestInfo.java -@@ -264,6 +_,7 @@ +@@ -268,6 +_,7 @@ BlockPos blockpos = this.getOrCalculateNorthwestCorner(); this.structureBlockEntity = StructureUtils.prepareTestStructure(this, blockpos, this.getRotation(), this.level); this.structureBlockPos = this.structureBlockEntity.getBlockPos(); diff --git a/patches/net/minecraft/gametest/framework/GameTestServer.java.patch b/patches/net/minecraft/gametest/framework/GameTestServer.java.patch index 162c353781..e648ea2aa8 100644 --- a/patches/net/minecraft/gametest/framework/GameTestServer.java.patch +++ b/patches/net/minecraft/gametest/framework/GameTestServer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/gametest/framework/GameTestServer.java +++ b/net/minecraft/gametest/framework/GameTestServer.java -@@ -151,6 +_,7 @@ +@@ -155,6 +_,7 @@ public boolean initServer() { this.setPlayerList(new PlayerList(this, this.registries(), this.playerDataStorage, 1) { }); @@ -8,7 +8,7 @@ this.loadLevel(); ServerLevel serverlevel = this.overworld(); this.testBatches = Lists.newArrayList(GameTestBatchFactory.fromTestFunction(this.testFunctions, serverlevel)); -@@ -158,6 +_,7 @@ +@@ -162,6 +_,7 @@ int i = 20000000; serverlevel.setWeatherParameters(20000000, 20000000, false, false); LOGGER.info("Started game test server"); diff --git a/patches/net/minecraft/gametest/framework/TestCommand.java.patch b/patches/net/minecraft/gametest/framework/TestCommand.java.patch index 9bfb27eae4..7bc73f3e4e 100644 --- a/patches/net/minecraft/gametest/framework/TestCommand.java.patch +++ b/patches/net/minecraft/gametest/framework/TestCommand.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/gametest/framework/TestCommand.java +++ b/net/minecraft/gametest/framework/TestCommand.java -@@ -361,7 +_,7 @@ +@@ -363,7 +_,7 @@ } else { BlockPos blockpos1 = blockpos.subtract(optional.get()); String s = blockpos1.getX() + ", " + blockpos1.getY() + ", " + blockpos1.getZ(); diff --git a/patches/net/minecraft/locale/Language.java.patch b/patches/net/minecraft/locale/Language.java.patch index 9f3cb451af..6ca12f12ea 100644 --- a/patches/net/minecraft/locale/Language.java.patch +++ b/patches/net/minecraft/locale/Language.java.patch @@ -1,19 +1,20 @@ --- a/net/minecraft/locale/Language.java +++ b/net/minecraft/locale/Language.java -@@ -36,8 +_,10 @@ - private static Language loadDefault() { - Builder builder = ImmutableMap.builder(); - BiConsumer biconsumer = builder::put; +@@ -36,9 +_,11 @@ + DeprecatedTranslationsInfo deprecatedtranslationsinfo = DeprecatedTranslationsInfo.loadFromDefaultResource(); + Map map = new HashMap<>(); + BiConsumer biconsumer = map::put; - parseTranslations(biconsumer, "/assets/minecraft/lang/en_us.json"); -- final Map map = builder.build(); + Map componentMap = new java.util.HashMap<>(); + parseTranslations(biconsumer, componentMap::put, "/assets/minecraft/lang/en_us.json"); -+ final Map map = new java.util.HashMap<>(builder.build()); + deprecatedtranslationsinfo.applyToMap(map); +- final Map map1 = Map.copyOf(map); ++ final Map map1 = map; // Neo keep the map mutable to make LanguageHook work + net.neoforged.neoforge.server.LanguageHook.captureLanguageMap(map, componentMap); return new Language() { @Override public String getOrDefault(String p_128127_, String p_265421_) { -@@ -64,21 +_,51 @@ +@@ -65,21 +_,51 @@ ) .isPresent(); } @@ -66,14 +67,14 @@ String s = UNSUPPORTED_FORMAT_PATTERN.matcher(GsonHelper.convertToString(entry.getValue(), entry.getKey())).replaceAll("%$1s"); p_128110_.accept(entry.getKey(), s); } -@@ -90,6 +_,13 @@ +@@ -91,6 +_,13 @@ public static void inject(Language p_128115_) { instance = p_128115_; + } + + // Neo: All helpers methods below are injected by Neo to ease modder's usage of Language -+ public Map getLanguageData() { return ImmutableMap.of(); } ++ public Map getLanguageData() { return com.google.common.collect.ImmutableMap.of(); } + + public @org.jetbrains.annotations.Nullable net.minecraft.network.chat.Component getComponent(String key) { + return null; diff --git a/patches/net/minecraft/network/FriendlyByteBuf.java.patch b/patches/net/minecraft/network/FriendlyByteBuf.java.patch index 5f72bfa0a5..b6e2de94ff 100644 --- a/patches/net/minecraft/network/FriendlyByteBuf.java.patch +++ b/patches/net/minecraft/network/FriendlyByteBuf.java.patch @@ -9,7 +9,7 @@ public static final int DEFAULT_NBT_QUOTA = 2097152; private final ByteBuf source; public static final short MAX_STRING_LENGTH = 32767; -@@ -1588,5 +_,10 @@ +@@ -1623,5 +_,10 @@ @Override public boolean release(int p_130347_) { return this.source.release(p_130347_); diff --git a/patches/net/minecraft/network/codec/ByteBufCodecs.java.patch b/patches/net/minecraft/network/codec/ByteBufCodecs.java.patch index b05fe14e4a..ac8e4a2731 100644 --- a/patches/net/minecraft/network/codec/ByteBufCodecs.java.patch +++ b/patches/net/minecraft/network/codec/ByteBufCodecs.java.patch @@ -1,19 +1,19 @@ --- a/net/minecraft/network/codec/ByteBufCodecs.java +++ b/net/minecraft/network/codec/ByteBufCodecs.java -@@ -463,7 +_,11 @@ +@@ -487,7 +_,11 @@ ) { return new StreamCodec() { - private IdMap getRegistryOrThrow(RegistryFriendlyByteBuf p_330361_) { -- return p_320353_.apply(p_330361_.registryAccess().registryOrThrow(p_319942_)); -+ var registry = p_330361_.registryAccess().registryOrThrow(p_319942_); + private IdMap getRegistryOrThrow(RegistryFriendlyByteBuf p_362297_) { +- return p_320353_.apply(p_362297_.registryAccess().lookupOrThrow(p_319942_)); ++ var registry = p_362297_.registryAccess().lookupOrThrow(p_319942_); + if (net.neoforged.neoforge.registries.RegistryManager.isNonSyncedBuiltInRegistry(registry)) { + throw new IllegalStateException("Cannot use ID syncing for non-synced built-in registry: " + registry.key()); + } + return p_320353_.apply(registry); } - public R decode(RegistryFriendlyByteBuf p_331253_) { -@@ -520,8 +_,25 @@ + public R decode(RegistryFriendlyByteBuf p_340887_) { +@@ -544,8 +_,25 @@ private static final int NAMED_SET = -1; private final StreamCodec> holderCodec = ByteBufCodecs.holderRegistry(p_332137_); @@ -27,31 +27,31 @@ + return (H) holderSet; + } + - public HolderSet decode(RegistryFriendlyByteBuf p_340887_) { - int i = VarInt.read(p_340887_) - 1; + public HolderSet decode(RegistryFriendlyByteBuf p_376912_) { + int i = VarInt.read(p_376912_) - 1; + // Neo: Co-opt negative VarInt values within the HolderSet codec as an HolderSetType id. + // Vanilla uses 0 for tag and [1, Integer.MAX_VALUE] for list size [0, Integer.MAX_VALUE - 1]. + // So we may encode the registry id for custom holder set types in [Integer.MIN_VALUE + 1, -1] (local variable i must not be underflow). + // The registry id for custom holder set types is (-1 - network id), while local variable i is (network id - 1), so the registry id would be (-2 - i). + if (i < -1) { -+ return this.holderSetCodec(net.neoforged.neoforge.registries.NeoForgeRegistries.HOLDER_SET_TYPES.byIdOrThrow(-2 - i)).decode(p_340887_); ++ return this.holderSetCodec(net.neoforged.neoforge.registries.NeoForgeRegistries.HOLDER_SET_TYPES.byIdOrThrow(-2 - i)).decode(p_376912_); + } if (i == -1) { - Registry registry = p_340887_.registryAccess().registryOrThrow(p_332137_); - return registry.getTag(TagKey.create(p_332137_, ResourceLocation.STREAM_CODEC.decode(p_340887_))).orElseThrow(); -@@ -537,6 +_,15 @@ + Registry registry = p_376912_.registryAccess().lookupOrThrow(p_332137_); + return registry.get(TagKey.create(p_332137_, ResourceLocation.STREAM_CODEC.decode(p_376912_))).orElseThrow(); +@@ -561,6 +_,15 @@ } - public void encode(RegistryFriendlyByteBuf p_341009_, HolderSet p_340834_) { + public void encode(RegistryFriendlyByteBuf p_376382_, HolderSet p_376430_) { + // Neo: Co-opt negative VarInt values within the HolderSet codec as an HolderSetType id. + // Vanilla uses 0 for tag and [1, Integer.MAX_VALUE] for list size [0, Integer.MAX_VALUE - 1] (local variable i in decode() must not be underflow). + // So we may encode the registry id for custom holder set types in [Integer.MIN_VALUE + 1, -1]. + // The network id for custom holder set types is (-1 - registry id) -+ if (p_341009_.getConnectionType().isNeoForge() && p_340834_ instanceof net.neoforged.neoforge.registries.holdersets.ICustomHolderSet customHolderSet) { -+ VarInt.write(p_341009_, -1 - net.neoforged.neoforge.registries.NeoForgeRegistries.HOLDER_SET_TYPES.getId(customHolderSet.type())); -+ this.holderSetCodec(customHolderSet.type()).encode(p_341009_, cast(customHolderSet)); ++ if (p_376382_.getConnectionType().isNeoForge() && p_376430_ instanceof net.neoforged.neoforge.registries.holdersets.ICustomHolderSet customHolderSet) { ++ VarInt.write(p_376382_, -1 - net.neoforged.neoforge.registries.NeoForgeRegistries.HOLDER_SET_TYPES.getId(customHolderSet.type())); ++ this.holderSetCodec(customHolderSet.type()).encode(p_376382_, cast(customHolderSet)); + return; + } - Optional> optional = p_340834_.unwrapKey(); + Optional> optional = p_376430_.unwrapKey(); if (optional.isPresent()) { - VarInt.write(p_341009_, 0); + VarInt.write(p_376382_, 0); diff --git a/patches/net/minecraft/network/protocol/common/ClientCommonPacketListener.java.patch b/patches/net/minecraft/network/protocol/common/ClientCommonPacketListener.java.patch index f9a18764ed..1b6b85fcf9 100644 --- a/patches/net/minecraft/network/protocol/common/ClientCommonPacketListener.java.patch +++ b/patches/net/minecraft/network/protocol/common/ClientCommonPacketListener.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/network/protocol/common/ClientCommonPacketListener.java +++ b/net/minecraft/network/protocol/common/ClientCommonPacketListener.java -@@ -3,7 +_,7 @@ - import net.minecraft.network.ClientboundPacketListener; +@@ -2,7 +_,7 @@ + import net.minecraft.network.protocol.cookie.ClientCookiePacketListener; --public interface ClientCommonPacketListener extends ClientCookiePacketListener, ClientboundPacketListener { -+public interface ClientCommonPacketListener extends ClientCookiePacketListener, ClientboundPacketListener, net.neoforged.neoforge.common.extensions.IClientCommonPacketListenerExtension { +-public interface ClientCommonPacketListener extends ClientCookiePacketListener { ++public interface ClientCommonPacketListener extends ClientCookiePacketListener, net.neoforged.neoforge.common.extensions.IClientCommonPacketListenerExtension { void handleKeepAlive(ClientboundKeepAlivePacket p_295236_); void handlePing(ClientboundPingPacket p_296451_); diff --git a/patches/net/minecraft/network/protocol/common/ClientboundCustomPayloadPacket.java.patch b/patches/net/minecraft/network/protocol/common/ClientboundCustomPayloadPacket.java.patch index f17a187ea5..f36844e8e2 100644 --- a/patches/net/minecraft/network/protocol/common/ClientboundCustomPayloadPacket.java.patch +++ b/patches/net/minecraft/network/protocol/common/ClientboundCustomPayloadPacket.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/network/protocol/common/ClientboundCustomPayloadPacket.java +++ b/net/minecraft/network/protocol/common/ClientboundCustomPayloadPacket.java -@@ -60,12 +_,16 @@ +@@ -62,12 +_,16 @@ ), p_333492_ -> { } diff --git a/patches/net/minecraft/network/protocol/common/ServerCommonPacketListener.java.patch b/patches/net/minecraft/network/protocol/common/ServerCommonPacketListener.java.patch index bb57676d72..c503189ba1 100644 --- a/patches/net/minecraft/network/protocol/common/ServerCommonPacketListener.java.patch +++ b/patches/net/minecraft/network/protocol/common/ServerCommonPacketListener.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/network/protocol/common/ServerCommonPacketListener.java +++ b/net/minecraft/network/protocol/common/ServerCommonPacketListener.java -@@ -3,7 +_,7 @@ +@@ -2,7 +_,7 @@ + import net.minecraft.network.protocol.cookie.ServerCookiePacketListener; - import net.minecraft.network.protocol.game.ServerPacketListener; --public interface ServerCommonPacketListener extends ServerCookiePacketListener, ServerPacketListener { -+public interface ServerCommonPacketListener extends ServerCookiePacketListener, ServerPacketListener, net.neoforged.neoforge.common.extensions.IServerCommonPacketListenerExtension { +-public interface ServerCommonPacketListener extends ServerCookiePacketListener { ++public interface ServerCommonPacketListener extends ServerCookiePacketListener, net.neoforged.neoforge.common.extensions.IServerCommonPacketListenerExtension { void handleKeepAlive(ServerboundKeepAlivePacket p_296457_); void handlePong(ServerboundPongPacket p_294309_); diff --git a/patches/net/minecraft/network/protocol/game/ServerGamePacketListener.java.patch b/patches/net/minecraft/network/protocol/game/ServerGamePacketListener.java.patch index 141ddf719f..f24f3d2b43 100644 --- a/patches/net/minecraft/network/protocol/game/ServerGamePacketListener.java.patch +++ b/patches/net/minecraft/network/protocol/game/ServerGamePacketListener.java.patch @@ -4,8 +4,8 @@ import net.minecraft.network.protocol.common.ServerCommonPacketListener; import net.minecraft.network.protocol.ping.ServerPingPacketListener; --public interface ServerGamePacketListener extends ServerPingPacketListener, ServerCommonPacketListener { -+public interface ServerGamePacketListener extends ServerPingPacketListener, ServerCommonPacketListener, net.neoforged.neoforge.common.extensions.IServerGamePacketListenerExtension { +-public interface ServerGamePacketListener extends ServerCommonPacketListener, ServerPingPacketListener { ++public interface ServerGamePacketListener extends ServerCommonPacketListener, ServerPingPacketListener, net.neoforged.neoforge.common.extensions.IServerGamePacketListenerExtension { @Override default ConnectionProtocol protocol() { return ConnectionProtocol.PLAY; diff --git a/patches/net/minecraft/resources/RegistryDataLoader.java.patch b/patches/net/minecraft/resources/RegistryDataLoader.java.patch index 13d15f4bb3..4a24d6d0f3 100644 --- a/patches/net/minecraft/resources/RegistryDataLoader.java.patch +++ b/patches/net/minecraft/resources/RegistryDataLoader.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/resources/RegistryDataLoader.java +++ b/net/minecraft/resources/RegistryDataLoader.java -@@ -100,7 +_,7 @@ +@@ -112,7 +_,7 @@ public static final List> DIMENSION_REGISTRIES = List.of( new RegistryDataLoader.RegistryData<>(Registries.LEVEL_STEM, LevelStem.CODEC) ); @@ -9,16 +9,16 @@ new RegistryDataLoader.RegistryData<>(Registries.BIOME, Biome.NETWORK_CODEC), new RegistryDataLoader.RegistryData<>(Registries.CHAT_TYPE, ChatType.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.TRIM_PATTERN, TrimPattern.DIRECT_CODEC), -@@ -112,7 +_,7 @@ - new RegistryDataLoader.RegistryData<>(Registries.BANNER_PATTERN, BannerPattern.DIRECT_CODEC), +@@ -125,7 +_,7 @@ new RegistryDataLoader.RegistryData<>(Registries.ENCHANTMENT, Enchantment.DIRECT_CODEC), - new RegistryDataLoader.RegistryData<>(Registries.JUKEBOX_SONG, JukeboxSong.DIRECT_CODEC) + new RegistryDataLoader.RegistryData<>(Registries.JUKEBOX_SONG, JukeboxSong.DIRECT_CODEC), + new RegistryDataLoader.RegistryData<>(Registries.INSTRUMENT, Instrument.DIRECT_CODEC) - ); + )); // Neo: Keep the list so custom registries can be added later - public static RegistryAccess.Frozen load(ResourceManager p_252046_, RegistryAccess p_249916_, List> p_250344_) { - return load((p_321412_, p_321413_) -> p_321412_.loadFromResources(p_252046_, p_321413_), p_249916_, p_250344_); -@@ -204,11 +_,16 @@ + public static RegistryAccess.Frozen load( + ResourceManager p_364116_, List> p_321716_, List> p_365382_ +@@ -247,11 +_,16 @@ Resource p_326141_, RegistrationInfo p_326033_ ) throws IOException { @@ -37,7 +37,7 @@ } } -@@ -221,7 +_,7 @@ +@@ -264,7 +_,7 @@ ) { String s = Registries.elementsDirPath(p_321557_.key()); FileToIdConverter filetoidconverter = FileToIdConverter.json(s); @@ -46,8 +46,8 @@ for (Entry entry : filetoidconverter.listMatchingResources(p_321535_).entrySet()) { ResourceLocation resourcelocation = entry.getKey(); -@@ -304,13 +_,20 @@ - void apply(RegistryDataLoader.Loader p_321864_, RegistryOps.RegistryInfoLookup p_321656_); +@@ -354,13 +_,20 @@ + public static record NetworkedRegistryData(List elements, TagNetworkSerialization.NetworkPayload tags) { } - public static record RegistryData(ResourceKey> key, Codec elementCodec, boolean requiredNonEmpty) { diff --git a/patches/net/minecraft/server/Bootstrap.java.patch b/patches/net/minecraft/server/Bootstrap.java.patch index 1aaee96a57..e775eb5eea 100644 --- a/patches/net/minecraft/server/Bootstrap.java.patch +++ b/patches/net/minecraft/server/Bootstrap.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/Bootstrap.java +++ b/net/minecraft/server/Bootstrap.java -@@ -52,6 +_,8 @@ +@@ -53,6 +_,8 @@ CauldronInteraction.bootStrap(); BuiltInRegistries.bootStrap(); CreativeModeTabs.validate(); @@ -9,7 +9,7 @@ wrapStreams(); bootstrapDuration.set(Duration.between(instant, Instant.now()).toMillis()); } -@@ -117,7 +_,6 @@ +@@ -119,7 +_,6 @@ Commands.validate(); } diff --git a/patches/net/minecraft/server/Main.java.patch b/patches/net/minecraft/server/Main.java.patch index 786a375e82..e32cfe17d8 100644 --- a/patches/net/minecraft/server/Main.java.patch +++ b/patches/net/minecraft/server/Main.java.patch @@ -86,14 +86,14 @@ LOGGER.error("Failed to load world data from {}", levelstoragesource$leveldirectory.oldDataFile(), ioexception); LOGGER.error( @@ -214,6 +_,9 @@ - worlddimensions = dedicatedserverproperties.createDimensions(p_307161_.datapackWorldgen()); + worlddimensions = dedicatedserverproperties.createDimensions(p_359487_.datapackWorldgen()); } + // Neo: Do a write-read-cycle to inject modded dimensions on first start of a dedicated server into its generated world dimensions list. -+ var registryOps = net.minecraft.resources.RegistryOps.create(net.minecraft.nbt.NbtOps.INSTANCE, p_307161_.datapackWorldgen()); ++ var registryOps = net.minecraft.resources.RegistryOps.create(net.minecraft.nbt.NbtOps.INSTANCE, p_359487_.datapackWorldgen()); + worlddimensions = WorldDimensions.CODEC.encoder().encodeStart(registryOps, worlddimensions).flatMap((writtenPayloadWithModdedDimensions) -> WorldDimensions.CODEC.decoder().parse(registryOps, writtenPayloadWithModdedDimensions)).resultOrPartial(LOGGER::error).orElse(worlddimensions); WorldDimensions.Complete worlddimensions$complete = worlddimensions.bake(registry); - Lifecycle lifecycle = worlddimensions$complete.lifecycle().add(p_307161_.datapackWorldgen().allRegistriesLifecycle()); + Lifecycle lifecycle = worlddimensions$complete.lifecycle().add(p_359487_.datapackWorldgen().allRegistriesLifecycle()); return new WorldLoader.DataLoadOutput<>( @@ -246,24 +_,22 @@ diff --git a/patches/net/minecraft/server/MinecraftServer.java.patch b/patches/net/minecraft/server/MinecraftServer.java.patch index cebd24b556..f6874df74e 100644 --- a/patches/net/minecraft/server/MinecraftServer.java.patch +++ b/patches/net/minecraft/server/MinecraftServer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -264,7 +_,7 @@ +@@ -275,7 +_,7 @@ public static S spin(Function p_129873_) { AtomicReference atomicreference = new AtomicReference<>(); @@ -9,16 +9,19 @@ thread.setUncaughtExceptionHandler((p_177909_, p_177910_) -> LOGGER.error("Uncaught exception in server thread", p_177910_)); if (Runtime.getRuntime().availableProcessors() > 4) { thread.setPriority(8); -@@ -315,7 +_,7 @@ +@@ -325,9 +_,9 @@ this.structureTemplateManager = new StructureTemplateManager(p_236726_.resourceManager(), p_236724_, p_236728_, holdergetter); this.serverThread = p_236723_; this.executor = Util.backgroundExecutor(); - this.potionBrewing = PotionBrewing.bootstrap(this.worldData.enabledFeatures()); + this.potionBrewing = PotionBrewing.bootstrap(this.worldData.enabledFeatures(), this.registryAccess()); + this.resources.managers.getRecipeManager().finalizeRecipeLoading(this.worldData.enabledFeatures()); +- this.fuelValues = FuelValues.vanillaBurnTimes(this.registries.compositeAccess(), this.worldData.enabledFeatures()); ++ this.fuelValues = net.neoforged.neoforge.common.DataMapHooks.populateFuelValues(this.registries.compositeAccess(), this.worldData.enabledFeatures()); + this.tickFrame = TracyClient.createDiscontinuousFrame("Server Tick"); } } - -@@ -372,6 +_,7 @@ +@@ -385,6 +_,7 @@ this.readScoreboard(dimensiondatastorage); this.commandStorage = new CommandStorage(dimensiondatastorage); WorldBorder worldborder = serverlevel.getWorldBorder(); @@ -26,7 +29,7 @@ if (!serverleveldata.isInitialized()) { try { setInitialSpawn(serverlevel, serverleveldata, worldoptions.generateBonusChest(), flag); -@@ -421,6 +_,7 @@ +@@ -434,6 +_,7 @@ ); worldborder.addListener(new BorderChangeListener.DelegateBorderChangeListener(serverlevel1.getWorldBorder())); this.levels.put(resourcekey1, serverlevel1); @@ -34,15 +37,15 @@ } } -@@ -432,6 +_,7 @@ +@@ -445,6 +_,7 @@ p_177898_.setSpawn(BlockPos.ZERO.above(80), 0.0F); } else { ServerChunkCache serverchunkcache = p_177897_.getChunkSource(); + if (net.neoforged.neoforge.event.EventHooks.onCreateWorldSpawn(p_177897_, p_177898_)) return; ChunkPos chunkpos = new ChunkPos(serverchunkcache.randomState().sampler().findSpawnPosition()); int i = serverchunkcache.getGenerator().getSpawnHeight(p_177897_); - if (i < p_177897_.getMinBuildHeight()) { -@@ -513,6 +_,7 @@ + if (i < p_177897_.getMinY()) { +@@ -526,6 +_,7 @@ ChunkPos chunkpos = new ChunkPos(k); serverlevel1.getChunkSource().updateChunkForced(chunkpos, true); } @@ -50,7 +53,7 @@ } } -@@ -620,6 +_,7 @@ +@@ -633,6 +_,7 @@ for (ServerLevel serverlevel2 : this.getAllLevels()) { if (serverlevel2 != null) { try { @@ -58,7 +61,7 @@ serverlevel2.close(); } catch (IOException ioexception1) { LOGGER.error("Exception closing the level", (Throwable)ioexception1); -@@ -666,9 +_,11 @@ +@@ -679,9 +_,11 @@ throw new IllegalStateException("Failed to initialize server"); } @@ -70,16 +73,16 @@ while (this.running) { long i; -@@ -714,6 +_,8 @@ +@@ -734,6 +_,8 @@ this.isReady = true; JvmProfiler.INSTANCE.onServerTick(this.smoothedTickTimeMillis); } + net.neoforged.neoforge.server.ServerLifecycleHooks.handleServerStopping(this); + net.neoforged.neoforge.server.ServerLifecycleHooks.expectServerStopped(); // Forge: Has to come before MinecraftServer#onServerCrash to avoid race conditions - } catch (Throwable throwable1) { - LOGGER.error("Encountered an unexpected exception", throwable1); - CrashReport crashreport = constructOrExtractCrashReport(throwable1); -@@ -725,6 +_,7 @@ + } catch (Throwable throwable2) { + LOGGER.error("Encountered an unexpected exception", throwable2); + CrashReport crashreport = constructOrExtractCrashReport(throwable2); +@@ -745,6 +_,7 @@ LOGGER.error("We were unable to save this crash report to disk."); } @@ -87,7 +90,7 @@ this.onServerCrash(crashreport); } finally { try { -@@ -737,6 +_,7 @@ +@@ -757,6 +_,7 @@ this.services.profileCache().clearExecutor(); } @@ -95,9 +98,9 @@ this.onServerExit(); } } -@@ -901,11 +_,13 @@ - public void tickServer(BooleanSupplier p_129871_) { - long i = Util.getNanos(); +@@ -947,11 +_,13 @@ + } + this.tickCount++; + net.neoforged.neoforge.event.EventHooks.fireServerTickPre(p_129871_, this); this.tickRateManager.tick(); @@ -109,15 +112,15 @@ } this.ticksUntilAutosave--; -@@ -927,6 +_,7 @@ - this.smoothedTickTimeMillis = this.smoothedTickTimeMillis * 0.8F + (float)j / (float)TimeUtil.NANOSECONDS_PER_MILLISECOND * 0.19999999F; +@@ -969,6 +_,7 @@ + this.smoothedTickTimeMillis = this.smoothedTickTimeMillis * 0.8F + (float)k / (float)TimeUtil.NANOSECONDS_PER_MILLISECOND * 0.19999999F; this.logTickMethodTime(i); - this.profiler.pop(); + profilerfiller.pop(); + net.neoforged.neoforge.event.EventHooks.fireServerTickPost(p_129871_, this); } - private void logTickMethodTime(long p_321837_) { -@@ -935,6 +_,16 @@ + private void autoSave() { +@@ -987,6 +_,16 @@ } } @@ -134,7 +137,7 @@ private int computeNextAutosaveInterval() { float f; if (this.tickRateManager.isSprinting()) { -@@ -966,7 +_,8 @@ +@@ -1018,7 +_,8 @@ Optional.of(serverstatus$players), Optional.of(ServerStatus.Version.current()), Optional.ofNullable(this.statusIcon), @@ -144,45 +147,45 @@ ); } -@@ -996,7 +_,8 @@ +@@ -1049,7 +_,8 @@ this.getFunctions().tick(); - this.profiler.popPush("levels"); + profilerfiller.popPush("levels"); - for (ServerLevel serverlevel : this.getAllLevels()) { -+ for(ServerLevel serverlevel : this.getWorldArray()) { ++ for (ServerLevel serverlevel : this.getWorldArray()) { + long tickStart = Util.getNanos(); - this.profiler.push(() -> serverlevel + " " + serverlevel.dimension().location()); + profilerfiller.push(() -> serverlevel + " " + serverlevel.dimension().location()); if (this.tickCount % 20 == 0) { - this.profiler.push("timeSync"); -@@ -1005,6 +_,7 @@ + profilerfiller.push("timeSync"); +@@ -1058,6 +_,7 @@ } - this.profiler.push("tick"); + profilerfiller.push("tick"); + net.neoforged.neoforge.event.EventHooks.fireLevelTickPre(serverlevel, p_129954_); try { serverlevel.tick(p_129954_); -@@ -1013,16 +_,18 @@ +@@ -1066,16 +_,18 @@ serverlevel.fillReportDetails(crashreport); throw new ReportedException(crashreport); } + net.neoforged.neoforge.event.EventHooks.fireLevelTickPost(serverlevel, p_129954_); - this.profiler.pop(); - this.profiler.pop(); + profilerfiller.pop(); + profilerfiller.pop(); + perWorldTickTimes.computeIfAbsent(serverlevel.dimension(), k -> new long[100])[this.tickCount % 100] = Util.getNanos() - tickStart; } - this.profiler.popPush("connection"); - this.getConnection().tick(); - this.profiler.popPush("players"); + profilerfiller.popPush("connection"); + this.tickConnection(); + profilerfiller.popPush("players"); this.playerList.tick(); - if (SharedConstants.IS_RUNNING_IN_IDE && this.tickRateManager.runsNormally()) { + if (net.neoforged.neoforge.gametest.GameTestHooks.isGametestEnabled() && this.tickRateManager.runsNormally()) { GameTestTicker.SINGLETON.tick(); } -@@ -1043,11 +_,17 @@ +@@ -1100,11 +_,17 @@ } private void synchronizeTime(ServerLevel p_276371_) { @@ -205,7 +208,7 @@ } public void forceTimeSynchronization() { -@@ -1118,7 +_,7 @@ +@@ -1176,7 +_,7 @@ @DontObfuscate public String getServerModName() { @@ -214,7 +217,7 @@ } public SystemReport fillSystemReport(SystemReport p_177936_) { -@@ -1441,7 +_,7 @@ +@@ -1492,7 +_,7 @@ public CompletableFuture reloadResources(Collection p_129862_) { CompletableFuture completablefuture = CompletableFuture.supplyAsync( @@ -223,15 +226,17 @@ this ) .thenCompose( -@@ -1478,6 +_,7 @@ +@@ -1532,7 +_,8 @@ this.getPlayerList().reloadResources(); this.functionManager.replaceLibrary(this.resources.managers.getFunctionLibrary()); this.structureTemplateManager.onResourceManagerReload(this.resources.resourceManager); +- this.fuelValues = FuelValues.vanillaBurnTimes(this.registries.compositeAccess(), this.worldData.enabledFeatures()); ++ this.fuelValues = net.neoforged.neoforge.common.DataMapHooks.populateFuelValues(this.registries.compositeAccess(), this.worldData.enabledFeatures()); + this.getPlayerList().getPlayers().forEach(this.getPlayerList()::sendPlayerPermissionLevel); //Forge: Fix newly added/modified commands not being sent to the client when commands reload. }, this ); -@@ -1495,8 +_,10 @@ +@@ -1550,8 +_,10 @@ FeatureFlagSet featureflagset = p_249869_ ? FeatureFlagSet.of() : p_341632_.enabledFeatures(); FeatureFlagSet featureflagset1 = p_249869_ ? FeatureFlags.REGISTRY.allFlags() : p_341632_.enabledFeatures(); p_248681_.reload(); @@ -243,7 +248,7 @@ } else { Set set = Sets.newLinkedHashSet(); -@@ -1542,6 +_,8 @@ +@@ -1597,6 +_,8 @@ set.add("vanilla"); } @@ -252,7 +257,7 @@ return configureRepositoryWithSelection(p_248681_, set, featureflagset, true); } } -@@ -1712,6 +_,31 @@ +@@ -1763,6 +_,31 @@ public abstract boolean isSingleplayerOwner(GameProfile p_129840_); @@ -284,7 +289,7 @@ public void dumpServerProperties(Path p_177911_) throws IOException { } -@@ -1873,6 +_,10 @@ +@@ -1921,6 +_,10 @@ public WorldData getWorldData() { return this.worldData; diff --git a/patches/net/minecraft/server/PlayerAdvancements.java.patch b/patches/net/minecraft/server/PlayerAdvancements.java.patch index c1dd7151ec..75e257181e 100644 --- a/patches/net/minecraft/server/PlayerAdvancements.java.patch +++ b/patches/net/minecraft/server/PlayerAdvancements.java.patch @@ -16,9 +16,9 @@ + net.neoforged.neoforge.event.EventHooks.onAdvancementProgressedEvent(this.player, p_300979_, advancementprogress, p_135990_, net.neoforged.neoforge.event.entity.player.AdvancementEvent.AdvancementProgressEvent.ProgressType.GRANT); if (!flag1 && advancementprogress.isDone()) { p_300979_.value().rewards().grant(this.player); - p_300979_.value().display().ifPresent(p_352686_ -> { - if (p_352686_.shouldAnnounceChat() && this.player.level().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) { - this.playerList.broadcastSystemMessage(p_352686_.getType().createAnnouncement(p_300979_, this.player), false); + p_300979_.value().display().ifPresent(p_375474_ -> { + if (p_375474_.shouldAnnounceChat() && this.player.serverLevel().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) { + this.playerList.broadcastSystemMessage(p_375474_.getType().createAnnouncement(p_300979_, this.player), false); } + net.neoforged.neoforge.event.EventHooks.onAdvancementEarnedEvent(this.player, p_300979_); }); diff --git a/patches/net/minecraft/server/ReloadableServerRegistries.java.patch b/patches/net/minecraft/server/ReloadableServerRegistries.java.patch new file mode 100644 index 0000000000..ff31d3b5cf --- /dev/null +++ b/patches/net/minecraft/server/ReloadableServerRegistries.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/server/ReloadableServerRegistries.java ++++ b/net/minecraft/server/ReloadableServerRegistries.java +@@ -61,8 +_,16 @@ + () -> { + WritableRegistry writableregistry = new MappedRegistry<>(p_335741_.registryKey(), Lifecycle.experimental()); + Map map = new HashMap<>(); ++ Map> optionalMap = new HashMap<>(); + String s = Registries.elementsDirPath(p_335741_.registryKey()); +- SimpleJsonResourceReloadListener.scanDirectory(p_335893_, s, p_336173_, p_335741_.codec(), map); ++ SimpleJsonResourceReloadListener.scanDirectory(p_335893_, s, p_336173_, p_335741_.conditionalCodec(), optionalMap); ++ optionalMap.forEach((rl, optionalEntry) -> { ++ optionalEntry.ifPresent(entry -> p_335741_.idSetter().accept(entry, rl)); ++ T value = optionalEntry.orElse(p_335741_.defaultValue()); ++ if (value instanceof LootTable lootTable) value = (T) net.neoforged.neoforge.event.EventHooks.loadLootTable(rl, lootTable); ++ if (value != null) ++ map.put(rl, value); ++ }); + map.forEach( + (p_335721_, p_335683_) -> writableregistry.register( + ResourceKey.create(p_335741_.registryKey(), p_335721_), (T)p_335683_, DEFAULT_REGISTRATION_INFO diff --git a/patches/net/minecraft/server/ReloadableServerResources.java.patch b/patches/net/minecraft/server/ReloadableServerResources.java.patch index cf23f14fbc..4af3bf71c6 100644 --- a/patches/net/minecraft/server/ReloadableServerResources.java.patch +++ b/patches/net/minecraft/server/ReloadableServerResources.java.patch @@ -1,19 +1,21 @@ --- a/net/minecraft/server/ReloadableServerResources.java +++ b/net/minecraft/server/ReloadableServerResources.java -@@ -49,6 +_,8 @@ - this.commands = new Commands(p_206858_, CommandBuildContext.simple(this.registryLookup, p_250695_)); - this.advancements = new ServerAdvancementManager(this.registryLookup); +@@ -41,6 +_,9 @@ + this.commands = new Commands(p_206858_, CommandBuildContext.simple(p_361583_, p_250695_)); + this.advancements = new ServerAdvancementManager(p_361583_); this.functionLibrary = new ServerFunctionLibrary(p_206859_, this.commands.getDispatcher()); -+ // Neo: Create context object -+ this.context = new net.neoforged.neoforge.common.conditions.ConditionContext(this.tagManager); ++ // Neo: Store registries and create context object ++ this.registryLookup = p_361583_; ++ this.context = new net.neoforged.neoforge.common.conditions.ConditionContext(this.postponedTags); } public ServerFunctionLibrary getFunctionLibrary() { -@@ -75,6 +_,24 @@ - return List.of(this.tagManager, this.recipes, this.functionLibrary, this.advancements); +@@ -67,6 +_,25 @@ + return List.of(this.recipes, this.functionLibrary, this.advancements); } -+ private final net.neoforged.neoforge.common.conditions.ICondition.IContext context; ++ private final HolderLookup.Provider registryLookup; ++ private final net.neoforged.neoforge.common.conditions.ConditionContext context; + + /** + * Exposes the current condition context for usage in other reload listeners.
@@ -34,12 +36,12 @@ public static CompletableFuture loadResources( ResourceManager p_248588_, LayeredRegistryAccess p_335667_, -@@ -90,14 +_,27 @@ +@@ -83,10 +_,24 @@ ReloadableServerResources reloadableserverresources = new ReloadableServerResources( - p_335211_.compositeAccess(), p_250212_, p_249301_, p_251126_ + p_359514_.layers(), p_359514_.lookupWithUpdatedTags(), p_250212_, p_249301_, p_363739_, p_251126_ ); + List listeners = new java.util.ArrayList<>(reloadableserverresources.listeners()); -+ listeners.addAll(net.neoforged.neoforge.event.EventHooks.onResourceReload(reloadableserverresources, p_335211_.compositeAccess())); ++ listeners.addAll(net.neoforged.neoforge.event.EventHooks.onResourceReload(reloadableserverresources, p_359514_.layers().compositeAccess())); + listeners.forEach(rl -> { + if (rl instanceof net.neoforged.neoforge.resource.ContextAwareReloadListener srl) srl.injectContext(reloadableserverresources.context, reloadableserverresources.registryLookup); + }); @@ -48,26 +50,22 @@ + p_248588_, listeners, p_249136_, p_249601_, DATA_RELOAD_INITIAL_TASK, LOGGER.isDebugEnabled() ) .done() - .whenComplete( - (p_323178_, p_323179_) -> reloadableserverresources.registryLookup - .missingTagAccessPolicy(ReloadableServerResources.MissingTagAccessPolicy.FAIL) - ) + .thenRun(() -> { + // Clear context after reload completes ++ reloadableserverresources.context.clear(); + listeners.forEach(rl -> { + if (rl instanceof net.neoforged.neoforge.resource.ContextAwareReloadListener srl) { -+ srl.injectContext(net.neoforged.neoforge.common.conditions.ICondition.IContext.EMPTY, RegistryAccess.EMPTY); ++ srl.injectContext(net.neoforged.neoforge.common.conditions.ICondition.IContext.EMPTY, net.minecraft.core.RegistryAccess.EMPTY); + } + }); + }) .thenApply(p_214306_ -> reloadableserverresources); } ); -@@ -107,6 +_,7 @@ - this.tagManager.getResult().forEach(p_335204_ -> updateRegistryTags(this.fullRegistryHolder.get(), (TagManager.LoadResult)p_335204_)); - AbstractFurnaceBlockEntity.invalidateCache(); - Blocks.rebuildCache(); -+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.TagsUpdatedEvent(this.fullRegistryHolder.get(), false, false)); - } +@@ -94,5 +_,6 @@ - private static void updateRegistryTags(RegistryAccess p_206871_, TagManager.LoadResult p_206872_) { + public void updateStaticRegistryTags() { + this.postponedTags.forEach(Registry.PendingTags::apply); ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.TagsUpdatedEvent(registryLookup, false, false)); + } + } diff --git a/patches/net/minecraft/server/ServerAdvancementManager.java.patch b/patches/net/minecraft/server/ServerAdvancementManager.java.patch deleted file mode 100644 index 2448b6d2a0..0000000000 --- a/patches/net/minecraft/server/ServerAdvancementManager.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/net/minecraft/server/ServerAdvancementManager.java -+++ b/net/minecraft/server/ServerAdvancementManager.java -@@ -39,11 +_,15 @@ - } - - protected void apply(Map p_136034_, ResourceManager p_136035_, ProfilerFiller p_136036_) { -- RegistryOps registryops = this.registries.createSerializationContext(JsonOps.INSTANCE); -+ RegistryOps registryops = this.makeConditionalOps(); // Neo: add condition context - Builder builder = ImmutableMap.builder(); - p_136034_.forEach((p_337529_, p_337530_) -> { - try { -- Advancement advancement = Advancement.CODEC.parse(registryops, p_337530_).getOrThrow(JsonParseException::new); -+ Advancement advancement = net.neoforged.neoforge.common.conditions.ICondition.getWithWithConditionsCodec(Advancement.CONDITIONAL_CODEC, registryops, p_337530_).orElse(null); -+ if (advancement == null) { -+ LOGGER.debug("Skipping loading advancement {} as its conditions were not met", p_337529_); -+ return; -+ } - this.validate(p_337529_, advancement); - builder.put(p_337529_, new AdvancementHolder(p_337529_, advancement)); - } catch (Exception exception) { diff --git a/patches/net/minecraft/server/WorldLoader.java.patch b/patches/net/minecraft/server/WorldLoader.java.patch index 67180986ab..807b389724 100644 --- a/patches/net/minecraft/server/WorldLoader.java.patch +++ b/patches/net/minecraft/server/WorldLoader.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/server/WorldLoader.java +++ b/net/minecraft/server/WorldLoader.java -@@ -33,7 +_,7 @@ - CloseableResourceManager closeableresourcemanager = pair.getSecond(); - LayeredRegistryAccess layeredregistryaccess = RegistryLayer.createRegistryAccess(); - LayeredRegistryAccess layeredregistryaccess1 = loadAndReplaceLayer( -- closeableresourcemanager, layeredregistryaccess, RegistryLayer.WORLDGEN, RegistryDataLoader.WORLDGEN_REGISTRIES -+ closeableresourcemanager, layeredregistryaccess, RegistryLayer.WORLDGEN, net.neoforged.neoforge.registries.DataPackRegistriesHooks.getDataPackRegistries() +@@ -41,7 +_,7 @@ ); - RegistryAccess.Frozen registryaccess$frozen = layeredregistryaccess1.getAccessForLoading(RegistryLayer.DIMENSIONS); - RegistryAccess.Frozen registryaccess$frozen1 = RegistryDataLoader.load( + RegistryAccess.Frozen registryaccess$frozen = layeredregistryaccess.getAccessForLoading(RegistryLayer.WORLDGEN); + List> list1 = TagLoader.buildUpdatedLookups(registryaccess$frozen, list); +- RegistryAccess.Frozen registryaccess$frozen1 = RegistryDataLoader.load(closeableresourcemanager, list1, RegistryDataLoader.WORLDGEN_REGISTRIES); ++ RegistryAccess.Frozen registryaccess$frozen1 = RegistryDataLoader.load(closeableresourcemanager, list1, net.neoforged.neoforge.registries.DataPackRegistriesHooks.getDataPackRegistries()); + List> list2 = Stream.concat(list1.stream(), registryaccess$frozen1.listRegistries()).toList(); + RegistryAccess.Frozen registryaccess$frozen2 = RegistryDataLoader.load(closeableresourcemanager, list2, RegistryDataLoader.DIMENSION_REGISTRIES); + WorldDataConfiguration worlddataconfiguration = pair.getFirst(); diff --git a/patches/net/minecraft/server/commands/SpreadPlayersCommand.java.patch b/patches/net/minecraft/server/commands/SpreadPlayersCommand.java.patch index 9f297b76ee..f61c49d353 100644 --- a/patches/net/minecraft/server/commands/SpreadPlayersCommand.java.patch +++ b/patches/net/minecraft/server/commands/SpreadPlayersCommand.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/commands/SpreadPlayersCommand.java +++ b/net/minecraft/server/commands/SpreadPlayersCommand.java -@@ -259,15 +_,22 @@ +@@ -259,16 +_,23 @@ spreadplayerscommand$position = p_138732_[i++]; } @@ -11,7 +11,8 @@ - (double)Mth.floor(spreadplayerscommand$position.z) + 0.5, - Set.of(), - entity.getYRot(), -- entity.getXRot() +- entity.getXRot(), +- true + net.neoforged.neoforge.event.entity.EntityTeleportEvent.SpreadPlayersCommand event = net.neoforged.neoforge.event.EventHooks.onEntityTeleportSpreadPlayersCommand(entity, + (double)Mth.floor(spreadplayerscommand$position.x) + 0.5, + spreadplayerscommand$position.getSpawnY(p_138731_, p_138733_), @@ -25,7 +26,8 @@ + event.getTargetZ(), + Set.of(), + entity.getYRot(), -+ entity.getXRot() ++ entity.getXRot(), ++ true + ); + } double d2 = Double.MAX_VALUE; diff --git a/patches/net/minecraft/server/commands/TeleportCommand.java.patch b/patches/net/minecraft/server/commands/TeleportCommand.java.patch index 2fe8f7c34f..70d1b71cd5 100644 --- a/patches/net/minecraft/server/commands/TeleportCommand.java.patch +++ b/patches/net/minecraft/server/commands/TeleportCommand.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/server/commands/TeleportCommand.java +++ b/net/minecraft/server/commands/TeleportCommand.java -@@ -270,6 +_,14 @@ +@@ -278,6 +_,14 @@ float p_139023_, - @Nullable TeleportCommand.LookAt p_139024_ + @Nullable LookAt p_380216_ ) throws CommandSyntaxException { + net.neoforged.neoforge.event.entity.EntityTeleportEvent.TeleportCommand event = net.neoforged.neoforge.event.EventHooks.onEntityTeleportCommand(p_139016_, p_139018_, p_139019_, p_139020_); + if (event.isCanceled()) { diff --git a/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch b/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch index fededefd4f..1085bf08f8 100644 --- a/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch +++ b/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java -@@ -80,6 +_,8 @@ +@@ -79,6 +_,8 @@ @Nullable private DebugSampleSubscriptionTracker debugSampleSubscriptionTracker; private final ServerLinks serverLinks; @@ -9,7 +9,7 @@ public DedicatedServer( Thread p_214789_, -@@ -103,6 +_,7 @@ +@@ -102,6 +_,7 @@ Thread thread = new Thread("Server console handler") { @Override public void run() { @@ -17,7 +17,7 @@ BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8)); String s1; -@@ -185,11 +_,13 @@ +@@ -184,11 +_,13 @@ long i = Util.getNanos(); SkullBlockEntity.setup(this.services, this); GameProfileCache.setUsesAuthentication(this.usesAuthentication()); @@ -31,7 +31,7 @@ if (dedicatedserverproperties.announcePlayerAchievements != null) { this.getGameRules().getRule(GameRules.RULE_ANNOUNCE_ADVANCEMENTS).set(dedicatedserverproperties.announcePlayerAchievements, this); } -@@ -217,6 +_,12 @@ +@@ -216,6 +_,12 @@ LOGGER.info("JMX monitoring enabled"); } @@ -44,7 +44,7 @@ return true; } } -@@ -295,6 +_,10 @@ +@@ -277,6 +_,10 @@ if (this.queryThreadGs4 != null) { this.queryThreadGs4.stop(); } @@ -55,7 +55,7 @@ } @Override -@@ -548,7 +_,12 @@ +@@ -530,7 +_,12 @@ @Override public void stopServer() { diff --git a/patches/net/minecraft/server/dedicated/DedicatedServerProperties.java.patch b/patches/net/minecraft/server/dedicated/DedicatedServerProperties.java.patch index f99e3d3db3..b9a564b407 100644 --- a/patches/net/minecraft/server/dedicated/DedicatedServerProperties.java.patch +++ b/patches/net/minecraft/server/dedicated/DedicatedServerProperties.java.patch @@ -8,4 +8,4 @@ + public final boolean onlineMode = this.get("online-mode", !net.minecraft.SharedConstants.IS_RUNNING_IN_IDE); public final boolean preventProxyConnections = this.get("prevent-proxy-connections", false); public final String serverIp = this.get("server-ip", ""); - public final boolean spawnAnimals = this.get("spawn-animals", true); + public final boolean pvp = this.get("pvp", true); diff --git a/patches/net/minecraft/server/dedicated/ServerWatchdog.java.patch b/patches/net/minecraft/server/dedicated/ServerWatchdog.java.patch index 0068d1268c..4045f347c1 100644 --- a/patches/net/minecraft/server/dedicated/ServerWatchdog.java.patch +++ b/patches/net/minecraft/server/dedicated/ServerWatchdog.java.patch @@ -1,19 +1,41 @@ --- a/net/minecraft/server/dedicated/ServerWatchdog.java +++ b/net/minecraft/server/dedicated/ServerWatchdog.java -@@ -49,14 +_,14 @@ - ThreadMXBean threadmxbean = ManagementFactory.getThreadMXBean(); - ThreadInfo[] athreadinfo = threadmxbean.dumpAllThreads(true, true); - StringBuilder stringbuilder = new StringBuilder(); -- Error error = new Error("Watchdog"); -+ Error error = new Error(String.format(java.util.Locale.ENGLISH, "ServerHangWatchdog detected that a single server tick took %.2f seconds (should be max 0.05)", k / 1000F)); // Forge: don't just make a crash report with a seemingly-inexplicable Error +@@ -46,7 +_,13 @@ + String.format(Locale.ROOT, "%.2f", this.server.tickRateManager().millisecondsPerTick() / (float)TimeUtil.MILLISECONDS_PER_SECOND) + ); + LOGGER.error(LogUtils.FATAL_MARKER, "Considering it to be crashed, server will forcibly shutdown."); +- CrashReport crashreport = createWatchdogCrashReport("Watching Server", this.server.getRunningThread().threadId()); ++ // Neo: don't just make a crash report with a seemingly-inexplicable Error ++ String message = String.format( ++ Locale.ROOT, ++ "ServerWatchdog detected that a single server tick took %.2f seconds (should be max %.2f)", ++ (float)k / (float)TimeUtil.NANOSECONDS_PER_SECOND, ++ this.server.tickRateManager().millisecondsPerTick() / (float)TimeUtil.MILLISECONDS_PER_SECOND); ++ CrashReport crashreport = createWatchdogCrashReport("Watching Server", this.server.getRunningThread().threadId(), message); + this.server.fillSystemReport(crashreport.getSystemReport()); + CrashReportCategory crashreportcategory = crashreport.addCategory("Performance stats"); + crashreportcategory.setDetail( +@@ -77,17 +_,21 @@ + } - for (ThreadInfo threadinfo : athreadinfo) { - if (threadinfo.getThreadId() == this.server.getRunningThread().getId()) { - error.setStackTrace(threadinfo.getStackTrace()); - } + public static CrashReport createWatchdogCrashReport(String p_363165_, long p_364052_) { ++ return createWatchdogCrashReport(p_363165_, p_364052_, "Watchdog"); ++ } ++ ++ public static CrashReport createWatchdogCrashReport(String p_363165_, long p_364052_, String message) { + ThreadMXBean threadmxbean = ManagementFactory.getThreadMXBean(); + ThreadInfo[] athreadinfo = threadmxbean.dumpAllThreads(true, true); + StringBuilder stringbuilder = new StringBuilder(); +- Error error = new Error("Watchdog"); ++ Error error = new Error(message); -- stringbuilder.append(threadinfo); -+ stringbuilder.append(net.neoforged.neoforge.logging.ThreadInfoUtil.getEntireStacktrace(threadinfo)); - stringbuilder.append("\n"); - } + for (ThreadInfo threadinfo : athreadinfo) { + if (threadinfo.getThreadId() == p_364052_) { + error.setStackTrace(threadinfo.getStackTrace()); + } + +- stringbuilder.append(threadinfo); ++ stringbuilder.append(net.neoforged.neoforge.logging.ThreadInfoUtil.getEntireStacktrace(threadinfo)); + stringbuilder.append("\n"); + } diff --git a/patches/net/minecraft/server/level/ChunkMap.java.patch b/patches/net/minecraft/server/level/ChunkMap.java.patch index 947e62b315..1a37c82136 100644 --- a/patches/net/minecraft/server/level/ChunkMap.java.patch +++ b/patches/net/minecraft/server/level/ChunkMap.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/level/ChunkMap.java +++ b/net/minecraft/server/level/ChunkMap.java -@@ -395,6 +_,7 @@ +@@ -400,6 +_,7 @@ this.modified = true; } @@ -8,7 +8,7 @@ return p_140179_; } } -@@ -508,8 +_,11 @@ +@@ -529,8 +_,11 @@ } else { ChunkAccess chunkaccess = p_140183_.getLatestChunk(); if (this.pendingUnloads.remove(p_140182_, p_140183_) && chunkaccess != null) { @@ -20,15 +20,23 @@ } this.save(chunkaccess); -@@ -756,6 +_,7 @@ - - this.level.getProfiler().incrementCounter("chunkSave"); - CompoundTag compoundtag = ChunkSerializer.write(this.level, p_140259_); -+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.ChunkDataEvent.Save(p_140259_, p_140259_.getLevel() != null ? p_140259_.getLevel() : this.level, compoundtag)); - this.write(chunkpos, compoundtag).exceptionally(p_351776_ -> { - this.level.getServer().reportChunkSaveFailure(p_351776_, this.storageInfo(), chunkpos); - return null; -@@ -817,9 +_,11 @@ +@@ -579,6 +_,7 @@ + Profiler.get().incrementCounter("chunkLoad"); + if (p_372662_.isPresent()) { + ChunkAccess chunkaccess = p_372662_.get().read(this.level, this.poiManager, this.storageInfo(), p_140418_); ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.ChunkDataEvent.Load(chunkaccess, p_372662_.get())); + this.markPosition(p_140418_, chunkaccess.getPersistedStatus().getChunkType()); + return chunkaccess; + } else { +@@ -778,6 +_,7 @@ + Profiler.get().incrementCounter("chunkSave"); + this.activeChunkWrites.incrementAndGet(); + SerializableChunkData serializablechunkdata = SerializableChunkData.copyOf(this.level, p_140259_); ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.ChunkDataEvent.Save(p_140259_, this.level, serializablechunkdata)); + CompletableFuture completablefuture = CompletableFuture.supplyAsync(serializablechunkdata::write, Util.backgroundExecutor()); + this.write(chunkpos, completablefuture::join).handle((p_381690_, p_381691_) -> { + if (p_381691_ != null) { +@@ -844,9 +_,11 @@ private static void markChunkPendingToSend(ServerPlayer p_295834_, LevelChunk p_296281_) { p_295834_.connection.chunkSender.markChunkPendingToSend(p_296281_); @@ -40,7 +48,7 @@ p_294215_.connection.chunkSender.dropChunk(p_294215_, p_294758_); } -@@ -1018,6 +_,7 @@ +@@ -1057,6 +_,7 @@ this.playerMap.unIgnorePlayer(p_140185_); } @@ -48,7 +56,7 @@ this.updateChunkTracking(p_140185_); } } -@@ -1069,7 +_,7 @@ +@@ -1108,7 +_,7 @@ } protected void addEntity(Entity p_140200_) { @@ -57,7 +65,7 @@ EntityType entitytype = p_140200_.getType(); int i = entitytype.clientTrackingRange() * 16; if (i != 0) { -@@ -1313,5 +_,20 @@ +@@ -1352,5 +_,20 @@ this.updatePlayer(serverplayer); } } @@ -74,7 +82,7 @@ + * Use this method to schedule tasks for loading chunks in your whenCompleteAsync method call so the tasks gets processed properly over time and not leak. + * See {@link net.neoforged.neoforge.server.command.generation.GenerationTask#enqueueChunks} as an example usage of this method. + */ -+ public void scheduleOnMainThreadMailbox(ChunkTaskPriorityQueueSorter.Message msg) { -+ mainThreadMailbox.tell(msg); ++ public void scheduleOnMainThreadMailbox(Runnable runnable) { ++ mainThreadExecutor.schedule(runnable); } } diff --git a/patches/net/minecraft/server/level/DistanceManager.java.patch b/patches/net/minecraft/server/level/DistanceManager.java.patch index b2ff618cbf..fb0d048821 100644 --- a/patches/net/minecraft/server/level/DistanceManager.java.patch +++ b/patches/net/minecraft/server/level/DistanceManager.java.patch @@ -1,15 +1,14 @@ --- a/net/minecraft/server/level/DistanceManager.java +++ b/net/minecraft/server/level/DistanceManager.java -@@ -54,6 +_,8 @@ +@@ -50,6 +_,7 @@ + final Executor mainThreadExecutor; private long ticketTickCounter; private int simulationDistance = 10; - + private final Long2ObjectOpenHashMap>> forcedTickets = new Long2ObjectOpenHashMap<>(); -+ + protected DistanceManager(Executor p_140774_, Executor p_140775_) { - ProcessorHandle processorhandle = ProcessorHandle.of("player ticket throttler", p_140775_::execute); - ChunkTaskPriorityQueueSorter chunktaskpriorityqueuesorter = new ChunkTaskPriorityQueueSorter(ImmutableList.of(processorhandle), p_140774_, 4); -@@ -152,6 +_,10 @@ + TaskScheduler taskscheduler = TaskScheduler.wrapExecutor("player ticket throttler", p_140775_); +@@ -150,6 +_,10 @@ if (p_140786_.getTicketLevel() < i) { this.ticketTracker.update(p_140785_, p_140786_.getTicketLevel(), true); } @@ -20,7 +19,7 @@ } void removeTicket(long p_140819_, Ticket p_140820_) { -@@ -164,6 +_,13 @@ +@@ -162,6 +_,13 @@ } this.ticketTracker.update(p_140819_, getTicketLevelAt(sortedarrayset), false); @@ -34,7 +33,7 @@ } public void addTicket(TicketType p_140793_, ChunkPos p_140794_, int p_140795_, T p_140796_) { -@@ -176,14 +_,20 @@ +@@ -174,14 +_,20 @@ } public void addRegionTicket(TicketType p_140841_, ChunkPos p_140842_, int p_140843_, T p_140844_) { @@ -57,10 +56,10 @@ long i = p_140851_.toLong(); this.removeTicket(i, ticket); this.tickingTicketsTracker.removeTicket(i, ticket); -@@ -267,6 +_,11 @@ +@@ -270,6 +_,11 @@ public String getDebugStatus() { - return this.ticketThrottler.getDebugStatus(); + return this.ticketDispatcher.getDebugStatus(); + } + + public boolean shouldForceTicks(long chunkPos) { diff --git a/patches/net/minecraft/server/level/GenerationChunkHolder.java.patch b/patches/net/minecraft/server/level/GenerationChunkHolder.java.patch index cf83f0dc4d..e34a1b6f11 100644 --- a/patches/net/minecraft/server/level/GenerationChunkHolder.java.patch +++ b/patches/net/minecraft/server/level/GenerationChunkHolder.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/server/level/GenerationChunkHolder.java +++ b/net/minecraft/server/level/GenerationChunkHolder.java -@@ -33,6 +_,7 @@ - private final AtomicReferenceArray>> futures = new AtomicReferenceArray<>(CHUNK_STATUSES.size()); +@@ -34,6 +_,7 @@ private final AtomicReference task = new AtomicReference<>(); private final AtomicInteger generationRefCount = new AtomicInteger(); + private volatile CompletableFuture generationSaveSyncFuture = CompletableFuture.completedFuture(null); + public net.minecraft.world.level.chunk.LevelChunk currentlyLoading; // Forge: Used to bypass future chain when loading chunks. public GenerationChunkHolder(ChunkPos p_347689_) { diff --git a/patches/net/minecraft/server/level/ServerChunkCache.java.patch b/patches/net/minecraft/server/level/ServerChunkCache.java.patch index a52a220bb9..1c3f4867c4 100644 --- a/patches/net/minecraft/server/level/ServerChunkCache.java.patch +++ b/patches/net/minecraft/server/level/ServerChunkCache.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java -@@ -45,7 +_,7 @@ - import net.minecraft.world.level.storage.DimensionDataStorage; +@@ -52,7 +_,7 @@ import net.minecraft.world.level.storage.LevelStorageSource; + import org.slf4j.Logger; -public class ServerChunkCache extends ChunkSource { +public class ServerChunkCache extends ChunkSource implements net.neoforged.neoforge.common.extensions.IServerChunkCacheExtension { - private static final List CHUNK_STATUSES = ChunkStatus.getStatusList(); + private static final Logger LOGGER = LogUtils.getLogger(); private final DistanceManager distanceManager; public final ServerLevel level; -@@ -150,6 +_,10 @@ +@@ -165,6 +_,10 @@ } } @@ -20,7 +20,7 @@ profilerfiller.incrementCounter("getChunkCacheMiss"); CompletableFuture> completablefuture = this.getChunkFutureMainThread(p_8360_, p_8361_, p_330876_, p_8363_); this.mainThreadProcessor.managedBlock(completablefuture::isDone); -@@ -184,6 +_,7 @@ +@@ -199,6 +_,7 @@ if (chunkholder == null) { return null; } else { @@ -28,16 +28,16 @@ ChunkAccess chunkaccess1 = chunkholder.getChunkIfPresent(ChunkStatus.FULL); if (chunkaccess1 != null) { this.storeInCache(i, chunkaccess1, ChunkStatus.FULL); -@@ -356,7 +_,7 @@ - for (ServerChunkCache.ChunkAndHolder serverchunkcache$chunkandholder : list) { - LevelChunk levelchunk1 = serverchunkcache$chunkandholder.chunk; - ChunkPos chunkpos = levelchunk1.getPos(); -- if (this.level.isNaturalSpawningAllowed(chunkpos) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkpos)) { -+ if ((this.level.isNaturalSpawningAllowed(chunkpos) && this.chunkMap.anyPlayerCloseEnoughForSpawning(chunkpos)) || this.distanceManager.shouldForceTicks(chunkpos.toLong())) { - levelchunk1.incrementInhabitedTime(j); - if (flag1 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkpos)) { - NaturalSpawner.spawnForChunk(this.level, levelchunk1, naturalspawner$spawnstate, this.spawnFriendlies, this.spawnEnemies, flag); -@@ -435,11 +_,17 @@ +@@ -384,7 +_,7 @@ + private void collectTickingChunks(List p_363421_) { + this.chunkMap.forEachSpawnCandidateChunk(p_370483_ -> { + LevelChunk levelchunk = p_370483_.getTickingChunk(); +- if (levelchunk != null && this.level.isNaturalSpawningAllowed(p_370483_.getPos())) { ++ if (levelchunk != null && this.level.isNaturalSpawningAllowed(p_370483_.getPos()) || this.distanceManager.shouldForceTicks(p_370483_.getPos().toLong())) { + p_363421_.add(levelchunk); + } + }); +@@ -480,11 +_,17 @@ } public void addRegionTicket(TicketType p_8388_, ChunkPos p_8389_, int p_8390_, T p_8391_) { diff --git a/patches/net/minecraft/server/level/ServerEntity.java.patch b/patches/net/minecraft/server/level/ServerEntity.java.patch index bdf1f7cbee..8df4830e9a 100644 --- a/patches/net/minecraft/server/level/ServerEntity.java.patch +++ b/patches/net/minecraft/server/level/ServerEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/level/ServerEntity.java +++ b/net/minecraft/server/level/ServerEntity.java -@@ -101,9 +_,9 @@ +@@ -104,9 +_,9 @@ if (this.entity instanceof ItemFrame itemframe && this.tickCount % 10 == 0) { ItemStack itemstack = itemframe.getItem(); @@ -12,7 +12,7 @@ if (mapitemsaveddata != null) { for (ServerPlayer serverplayer : this.level.players()) { mapitemsaveddata.tickCarriedBy(serverplayer, itemstack); -@@ -233,22 +_,25 @@ +@@ -274,22 +_,25 @@ public void removePairing(ServerPlayer p_8535_) { this.entity.stopSeenByPlayer(p_8535_); p_8535_.connection.send(new ClientboundRemoveEntitiesPacket(this.entity.getId())); diff --git a/patches/net/minecraft/server/level/ServerLevel.java.patch b/patches/net/minecraft/server/level/ServerLevel.java.patch index 411052eadc..64e787851b 100644 --- a/patches/net/minecraft/server/level/ServerLevel.java.patch +++ b/patches/net/minecraft/server/level/ServerLevel.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -199,7 +_,7 @@ +@@ -202,7 +_,7 @@ private final List customSpawners; @Nullable private EndDragonFight dragonFight; @@ -9,15 +9,15 @@ private final StructureManager structureManager; private final StructureCheck structureCheck; private final boolean tickTime; -@@ -232,7 +_,6 @@ - ); +@@ -225,7 +_,6 @@ + super(p_215002_, p_215003_, p_214999_.registryAccess(), p_215004_.type(), false, p_215006_, p_215007_, p_214999_.getMaxChainedNeighborUpdates()); this.tickTime = p_215009_; this.server = p_214999_; - this.customSpawners = p_215008_; this.serverLevelData = p_215002_; ChunkGenerator chunkgenerator = p_215004_.generator(); boolean flag = p_214999_.forceSynchronousWrites(); -@@ -298,6 +_,11 @@ +@@ -291,6 +_,11 @@ this.randomSequences = Objects.requireNonNullElseGet( p_288977_, () -> this.getDataStorage().computeIfAbsent(RandomSequences.factory(i), "random_sequences") ); @@ -29,7 +29,7 @@ } @Deprecated -@@ -342,7 +_,7 @@ +@@ -336,7 +_,7 @@ if (this.sleepStatus.areEnoughSleeping(i) && this.sleepStatus.areEnoughDeepSleeping(i, this.players)) { if (this.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) { long j = this.levelData.getDayTime() + 24000L; @@ -38,7 +38,7 @@ } this.wakeUpAllPlayers(); -@@ -380,7 +_,7 @@ +@@ -374,7 +_,7 @@ this.handlingTick = false; profilerfiller.pop(); @@ -47,27 +47,27 @@ if (flag1) { this.resetEmptyTime(); } -@@ -412,7 +_,9 @@ - } +@@ -407,7 +_,9 @@ + } - profilerfiller.push("tick"); -- this.guardEntityTick(this::tickNonPassenger, p_308566_); -+ if (!p_308566_.isRemoved() && !(p_308566_ instanceof net.neoforged.neoforge.entity.PartEntity)) { -+ this.guardEntityTick(this::tickNonPassenger, p_308566_); -+ } - profilerfiller.pop(); - } - } -@@ -438,7 +_,7 @@ - this.serverLevelData.setGameTime(i); + profilerfiller.push("tick"); +- this.guardEntityTick(this::tickNonPassenger, p_359620_); ++ if (!p_359620_.isRemoved() && !(p_359620_ instanceof net.neoforged.neoforge.entity.PartEntity)) { ++ this.guardEntityTick(this::tickNonPassenger, p_359620_); ++ } + profilerfiller.pop(); + } + } +@@ -436,7 +_,7 @@ this.serverLevelData.getScheduledEvents().tick(this.server, i); - if (this.levelData.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) { + Profiler.get().pop(); + if (this.serverLevelData.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) { - this.setDayTime(this.levelData.getDayTime() + 1L); + this.setDayTime(this.levelData.getDayTime() + advanceDaytime()); } } } -@@ -542,6 +_,7 @@ +@@ -534,6 +_,7 @@ BlockPos blockpos = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, p_295060_); BlockPos blockpos1 = blockpos.below(); Biome biome = this.getBiome(blockpos).value(); @@ -75,7 +75,7 @@ if (biome.shouldFreeze(this, blockpos1)) { this.setBlockAndUpdate(blockpos1, Blocks.ICE.defaultBlockState()); } -@@ -714,15 +_,19 @@ +@@ -706,15 +_,19 @@ .broadcastAll(new ClientboundGameEventPacket(ClientboundGameEventPacket.THUNDER_LEVEL_CHANGE, this.thunderLevel), this.dimension()); } @@ -99,9 +99,9 @@ } } -@@ -758,7 +_,11 @@ +@@ -751,7 +_,11 @@ p_8648_.tickCount++; - this.getProfiler().push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(p_8648_.getType()).toString()); + profilerfiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(p_8648_.getType()).toString()); profilerfiller.incrementCounter("tickNonPassenger"); - p_8648_.tick(); + // Neo: Permit cancellation of Entity#tick via EntityTickEvent.Pre @@ -109,10 +109,10 @@ + p_8648_.tick(); + net.neoforged.neoforge.event.EventHooks.fireEntityTickPost(p_8648_); + } - this.getProfiler().pop(); + profilerfiller.pop(); for (Entity entity : p_8648_.getPassengers()) { -@@ -807,6 +_,7 @@ +@@ -800,6 +_,7 @@ } else { this.entityManager.autoSave(); } @@ -120,7 +120,7 @@ } } -@@ -896,6 +_,7 @@ +@@ -894,6 +_,7 @@ } private void addPlayer(ServerPlayer p_8854_) { @@ -128,7 +128,7 @@ Entity entity = this.getEntities().get(p_8854_.getUUID()); if (entity != null) { LOGGER.warn("Force-added player with duplicate UUID {}", p_8854_.getUUID()); -@@ -903,7 +_,8 @@ +@@ -901,7 +_,8 @@ this.removePlayerImmediately((ServerPlayer)entity, Entity.RemovalReason.DISCARDED); } @@ -138,7 +138,7 @@ } private boolean addEntity(Entity p_8873_) { -@@ -911,7 +_,12 @@ +@@ -909,7 +_,12 @@ LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityType.getKey(p_8873_.getType())); return false; } else { @@ -152,7 +152,7 @@ } } -@@ -959,6 +_,12 @@ +@@ -957,6 +_,12 @@ float p_263390_, long p_263403_ ) { @@ -165,7 +165,7 @@ this.server .getPlayerList() .broadcast( -@@ -976,6 +_,12 @@ +@@ -974,6 +_,12 @@ public void playSeededSound( @Nullable Player p_263545_, Entity p_263544_, Holder p_263491_, SoundSource p_263542_, float p_263530_, float p_263520_, long p_263490_ ) { @@ -178,7 +178,7 @@ this.server .getPlayerList() .broadcast( -@@ -1019,6 +_,7 @@ +@@ -1032,6 +_,7 @@ @Override public void gameEvent(Holder p_316597_, Vec3 p_215042_, GameEvent.Context p_215043_) { @@ -186,24 +186,43 @@ this.gameEventDispatcher.post(p_316597_, p_215042_, p_215043_); } -@@ -1057,11 +_,16 @@ +@@ -1070,6 +_,7 @@ @Override public void updateNeighborsAt(BlockPos p_215045_, Block p_215046_) { + net.neoforged.neoforge.event.EventHooks.onNeighborNotify(this, p_215045_, this.getBlockState(p_215045_), java.util.EnumSet.allOf(Direction.class), false).isCanceled(); - this.neighborUpdater.updateNeighborsAtExceptFromFacing(p_215045_, p_215046_, null); + this.updateNeighborsAt(p_215045_, p_215046_, ExperimentalRedstoneUtils.initialOrientation(this, null, null)); } +@@ -1080,6 +_,10 @@ + @Override - public void updateNeighborsAtExceptFromFacing(BlockPos p_215052_, Block p_215053_, Direction p_215054_) { + public void updateNeighborsAtExceptFromFacing(BlockPos p_215052_, Block p_215053_, Direction p_215054_, @Nullable Orientation p_365231_) { + java.util.EnumSet directions = java.util.EnumSet.allOf(Direction.class); + directions.remove(p_215054_); + if (net.neoforged.neoforge.event.EventHooks.onNeighborNotify(this, p_215052_, this.getBlockState(p_215052_), directions, false).isCanceled()) + return; - this.neighborUpdater.updateNeighborsAtExceptFromFacing(p_215052_, p_215053_, p_215054_); + this.neighborUpdater.updateNeighborsAtExceptFromFacing(p_215052_, p_215053_, p_215054_, p_365231_); } -@@ -1713,8 +_,8 @@ +@@ -1125,7 +_,7 @@ + Explosion.BlockInteraction explosion$blockinteraction = switch (p_255827_) { + case NONE -> Explosion.BlockInteraction.KEEP; + case BLOCK -> this.getDestroyType(GameRules.RULE_BLOCK_EXPLOSION_DROP_DECAY); +- case MOB -> this.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ++ case MOB -> net.neoforged.neoforge.event.EventHooks.canEntityGrief(this, p_256039_) + ? this.getDestroyType(GameRules.RULE_MOB_EXPLOSION_DROP_DECAY) + : Explosion.BlockInteraction.KEEP; + case TNT -> this.getDestroyType(GameRules.RULE_TNT_EXPLOSION_DROP_DECAY); +@@ -1133,6 +_,7 @@ + }; + Vec3 vec3 = new Vec3(p_256067_, p_256370_, p_256153_); + ServerExplosion serverexplosion = new ServerExplosion(this, p_256039_, p_255778_, p_256002_, vec3, p_256045_, p_255686_, explosion$blockinteraction); ++ if (net.neoforged.neoforge.event.EventHooks.onExplosionStart(this, serverexplosion)) return; + serverexplosion.explode(); + ParticleOptions particleoptions = serverexplosion.isSmall() ? p_312436_ : p_312391_; + +@@ -1740,8 +_,8 @@ ServerLevel.this.navigatingMobs.add(mob); } @@ -214,7 +233,7 @@ ServerLevel.this.dragonParts.put(enderdragonpart.getId(), enderdragonpart); } } -@@ -1733,24 +_,106 @@ +@@ -1760,24 +_,106 @@ if (ServerLevel.this.isUpdatingNavigations) { String s = "onTrackingStart called during navigation iteration"; Util.logAndPauseIfInIde( diff --git a/patches/net/minecraft/server/level/ServerPlayer.java.patch b/patches/net/minecraft/server/level/ServerPlayer.java.patch index 9ead220877..a0e3dd567a 100644 --- a/patches/net/minecraft/server/level/ServerPlayer.java.patch +++ b/patches/net/minecraft/server/level/ServerPlayer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -252,6 +_,10 @@ +@@ -278,6 +_,10 @@ } private void broadcastDataValue(AbstractContainerMenu p_143455_, int p_143456_, int p_143457_) { @@ -11,7 +11,7 @@ ServerPlayer.this.connection.send(new ClientboundContainerSetDataPacket(p_143455_.containerId, p_143456_, p_143457_)); } }; -@@ -606,6 +_,11 @@ +@@ -768,6 +_,11 @@ this.connection.send(new ClientboundSetExperiencePacket(this.experienceProgress, this.totalExperience, this.experienceLevel)); } @@ -23,15 +23,15 @@ if (this.tickCount % 20 == 0) { CriteriaTriggers.LOCATION.trigger(this); } -@@ -657,6 +_,7 @@ +@@ -850,6 +_,7 @@ @Override public void die(DamageSource p_9035_) { this.gameEvent(GameEvent.ENTITY_DIE); + if (net.neoforged.neoforge.common.CommonHooks.onLivingDeath(this, p_9035_)) return; - boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); + boolean flag = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); if (flag) { Component component = this.getCombatTracker().getDeathMessage(); -@@ -826,7 +_,7 @@ +@@ -1019,7 +_,7 @@ return BedBlock.findStandUpPosition(EntityType.PLAYER, p_348505_, p_348607_, blockstate.getValue(BedBlock.FACING), p_348481_) .map(p_348148_ -> ServerPlayer.RespawnPosAngle.of(p_348148_, p_348607_)); } else if (!p_348513_) { @@ -40,37 +40,37 @@ } else { boolean flag = block.isPossibleToRespawnInThis(blockstate); BlockState blockstate1 = p_348505_.getBlockState(p_348607_.above()); -@@ -854,6 +_,7 @@ +@@ -1046,6 +_,7 @@ + @Nullable - @Override - public Entity changeDimension(DimensionTransition p_350472_) { -+ if (!net.neoforged.neoforge.common.CommonHooks.onTravelToDimension(this, p_350472_.newLevel().dimension())) return null; + public ServerPlayer teleport(TeleportTransition p_379854_) { ++ if (!net.neoforged.neoforge.common.CommonHooks.onTravelToDimension(this, p_379854_.newLevel().dimension())) return null; if (this.isRemoved()) { return null; } else { -@@ -877,7 +_,7 @@ +@@ -1073,7 +_,7 @@ PlayerList playerlist = this.server.getPlayerList(); playerlist.sendPlayerPermissionLevel(this); serverlevel1.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION); - this.unsetRemoved(); + this.revive(); - serverlevel1.getProfiler().push("moving"); + ProfilerFiller profilerfiller = Profiler.get(); + profilerfiller.push("moving"); if (resourcekey == Level.OVERWORLD && serverlevel.dimension() == Level.NETHER) { - this.enteredNetherPosition = this.position(); -@@ -895,10 +_,12 @@ +@@ -1093,10 +_,12 @@ playerlist.sendLevelInfo(this, serverlevel); playerlist.sendAllPlayerInfo(this); playerlist.sendActivePlayerEffects(this); + // TODO 1.21: Play custom teleport sound - p_350472_.postDimensionTransition().onTransition(this); + p_379854_.postTeleportTransition().onTransition(this); this.lastSentExp = -1; this.lastSentHealth = -1.0F; this.lastSentFood = -1; -+ net.neoforged.neoforge.event.EventHooks.firePlayerChangedDimensionEvent(this, resourcekey, p_350472_.newLevel().dimension()); ++ net.neoforged.neoforge.event.EventHooks.firePlayerChangedDimensionEvent(this, resourcekey, p_379854_.newLevel().dimension()); return this; } } -@@ -934,6 +_,15 @@ +@@ -1137,6 +_,15 @@ @Override public Either startSleepInBed(BlockPos p_9115_) { @@ -86,7 +86,7 @@ Direction direction = this.level().getBlockState(p_9115_).getValue(HorizontalDirectionalBlock.FACING); if (this.isSleeping() || !this.isAlive()) { return Either.left(Player.BedSleepingProblem.OTHER_PROBLEM); -@@ -962,7 +_,21 @@ +@@ -1165,7 +_,21 @@ return Either.left(Player.BedSleepingProblem.NOT_SAFE); } } @@ -109,7 +109,7 @@ Either either = super.startSleepInBed(p_9115_).ifRight(p_9029_ -> { this.awardStat(Stats.SLEEP_IN_BED); CriteriaTriggers.SLEPT_IN_BED.trigger(this); -@@ -984,6 +_,7 @@ +@@ -1187,6 +_,7 @@ } private boolean bedInRange(BlockPos p_9117_, Direction p_9118_) { @@ -117,7 +117,7 @@ return this.isReachableBedBlock(p_9117_) || this.isReachableBedBlock(p_9117_.relative(p_9118_.getOpposite())); } -@@ -1074,11 +_,19 @@ +@@ -1277,11 +_,19 @@ @Override public OptionalInt openMenu(@Nullable MenuProvider p_9033_) { @@ -137,7 +137,7 @@ } this.nextContainerCounter(); -@@ -1090,10 +_,16 @@ +@@ -1293,10 +_,16 @@ return OptionalInt.empty(); } else { @@ -154,7 +154,7 @@ return OptionalInt.of(this.containerCounter); } } -@@ -1115,6 +_,7 @@ +@@ -1318,6 +_,7 @@ this.connection.send(new ClientboundHorseScreenOpenPacket(this.containerCounter, i, p_9059_.getId())); this.containerMenu = new HorseInventoryMenu(this.containerCounter, this.getInventory(), p_9060_, p_9059_, i); this.initMenu(this.containerMenu); @@ -162,7 +162,7 @@ } @Override -@@ -1143,6 +_,7 @@ +@@ -1346,6 +_,7 @@ public void doCloseContainer() { this.containerMenu.removed(this); this.inventoryMenu.transferState(this.containerMenu); @@ -170,7 +170,7 @@ this.containerMenu = this.inventoryMenu; } -@@ -1375,6 +_,15 @@ +@@ -1569,6 +_,15 @@ this.setShoulderEntityLeft(p_9016_.getShoulderEntityLeft()); this.setShoulderEntityRight(p_9016_.getShoulderEntityRight()); this.setLastDeathLocation(p_9016_.getLastDeathLocation()); @@ -186,7 +186,7 @@ } @Override -@@ -1469,6 +_,8 @@ +@@ -1674,6 +_,8 @@ public boolean setGameMode(GameType p_143404_) { boolean flag = this.isSpectator(); @@ -195,15 +195,15 @@ if (!this.gameMode.changeGameModeForPlayer(p_143404_)) { return false; } else { -@@ -1617,6 +_,7 @@ +@@ -1848,6 +_,7 @@ public void setCamera(@Nullable Entity p_9214_) { Entity entity = this.getCamera(); this.camera = (Entity)(p_9214_ == null ? this : p_9214_); + while (this.camera instanceof net.neoforged.neoforge.entity.PartEntity partEntity) this.camera = partEntity.getParent(); // Neo: fix MC-46486 if (entity != this.camera) { if (this.camera.level() instanceof ServerLevel serverlevel) { - this.teleportTo(serverlevel, this.camera.getX(), this.camera.getY(), this.camera.getZ(), Set.of(), this.getYRot(), this.getXRot()); -@@ -1653,7 +_,11 @@ + this.teleportTo(serverlevel, this.camera.getX(), this.camera.getY(), this.camera.getZ(), Set.of(), this.getYRot(), this.getXRot(), false); +@@ -1884,7 +_,11 @@ @Nullable public Component getTabListDisplayName() { @@ -215,8 +215,8 @@ + return this.tabListDisplayName; } - @Override -@@ -1710,6 +_,7 @@ + public int getTabListOrder() { +@@ -1933,6 +_,7 @@ } public void setRespawnPosition(ResourceKey p_9159_, @Nullable BlockPos p_9160_, float p_9161_, boolean p_9162_, boolean p_9163_) { @@ -224,7 +224,7 @@ if (p_9160_ != null) { boolean flag = p_9160_.equals(this.respawnPosition) && p_9159_.equals(this.respawnDimension); if (p_9163_ && !flag) { -@@ -1767,6 +_,8 @@ +@@ -1990,6 +_,8 @@ if (itementity == null) { return null; } else { @@ -233,7 +233,7 @@ this.level().addFreshEntity(itementity); ItemStack itemstack = itementity.getItem(); if (p_9087_) { -@@ -1781,6 +_,75 @@ +@@ -2039,6 +_,75 @@ } } @@ -309,7 +309,7 @@ public TextFilter getTextFilter() { return this.textFilter; } -@@ -1841,9 +_,12 @@ +@@ -2099,9 +_,12 @@ public boolean drop(boolean p_182295_) { Inventory inventory = this.getInventory(); @@ -322,13 +322,4 @@ + return net.neoforged.neoforge.common.CommonHooks.onPlayerTossEvent(this, itemstack, true) != null; } - public boolean allowsListing() { -@@ -1958,7 +_,7 @@ - this.awardStat(Stats.ITEM_BROKEN.get(p_348565_)); - } - -- static record RespawnPosAngle(Vec3 position, float yaw) { -+ public static record RespawnPosAngle(Vec3 position, float yaw) { - public static ServerPlayer.RespawnPosAngle of(Vec3 p_348670_, BlockPos p_348504_) { - return new ServerPlayer.RespawnPosAngle(p_348670_, calculateLookAtYaw(p_348670_, p_348504_)); - } + @Override diff --git a/patches/net/minecraft/server/level/ServerPlayerGameMode.java.patch b/patches/net/minecraft/server/level/ServerPlayerGameMode.java.patch index 82bca3b23f..1d50dd049e 100644 --- a/patches/net/minecraft/server/level/ServerPlayerGameMode.java.patch +++ b/patches/net/minecraft/server/level/ServerPlayerGameMode.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -72,7 +_,10 @@ +@@ -70,7 +_,10 @@ protected void setGameModeForPlayer(GameType p_9274_, @Nullable GameType p_9275_) { this.previousGameModeForPlayer = p_9275_; this.gameModeForPlayer = p_9274_; @@ -11,7 +11,7 @@ } public GameType getGameModeForPlayer() { -@@ -133,6 +_,10 @@ +@@ -131,6 +_,10 @@ } public void handleBlockBreakAction(BlockPos p_215120_, ServerboundPlayerActionPacket.Action p_215121_, Direction p_215122_, int p_215123_, int p_215124_) { @@ -21,8 +21,8 @@ + } if (!this.player.canInteractWithBlock(p_215120_, 1.0)) { this.debugLogging(p_215120_, false, p_215124_, "too far"); - } else if (p_215120_.getY() >= p_215123_) { -@@ -171,6 +_,7 @@ + } else if (p_215120_.getY() > p_215123_) { +@@ -169,6 +_,7 @@ blockstate, p_348149_ -> this.player.onEquippedItemBroken(p_348149_, EquipmentSlot.MAINHAND) ); @@ -30,7 +30,7 @@ blockstate.attack(this.level, p_215120_, this.player); f = blockstate.getDestroyProgress(this.player, this.player.level(), p_215120_); } -@@ -238,7 +_,8 @@ +@@ -236,7 +_,8 @@ public boolean destroyBlock(BlockPos p_9281_) { BlockState blockstate1 = this.level.getBlockState(p_9281_); @@ -40,7 +40,7 @@ return false; } else { BlockEntity blockentity = this.level.getBlockEntity(p_9281_); -@@ -250,26 +_,45 @@ +@@ -248,26 +_,45 @@ return false; } else { BlockState blockstate = block.playerWillDestroy(this.level, p_9281_, blockstate1, this.player); @@ -91,16 +91,16 @@ } public InteractionResult useItem(ServerPlayer p_9262_, Level p_9263_, ItemStack p_9264_, InteractionHand p_9265_) { -@@ -278,6 +_,8 @@ - } else if (p_9262_.getCooldowns().isOnCooldown(p_9264_.getItem())) { +@@ -276,6 +_,8 @@ + } else if (p_9262_.getCooldowns().isOnCooldown(p_9264_)) { return InteractionResult.PASS; } else { + InteractionResult cancelResult = net.neoforged.neoforge.common.CommonHooks.onItemRightClick(p_9262_, p_9265_); + if (cancelResult != null) return cancelResult; int i = p_9264_.getCount(); int j = p_9264_.getDamageValue(); - InteractionResultHolder interactionresultholder = p_9264_.use(p_9263_, p_9262_, p_9265_); -@@ -309,7 +_,10 @@ + InteractionResult interactionresult = p_9264_.use(p_9263_, p_9262_, p_9265_); +@@ -313,7 +_,10 @@ BlockState blockstate = p_9267_.getBlockState(blockpos); if (!blockstate.getBlock().isEnabled(p_9267_.enabledFeatures())) { return InteractionResult.FAIL; @@ -112,7 +112,7 @@ MenuProvider menuprovider = blockstate.getMenuProvider(p_9267_, blockpos); if (menuprovider != null) { p_9266_.openMenu(menuprovider); -@@ -318,10 +_,15 @@ +@@ -322,10 +_,15 @@ return InteractionResult.PASS; } } else { @@ -127,17 +127,17 @@ ItemStack itemstack = p_9268_.copy(); - if (!flag1) { + if (event.getUseBlock().isTrue() || (event.getUseBlock().isDefault() && !flag1)) { - ItemInteractionResult iteminteractionresult = blockstate.useItemOn(p_9266_.getItemInHand(p_9269_), p_9267_, p_9266_, p_9269_, p_9270_); - if (iteminteractionresult.consumesAction()) { + InteractionResult interactionresult = blockstate.useItemOn(p_9266_.getItemInHand(p_9269_), p_9267_, p_9266_, p_9269_, p_9270_); + if (interactionresult.consumesAction()) { CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(p_9266_, blockpos, itemstack); -@@ -337,8 +_,8 @@ +@@ -341,8 +_,8 @@ } } -- if (!p_9268_.isEmpty() && !p_9266_.getCooldowns().isOnCooldown(p_9268_.getItem())) { +- if (!p_9268_.isEmpty() && !p_9266_.getCooldowns().isOnCooldown(p_9268_)) { - UseOnContext useoncontext = new UseOnContext(p_9266_, p_9269_, p_9270_); -+ if (event.getUseItem().isTrue() || (!p_9268_.isEmpty() && !p_9266_.getCooldowns().isOnCooldown(p_9268_.getItem()))) { ++ if (event.getUseItem().isTrue() || (!p_9268_.isEmpty() && !p_9266_.getCooldowns().isOnCooldown(p_9268_))) { + if (event.getUseItem().isFalse()) return InteractionResult.PASS; - InteractionResult interactionresult1; + InteractionResult interactionresult2; if (this.isCreative()) { int i = p_9268_.getCount(); diff --git a/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch b/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch index bc534702f9..0754746778 100644 --- a/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch +++ b/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -42,6 +_,10 @@ +@@ -43,6 +_,10 @@ private boolean closed = false; private int latency; private volatile boolean suspendFlushingOnServerThread = false; @@ -11,7 +11,7 @@ public ServerCommonPacketListenerImpl(MinecraftServer p_295057_, Connection p_294822_, CommonListenerCookie p_301980_) { this.server = p_295057_; -@@ -49,6 +_,8 @@ +@@ -50,6 +_,8 @@ this.keepAliveTime = Util.getMillis(); this.latency = p_301980_.latency(); this.transferred = p_301980_.transferred(); @@ -20,7 +20,7 @@ } private void close() { -@@ -83,6 +_,32 @@ +@@ -90,6 +_,32 @@ @Override public void handleCustomPayload(ServerboundCustomPayloadPacket p_294276_) { @@ -53,7 +53,7 @@ } @Override -@@ -141,7 +_,10 @@ +@@ -148,7 +_,10 @@ this.send(p_294278_, null); } @@ -64,7 +64,7 @@ if (p_295099_.isTerminal()) { this.close(); } -@@ -183,7 +_,41 @@ +@@ -190,7 +_,41 @@ return this.latency; } diff --git a/patches/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/patches/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index 303149aeec..74247bc5af 100644 --- a/patches/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/patches/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -12,7 +12,7 @@ this.send(new ClientboundMoveVehiclePacket(entity)); return; } -@@ -462,6 +_,23 @@ +@@ -463,6 +_,23 @@ } } @@ -36,7 +36,7 @@ private boolean noBlocksAround(Entity p_9794_) { return p_9794_.level() .getBlockStates(p_9794_.getBoundingBox().inflate(0.0625).expandTowards(0.0, -0.55, 0.0)) -@@ -927,7 +_,7 @@ +@@ -930,7 +_,7 @@ && !flag1 && this.player.gameMode.getGameModeForPlayer() != GameType.SPECTATOR && !this.server.isFlightAllowed() @@ -45,7 +45,7 @@ && !this.player.hasEffect(MobEffects.LEVITATION) && !flag && !flag3 -@@ -1031,8 +_,10 @@ +@@ -1041,8 +_,10 @@ case SWAP_ITEM_WITH_OFFHAND: if (!this.player.isSpectator()) { ItemStack itemstack = this.player.getItemInHand(InteractionHand.OFF_HAND); @@ -58,16 +58,16 @@ this.player.stopUsingItem(); } -@@ -1060,7 +_,7 @@ +@@ -1070,7 +_,7 @@ .handleBlockBreakAction( - blockpos, serverboundplayeractionpacket$action, p_9889_.getDirection(), this.player.level().getMaxBuildHeight(), p_9889_.getSequence() + blockpos, serverboundplayeractionpacket$action, p_9889_.getDirection(), this.player.level().getMaxY(), p_9889_.getSequence() ); - this.player.connection.ackBlockChangesUpTo(p_9889_.getSequence()); + this.player.connection.ackBlockChangesUpTo =p_9889_.getSequence(); return; default: throw new IllegalArgumentException("Invalid player action"); -@@ -1079,7 +_,7 @@ +@@ -1089,7 +_,7 @@ @Override public void handleUseItemOn(ServerboundUseItemOnPacket p_9930_) { PacketUtils.ensureRunningOnSameThread(p_9930_, this, this.player.serverLevel()); @@ -76,7 +76,7 @@ ServerLevel serverlevel = this.player.serverLevel(); InteractionHand interactionhand = p_9930_.getHand(); ItemStack itemstack = this.player.getItemInHand(interactionhand); -@@ -1231,8 +_,9 @@ +@@ -1242,8 +_,9 @@ } CompletableFuture completablefuture = this.filterTextPacket(playerchatmessage.signedContent()); @@ -87,7 +87,7 @@ PlayerChatMessage playerchatmessage1 = playerchatmessage.withUnsignedContent(component).filter(p_300785_.mask()); this.broadcastChatMessage(playerchatmessage1); }); -@@ -1561,7 +_,11 @@ +@@ -1569,7 +_,11 @@ @Override public void onInteraction(InteractionHand p_143682_, Vec3 p_143683_) { @@ -100,7 +100,7 @@ } @Override -@@ -1753,13 +_,15 @@ +@@ -1785,13 +_,15 @@ @Override public void handlePlayerAbilities(ServerboundPlayerAbilitiesPacket p_9887_) { PacketUtils.ensureRunningOnSameThread(p_9887_, this, this.player.serverLevel()); @@ -117,7 +117,7 @@ } @Override -@@ -1812,7 +_,7 @@ +@@ -1844,7 +_,7 @@ this.connection .setupInboundProtocol( ConfigurationProtocols.SERVERBOUND, @@ -126,7 +126,7 @@ ); } } -@@ -1847,6 +_,7 @@ +@@ -1879,6 +_,7 @@ @Override public void handleCustomPayload(ServerboundCustomPayloadPacket p_333887_) { diff --git a/patches/net/minecraft/server/packs/repository/PackRepository.java.patch b/patches/net/minecraft/server/packs/repository/PackRepository.java.patch index ded59feb90..fce53d7223 100644 --- a/patches/net/minecraft/server/packs/repository/PackRepository.java.patch +++ b/patches/net/minecraft/server/packs/repository/PackRepository.java.patch @@ -25,7 +25,7 @@ } return ImmutableMap.copyOf(map); -@@ -77,11 +_,12 @@ +@@ -82,11 +_,12 @@ } public List rebuildSelected(Collection p_10518_) { @@ -40,7 +40,7 @@ } } -@@ -93,7 +_,7 @@ +@@ -98,7 +_,7 @@ } public Collection getAvailableIds() { @@ -49,7 +49,7 @@ } public Collection getAvailablePacks() { -@@ -101,7 +_,7 @@ +@@ -106,7 +_,7 @@ } public Collection getSelectedIds() { @@ -58,7 +58,7 @@ } public FeatureFlagSet getRequestedFeatureFlags() { -@@ -115,6 +_,10 @@ +@@ -120,6 +_,10 @@ @Nullable public Pack getPack(String p_10508_) { return this.available.get(p_10508_); diff --git a/patches/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java.patch b/patches/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java.patch index 00214f465c..3745422f2c 100644 --- a/patches/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java.patch +++ b/patches/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java.patch @@ -1,11 +1,42 @@ --- a/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java +++ b/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java -@@ -49,4 +_,8 @@ +@@ -41,13 +_,15 @@ + + protected Map prepare(ResourceManager p_10771_, ProfilerFiller p_10772_) { + Map map = new HashMap<>(); +- scanDirectory(p_10771_, this.directory, this.ops, this.codec, map); ++ // Neo: add condition context ++ scanDirectory(p_10771_, this.directory, this.makeConditionalOps(), this.codec, map); + return map; + } + + public static void scanDirectory( + ResourceManager p_279308_, String p_279131_, DynamicOps p_371830_, Codec p_371493_, Map p_279404_ + ) { ++ var conditionalCodec = net.neoforged.neoforge.common.conditions.ConditionalOps.createConditionalCodec(p_371493_); + FileToIdConverter filetoidconverter = FileToIdConverter.json(p_279131_); + + for (Entry entry : filetoidconverter.listMatchingResources(p_279308_).entrySet()) { +@@ -55,8 +_,10 @@ + ResourceLocation resourcelocation1 = filetoidconverter.fileToId(resourcelocation); + + try (Reader reader = entry.getValue().openAsReader()) { +- p_371493_.parse(p_371830_, JsonParser.parseReader(reader)).ifSuccess(p_371454_ -> { +- if (p_279404_.putIfAbsent(resourcelocation1, (T)p_371454_) != null) { ++ conditionalCodec.parse(p_371830_, JsonParser.parseReader(reader)).ifSuccess(p_371454_ -> { ++ if (p_371454_.isEmpty()) { ++ LOGGER.debug("Skipping loading data file '{}' from '{}' as its conditions were not met", resourcelocation1, resourcelocation); ++ } else if (p_279404_.putIfAbsent(resourcelocation1, p_371454_.get()) != null) { + throw new IllegalStateException("Duplicate data file ignored with ID " + resourcelocation1); + } + }).ifError(p_371566_ -> LOGGER.error("Couldn't parse data file '{}' from '{}': {}", resourcelocation1, resourcelocation, p_371566_)); +@@ -64,5 +_,9 @@ + LOGGER.error("Couldn't parse data file '{}' from '{}'", resourcelocation1, resourcelocation, jsonparseexception); } } - } ++ } + + protected ResourceLocation getPreparedPath(ResourceLocation rl) { + return rl.withPath(this.directory + "/" + rl.getPath() + ".json"); -+ } + } } diff --git a/patches/net/minecraft/server/packs/resources/SimplePreparableReloadListener.java.patch b/patches/net/minecraft/server/packs/resources/SimplePreparableReloadListener.java.patch index 2d1ba1e6ae..afdb34f2fe 100644 --- a/patches/net/minecraft/server/packs/resources/SimplePreparableReloadListener.java.patch +++ b/patches/net/minecraft/server/packs/resources/SimplePreparableReloadListener.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/server/packs/resources/SimplePreparableReloadListener.java +++ b/net/minecraft/server/packs/resources/SimplePreparableReloadListener.java -@@ -4,7 +_,7 @@ - import java.util.concurrent.Executor; +@@ -5,7 +_,7 @@ + import net.minecraft.util.profiling.Profiler; import net.minecraft.util.profiling.ProfilerFiller; -public abstract class SimplePreparableReloadListener implements PreparableReloadListener { +public abstract class SimplePreparableReloadListener extends net.neoforged.neoforge.resource.ContextAwareReloadListener implements PreparableReloadListener { @Override public final CompletableFuture reload( - PreparableReloadListener.PreparationBarrier p_10780_, + PreparableReloadListener.PreparationBarrier p_10780_, ResourceManager p_10781_, Executor p_10784_, Executor p_10785_ diff --git a/patches/net/minecraft/server/players/PlayerList.java.patch b/patches/net/minecraft/server/players/PlayerList.java.patch index 1e598eb735..a3c0ab6718 100644 --- a/patches/net/minecraft/server/players/PlayerList.java.patch +++ b/patches/net/minecraft/server/players/PlayerList.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -128,6 +_,7 @@ +@@ -129,6 +_,7 @@ private boolean allowCommandsForAllPlayers; private static final boolean ALLOW_LOGOUTIVATOR = false; private int sendAllPlayerInfoIn; @@ -8,7 +8,7 @@ public PlayerList(MinecraftServer p_203842_, LayeredRegistryAccess p_251844_, PlayerDataStorage p_203844_, int p_203845_) { this.server = p_203842_; -@@ -177,7 +_,7 @@ +@@ -178,7 +_,7 @@ p_11263_.loadGameTypes(optional1.orElse(null)); ServerGamePacketListenerImpl servergamepacketlistenerimpl = new ServerGamePacketListenerImpl(this.server, p_11262_, p_11263_, p_301988_); p_11262_.setupInboundProtocol( @@ -17,23 +17,23 @@ ); GameRules gamerules = serverlevel1.getGameRules(); boolean flag = gamerules.getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN); -@@ -201,6 +_,7 @@ +@@ -202,6 +_,7 @@ servergamepacketlistenerimpl.send(new ClientboundChangeDifficultyPacket(leveldata.getDifficulty(), leveldata.isDifficultyLocked())); servergamepacketlistenerimpl.send(new ClientboundPlayerAbilitiesPacket(p_11263_.getAbilities())); - servergamepacketlistenerimpl.send(new ClientboundSetCarriedItemPacket(p_11263_.getInventory().selected)); + servergamepacketlistenerimpl.send(new ClientboundSetHeldSlotPacket(p_11263_.getInventory().selected)); + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.OnDatapackSyncEvent(this, p_11263_)); - servergamepacketlistenerimpl.send(new ClientboundUpdateRecipesPacket(this.server.getRecipeManager().getOrderedRecipes())); - this.sendPlayerPermissionLevel(p_11263_); - p_11263_.getStats().markAllDirty(); -@@ -265,6 +_,7 @@ - } - + RecipeManager recipemanager = this.server.getRecipeManager(); + servergamepacketlistenerimpl.send( + new ClientboundUpdateRecipesPacket(recipemanager.getSynchronizedItemProperties(), recipemanager.getSynchronizedStonecutterRecipes()) +@@ -236,6 +_,7 @@ + p_11263_.loadAndSpawnEnderpearls(optional1); + p_11263_.loadAndSpawnParentVehicle(optional1); p_11263_.initInventoryMenu(); + net.neoforged.neoforge.event.EventHooks.firePlayerLoggedIn( p_11263_ ); } protected void updateEntireScoreboard(ServerScoreboard p_11274_, ServerPlayer p_11275_) { -@@ -330,6 +_,7 @@ +@@ -301,6 +_,7 @@ optional = Optional.of(compoundtag); p_11225_.load(compoundtag); LOGGER.debug("loading single player"); @@ -41,7 +41,7 @@ } else { optional = this.playerIo.load(p_11225_); } -@@ -338,6 +_,7 @@ +@@ -309,6 +_,7 @@ } protected void save(ServerPlayer p_11277_) { @@ -49,7 +49,7 @@ this.playerIo.save(p_11277_); ServerStatsCounter serverstatscounter = this.stats.get(p_11277_.getUUID()); if (serverstatscounter != null) { -@@ -351,6 +_,7 @@ +@@ -322,6 +_,7 @@ } public void remove(ServerPlayer p_11287_) { @@ -57,37 +57,37 @@ ServerLevel serverlevel = p_11287_.serverLevel(); p_11287_.awardStat(Stats.LEAVE_GAME); this.save(p_11287_); -@@ -440,13 +_,20 @@ +@@ -416,13 +_,20 @@ this.players.remove(p_11237_); p_11237_.serverLevel().removePlayerImmediately(p_11237_, p_348558_); - DimensionTransition dimensiontransition = p_11237_.findRespawnPositionAndUseSpawnBlock(p_11238_, DimensionTransition.DO_NOTHING); + TeleportTransition teleporttransition = p_11237_.findRespawnPositionAndUseSpawnBlock(!p_11238_, TeleportTransition.DO_NOTHING); + + // Neo: Allow changing the respawn position of players. The local dimension transition is updated with the new target. -+ var event = net.neoforged.neoforge.event.EventHooks.firePlayerRespawnPositionEvent(p_11237_, dimensiontransition, p_11238_); -+ dimensiontransition = event.getDimensionTransition(); ++ var event = net.neoforged.neoforge.event.EventHooks.firePlayerRespawnPositionEvent(p_11237_, teleporttransition, p_11238_); ++ teleporttransition = event.getTeleportTransition(); + - ServerLevel serverlevel = dimensiontransition.newLevel(); + ServerLevel serverlevel = teleporttransition.newLevel(); ServerPlayer serverplayer = new ServerPlayer(this.server, serverlevel, p_11237_.getGameProfile(), p_11237_.clientInformation()); serverplayer.connection = p_11237_.connection; serverplayer.restoreFrom(p_11237_, p_11238_); serverplayer.setId(p_11237_.getId()); serverplayer.setMainArm(p_11237_.getMainArm()); -- if (!dimensiontransition.missingRespawnBlock()) { +- if (!teleporttransition.missingRespawnBlock()) { + + // Neo: Allow the event to control if the original spawn position is copied + if (event.copyOriginalSpawnPosition()) { serverplayer.copyRespawnPosition(p_11237_); } -@@ -477,6 +_,7 @@ +@@ -453,6 +_,7 @@ this.playersByUUID.put(serverplayer.getUUID(), serverplayer); serverplayer.initInventoryMenu(); serverplayer.setHealth(serverplayer.getHealth()); + net.neoforged.neoforge.event.EventHooks.firePlayerRespawnEvent(serverplayer, p_11238_); - if (!p_11238_) { - BlockPos blockpos = BlockPos.containing(dimensiontransition.pos()); - BlockState blockstate = serverlevel.getBlockState(blockpos); -@@ -582,6 +_,7 @@ + BlockPos blockpos = serverplayer.getRespawnPosition(); + ServerLevel serverlevel2 = this.server.getLevel(serverplayer.getRespawnDimension()); + if (!p_11238_ && blockpos != null && serverlevel2 != null) { +@@ -559,6 +_,7 @@ } public void op(GameProfile p_11254_) { @@ -95,7 +95,7 @@ this.ops.add(new ServerOpListEntry(p_11254_, this.server.getOperatorUserPermissionLevel(), this.ops.canBypassPlayerLimit(p_11254_))); ServerPlayer serverplayer = this.getPlayer(p_11254_.getId()); if (serverplayer != null) { -@@ -590,6 +_,7 @@ +@@ -567,6 +_,7 @@ } public void deop(GameProfile p_11281_) { @@ -103,7 +103,7 @@ this.ops.remove(p_11281_); ServerPlayer serverplayer = this.getPlayer(p_11281_.getId()); if (serverplayer != null) { -@@ -682,8 +_,12 @@ +@@ -659,8 +_,12 @@ public void sendLevelInfo(ServerPlayer p_11230_, ServerLevel p_11231_) { WorldBorder worldborder = this.server.overworld().getWorldBorder(); p_11230_.connection.send(new ClientboundInitializeBorderPacket(worldborder)); @@ -116,7 +116,7 @@ p_11230_.connection.send(new ClientboundSetDefaultSpawnPositionPacket(p_11231_.getSharedSpawnPos(), p_11231_.getSharedSpawnAngle())); if (p_11231_.isRaining()) { p_11230_.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.START_RAINING, 0.0F)); -@@ -808,13 +_,6 @@ +@@ -785,13 +_,6 @@ if (serverstatscounter == null) { File file1 = this.server.getWorldPath(LevelResource.PLAYER_STATS_DIR).toFile(); File file2 = new File(file1, uuid + ".json"); @@ -130,7 +130,7 @@ serverstatscounter = new ServerStatsCounter(this.server, file2); this.stats.put(uuid, serverstatscounter); -@@ -832,6 +_,8 @@ +@@ -809,6 +_,8 @@ this.advancements.put(uuid, playeradvancements); } @@ -139,7 +139,7 @@ playeradvancements.setPlayer(p_11297_); return playeradvancements; } -@@ -859,7 +_,7 @@ +@@ -836,7 +_,7 @@ } public List getPlayers() { @@ -148,11 +148,11 @@ } @Nullable -@@ -876,6 +_,7 @@ +@@ -853,6 +_,7 @@ playeradvancements.reload(this.server.getAdvancements()); } + net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.OnDatapackSyncEvent(this, null)); this.broadcastAll(new ClientboundUpdateTagsPacket(TagNetworkSerialization.serializeTagsToNetwork(this.registries))); - ClientboundUpdateRecipesPacket clientboundupdaterecipespacket = new ClientboundUpdateRecipesPacket(this.server.getRecipeManager().getOrderedRecipes()); - + RecipeManager recipemanager = this.server.getRecipeManager(); + ClientboundUpdateRecipesPacket clientboundupdaterecipespacket = new ClientboundUpdateRecipesPacket( diff --git a/patches/net/minecraft/stats/RecipeBookSettings.java.patch b/patches/net/minecraft/stats/RecipeBookSettings.java.patch index 193097328f..a778f73da6 100644 --- a/patches/net/minecraft/stats/RecipeBookSettings.java.patch +++ b/patches/net/minecraft/stats/RecipeBookSettings.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/stats/RecipeBookSettings.java +++ b/net/minecraft/stats/RecipeBookSettings.java -@@ -11,7 +_,7 @@ - import net.minecraft.world.inventory.RecipeBookType; - - public final class RecipeBookSettings { +@@ -14,7 +_,7 @@ + public static final StreamCodec STREAM_CODEC = StreamCodec.ofMember( + RecipeBookSettings::write, RecipeBookSettings::read + ); - private static final Map> TAG_FIELDS = ImmutableMap.of( + private static final Map> TAG_FIELDS = net.neoforged.neoforge.common.CommonHooks.buildRecipeBookTypeTagFields(ImmutableMap.of( RecipeBookType.CRAFTING, Pair.of("isGuiOpen", "isFilteringCraftable"), RecipeBookType.FURNACE, -@@ -20,7 +_,7 @@ +@@ -23,7 +_,7 @@ Pair.of("isBlastingFurnaceGuiOpen", "isBlastingFurnaceFilteringCraftable"), RecipeBookType.SMOKER, Pair.of("isSmokerGuiOpen", "isSmokerFilteringCraftable") @@ -18,13 +18,13 @@ private final Map states; private RecipeBookSettings(Map p_12730_) { -@@ -54,7 +_,8 @@ - public static RecipeBookSettings read(FriendlyByteBuf p_12753_) { - Map map = Maps.newEnumMap(RecipeBookType.class); +@@ -72,7 +_,8 @@ + private static RecipeBookSettings read(FriendlyByteBuf p_12753_) { + Map map = new EnumMap<>(RecipeBookType.class); - for (RecipeBookType recipebooktype : RecipeBookType.values()) { + // Neo: filter out modded RecipeBookTypes when connected to a vanilla server + for (RecipeBookType recipebooktype : net.neoforged.neoforge.common.CommonHooks.getFilteredRecipeBookTypeValues()) { boolean flag = p_12753_.readBoolean(); boolean flag1 = p_12753_.readBoolean(); - map.put(recipebooktype, new RecipeBookSettings.TypeSettings(flag, flag1)); + if (flag || flag1) { diff --git a/patches/net/minecraft/tags/BlockTags.java.patch b/patches/net/minecraft/tags/BlockTags.java.patch index d4f91e54c6..53e8b18d50 100644 --- a/patches/net/minecraft/tags/BlockTags.java.patch +++ b/patches/net/minecraft/tags/BlockTags.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/tags/BlockTags.java +++ b/net/minecraft/tags/BlockTags.java -@@ -196,4 +_,8 @@ +@@ -198,4 +_,8 @@ private static TagKey create(String p_203847_) { return TagKey.create(Registries.BLOCK, ResourceLocation.withDefaultNamespace(p_203847_)); } diff --git a/patches/net/minecraft/tags/ItemTags.java.patch b/patches/net/minecraft/tags/ItemTags.java.patch index 8a9759eb48..9dd688d2d9 100644 --- a/patches/net/minecraft/tags/ItemTags.java.patch +++ b/patches/net/minecraft/tags/ItemTags.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/tags/ItemTags.java +++ b/net/minecraft/tags/ItemTags.java -@@ -159,4 +_,8 @@ +@@ -183,4 +_,8 @@ private static TagKey bind(String p_203855_) { return TagKey.create(Registries.ITEM, ResourceLocation.withDefaultNamespace(p_203855_)); } diff --git a/patches/net/minecraft/tags/TagEntry.java.patch b/patches/net/minecraft/tags/TagEntry.java.patch index 3be0c67f65..bbfb68721b 100644 --- a/patches/net/minecraft/tags/TagEntry.java.patch +++ b/patches/net/minecraft/tags/TagEntry.java.patch @@ -18,7 +18,7 @@ + public interface Lookup { @Nullable - T element(ResourceLocation p_215956_); + T element(ResourceLocation p_215956_, boolean p_379371_); - - @Nullable Collection tag(ResourceLocation p_215957_); diff --git a/patches/net/minecraft/tags/TagLoader.java.patch b/patches/net/minecraft/tags/TagLoader.java.patch index 6e7fa7b78f..e18606c9a5 100644 --- a/patches/net/minecraft/tags/TagLoader.java.patch +++ b/patches/net/minecraft/tags/TagLoader.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/tags/TagLoader.java +++ b/net/minecraft/tags/TagLoader.java -@@ -57,6 +_,7 @@ +@@ -64,6 +_,7 @@ String s = resource.sourcePackId(); tagfile.entries().forEach(p_215997_ -> list.add(new TagLoader.EntryWithSource(p_215997_, s))); @@ -8,43 +8,35 @@ } catch (Exception exception) { LOGGER.error("Couldn't read tag list {} from {} in data pack {}", resourcelocation1, resourcelocation, resource.sourcePackId(), exception); } -@@ -67,16 +_,17 @@ - } - - private Either, Collection> build(TagEntry.Lookup p_215979_, List p_215980_) { -- Builder builder = ImmutableSet.builder(); -+ var builder = new java.util.LinkedHashSet(); // Set must retain insertion order, some tag consumers rely on this being the case (see NeoForge#256) +@@ -78,7 +_,8 @@ List list = new ArrayList<>(); for (TagLoader.EntryWithSource tagloader$entrywithsource : p_215980_) { -- if (!tagloader$entrywithsource.entry().build(p_215979_, builder::add)) { -+ if (!tagloader$entrywithsource.entry().build(p_215979_, tagloader$entrywithsource.remove() ? builder::remove : builder::add)) { +- if (!tagloader$entrywithsource.entry().build(p_215979_, sequencedset::add)) { ++ if (!tagloader$entrywithsource.entry().build(p_215979_, tagloader$entrywithsource.remove() ? sequencedset::remove : sequencedset::add)) { + if (!tagloader$entrywithsource.remove()) // Treat all removals as optional at runtime. If it was missing, then it could of never been added. list.add(tagloader$entrywithsource); } } - -- return list.isEmpty() ? Either.right(builder.build()) : Either.left(list); -+ return list.isEmpty() ? Either.right(List.copyOf(builder)) : Either.left(list); - } - - public Map> build(Map> p_203899_) { -@@ -104,7 +_,7 @@ - p_215977_ -> LOGGER.error( +@@ -111,7 +_,7 @@ + p_359633_ -> LOGGER.error( "Couldn't load tag {} as it is missing following references: {}", - p_284682_, -- p_215977_.stream().map(Objects::toString).collect(Collectors.joining(", ")) -+ p_215977_.stream().map(Objects::toString).collect(Collectors.joining("\n\t", "\n\t", "")) + p_359645_, +- p_359633_.stream().map(Objects::toString).collect(Collectors.joining(", ")) ++ p_359633_.stream().map(Objects::toString).collect(Collectors.joining("\n\t", "\n\t", "")) ) ) - .ifRight(p_216001_ -> map.put(p_284682_, (Collection)p_216001_)) -@@ -116,7 +_,8 @@ - return this.build(this.load(p_203901_)); + .ifRight(p_364232_ -> map.put(p_359645_, (List)p_364232_)) +@@ -183,7 +_,11 @@ + } } - public static record EntryWithSource(TagEntry entry, String source) { + public static record EntryWithSource(TagEntry entry, String source, boolean remove) { -+ public EntryWithSource(TagEntry entry, String source) { this(entry, source, false); } ++ public EntryWithSource(TagEntry entry, String source) { ++ this(entry, source, false); ++ } ++ @Override public String toString() { return this.entry + " (from " + this.source + ")"; diff --git a/patches/net/minecraft/util/SpawnUtil.java.patch b/patches/net/minecraft/util/SpawnUtil.java.patch index 9b3eea749e..558cc70a2a 100644 --- a/patches/net/minecraft/util/SpawnUtil.java.patch +++ b/patches/net/minecraft/util/SpawnUtil.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/util/SpawnUtil.java +++ b/net/minecraft/util/SpawnUtil.java -@@ -35,7 +_,7 @@ +@@ -36,7 +_,7 @@ && moveToPossibleSpawnPosition(p_216406_, p_216410_, blockpos$mutableblockpos, p_216411_)) { - T t = (T)p_216404_.create(p_216406_, null, blockpos$mutableblockpos, p_216405_, false, false); + T t = (T)p_216404_.create(p_216406_, null, blockpos$mutableblockpos, p_364255_, false, false); if (t != null) { -- if (t.checkSpawnRules(p_216406_, p_216405_) && t.checkSpawnObstruction(p_216406_)) { -+ if (net.neoforged.neoforge.event.EventHooks.checkSpawnPosition(t, p_216406_, p_216405_)) { +- if (t.checkSpawnRules(p_216406_, p_364255_) && t.checkSpawnObstruction(p_216406_)) { ++ if (net.neoforged.neoforge.event.EventHooks.checkSpawnPosition(t, p_216406_, p_364255_)) { p_216406_.addFreshEntityWithPassengers(t); return Optional.of(t); } diff --git a/patches/net/minecraft/util/context/ContextMap.java.patch b/patches/net/minecraft/util/context/ContextMap.java.patch new file mode 100644 index 0000000000..86160aa256 --- /dev/null +++ b/patches/net/minecraft/util/context/ContextMap.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/util/context/ContextMap.java ++++ b/net/minecraft/util/context/ContextMap.java +@@ -73,7 +_,7 @@ + + public ContextMap create(ContextKeySet p_381168_) { + Set> set = Sets.difference(this.params.keySet(), p_381168_.allowed()); +- if (!set.isEmpty()) { ++ if (false && !set.isEmpty()) { + throw new IllegalArgumentException("Parameters not allowed in this parameter set: " + set); + } else { + Set> set1 = Sets.difference(p_381168_.required(), this.params.keySet()); diff --git a/patches/net/minecraft/util/datafix/DataFixers.java.patch b/patches/net/minecraft/util/datafix/DataFixers.java.patch index b6fe2020c6..7d19c8c1d7 100644 --- a/patches/net/minecraft/util/datafix/DataFixers.java.patch +++ b/patches/net/minecraft/util/datafix/DataFixers.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/util/datafix/DataFixers.java +++ b/net/minecraft/util/datafix/DataFixers.java -@@ -1292,10 +_,35 @@ +@@ -1307,10 +_,35 @@ Schema schema199 = p_14514_.addSchema(3800, SAME_NAMESPACED); UnaryOperator unaryoperator2 = createRenamer(Map.of("minecraft:scute", "minecraft:turtle_scute")); p_14514_.addFixer(ItemRenameFix.create(schema199, "Rename scute item to turtle_scute", unaryoperator2)); @@ -24,7 +24,7 @@ + // Neo: rename neo attributes to new MC attributes + // Happens in 24w03a + Schema neoSchema3804 = p_14514_.addSchema(3804, SAME_NAMESPACED); -+ p_14514_.addFixer(new AttributesRename( ++ p_14514_.addFixer(new AttributesRenameLegacy( + neoSchema3804, + "(Neo) Rename reach attributes to vanilla", + createRenamer(ImmutableMap.of( @@ -36,15 +36,15 @@ Schema schema201 = p_14514_.addSchema(3807, V3807::new); p_14514_.addFixer(new AddNewChoices(schema201, "Added Vault", References.BLOCK_ENTITY)); Schema schema202 = p_14514_.addSchema(3807, 1, SAME_NAMESPACED); -@@ -1316,6 +_,18 @@ - p_14514_.addFixer( - new AttributesRename(schema209, "Rename jump strength attribute", createRenamer("minecraft:horse.jump_strength", "minecraft:generic.jump_strength")) +@@ -1333,6 +_,18 @@ + schema209, "Rename jump strength attribute", createRenamer("minecraft:horse.jump_strength", "minecraft:generic.jump_strength") + ) ); + + // Neo: rename neo attributes to new MC attributes + // Happens in 24w06a + Schema neoSchema3815 = p_14514_.addSchema(3815, SAME_NAMESPACED); -+ p_14514_.addFixer(new AttributesRename( ++ p_14514_.addFixer(new AttributesRenameLegacy( + neoSchema3815, + "(Neo) Rename gravity attribute to vanilla", + createRenamer( diff --git a/patches/net/minecraft/util/thread/BlockableEventLoop.java.patch b/patches/net/minecraft/util/thread/BlockableEventLoop.java.patch index 39297f647a..3a19f55b67 100644 --- a/patches/net/minecraft/util/thread/BlockableEventLoop.java.patch +++ b/patches/net/minecraft/util/thread/BlockableEventLoop.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/util/thread/BlockableEventLoop.java +++ b/net/minecraft/util/thread/BlockableEventLoop.java -@@ -56,10 +_,15 @@ +@@ -59,10 +_,15 @@ } public CompletableFuture submitAsync(Runnable p_18690_) { diff --git a/patches/net/minecraft/world/effect/MobEffect.java.patch b/patches/net/minecraft/world/effect/MobEffect.java.patch index c8eef70796..135584ef6b 100644 --- a/patches/net/minecraft/world/effect/MobEffect.java.patch +++ b/patches/net/minecraft/world/effect/MobEffect.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/effect/MobEffect.java +++ b/net/minecraft/world/effect/MobEffect.java -@@ -35,7 +_,7 @@ +@@ -36,7 +_,7 @@ import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.flag.FeatureFlags; @@ -9,7 +9,7 @@ public static final Codec> CODEC = BuiltInRegistries.MOB_EFFECT.holderByNameCodec(); public static final StreamCodec> STREAM_CODEC = ByteBufCodecs.holderRegistry(Registries.MOB_EFFECT); private static final int AMBIENT_ALPHA = Mth.floor(38.25F); -@@ -130,6 +_,18 @@ +@@ -133,6 +_,18 @@ return this; } @@ -28,19 +28,11 @@ public MobEffect setBlendDuration(int p_316265_) { this.blendDurationTicks = p_316265_; return this; -@@ -181,8 +_,24 @@ +@@ -184,8 +_,16 @@ return this.requiredFeatures; } - static record AttributeTemplate(ResourceLocation id, double amount, AttributeModifier.Operation operation) { -+ /** -+ * Neo: Allowing mods to define client behavior for their MobEffects -+ * @deprecated Use {@link net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent} instead -+ */ -+ @Deprecated(forRemoval = true, since = "1.21") -+ public void initializeClient(java.util.function.Consumer consumer) { -+ } -+ + static record AttributeTemplate(ResourceLocation id, double amount, AttributeModifier.Operation operation, @Nullable it.unimi.dsi.fastutil.ints.Int2DoubleFunction curve) { + + public AttributeTemplate(ResourceLocation id, double amount, AttributeModifier.Operation operation) { diff --git a/patches/net/minecraft/world/effect/MobEffectInstance.java.patch b/patches/net/minecraft/world/effect/MobEffectInstance.java.patch index 0c314eaa46..9fb8638906 100644 --- a/patches/net/minecraft/world/effect/MobEffectInstance.java.patch +++ b/patches/net/minecraft/world/effect/MobEffectInstance.java.patch @@ -1,42 +1,6 @@ --- a/net/minecraft/world/effect/MobEffectInstance.java +++ b/net/minecraft/world/effect/MobEffectInstance.java -@@ -80,6 +_,7 @@ - this.visible = p_19532_; - this.showIcon = p_19533_; - this.hiddenEffect = p_316863_; -+ this.effect.value().fillEffectCures(this.cures, this); - } - - public MobEffectInstance(MobEffectInstance p_19543_) { -@@ -97,6 +_,8 @@ - p_324529_.showIcon(), - p_324529_.hiddenEffect().map(p_323227_ -> new MobEffectInstance(p_324441_, p_323227_)).orElse(null) - ); -+ this.cures.clear(); -+ p_324529_.cures().ifPresent(this.cures::addAll); - } - - private MobEffectInstance.Details asDetails() { -@@ -106,7 +_,8 @@ - this.isAmbient(), - this.isVisible(), - this.showIcon(), -- Optional.ofNullable(this.hiddenEffect).map(MobEffectInstance::asDetails) -+ Optional.ofNullable(this.hiddenEffect).map(MobEffectInstance::asDetails), -+ Optional.of(this.getCures()).filter(cures -> !cures.isEmpty()) - ); - } - -@@ -124,6 +_,8 @@ - this.ambient = p_19549_.ambient; - this.visible = p_19549_.visible; - this.showIcon = p_19549_.showIcon; -+ this.cures.clear(); -+ this.cures.addAll(p_19549_.cures); - } - - public boolean update(MobEffectInstance p_19559_) { -@@ -324,11 +_,11 @@ +@@ -327,11 +_,11 @@ .compareFalseFirst(this.isAmbient(), p_19566_.isAmbient()) .compareFalseFirst(this.isInfiniteDuration(), p_19566_.isInfiniteDuration()) .compare(this.getDuration(), p_19566_.getDuration()) @@ -50,77 +14,27 @@ .result(); } -@@ -348,6 +_,15 @@ - this.blendState.setImmediate(this); - } - -+ private final java.util.Set cures = com.google.common.collect.Sets.newIdentityHashSet(); -+ -+ /** -+ * {@return the {@link net.neoforged.neoforge.common.EffectCure}s which can cure the {@link MobEffect} held by this {@link MobEffectInstance}} -+ */ -+ public java.util.Set getCures() { -+ return cures; -+ } -+ - static class BlendState { - private float factor; - private float factorPreviousFrame; -@@ -395,8 +_,7 @@ +@@ -398,8 +_,7 @@ } static record Details( - int amplifier, int duration, boolean ambient, boolean showParticles, boolean showIcon, Optional hiddenEffect - ) { -+ int amplifier, int duration, boolean ambient, boolean showParticles, boolean showIcon, Optional hiddenEffect, Optional> cures) { ++ int amplifier, int duration, boolean ambient, boolean showParticles, boolean showIcon, Optional hiddenEffect) { public static final MapCodec MAP_CODEC = MapCodec.recursive( "MobEffectInstance.Details", p_323465_ -> RecordCodecBuilder.mapCodec( -@@ -407,12 +_,14 @@ +@@ -410,11 +_,11 @@ Codec.BOOL.optionalFieldOf("show_particles", Boolean.valueOf(true)).forGetter(MobEffectInstance.Details::showParticles), Codec.BOOL.optionalFieldOf("show_icon").forGetter(p_323788_ -> Optional.of(p_323788_.showIcon())), p_323465_.optionalFieldOf("hidden_effect").forGetter(MobEffectInstance.Details::hiddenEffect) -+ // Neo: Add additional serialization logic for custom EffectCure(s) -+ , net.neoforged.neoforge.common.util.NeoForgeExtraCodecs.setOf(net.neoforged.neoforge.common.EffectCure.CODEC).optionalFieldOf("neoforge:cures").forGetter(MobEffectInstance.Details::cures) - ) +- ) ++ ) .apply(p_324063_, MobEffectInstance.Details::create) ) ); - public static final StreamCodec STREAM_CODEC = StreamCodec.recursive( -- p_329990_ -> StreamCodec.composite( + public static final StreamCodec STREAM_CODEC = StreamCodec.recursive( -+ p_329990_ -> net.neoforged.neoforge.network.codec.NeoForgeStreamCodecs.composite( + p_329990_ -> StreamCodec.composite( ByteBufCodecs.VAR_INT, MobEffectInstance.Details::amplifier, - ByteBufCodecs.VAR_INT, -@@ -425,6 +_,12 @@ - MobEffectInstance.Details::showIcon, - p_329990_.apply(ByteBufCodecs::optional), - MobEffectInstance.Details::hiddenEffect, -+ // Neo: Add additional serialization logic for custom EffectCure(s) -+ net.neoforged.neoforge.network.codec.NeoForgeStreamCodecs.connectionAware( -+ ByteBufCodecs.optional(net.neoforged.neoforge.common.EffectCure.STREAM_CODEC.apply(ByteBufCodecs.collection(java.util.HashSet::new))), -+ net.neoforged.neoforge.network.codec.NeoForgeStreamCodecs.uncheckedUnit(Optional.empty()) -+ ), -+ MobEffectInstance.Details::cures, - MobEffectInstance.Details::new - ) - ); -@@ -434,5 +_,17 @@ - ) { - return new MobEffectInstance.Details(p_323657_, p_324205_, p_324263_, p_324000_, p_323607_.orElse(p_324000_), p_324604_); - } -+ -+ private static MobEffectInstance.Details create( -+ int p_323657_, int p_324205_, boolean p_324263_, boolean p_324000_, Optional p_323607_, Optional p_324604_, Optional> cures -+ ) { -+ return new MobEffectInstance.Details(p_323657_, p_324205_, p_324263_, p_324000_, p_323607_.orElse(p_324000_), p_324604_, cures); -+ } -+ -+ @Deprecated -+ Details(int amplifier, int duration, boolean ambient, boolean showParticles, boolean showIcon, Optional hiddenEffect) { -+ this(amplifier, duration, ambient, showParticles, showIcon, hiddenEffect, Optional.empty()); -+ } -+ - } - } diff --git a/patches/net/minecraft/world/effect/PoisonMobEffect.java.patch b/patches/net/minecraft/world/effect/PoisonMobEffect.java.patch index 39db38e109..d2c1139e5e 100644 --- a/patches/net/minecraft/world/effect/PoisonMobEffect.java.patch +++ b/patches/net/minecraft/world/effect/PoisonMobEffect.java.patch @@ -1,16 +1,16 @@ --- a/net/minecraft/world/effect/PoisonMobEffect.java +++ b/net/minecraft/world/effect/PoisonMobEffect.java -@@ -10,7 +_,12 @@ +@@ -11,7 +_,12 @@ @Override - public boolean applyEffectTick(LivingEntity p_296276_, int p_296233_) { + public boolean applyEffectTick(ServerLevel p_376442_, LivingEntity p_296276_, int p_296233_) { if (p_296276_.getHealth() > 1.0F) { -- p_296276_.hurt(p_296276_.damageSources().magic(), 1.0F); +- p_296276_.hurtServer(p_376442_, p_296276_.damageSources().magic(), 1.0F); + // Neo: Replace DamageSources#magic() with neoforge:poison to allow differentiating poison damage. + // Fallback to minecraft:magic in client code when connecting to a vanilla server. + // LivingEntity#hurt(DamageSource) will no-op in client code immediately, but the holder is resolved before the no-op. + var dTypeReg = p_296276_.damageSources().damageTypes; -+ var dType = dTypeReg.getHolder(net.neoforged.neoforge.common.NeoForgeMod.POISON_DAMAGE).orElse(dTypeReg.getHolderOrThrow(net.minecraft.world.damagesource.DamageTypes.MAGIC)); -+ p_296276_.hurt(new net.minecraft.world.damagesource.DamageSource(dType), 1.0F); ++ var dType = dTypeReg.get(net.neoforged.neoforge.common.NeoForgeMod.POISON_DAMAGE).orElse(dTypeReg.getOrThrow(net.minecraft.world.damagesource.DamageTypes.MAGIC)); ++ p_296276_.hurtServer(p_376442_, new net.minecraft.world.damagesource.DamageSource(dType), 1.0F); } return true; diff --git a/patches/net/minecraft/world/entity/Entity.java.patch b/patches/net/minecraft/world/entity/Entity.java.patch index d9fa9191ff..801a7043a6 100644 --- a/patches/net/minecraft/world/entity/Entity.java.patch +++ b/patches/net/minecraft/world/entity/Entity.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -128,7 +_,7 @@ +@@ -136,7 +_,7 @@ import net.minecraft.world.scores.Team; import org.slf4j.Logger; --public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, CommandSource, ScoreHolder { -+public abstract class Entity extends net.neoforged.neoforge.attachment.AttachmentHolder implements SyncedDataHolder, Nameable, EntityAccess, CommandSource, ScoreHolder, net.neoforged.neoforge.common.extensions.IEntityExtension { +-public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder { ++public abstract class Entity extends net.neoforged.neoforge.attachment.AttachmentHolder implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder, net.neoforged.neoforge.common.extensions.IEntityExtension { private static final Logger LOGGER = LogUtils.getLogger(); public static final String ID_TAG = "id"; public static final String PASSENGERS_TAG = "Passengers"; -@@ -149,6 +_,7 @@ +@@ -157,6 +_,7 @@ private static final double LAVA_SLOW_FLOW_SCALE = 0.0023333333333333335; public static final String UUID_TAG = "UUID"; private static double viewScale = 1.0; @@ -17,7 +17,7 @@ private final EntityType type; private int id = ENTITY_COUNTER.incrementAndGet(); public boolean blocksBuilding; -@@ -194,8 +_,10 @@ +@@ -201,8 +_,10 @@ public int tickCount; private int remainingFireTicks = -this.getFireImmuneTicks(); protected boolean wasTouchingWater; @@ -28,7 +28,7 @@ private final Set> fluidOnEyes = new HashSet<>(); public int invulnerableTime; protected boolean firstTick = true; -@@ -263,7 +_,10 @@ +@@ -271,7 +_,10 @@ this.defineSynchedData(synchedentitydata$builder); this.entityData = synchedentitydata$builder.build(); this.setPos(0.0, 0.0, 0.0); @@ -39,7 +39,7 @@ } public boolean isColliding(BlockPos p_20040_, BlockState p_20041_) { -@@ -467,7 +_,7 @@ +@@ -478,7 +_,7 @@ if (this.isInLava()) { this.lavaHurt(); @@ -48,36 +48,22 @@ } this.checkBelowWorld(); -@@ -673,7 +_,7 @@ - double d1 = vec3.x; - double d2 = vec3.y; - double d3 = vec3.z; -- this.flyDist = this.flyDist + (float)(vec3.length() * 0.6); -+ this.flyDist = (float)((double)this.flyDist + vec3.length() * 0.6D); - BlockPos blockpos1 = this.getOnPos(); - BlockState blockstate1 = this.level().getBlockState(blockpos1); - boolean flag1 = this.isStateClimbable(blockstate1); -@@ -717,16 +_,16 @@ - this.setRemainingFireTicks(-this.getFireImmuneTicks()); - } - -- if (this.wasOnFire && (this.isInPowderSnow || this.isInWaterRainOrBubble())) { -+ if (this.wasOnFire && (this.isInPowderSnow || this.isInWaterRainOrBubble() || this.isInFluidType((fluidType, height) -> this.canFluidExtinguish(fluidType)))) { - this.playEntityOnFireExtinguishedSound(); - } +@@ -763,12 +_,12 @@ + this.setRemainingFireTicks(-this.getFireImmuneTicks()); } -- if (this.isOnFire() && (this.isInPowderSnow || this.isInWaterRainOrBubble())) { -+ if (this.isOnFire() && (this.isInPowderSnow || this.isInWaterRainOrBubble() || this.isInFluidType((fluidType, height) -> this.canFluidExtinguish(fluidType)))) { - this.setRemainingFireTicks(-this.getFireImmuneTicks()); +- if (this.wasOnFire && (this.isInPowderSnow || this.isInWaterRainOrBubble())) { ++ if (this.wasOnFire && (this.isInPowderSnow || this.isInWaterRainOrBubble()|| this.isInFluidType((fluidType, height) -> this.canFluidExtinguish(fluidType)))) { + this.playEntityOnFireExtinguishedSound(); } + } -- this.level().getProfiler().pop(); -+ this.level.getProfiler().pop(); +- if (this.isOnFire() && (this.isInPowderSnow || this.isInWaterRainOrBubble())) { ++ if (this.isOnFire() && (this.isInPowderSnow || this.isInWaterRainOrBubble()|| this.isInFluidType((fluidType, height) -> this.canFluidExtinguish(fluidType)))) { + this.setRemainingFireTicks(-this.getFireImmuneTicks()); } } - } -@@ -812,9 +_,7 @@ +@@ -848,9 +_,7 @@ return blockpos; } else { BlockState blockstate = this.level().getBlockState(blockpos); @@ -88,7 +74,7 @@ ? blockpos.atY(Mth.floor(this.position.y - (double)p_216987_)) : blockpos; } -@@ -1076,19 +_,19 @@ +@@ -1132,19 +_,19 @@ return !blockstate.is(BlockTags.INSIDE_STEP_SOUND_BLOCKS) && !blockstate.is(BlockTags.COMBINATION_STEP_SOUND_BLOCKS) ? p_278049_ : blockpos; } @@ -114,7 +100,7 @@ this.playSound(soundtype.getStepSound(), soundtype.getVolume() * 0.15F, soundtype.getPitch()); } -@@ -1241,20 +_,23 @@ +@@ -1297,20 +_,23 @@ public void updateSwimming() { if (this.isSwimming()) { @@ -135,7 +121,7 @@ - double d0 = this.level().dimensionType().ultraWarm() ? 0.007 : 0.0023333333333333335; - boolean flag = this.updateFluidHeightAndDoFluidPushing(FluidTags.LAVA, d0); - return this.isInWater() || flag; -+ if (this.isInFluidType() && !(this.getVehicle() instanceof Boat)) { ++ if (this.isInFluidType() && !(this.getVehicle() instanceof AbstractBoat)) { + this.fallDistance *= this.forgeFluidTypeHeight.object2DoubleEntrySet().stream().filter(e -> !e.getKey().isAir() && !e.getKey().isVanilla()).map(e -> this.getFluidFallDistanceModifier(e.getKey())).min(Float::compare).orElse(1F); + if (this.isInFluidType((fluidType, height) -> !fluidType.isAir() && !fluidType.isVanilla() && this.canFluidExtinguish(fluidType))) this.clearFire(); + } @@ -143,15 +129,15 @@ } void updateInWaterStateAndDoWaterCurrentPushing() { -@@ -1279,6 +_,7 @@ +@@ -1335,6 +_,7 @@ private void updateFluidOnEyes() { this.wasEyeInWater = this.isEyeInFluid(FluidTags.WATER); this.fluidOnEyes.clear(); + this.forgeFluidTypeOnEyes = net.neoforged.neoforge.common.NeoForgeMod.EMPTY_TYPE.value(); double d0 = this.getEyeY(); - if (this.getVehicle() instanceof Boat boat && !boat.isUnderWater() && boat.getBoundingBox().maxY >= d0 && boat.getBoundingBox().minY <= d0) { - return; -@@ -1288,7 +_,7 @@ + if (this.getVehicle() instanceof AbstractBoat abstractboat + && !abstractboat.isUnderWater() +@@ -1347,7 +_,7 @@ FluidState fluidstate = this.level().getFluidState(blockpos); double d1 = (double)((float)blockpos.getY() + fluidstate.getHeight(this.level(), blockpos)); if (d1 > d0) { @@ -160,7 +146,7 @@ } } -@@ -1333,12 +_,13 @@ +@@ -1392,12 +_,13 @@ } public boolean canSpawnSprintParticle() { @@ -175,7 +161,7 @@ if (blockstate.getRenderShape() != RenderShape.INVISIBLE) { Vec3 vec3 = this.getDeltaMovement(); BlockPos blockpos1 = this.blockPosition(); -@@ -1352,16 +_,19 @@ +@@ -1411,16 +_,19 @@ d1 = Mth.clamp(d1, (double)blockpos.getZ(), (double)blockpos.getZ() + 1.0); } @@ -197,7 +183,7 @@ } public void moveRelative(float p_19921_, Vec3 p_19922_) { -@@ -1704,6 +_,10 @@ +@@ -1799,6 +_,10 @@ p_20241_.put("Tags", listtag); } @@ -208,7 +194,7 @@ this.addAdditionalSaveData(p_20241_); if (this.isVehicle()) { ListTag listtag1 = new ListTag(); -@@ -1784,6 +_,8 @@ +@@ -1880,6 +_,8 @@ this.setGlowingTag(p_20259_.getBoolean("Glowing")); this.setTicksFrozen(p_20259_.getInt("TicksFrozen")); this.hasVisualFire = p_20259_.getBoolean("HasVisualFire"); @@ -217,16 +203,16 @@ if (p_20259_.contains("Tags", 9)) { this.tags.clear(); ListTag listtag3 = p_20259_.getList("Tags", 8); -@@ -1868,6 +_,8 @@ +@@ -1962,6 +_,8 @@ } else { - ItemEntity itementity = new ItemEntity(this.level(), this.getX(), this.getY() + (double)p_19986_, this.getZ(), p_19985_); + ItemEntity itementity = new ItemEntity(p_376141_, this.getX(), this.getY() + (double)p_376881_, this.getZ(), p_376472_); itementity.setDefaultPickUpDelay(); + if (captureDrops() != null) captureDrops().add(itementity); + else - this.level().addFreshEntity(itementity); + p_376141_.addFreshEntity(itementity); return itementity; } -@@ -1935,7 +_,11 @@ +@@ -2029,7 +_,11 @@ public void rideTick() { this.setDeltaMovement(Vec3.ZERO); @@ -239,7 +225,7 @@ if (this.isPassenger()) { this.getVehicle().positionRider(this); } -@@ -1993,6 +_,7 @@ +@@ -2089,6 +_,7 @@ } } @@ -247,7 +233,7 @@ if (p_19967_ || this.canRide(p_19966_) && p_19966_.canAddPassenger(this)) { if (this.isPassenger()) { this.stopRiding(); -@@ -2024,6 +_,7 @@ +@@ -2120,6 +_,7 @@ public void removeVehicle() { if (this.vehicle != null) { Entity entity = this.vehicle; @@ -255,7 +241,7 @@ this.vehicle = null; entity.removePassenger(this); } -@@ -2073,6 +_,8 @@ +@@ -2169,6 +_,8 @@ return this.passengers.isEmpty(); } @@ -264,7 +250,7 @@ protected boolean couldAcceptPassenger() { return true; } -@@ -2257,7 +_,7 @@ +@@ -2357,7 +_,7 @@ } public boolean isVisuallyCrawling() { @@ -273,16 +259,16 @@ } public void setSwimming(boolean p_20283_) { -@@ -2366,7 +_,7 @@ +@@ -2470,7 +_,7 @@ this.igniteForSeconds(8.0F); } -- this.hurt(this.damageSources().lightningBolt(), 5.0F); +- this.hurtServer(p_19927_, this.damageSources().lightningBolt(), 5.0F); + this.hurt(this.damageSources().lightningBolt(), p_19928_.getDamage()); } public void onAboveBubbleCol(boolean p_20313_) { -@@ -2461,7 +_,7 @@ +@@ -2565,7 +_,7 @@ } protected Component getTypeName() { @@ -291,10 +277,10 @@ } public boolean is(Entity p_20356_) { -@@ -2516,10 +_,11 @@ +@@ -2620,10 +_,11 @@ } - public boolean isInvulnerableTo(DamageSource p_20122_) { + protected final boolean isInvulnerableToBase(DamageSource p_20122_) { - return this.isRemoved() + boolean isVanillaInvulnerable = this.isRemoved() || this.invulnerable && !p_20122_.is(DamageTypeTags.BYPASSES_INVULNERABILITY) && !p_20122_.isCreativePlayer() @@ -304,15 +290,15 @@ } public boolean isInvulnerable() { -@@ -2544,6 +_,7 @@ +@@ -2648,6 +_,7 @@ @Nullable - public Entity changeDimension(DimensionTransition p_350951_) { -+ if (!net.neoforged.neoforge.common.CommonHooks.onTravelToDimension(this, p_350951_.newLevel().dimension())) return null; + public Entity teleport(TeleportTransition p_379899_) { ++ if (!net.neoforged.neoforge.common.CommonHooks.onTravelToDimension(this, p_379899_.newLevel().dimension())) return null; if (this.level() instanceof ServerLevel serverlevel && !this.isRemoved()) { - ServerLevel serverlevel1 = p_350951_.newLevel(); - List list = this.getPassengers(); -@@ -2667,6 +_,7 @@ + ServerLevel serverlevel1 = p_379899_.newLevel(); + boolean flag = serverlevel1.dimension() != serverlevel.dimension(); +@@ -2855,6 +_,7 @@ return this.stringUUID; } @@ -320,7 +306,7 @@ public boolean isPushedByFluid() { return true; } -@@ -2783,6 +_,8 @@ +@@ -2963,6 +_,8 @@ EntityDimensions entitydimensions = this.dimensions; Pose pose = this.getPose(); EntityDimensions entitydimensions1 = this.getDimensions(pose); @@ -329,7 +315,7 @@ this.dimensions = entitydimensions1; this.eyeHeight = entitydimensions1.eyeHeight(); this.reapplyPosition(); -@@ -3110,9 +_,17 @@ +@@ -3268,9 +_,17 @@ return Mth.lerp(p_352259_, this.yRotO, this.yRot); } @@ -348,7 +334,7 @@ } else { AABB aabb = this.getBoundingBox().deflate(0.001); int i = Mth.floor(aabb.minX); -@@ -3127,25 +_,36 @@ +@@ -3285,25 +_,36 @@ Vec3 vec3 = Vec3.ZERO; int k1 = 0; BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); @@ -392,7 +378,7 @@ } } } -@@ -3153,27 +_,30 @@ +@@ -3311,27 +_,30 @@ } } @@ -433,7 +419,7 @@ } } -@@ -3186,7 +_,10 @@ +@@ -3344,7 +_,10 @@ return !this.level().hasChunksAt(i, k, j, l); } @@ -444,7 +430,7 @@ return this.fluidHeight.getDouble(p_204037_); } -@@ -3323,6 +_,7 @@ +@@ -3481,6 +_,7 @@ this.levelCallback.onMove(); } @@ -452,9 +438,9 @@ } public void checkDespawn() { -@@ -3449,6 +_,128 @@ +@@ -3606,6 +_,128 @@ - public boolean mayInteract(Level p_146843_, BlockPos p_146844_) { + public boolean mayInteract(ServerLevel p_376870_, BlockPos p_146844_) { return true; + } + @@ -492,7 +478,7 @@ + + // Neo: Set the default behavior for trampling on Farmland + @Override -+ public boolean canTrample(BlockState state, BlockPos pos, float fallDistance) { ++ public boolean canTrample(ServerLevel level, BlockState state, BlockPos pos, float fallDistance) { + return level.random.nextFloat() < fallDistance - 0.5F + && this instanceof LivingEntity + && (this instanceof Player || net.neoforged.neoforge.event.EventHooks.canEntityGrief(level, this)) diff --git a/patches/net/minecraft/world/entity/EntityType.java.patch b/patches/net/minecraft/world/entity/EntityType.java.patch index 1f3f299099..4439873672 100644 --- a/patches/net/minecraft/world/entity/EntityType.java.patch +++ b/patches/net/minecraft/world/entity/EntityType.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/EntityType.java +++ b/net/minecraft/world/entity/EntityType.java -@@ -834,6 +_,10 @@ +@@ -1088,6 +_,10 @@ private final float spawnDimensionsScale; private final FeatureFlagSet requiredFeatures; @@ -8,14 +8,14 @@ + private final java.util.function.ToIntFunction> trackingRangeSupplier; + private final java.util.function.ToIntFunction> updateIntervalSupplier; + - private static EntityType register(String p_20635_, EntityType.Builder p_20636_) { - return Registry.register(BuiltInRegistries.ENTITY_TYPE, p_20635_, p_20636_.build(p_20635_)); + private static EntityType register(ResourceKey> p_368669_, EntityType.Builder p_368714_) { + return Registry.register(BuiltInRegistries.ENTITY_TYPE, p_368669_, p_368714_.build(p_368669_)); } -@@ -860,6 +_,26 @@ - int p_273451_, +@@ -1124,6 +_,28 @@ + Optional> p_368696_, FeatureFlagSet p_273518_ ) { -+ this(p_273268_, p_272918_, p_273417_, p_273389_, p_273556_, p_272654_, p_273631_, p_272946_, p_338404_, p_272895_, p_273451_, p_273518_, EntityType::defaultTrackDeltasSupplier, EntityType::defaultTrackingRangeSupplier, EntityType::defaultUpdateIntervalSupplier); ++ this(p_273268_, p_272918_, p_273417_, p_273389_, p_273556_, p_272654_, p_273631_, p_272946_, p_338404_, p_272895_, p_273451_, p_368582_, p_368696_, p_273518_, EntityType::defaultTrackDeltasSupplier, EntityType::defaultTrackingRangeSupplier, EntityType::defaultUpdateIntervalSupplier); + } + + public EntityType( @@ -30,6 +30,8 @@ + float p_338404_, + int p_272895_, + int p_273451_, ++ String p_368582_, ++ Optional> p_368696_, + FeatureFlagSet p_273518_, + final java.util.function.Predicate> trackDeltasSupplier, + final java.util.function.ToIntFunction> trackingRangeSupplier, @@ -38,9 +40,9 @@ this.factory = p_273268_; this.category = p_272918_; this.canSpawnFarFromPlayer = p_272654_; -@@ -872,6 +_,9 @@ - this.clientTrackingRange = p_272895_; - this.updateInterval = p_273451_; +@@ -1138,6 +_,9 @@ + this.descriptionId = p_368582_; + this.lootTable = p_368696_; this.requiredFeatures = p_273518_; + this.trackDeltasSupplier = trackDeltasSupplier; + this.trackingRangeSupplier = trackingRangeSupplier; @@ -48,10 +50,10 @@ } @Nullable -@@ -958,6 +_,15 @@ +@@ -1228,6 +_,15 @@ mob.yHeadRot = mob.getYRot(); mob.yBodyRot = mob.getYRot(); - mob.finalizeSpawn(p_262637_, p_262637_.getCurrentDifficultyAt(mob.blockPosition()), p_262666_, null); + mob.finalizeSpawn(p_262637_, p_262637_.getCurrentDifficultyAt(mob.blockPosition()), p_360546_, null); + + if (mob.isSpawnCancelled()) { + // Neo: Discard mob, spawn was cancelled @@ -64,7 +66,7 @@ mob.playAmbientSound(); } -@@ -1149,14 +_,23 @@ +@@ -1410,14 +_,23 @@ } public int clientTrackingRange() { @@ -88,8 +90,8 @@ return this != PLAYER && this != LLAMA_SPIT && this != WITHER -@@ -1192,6 +_,8 @@ - return this.builtInRegistryHolder; +@@ -1469,6 +_,8 @@ + return (p_375561_, p_375562_) -> new ChestRaft(p_375561_, p_375562_, p_376648_); } + public Stream>> getTags() {return this.builtInRegistryHolder().tags();} @@ -97,9 +99,9 @@ public static class Builder { private final EntityType.EntityFactory factory; private final MobCategory category; -@@ -1207,6 +_,10 @@ - private EntityAttachments.Builder attachments = EntityAttachments.builder(); - private FeatureFlagSet requiredFeatures = FeatureFlags.VANILLA_SET; +@@ -1488,6 +_,10 @@ + ); + private DependantName, String> descriptionId = p_367918_ -> Util.makeDescriptionId("entity", p_367918_.location()); + private java.util.function.Predicate> velocityUpdateSupplier = EntityType::defaultTrackDeltasSupplier; + private java.util.function.ToIntFunction> trackingRangeSupplier = EntityType::defaultTrackingRangeSupplier; @@ -108,32 +110,32 @@ private Builder(EntityType.EntityFactory p_20696_, MobCategory p_20697_) { this.factory = p_20696_; this.category = p_20697_; -@@ -1314,6 +_,21 @@ +@@ -1600,6 +_,21 @@ return this; } + public EntityType.Builder setUpdateInterval(int interval) { -+ this.updateIntervalSupplier = t->interval; -+ return this; ++ this.updateIntervalSupplier = t->interval; ++ return this; + } + + public EntityType.Builder setTrackingRange(int range) { -+ this.trackingRangeSupplier = t->range; -+ return this; ++ this.trackingRangeSupplier = t->range; ++ return this; + } + + public EntityType.Builder setShouldReceiveVelocityUpdates(boolean value) { -+ this.velocityUpdateSupplier = t->value; -+ return this; ++ this.velocityUpdateSupplier = t->value; ++ return this; + } + - public EntityType build(String p_20713_) { + public EntityType build(ResourceKey> p_368626_) { if (this.serialize) { - Util.fetchChoiceType(References.ENTITY_TREE, p_20713_); -@@ -1331,7 +_,10 @@ - this.spawnDimensionsScale, - this.clientTrackingRange, + Util.fetchChoiceType(References.ENTITY_TREE, p_368626_.location().toString()); +@@ -1619,7 +_,10 @@ this.updateInterval, + this.descriptionId.get(p_368626_), + this.lootTable.get(p_368626_), - this.requiredFeatures + this.requiredFeatures, + velocityUpdateSupplier, diff --git a/patches/net/minecraft/world/entity/ExperienceOrb.java.patch b/patches/net/minecraft/world/entity/ExperienceOrb.java.patch index d81cfa82bb..9a5df1bf49 100644 --- a/patches/net/minecraft/world/entity/ExperienceOrb.java.patch +++ b/patches/net/minecraft/world/entity/ExperienceOrb.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/entity/ExperienceOrb.java +++ b/net/minecraft/world/entity/ExperienceOrb.java -@@ -112,7 +_,8 @@ - this.move(MoverType.SELF, this.getDeltaMovement()); +@@ -113,7 +_,8 @@ + this.applyEffectsFromBlocks(); float f = 0.98F; if (this.onGround()) { - f = this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getFriction() * 0.98F; @@ -10,7 +10,7 @@ } this.setDeltaMovement(this.getDeltaMovement().multiply((double)f, 0.98, (double)f)); -@@ -133,7 +_,7 @@ +@@ -134,7 +_,7 @@ private void scanForEntities() { if (this.followingPlayer == null || this.followingPlayer.distanceToSqr(this) > 64.0) { @@ -19,7 +19,7 @@ } if (this.level() instanceof ServerLevel) { -@@ -228,6 +_,7 @@ +@@ -232,6 +_,7 @@ public void playerTouch(Player p_20792_) { if (p_20792_ instanceof ServerPlayer serverplayer) { if (p_20792_.takeXpDelay == 0) { @@ -27,7 +27,7 @@ p_20792_.takeXpDelay = 2; p_20792_.take(this, 1); int i = this.repairPlayerItems(serverplayer, this.value); -@@ -247,7 +_,7 @@ +@@ -251,7 +_,7 @@ Optional optional = EnchantmentHelper.getRandomItemWith(EnchantmentEffectComponents.REPAIR_WITH_XP, p_344821_, ItemStack::isDamaged); if (optional.isPresent()) { ItemStack itemstack = optional.get().itemStack(); diff --git a/patches/net/minecraft/world/entity/LightningBolt.java.patch b/patches/net/minecraft/world/entity/LightningBolt.java.patch index f74497ef94..8a59dc341c 100644 --- a/patches/net/minecraft/world/entity/LightningBolt.java.patch +++ b/patches/net/minecraft/world/entity/LightningBolt.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/LightningBolt.java +++ b/net/minecraft/world/entity/LightningBolt.java -@@ -38,6 +_,7 @@ +@@ -39,6 +_,7 @@ private ServerPlayer cause; private final Set hitEntities = Sets.newHashSet(); private int blocksSetOnFire; diff --git a/patches/net/minecraft/world/entity/LivingEntity.java.patch b/patches/net/minecraft/world/entity/LivingEntity.java.patch index b22fc4915b..ebb7a0cbf9 100644 --- a/patches/net/minecraft/world/entity/LivingEntity.java.patch +++ b/patches/net/minecraft/world/entity/LivingEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -132,7 +_,7 @@ +@@ -137,7 +_,7 @@ import net.minecraft.world.scores.Scoreboard; import org.slf4j.Logger; @@ -9,22 +9,43 @@ private static final Logger LOGGER = LogUtils.getLogger(); private static final String TAG_ACTIVE_EFFECTS = "active_effects"; private static final ResourceLocation SPEED_MODIFIER_POWDER_SNOW_ID = ResourceLocation.withDefaultNamespace("powder_snow"); -@@ -254,6 +_,14 @@ - private boolean skipDropExperience; - private final Reference2ObjectMap> activeLocationDependentEnchantments = new Reference2ObjectArrayMap<>(); +@@ -179,13 +_,18 @@ + public static final float EXTRA_RENDER_CULLING_SIZE_WITH_BIG_HAT = 0.5F; + public static final float DEFAULT_BABY_SCALE = 0.5F; + public static final String ATTRIBUTES_FIELD = "attributes"; +- public static final Predicate PLAYER_NOT_WEARING_DISGUISE_ITEM = p_379074_ -> { ++ public static final java.util.function.BiPredicate PLAYER_NOT_WEARING_DISGUISE_ITEM_FOR_TARGET = (p_379074_, target) -> { + if (p_379074_ instanceof Player player) { + ItemStack itemstack = player.getItemBySlot(EquipmentSlot.HEAD); +- return !itemstack.is(ItemTags.GAZE_DISGUISE_EQUIPMENT); ++ return !itemstack.isGazeDisguise(player, target); + } else { + return true; + } ++ }; ++ /** @deprecated Neo: use {@link #PLAYER_NOT_WEARING_DISGUISE_ITEM_FOR_TARGET} with target info instead */ ++ @Deprecated ++ public static final Predicate PLAYER_NOT_WEARING_DISGUISE_ITEM = p_379074_ -> { ++ return PLAYER_NOT_WEARING_DISGUISE_ITEM_FOR_TARGET.test(p_379074_, null); + }; + private final AttributeMap attributes; + private final CombatTracker combatTracker = new CombatTracker(this); +@@ -268,6 +_,14 @@ + EquipmentSlot.class + ); protected float appliedScale = 1.0F; + /** + * This field stores information about damage dealt to this entity. + * a new {@link net.neoforged.neoforge.common.damagesource.DamageContainer} is instantiated + * via {@link #hurt(DamageSource, float)} after invulnerability checks, and is removed from + * the stack before the method's return. -+ **/ ++ **/ + @Nullable + protected java.util.Stack damageContainers = new java.util.Stack<>(); protected LivingEntity(EntityType p_20966_, Level p_20967_) { super(p_20966_, p_20967_); -@@ -320,7 +_,9 @@ +@@ -334,7 +_,9 @@ .add(Attributes.EXPLOSION_KNOCKBACK_RESISTANCE) .add(Attributes.WATER_MOVEMENT_EFFICIENCY) .add(Attributes.MOVEMENT_EFFICIENCY) @@ -35,17 +56,17 @@ } @Override -@@ -348,7 +_,8 @@ +@@ -362,7 +_,8 @@ float f = (float)Mth.ceil((double)this.fallDistance - d7); double d4 = Math.min((double)(0.2F + f / 15.0F), 2.5); int i = (int)(150.0 * d4); -- ((ServerLevel)this.level()).sendParticles(new BlockParticleOption(ParticleTypes.BLOCK, p_20992_), d0, d1, d2, i, 0.0, 0.0, 0.0, 0.15F); +- serverlevel.sendParticles(new BlockParticleOption(ParticleTypes.BLOCK, p_20992_), d0, d1, d2, i, 0.0, 0.0, 0.0, 0.15F); + if (!p_20992_.addLandingEffects((ServerLevel) this.level(), p_20993_, p_20992_, this, i)) + ((ServerLevel)this.level()).sendParticles(new BlockParticleOption(ParticleTypes.BLOCK, p_20992_).setPos(p_20993_), d0, d1, d2, i, 0.0, 0.0, 0.0, 0.15F); } } -@@ -358,6 +_,7 @@ +@@ -372,6 +_,7 @@ } } @@ -53,7 +74,7 @@ public final boolean canBreatheUnderwater() { return this.getType().is(EntityTypeTags.CAN_BREATHE_UNDER_WATER); } -@@ -403,6 +_,9 @@ +@@ -418,6 +_,9 @@ } } @@ -63,7 +84,7 @@ if (this.isEyeInFluid(FluidTags.WATER) && !this.level().getBlockState(BlockPos.containing(this.getX(), this.getEyeY(), this.getZ())).is(Blocks.BUBBLE_COLUMN)) { boolean flag1 = !this.canBreatheUnderwater() -@@ -441,7 +_,7 @@ +@@ -456,7 +_,7 @@ } } @@ -72,16 +93,16 @@ this.extinguishFire(); } -@@ -772,7 +_,7 @@ +@@ -787,7 +_,7 @@ Holder holder = iterator.next(); MobEffectInstance mobeffectinstance = this.activeEffects.get(holder); if (!mobeffectinstance.tick(this, () -> this.onEffectUpdated(mobeffectinstance, true, null))) { - if (!this.level().isClientSide) { + if (!this.level().isClientSide && !net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.entity.living.MobEffectEvent.Expired(this, mobeffectinstance)).isCanceled()) { iterator.remove(); - this.onEffectRemoved(mobeffectinstance); + this.onEffectsRemoved(List.of(mobeffectinstance)); } -@@ -817,8 +_,9 @@ +@@ -832,8 +_,9 @@ List list = this.activeEffects .values() .stream() @@ -93,7 +114,7 @@ .toList(); this.entityData.set(DATA_EFFECT_PARTICLES, list); this.entityData.set(DATA_EFFECT_AMBIENCE_ID, areAllEffectsAmbient(this.activeEffects.values())); -@@ -858,6 +_,7 @@ +@@ -873,6 +_,7 @@ } } @@ -101,18 +122,23 @@ return d0; } -@@ -899,7 +_,9 @@ - - boolean flag; - for (flag = false; iterator.hasNext(); flag = true) { -- this.onEffectRemoved(iterator.next()); -+ MobEffectInstance effect = iterator.next(); -+ if(net.neoforged.neoforge.event.EventHooks.onEffectRemoved(this, effect, null)) continue; -+ this.onEffectRemoved(effect); - iterator.remove(); - } - -@@ -929,11 +_,12 @@ +@@ -908,8 +_,13 @@ + } else if (this.activeEffects.isEmpty()) { + return false; + } else { +- Map, MobEffectInstance> map = Maps.newHashMap(this.activeEffects); +- this.activeEffects.clear(); ++ Map, MobEffectInstance> map = new java.util.HashMap<>(this.activeEffects.size()); ++ for (Map.Entry, MobEffectInstance> entry : this.activeEffects.entrySet()) { ++ if (!net.neoforged.neoforge.event.EventHooks.onEffectRemoved(this, entry.getValue())) { ++ map.put(entry.getKey(), entry.getValue()); ++ } ++ } ++ map.keySet().forEach(this.activeEffects::remove); + this.onEffectsRemoved(map.values()); + return true; + } +@@ -937,11 +_,12 @@ } public boolean addEffect(MobEffectInstance p_147208_, @Nullable Entity p_147209_) { @@ -126,7 +152,7 @@ if (mobeffectinstance == null) { this.activeEffects.put(p_147208_.getEffect(), p_147208_); this.onEffectAdded(p_147208_, p_147209_); -@@ -949,6 +_,14 @@ +@@ -957,6 +_,14 @@ } } @@ -141,7 +167,7 @@ public boolean canBeAffected(MobEffectInstance p_21197_) { if (this.getType().is(EntityTypeTags.IMMUNE_TO_INFESTED)) { return !p_21197_.is(MobEffects.INFESTED); -@@ -962,7 +_,7 @@ +@@ -970,7 +_,7 @@ } public void forceAddEffect(MobEffectInstance p_147216_, @Nullable Entity p_147217_) { @@ -150,15 +176,15 @@ MobEffectInstance mobeffectinstance = this.activeEffects.put(p_147216_.getEffect(), p_147216_); if (mobeffectinstance == null) { this.onEffectAdded(p_147216_, p_147217_); -@@ -983,6 +_,7 @@ +@@ -991,6 +_,7 @@ } public boolean removeEffect(Holder p_316570_) { -+ if (net.neoforged.neoforge.event.EventHooks.onEffectRemoved(this, p_316570_, null)) return false; ++ if (net.neoforged.neoforge.event.EventHooks.onEffectRemoved(this, p_316570_)) return false; MobEffectInstance mobeffectinstance = this.removeEffectNoUpdate(p_316570_); if (mobeffectinstance != null) { - this.onEffectRemoved(mobeffectinstance); -@@ -1061,6 +_,8 @@ + this.onEffectsRemoved(List.of(mobeffectinstance)); +@@ -1072,6 +_,8 @@ } public void heal(float p_21116_) { @@ -167,71 +193,75 @@ float f = this.getHealth(); if (f > 0.0F) { this.setHealth(f + p_21116_); -@@ -1090,23 +_,30 @@ - } else if (p_21016_.is(DamageTypeTags.IS_FIRE) && this.hasEffect(MobEffects.FIRE_RESISTANCE)) { +@@ -1099,11 +_,14 @@ + } else if (p_376460_.is(DamageTypeTags.IS_FIRE) && this.hasEffect(MobEffects.FIRE_RESISTANCE)) { return false; } else { -+ this.damageContainers.push(new net.neoforged.neoforge.common.damagesource.DamageContainer(p_21016_, p_21017_)); ++ this.damageContainers.push(new net.neoforged.neoforge.common.damagesource.DamageContainer(p_376460_, p_376610_)); + if (net.neoforged.neoforge.common.CommonHooks.onEntityIncomingDamage(this, this.damageContainers.peek())) return false; - if (this.isSleeping() && !this.level().isClientSide) { + if (this.isSleeping()) { this.stopSleeping(); } this.noActionTime = 0; -+ p_21017_ = this.damageContainers.peek().getNewDamage(); //Neo: enforce damage container as source of truth for damage amount - float f = p_21017_; ++ p_376610_ = this.damageContainers.peek().getNewDamage(); //Neo: enforce damage container as source of truth for damage amount + if (p_376610_ < 0.0F) { + p_376610_ = 0.0F; + } +@@ -1111,15 +_,19 @@ + float f = p_376610_; boolean flag = false; float f1 = 0.0F; -- if (p_21017_ > 0.0F && this.isDamageSourceBlocked(p_21016_)) { -- this.hurtCurrentlyUsedShield(p_21017_); -- f1 = p_21017_; -- p_21017_ = 0.0F; +- if (p_376610_ > 0.0F && this.isDamageSourceBlocked(p_376460_)) { +- this.hurtCurrentlyUsedShield(p_376610_); +- f1 = p_376610_; +- p_376610_ = 0.0F; + net.neoforged.neoforge.event.entity.living.LivingShieldBlockEvent ev; -+ if (p_21017_ > 0.0F && (ev = net.neoforged.neoforge.common.CommonHooks.onDamageBlock(this, this.damageContainers.peek(), this.isDamageSourceBlocked(p_21016_))).getBlocked()) { ++ if (p_376610_ > 0.0F && (ev = net.neoforged.neoforge.common.CommonHooks.onDamageBlock(this, this.damageContainers.peek(), this.isDamageSourceBlocked(p_376460_))).getBlocked()) { + this.damageContainers.peek().setBlockedDamage(ev); -+ if(ev.shieldDamage() > 0) { ++ if (ev.shieldDamage() > 0) { + this.hurtCurrentlyUsedShield(ev.shieldDamage()); + } + f1 = ev.getBlockedDamage(); -+ p_21017_ = ev.getDamageContainer().getNewDamage(); - if (!p_21016_.is(DamageTypeTags.IS_PROJECTILE) && p_21016_.getDirectEntity() instanceof LivingEntity livingentity) { ++ p_376610_ = ev.getDamageContainer().getNewDamage(); + if (!p_376460_.is(DamageTypeTags.IS_PROJECTILE) && p_376460_.getDirectEntity() instanceof LivingEntity livingentity) { this.blockUsingShield(livingentity); } - flag = true; -+ flag = p_21017_ <= 0; ++ flag = p_376610_ <= 0; } - if (p_21016_.is(DamageTypeTags.IS_FREEZING) && this.getType().is(EntityTypeTags.FREEZE_HURTS_EXTRA_TYPES)) { -@@ -1118,10 +_,12 @@ - p_21017_ *= 0.75F; + if (p_376460_.is(DamageTypeTags.IS_FREEZING) && this.getType().is(EntityTypeTags.FREEZE_HURTS_EXTRA_TYPES)) { +@@ -1135,10 +_,12 @@ + if (Float.isNaN(p_376610_) || Float.isInfinite(p_376610_)) { + p_376610_ = Float.MAX_VALUE; } ++ this.damageContainers.peek().setNewDamage(p_376610_); //update container with vanilla changes -+ this.damageContainers.peek().setNewDamage(p_21017_); //update container with vanilla changes - this.walkAnimation.setSpeed(1.5F); boolean flag1 = true; - if ((float)this.invulnerableTime > 10.0F && !p_21016_.is(DamageTypeTags.BYPASSES_COOLDOWN)) { - if (p_21017_ <= this.lastHurt) { + if ((float)this.invulnerableTime > 10.0F && !p_376460_.is(DamageTypeTags.BYPASSES_COOLDOWN)) { + if (p_376610_ <= this.lastHurt) { + this.damageContainers.pop(); return false; } -@@ -1130,12 +_,13 @@ +@@ -1147,12 +_,13 @@ flag1 = false; } else { - this.lastHurt = p_21017_; + this.lastHurt = p_376610_; - this.invulnerableTime = 20; + this.invulnerableTime = this.damageContainers.peek().getPostAttackInvulnerabilityTicks(); - this.actuallyHurt(p_21016_, p_21017_); + this.actuallyHurt(p_376221_, p_376460_, p_376610_); this.hurtDuration = 10; this.hurtTime = this.hurtDuration; } -+ p_21017_ = this.damageContainers.peek().getNewDamage(); //update local with container value - Entity entity = p_21016_.getEntity(); ++ p_376610_ = this.damageContainers.peek().getNewDamage(); //update local with container value + Entity entity = p_376460_.getEntity(); if (entity != null) { if (entity instanceof LivingEntity livingentity1 -@@ -1147,9 +_,9 @@ +@@ -1164,9 +_,9 @@ if (entity instanceof Player player1) { this.lastHurtByPlayerTime = 100; this.lastHurtByPlayer = player1; @@ -243,40 +273,24 @@ this.lastHurtByPlayer = player; } else { this.lastHurtByPlayer = null; -@@ -1220,6 +_,7 @@ - CriteriaTriggers.PLAYER_HURT_ENTITY.trigger((ServerPlayer)entity, this, p_21016_, f, p_21017_, flag); +@@ -1237,6 +_,7 @@ + CriteriaTriggers.PLAYER_HURT_ENTITY.trigger(serverplayer1, this, p_376460_, f, p_376610_, flag); } + this.damageContainers.pop(); return flag2; } } -@@ -1240,7 +_,7 @@ - +@@ -1259,7 +_,7 @@ for (InteractionHand interactionhand : InteractionHand.values()) { ItemStack itemstack1 = this.getItemInHand(interactionhand); -- if (itemstack1.is(Items.TOTEM_OF_UNDYING)) { -+ if (itemstack1.is(Items.TOTEM_OF_UNDYING) && net.neoforged.neoforge.common.CommonHooks.onLivingUseTotem(this, p_21263_, itemstack1, interactionhand)) { + deathprotection = itemstack1.get(DataComponents.DEATH_PROTECTION); +- if (deathprotection != null) { ++ if (deathprotection != null && net.neoforged.neoforge.common.CommonHooks.onLivingUseTotem(this, p_21263_, itemstack1, interactionhand)) { itemstack = itemstack1.copy(); itemstack1.shrink(1); break; -@@ -1249,13 +_,13 @@ - - if (itemstack != null) { - if (this instanceof ServerPlayer serverplayer) { -- serverplayer.awardStat(Stats.ITEM_USED.get(Items.TOTEM_OF_UNDYING)); -+ serverplayer.awardStat(Stats.ITEM_USED.get(Items.TOTEM_OF_UNDYING), 1); - CriteriaTriggers.USED_TOTEM.trigger(serverplayer, itemstack); - this.gameEvent(GameEvent.ITEM_INTERACT_FINISH); - } - - this.setHealth(1.0F); -- this.removeAllEffects(); -+ this.removeEffectsCuredBy(net.neoforged.neoforge.common.EffectCures.PROTECTED_BY_TOTEM); - this.addEffect(new MobEffectInstance(MobEffects.REGENERATION, 900, 1)); - this.addEffect(new MobEffectInstance(MobEffects.ABSORPTION, 100, 1)); - this.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, 800, 0)); -@@ -1326,6 +_,7 @@ +@@ -1343,6 +_,7 @@ } public void die(DamageSource p_21014_) { @@ -284,45 +298,45 @@ if (!this.isRemoved() && !this.dead) { Entity entity = p_21014_.getEntity(); LivingEntity livingentity = this.getKillCredit(); -@@ -1361,7 +_,7 @@ - if (!this.level().isClientSide) { +@@ -1378,7 +_,7 @@ + if (this.level() instanceof ServerLevel serverlevel) { boolean flag = false; if (p_21269_ instanceof WitherBoss) { -- if (this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.level(), p_21269_)) { +- if (serverlevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (net.neoforged.neoforge.event.EventHooks.canEntityGrief(serverlevel, p_21269_)) { BlockPos blockpos = this.blockPosition(); BlockState blockstate = Blocks.WITHER_ROSE.defaultBlockState(); if (this.level().getBlockState(blockpos).isAir() && blockstate.canSurvive(this.level(), blockpos)) { -@@ -1379,6 +_,7 @@ +@@ -1396,6 +_,7 @@ } protected void dropAllDeathLoot(ServerLevel p_348524_, DamageSource p_21192_) { + this.captureDrops(new java.util.ArrayList<>()); boolean flag = this.lastHurtByPlayerTime > 0; if (this.shouldDropLoot() && p_348524_.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { - this.dropFromLootTable(p_21192_, flag); -@@ -1387,6 +_,10 @@ + this.dropFromLootTable(p_348524_, p_21192_, flag); +@@ -1404,6 +_,10 @@ - this.dropEquipment(); - this.dropExperience(p_21192_.getEntity()); + this.dropEquipment(p_348524_); + this.dropExperience(p_348524_, p_21192_.getEntity()); + + Collection drops = captureDrops(null); + if (!net.neoforged.neoforge.common.CommonHooks.onLivingDrops(this, p_21192_, drops, lastHurtByPlayerTime > 0)) + drops.forEach(e -> level().addFreshEntity(e)); } - protected void dropEquipment() { -@@ -1399,7 +_,8 @@ + protected void dropEquipment(ServerLevel p_376330_) { +@@ -1415,7 +_,8 @@ this.isAlwaysExperienceDropper() - || this.lastHurtByPlayerTime > 0 && this.shouldDropExperience() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT) + || this.lastHurtByPlayerTime > 0 && this.shouldDropExperience() && p_376909_.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT) )) { -- ExperienceOrb.award(serverlevel, this.position(), this.getExperienceReward(serverlevel, p_345346_)); -+ int reward = net.neoforged.neoforge.event.EventHooks.getExperienceDrop(this, this.lastHurtByPlayer, this.getExperienceReward(serverlevel, p_345346_)); +- ExperienceOrb.award(p_376909_, this.position(), this.getExperienceReward(p_376909_, p_345346_)); ++ int reward = net.neoforged.neoforge.event.EventHooks.getExperienceDrop(this, this.lastHurtByPlayer, this.getExperienceReward(p_376909_, p_345346_)); + ExperienceOrb.award((ServerLevel) this.level(), this.position(), reward); } } -@@ -1440,6 +_,11 @@ +@@ -1496,6 +_,11 @@ } public void knockback(double p_147241_, double p_147242_, double p_147243_) { @@ -334,7 +348,7 @@ p_147241_ *= 1.0 - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE); if (!(p_147241_ <= 0.0)) { this.hasImpulse = true; -@@ -1521,15 +_,9 @@ +@@ -1569,15 +_,9 @@ } else { BlockPos blockpos = this.blockPosition(); BlockState blockstate = this.getInBlockState(); @@ -353,7 +367,27 @@ } } -@@ -1558,6 +_,11 @@ +@@ -1595,10 +_,18 @@ + return !this.isRemoved() && this.getHealth() > 0.0F; + } + ++ /** @deprecated Neo: use {@link #isLookingAtMe(LivingEntity, double, boolean, boolean, java.util.function.BiPredicate, DoubleSupplier...)} instead */ ++ @Deprecated + public boolean isLookingAtMe( + LivingEntity p_379420_, double p_379671_, boolean p_380253_, boolean p_380067_, Predicate p_380351_, DoubleSupplier... p_380073_ + ) { +- if (!p_380351_.test(p_379420_)) { ++ return isLookingAtMe(p_379420_, p_379671_, p_380253_, p_380067_, (observer, target) -> p_380351_.test(observer), p_380073_); ++ } ++ ++ public boolean isLookingAtMe( ++ LivingEntity p_379420_, double p_379671_, boolean p_380253_, boolean p_380067_, java.util.function.BiPredicate p_380351_, DoubleSupplier... p_380073_ ++ ) { ++ if (!p_380351_.test(p_379420_, this)) { + return false; + } else { + Vec3 vec3 = p_379420_.getViewVector(1.0F).normalize(); +@@ -1630,6 +_,11 @@ @Override public boolean causeFallDamage(float p_147187_, float p_147188_, DamageSource p_147189_) { @@ -365,7 +399,7 @@ boolean flag = super.causeFallDamage(p_147187_, p_147188_, p_147189_); int i = this.calculateFallDamage(p_147187_, p_147188_); if (i > 0) { -@@ -1585,9 +_,10 @@ +@@ -1657,9 +_,10 @@ int i = Mth.floor(this.getX()); int j = Mth.floor(this.getY() - 0.2F); int k = Mth.floor(this.getZ()); @@ -378,7 +412,7 @@ this.playSound(soundtype.getFallSound(), soundtype.getVolume() * 0.5F, soundtype.getPitch() * 0.75F); } } -@@ -1616,6 +_,8 @@ +@@ -1688,6 +_,8 @@ if (!(p_330394_ <= 0.0F)) { int i = (int)Math.max(1.0F, p_330394_ / 4.0F); @@ -386,8 +420,8 @@ + if (true) return; //Neo: Invalidates the loop. Armor damage happens in common hook. for (EquipmentSlot equipmentslot : p_331314_) { ItemStack itemstack = this.getItemBySlot(equipmentslot); - if (itemstack.getItem() instanceof ArmorItem && itemstack.canBeHurtBy(p_330843_)) { -@@ -1648,6 +_,7 @@ + Equippable equippable = itemstack.get(DataComponents.EQUIPPABLE); +@@ -1721,6 +_,7 @@ p_21194_ = Math.max(f / 25.0F, 0.0F); float f2 = f1 - p_21194_; if (f2 > 0.0F && f2 < 3.4028235E37F) { @@ -395,7 +429,7 @@ if (this instanceof ServerPlayer) { ((ServerPlayer)this).awardStat(Stats.DAMAGE_RESISTED, Math.round(f2 * 10.0F)); } else if (p_21193_.getEntity() instanceof ServerPlayer) { -@@ -1670,6 +_,7 @@ +@@ -1743,6 +_,7 @@ if (f3 > 0.0F) { p_21194_ = CombatRules.getDamageAfterMagicAbsorb(p_21194_, f3); @@ -403,10 +437,10 @@ } return p_21194_; -@@ -1679,11 +_,14 @@ +@@ -1752,11 +_,14 @@ - protected void actuallyHurt(DamageSource p_21240_, float p_21241_) { - if (!this.isInvulnerableTo(p_21240_)) { + protected void actuallyHurt(ServerLevel p_376745_, DamageSource p_21240_, float p_21241_) { + if (!this.isInvulnerableTo(p_376745_, p_21240_)) { - p_21241_ = this.getDamageAfterArmorAbsorb(p_21240_, p_21241_); - p_21241_ = this.getDamageAfterMagicAbsorb(p_21240_, p_21241_); - float f1 = Math.max(p_21241_ - this.getAbsorptionAmount(), 0.0F); @@ -423,7 +457,7 @@ if (f > 0.0F && f < 3.4028235E37F && p_21240_.getEntity() instanceof ServerPlayer serverplayer) { serverplayer.awardStat(Stats.DAMAGE_DEALT_ABSORBED, Math.round(f * 10.0F)); } -@@ -1691,9 +_,10 @@ +@@ -1764,9 +_,10 @@ if (f1 != 0.0F) { this.getCombatTracker().recordDamage(p_21240_, f1); this.setHealth(this.getHealth() - f1); @@ -435,7 +469,7 @@ } } -@@ -1747,6 +_,8 @@ +@@ -1820,6 +_,8 @@ } public void swing(InteractionHand p_21012_, boolean p_21013_) { @@ -444,7 +478,7 @@ if (!this.swinging || this.swingTime >= this.getCurrentSwingDuration() / 2 || this.swingTime < 0) { this.swingTime = -1; this.swinging = true; -@@ -1859,8 +_,10 @@ +@@ -1933,8 +_,10 @@ private void swapHandItems() { ItemStack itemstack = this.getItemBySlot(EquipmentSlot.OFFHAND); @@ -457,7 +491,7 @@ } @Override -@@ -2064,15 +_,18 @@ +@@ -2152,15 +_,18 @@ } this.hasImpulse = true; @@ -478,42 +512,54 @@ } protected float getWaterSlowDown() { -@@ -2097,7 +_,8 @@ - } - +@@ -2184,7 +_,7 @@ + public void travel(Vec3 p_21280_) { + if (this.isControlledByLocalInstance()) { FluidState fluidstate = this.level().getFluidState(this.blockPosition()); -- if (this.isInWater() && this.isAffectedByFluids() && !this.canStandOnFluid(fluidstate)) { +- if ((this.isInWater() || this.isInLava()) && this.isAffectedByFluids() && !this.canStandOnFluid(fluidstate)) { + if ((this.isInWater() || (this.isInFluidType(fluidstate) && fluidstate.getFluidType() != net.neoforged.neoforge.common.NeoForgeMod.LAVA_TYPE.value())) && this.isAffectedByFluids() && !this.canStandOnFluid(fluidstate)) { -+ if (this.isInWater() || (this.isInFluidType(fluidstate) && !this.moveInFluid(fluidstate, p_21280_, d0))) { - double d9 = this.getY(); - float f4 = this.isSprinting() ? 0.9F : this.getWaterSlowDown(); - float f5 = 0.02F; -@@ -2115,6 +_,7 @@ - f4 = 0.96F; - } + this.travelInFluid(p_21280_); + } else if (this.isFallFlying()) { + this.travelFallFlying(); +@@ -2196,7 +_,7 @@ + + private void travelInAir(Vec3 p_362457_) { + BlockPos blockpos = this.getBlockPosBelowThatAffectsMyMovement(); +- float f = this.onGround() ? this.level().getBlockState(blockpos).getBlock().getFriction() : 1.0F; ++ float f = this.onGround() ? this.level().getBlockState(blockpos).getFriction(this.level(), blockpos, this) : 1.0F; + float f1 = f * 0.91F; + Vec3 vec3 = this.handleRelativeFrictionAndCalculateMovement(p_362457_, f); + double d0 = vec3.y; +@@ -2219,11 +_,19 @@ + } + } -+ f5 *= (float)this.getAttributeValue(net.neoforged.neoforge.common.NeoForgeMod.SWIM_SPEED); - this.moveRelative(f5, p_21280_); - this.move(MoverType.SELF, this.getDeltaMovement()); - Vec3 vec36 = this.getDeltaMovement(); -@@ -2128,6 +_,7 @@ - if (this.horizontalCollision && this.isFree(vec32.x, vec32.y + 0.6F - this.getY() + d9, vec32.z)) { - this.setDeltaMovement(vec32.x, 0.3F, vec32.z); - } -+ } - } else if (this.isInLava() && this.isAffectedByFluids() && !this.canStandOnFluid(fluidstate)) { - double d8 = this.getY(); - this.moveRelative(0.02F, p_21280_); -@@ -2190,7 +_,7 @@ - } - } else { - BlockPos blockpos = this.getBlockPosBelowThatAffectsMyMovement(); -- float f2 = this.level().getBlockState(blockpos).getBlock().getFriction(); -+ float f2 = this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getFriction(level(), this.getBlockPosBelowThatAffectsMyMovement(), this); - float f3 = this.onGround() ? f2 * 0.91F : 0.91F; - Vec3 vec35 = this.handleRelativeFrictionAndCalculateMovement(p_21280_, f2); - double d2 = vec35.y; -@@ -2284,7 +_,7 @@ ++ /** ++ * @deprecated Neo: use {@link #travelInFluid(Vec3, FluidState)} instead ++ */ ++ @Deprecated + private void travelInFluid(Vec3 p_365480_) { ++ travelInFluid(p_365480_, net.minecraft.world.level.material.Fluids.EMPTY.defaultFluidState()); ++ } ++ ++ private void travelInFluid(Vec3 p_365480_, FluidState fluidState) { + boolean flag = this.getDeltaMovement().y <= 0.0; + double d0 = this.getY(); + double d1 = this.getEffectiveGravity(); +- if (this.isInWater()) { ++ if (this.isInWater() || (this.isInFluidType(fluidState) && !this.moveInFluid(fluidState, p_365480_, d1))) { + float f = this.isSprinting() ? 0.9F : this.getWaterSlowDown(); + float f1 = 0.02F; + float f2 = (float)this.getAttributeValue(Attributes.WATER_MOVEMENT_EFFICIENCY); +@@ -2240,6 +_,7 @@ + f = 0.96F; + } + ++ f1 *= (float)this.getAttributeValue(net.neoforged.neoforge.common.NeoForgeMod.SWIM_SPEED); + this.moveRelative(f1, p_365480_); + this.move(MoverType.SELF, this.getDeltaMovement()); + Vec3 vec3 = this.getDeltaMovement(); +@@ -2389,7 +_,7 @@ double d0 = Mth.clamp(p_21298_.x, -0.15F, 0.15F); double d1 = Mth.clamp(p_21298_.z, -0.15F, 0.15F); double d2 = Math.max(p_21298_.y, -0.15F); @@ -522,7 +568,7 @@ d2 = 0.0; } -@@ -2466,6 +_,7 @@ +@@ -2574,6 +_,7 @@ }; ItemStack itemstack1 = this.getItemBySlot(equipmentslot); if (this.equipmentHasChanged(itemstack, itemstack1)) { @@ -530,8 +576,8 @@ if (map == null) { map = Maps.newEnumMap(EquipmentSlot.class); } -@@ -2637,6 +_,9 @@ - this.level().getProfiler().push("jump"); +@@ -2733,6 +_,9 @@ + profilerfiller.push("jump"); if (this.jumping && this.isAffectedByFluids()) { double d3; + net.neoforged.neoforge.fluids.FluidType fluidType = this.getMaxHeightFluidType(); @@ -540,7 +586,7 @@ if (this.isInLava()) { d3 = this.getFluidHeight(FluidTags.LAVA); } else { -@@ -2647,15 +_,17 @@ +@@ -2743,15 +_,17 @@ double d4 = this.getFluidJumpThreshold(); if (!flag || this.onGround() && !(d3 > d4)) { if (!this.isInLava() || this.onGround() && !(d3 > d4)) { @@ -560,16 +606,7 @@ } } else { this.noJumpDelay = 0; -@@ -2720,6 +_,8 @@ - boolean flag = this.getSharedFlag(7); - if (flag && !this.onGround() && !this.isPassenger() && !this.hasEffect(MobEffects.LEVITATION)) { - ItemStack itemstack = this.getItemBySlot(EquipmentSlot.CHEST); -+ flag = itemstack.canElytraFly(this) && itemstack.elytraFlightTick(this, this.fallFlyTicks); -+ if (false) //Neo: Moved to ElytraItem - if (itemstack.is(Items.ELYTRA) && ElytraItem.isFlyEnabled(itemstack)) { - flag = true; - int i = this.fallFlyTicks + 1; -@@ -2979,8 +_,11 @@ +@@ -3104,8 +_,11 @@ private void updatingUsingItem() { if (this.isUsingItem()) { @@ -583,7 +620,7 @@ this.updateUsingItem(this.useItem); } else { this.stopUsingItem(); -@@ -2989,12 +_,15 @@ +@@ -3114,8 +_,11 @@ } protected void updateUsingItem(ItemStack p_147201_) { @@ -591,16 +628,12 @@ + this.useItemRemaining = net.neoforged.neoforge.event.EventHooks.onItemUseTick(this, p_147201_, this.getUseItemRemainingTicks()); + if (this.getUseItemRemainingTicks() > 0) p_147201_.onUseTick(this.level(), this, this.getUseItemRemainingTicks()); - if (this.shouldTriggerItemUseEffects()) { - this.triggerItemUseEffects(p_147201_, 5); - } - - if (--this.useItemRemaining == 0 && !this.level().isClientSide && !p_147201_.useOnRelease()) { + if (--this.useItemRemaining <= 0 && !this.level().isClientSide && !p_147201_.useOnRelease()) { this.completeUsingItem(); } } -@@ -3029,8 +_,10 @@ +@@ -3143,8 +_,10 @@ public void startUsingItem(InteractionHand p_21159_) { ItemStack itemstack = this.getItemInHand(p_21159_); if (!itemstack.isEmpty() && !this.isUsingItem()) { @@ -612,17 +645,17 @@ if (!this.level().isClientSide) { this.setLivingEntityFlag(1, true); this.setLivingEntityFlag(2, p_21159_ == InteractionHand.OFF_HAND); -@@ -3111,7 +_,8 @@ +@@ -3207,7 +_,8 @@ + this.releaseUsingItem(); } else { if (!this.useItem.isEmpty() && this.isUsingItem()) { - this.triggerItemUseEffects(this.useItem, 16); - ItemStack itemstack = this.useItem.finishUsingItem(this.level(), this); + ItemStack copy = this.useItem.copy(); + ItemStack itemstack = net.neoforged.neoforge.event.EventHooks.onItemUseFinish(this, copy, getUseItemRemainingTicks(), this.useItem.finishUsingItem(this.level(), this)); if (itemstack != this.useItem) { this.setItemInHand(interactionhand, itemstack); } -@@ -3136,7 +_,11 @@ +@@ -3235,7 +_,11 @@ public void releaseUsingItem() { if (!this.useItem.isEmpty()) { @@ -634,7 +667,7 @@ if (this.useItem.useOnRelease()) { this.updatingUsingItem(); } -@@ -3146,6 +_,7 @@ +@@ -3245,6 +_,7 @@ } public void stopUsingItem() { @@ -642,16 +675,16 @@ if (!this.level().isClientSide) { boolean flag = this.isUsingItem(); this.setLivingEntityFlag(1, false); -@@ -3161,7 +_,7 @@ - public boolean isBlocking() { +@@ -3265,7 +_,7 @@ + public ItemStack getItemBlockingWith() { if (this.isUsingItem() && !this.useItem.isEmpty()) { Item item = this.useItem.getItem(); -- return item.getUseAnimation(this.useItem) != UseAnim.BLOCK ? false : item.getUseDuration(this.useItem, this) - this.useItemRemaining >= 5; -+ return !this.useItem.canPerformAction(net.neoforged.neoforge.common.ItemAbilities.SHIELD_BLOCK) ? false : item.getUseDuration(this.useItem, this) - this.useItemRemaining >= 5; - } else { - return false; - } -@@ -3302,8 +_,8 @@ +- if (item.getUseAnimation(this.useItem) != ItemUseAnimation.BLOCK) { ++ if (!this.useItem.canPerformAction(net.neoforged.neoforge.common.ItemAbilities.SHIELD_BLOCK)) { + return null; + } else { + return item.getUseDuration(this.useItem, this) - this.useItemRemaining < 5 ? null : this.useItem; +@@ -3410,8 +_,8 @@ } BlockState blockstate = this.level().getBlockState(p_21141_); @@ -662,11 +695,11 @@ } this.setPose(Pose.SLEEPING); -@@ -3318,15 +_,17 @@ +@@ -3426,15 +_,17 @@ } private boolean checkBedExists() { -- return this.getSleepingPos().map(p_352707_ -> this.level().getBlockState(p_352707_).getBlock() instanceof BedBlock).orElse(false); +- return this.getSleepingPos().map(p_381383_ -> this.level().getBlockState(p_381383_).getBlock() instanceof BedBlock).orElse(false); + // Neo: Overwrite the vanilla instanceof BedBlock check with isBed and fire the CanContinueSleepingEvent. + boolean hasBed = this.getSleepingPos().map(pos -> this.level().getBlockState(pos).isBed(this.level(), pos, this)).orElse(false); + return net.neoforged.neoforge.event.EventHooks.canEntityContinueSleeping(this, hasBed ? null : Player.BedSleepingProblem.NOT_POSSIBLE_HERE); @@ -683,7 +716,7 @@ Vec3 vec31 = BedBlock.findStandUpPosition(this.getType(), this.level(), p_261435_, direction, this.getYRot()).orElseGet(() -> { BlockPos blockpos = p_261435_.above(); return new Vec3((double)blockpos.getX() + 0.5, (double)blockpos.getY() + 0.1, (double)blockpos.getZ() + 0.5); -@@ -3347,7 +_,9 @@ +@@ -3455,7 +_,9 @@ @Nullable public Direction getBedOrientation() { BlockPos blockpos = this.getSleepingPos().orElse(null); @@ -694,7 +727,7 @@ } @Override -@@ -3356,11 +_,11 @@ +@@ -3464,7 +_,7 @@ } public ItemStack getProjectile(ItemStack p_21272_) { @@ -702,61 +735,17 @@ + return net.neoforged.neoforge.common.CommonHooks.getProjectile(this, p_21272_, ItemStack.EMPTY); } - public final ItemStack eat(Level p_21067_, ItemStack p_21068_) { -- FoodProperties foodproperties = p_21068_.get(DataComponents.FOOD); -+ FoodProperties foodproperties = p_21068_.getFoodProperties(this); - return foodproperties != null ? this.eat(p_21067_, p_21068_, foodproperties) : p_21068_; - } - -@@ -3411,6 +_,38 @@ - return p_320526_ == InteractionHand.MAIN_HAND ? EquipmentSlot.MAINHAND : EquipmentSlot.OFFHAND; + private static byte entityEventForEquipmentBreak(EquipmentSlot p_21267_) { +@@ -3519,6 +_,8 @@ } -+ /** -+ * Neo: Removes all potion effects that have the given {@link net.neoforged.neoforge.common.EffectCure} in their set of cures -+ * @param cure the EffectCure being used -+ */ -+ public boolean removeEffectsCuredBy(net.neoforged.neoforge.common.EffectCure cure) { -+ if (this.level().isClientSide) -+ return false; -+ boolean ret = false; -+ Iterator itr = this.activeEffects.values().iterator(); -+ while (itr.hasNext()) { -+ MobEffectInstance effect = itr.next(); -+ if (effect.getCures().contains(cure) && !net.neoforged.neoforge.event.EventHooks.onEffectRemoved(this, effect, cure)) { -+ this.onEffectRemoved(effect); -+ itr.remove(); -+ ret = true; -+ this.effectsDirty = true; -+ } -+ } -+ return ret; -+ } -+ -+ /** -+ * Neo: Returns true if the entity's rider (EntityPlayer) should face forward when mounted. -+ * currently only used in vanilla code by pigs. -+ * -+ * @param player The player who is riding the entity. -+ * @return If the player should orient the same direction as this entity. -+ */ -+ public boolean shouldRiderFaceForward(Player player) { -+ return this instanceof net.minecraft.world.entity.animal.Pig; -+ } -+ - @Override - public AABB getBoundingBoxForCulling() { - if (this.getItemBySlot(EquipmentSlot.HEAD).is(Items.DRAGON_HEAD)) { -@@ -3422,6 +_,8 @@ - } - - public EquipmentSlot getEquipmentSlotForItem(ItemStack p_147234_) { + public final EquipmentSlot getEquipmentSlotForItem(ItemStack p_147234_) { + final EquipmentSlot slot = p_147234_.getEquipmentSlot(); + if (slot != null) return slot; // FORGE: Allow modders to set a non-default equipment slot for a stack; e.g. a non-armor chestplate-slot item - Equipable equipable = Equipable.get(p_147234_); - if (equipable != null) { - EquipmentSlot equipmentslot = equipable.getEquipmentSlot(); -@@ -3507,7 +_,7 @@ + Equippable equippable = p_147234_.get(DataComponents.EQUIPPABLE); + return equippable != null && this.canUseSlot(equippable.slot()) ? equippable.slot() : EquipmentSlot.MAINHAND; + } +@@ -3604,7 +_,7 @@ } public boolean canDisableShield() { diff --git a/patches/net/minecraft/world/entity/Mob.java.patch b/patches/net/minecraft/world/entity/Mob.java.patch index 5ed8d6f87e..715ee233ce 100644 --- a/patches/net/minecraft/world/entity/Mob.java.patch +++ b/patches/net/minecraft/world/entity/Mob.java.patch @@ -1,16 +1,18 @@ --- a/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java -@@ -131,6 +_,9 @@ +@@ -135,6 +_,11 @@ private Leashable.LeashData leashData; private BlockPos restrictCenter = BlockPos.ZERO; private float restrictRadius = -1.0F; + @Nullable -+ private MobSpawnType spawnType; ++ private EntitySpawnReason spawnType; + private boolean spawnCancelled = false; ++ /** Neo: Prevent immediate spawning from conversions to capture conversion results for events */ ++ protected boolean preventConversionSpawns = false; protected Mob(EntityType p_21368_, Level p_21369_) { super(p_21368_, p_21369_); -@@ -237,7 +_,10 @@ +@@ -241,7 +_,10 @@ } public void setTarget(@Nullable LivingEntity p_21544_) { @@ -22,7 +24,7 @@ } @Override -@@ -346,6 +_,12 @@ +@@ -344,6 +_,12 @@ if (!this.level().isClientSide && this.tickCount % 5 == 0) { this.updateControlFlags(); } @@ -30,12 +32,12 @@ + // Neo: Animal armor tick patch + if (this.canUseSlot(EquipmentSlot.BODY)) { + ItemStack stack = this.getBodyArmorItem(); -+ if (isBodyArmorItem(stack)) stack.onAnimalArmorTick(level(), this); ++ if (stack.has(DataComponents.EQUIPPABLE)) stack.onAnimalArmorTick(level(), this); + } } protected void updateControlFlags() { -@@ -425,6 +_,9 @@ +@@ -423,6 +_,9 @@ if (this.isNoAi()) { p_21484_.putBoolean("NoAI", this.isNoAi()); } @@ -45,14 +47,14 @@ } @Override -@@ -484,6 +_,14 @@ +@@ -482,6 +_,14 @@ } this.setNoAi(p_21450_.getBoolean("NoAI")); + + if (p_21450_.contains("neoforge:spawn_type")) { + try { -+ this.spawnType = MobSpawnType.valueOf(p_21450_.getString("neoforge:spawn_type")); ++ this.spawnType = EntitySpawnReason.valueOf(p_21450_.getString("neoforge:spawn_type")); + } catch (Exception ex) { + p_21450_.remove("neoforge:spawn_type"); + } @@ -60,24 +62,22 @@ } @Override -@@ -539,7 +_,7 @@ +@@ -534,7 +_,7 @@ && this.canPickUpLoot() && this.isAlive() && !this.dead -- && this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ && net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.level(), this)) { +- && serverlevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ && net.neoforged.neoforge.event.EventHooks.canEntityGrief(serverlevel, this)) { Vec3i vec3i = this.getPickupReach(); for (ItemEntity itementity : this.level() -@@ -666,6 +_,10 @@ - - private double getApproximateAttackDamageWithItem(ItemStack p_330413_) { - ItemAttributeModifiers itemattributemodifiers = p_330413_.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY); -+ +@@ -666,6 +_,8 @@ + private double getApproximateAttributeWith(ItemStack p_371461_, Holder p_371421_, EquipmentSlot p_371891_) { + double d0 = this.getAttributes().hasAttribute(p_371421_) ? this.getAttributeBaseValue(p_371421_) : 0.0; + ItemAttributeModifiers itemattributemodifiers = p_371461_.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY); + // Neo: Respect gameplay modifiers -+ itemattributemodifiers = p_330413_.getAttributeModifiers(); -+ - return itemattributemodifiers.compute(this.getAttributeBaseValue(Attributes.ATTACK_DAMAGE), EquipmentSlot.MAINHAND); ++ itemattributemodifiers = p_371461_.getAttributeModifiers(); + return itemattributemodifiers.compute(d0, p_371891_); } @@ -701,6 +_,7 @@ @@ -88,7 +88,7 @@ if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) { this.discard(); } else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) { -@@ -1133,6 +_,11 @@ +@@ -1127,6 +_,11 @@ } } @@ -98,17 +98,25 @@ + @Deprecated + @org.jetbrains.annotations.ApiStatus.OverrideOnly @Nullable - public SpawnGroupData finalizeSpawn(ServerLevelAccessor p_21434_, DifficultyInstance p_21435_, MobSpawnType p_21436_, @Nullable SpawnGroupData p_21437_) { - RandomSource randomsource = p_21434_.getRandom(); -@@ -1144,6 +_,7 @@ + public SpawnGroupData finalizeSpawn( + ServerLevelAccessor p_21434_, DifficultyInstance p_21435_, EntitySpawnReason p_363352_, @Nullable SpawnGroupData p_21437_ +@@ -1140,6 +_,7 @@ } this.setLeftHanded(randomsource.nextFloat() < 0.05F); -+ this.spawnType = p_21436_; ++ this.spawnType = p_363352_; return p_21437_; } -@@ -1470,14 +_,24 @@ +@@ -1281,6 +_,7 @@ + } else { + p_371709_.type().convert(this, t, p_371709_); + p_371266_.finalizeConversion(t); ++ if (!preventConversionSpawns) + if (this.level() instanceof ServerLevel serverlevel) { + serverlevel.addFreshEntity(t); + } +@@ -1452,14 +_,24 @@ } @Override @@ -135,19 +143,19 @@ public void removeFreeWill() { this.removeAllGoals(p_351790_ -> true); @@ -1503,5 +_,40 @@ - public ItemStack getPickResult() { - SpawnEggItem spawneggitem = SpawnEggItem.byId(this.getType()); - return spawneggitem == null ? null : new ItemStack(spawneggitem); + @VisibleForTesting + public float[] getArmorDropChances() { + return this.armorDropChances; + } + + /** -+ * Returns the type of spawn that created this mob, if applicable. -+ * If it could not be determined, this will return null. -+ *

-+ * This is set via {@link Mob#finalizeSpawn}, so you should not call this from within that method, instead using the parameter. -+ */ ++ * Returns the type of spawn that created this mob, if applicable. ++ * If it could not be determined, this will return null. ++ *

++ * This is set via {@link Mob#finalizeSpawn}, so you should not call this from within that method, instead using the parameter. ++ */ + @Nullable -+ public final MobSpawnType getSpawnType() { ++ public final EntitySpawnReason getSpawnType() { + return this.spawnType; + } + diff --git a/patches/net/minecraft/world/entity/Shearable.java.patch b/patches/net/minecraft/world/entity/Shearable.java.patch index 251e6be55b..58aef72f93 100644 --- a/patches/net/minecraft/world/entity/Shearable.java.patch +++ b/patches/net/minecraft/world/entity/Shearable.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/world/entity/Shearable.java +++ b/net/minecraft/world/entity/Shearable.java -@@ -2,8 +_,20 @@ - +@@ -4,8 +_,20 @@ import net.minecraft.sounds.SoundSource; + import net.minecraft.world.item.ItemStack; -public interface Shearable { +/** @@ -11,13 +11,13 @@ +@Deprecated +public interface Shearable extends net.neoforged.neoforge.common.IShearable { + /** -+ * @deprecated Neo: Use {@link net.neoforged.neoforge.common.IShearable#onSheared(net.minecraft.world.entity.player.Player, net.minecraft.world.item.ItemStack, net.minecraft.world.level.Level, net.minecraft.core.BlockPos, int)} instead. ++ * @deprecated Neo: Use {@link net.neoforged.neoforge.common.IShearable#onSheared(net.minecraft.world.entity.player.Player, net.minecraft.world.item.ItemStack, net.minecraft.world.level.Level, net.minecraft.core.BlockPos)} instead. + */ + @Deprecated - void shear(SoundSource p_21749_); + void shear(ServerLevel p_376429_, SoundSource p_21749_, ItemStack p_372963_); + /** -+ * @deprecated Neo: Use {@link net.neoforged.neoforge.common.IShearable#isShearable(net.minecraft.world.item.ItemStack, net.minecraft.world.level.Level, net.minecraft.core.BlockPos)} instead. ++ * @deprecated Neo: Use {@link net.neoforged.neoforge.common.IShearable#isShearable(net.minecraft.world.entity.player.Player, net.minecraft.world.item.ItemStack, net.minecraft.world.level.Level, net.minecraft.core.BlockPos)} instead. + */ + @Deprecated boolean readyForShearing(); diff --git a/patches/net/minecraft/world/entity/SpawnPlacements.java.patch b/patches/net/minecraft/world/entity/SpawnPlacements.java.patch index 0be5926d4c..4717f19fc6 100644 --- a/patches/net/minecraft/world/entity/SpawnPlacements.java.patch +++ b/patches/net/minecraft/world/entity/SpawnPlacements.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/SpawnPlacements.java +++ b/net/minecraft/world/entity/SpawnPlacements.java -@@ -46,6 +_,10 @@ +@@ -47,6 +_,10 @@ public class SpawnPlacements { private static final Map, SpawnPlacements.Data> DATA_BY_TYPE = Maps.newHashMap(); @@ -11,13 +11,13 @@ private static void register( EntityType p_21755_, SpawnPlacementType p_321847_, Heightmap.Types p_21757_, SpawnPlacements.SpawnPredicate p_21758_ ) { -@@ -73,7 +_,13 @@ - EntityType p_217075_, ServerLevelAccessor p_217076_, MobSpawnType p_217077_, BlockPos p_217078_, RandomSource p_217079_ +@@ -74,7 +_,13 @@ + EntityType p_217075_, ServerLevelAccessor p_217076_, EntitySpawnReason p_361433_, BlockPos p_217078_, RandomSource p_217079_ ) { SpawnPlacements.Data spawnplacements$data = DATA_BY_TYPE.get(p_217075_); -- return spawnplacements$data == null || ((SpawnPredicate)spawnplacements$data.predicate).test(p_217075_, p_217076_, p_217077_, p_217078_, p_217079_); -+ boolean vanillaResult = spawnplacements$data == null || spawnplacements$data.predicate.test((EntityType)p_217075_, p_217076_, p_217077_, p_217078_, p_217079_); -+ return net.neoforged.neoforge.event.EventHooks.checkSpawnPlacements(p_217075_, p_217076_, p_217077_, p_217078_, p_217079_, vanillaResult); +- return spawnplacements$data == null || ((SpawnPredicate)spawnplacements$data.predicate).test(p_217075_, p_217076_, p_361433_, p_217078_, p_217079_); ++ boolean vanillaResult = spawnplacements$data == null || spawnplacements$data.predicate.test((EntityType)p_217075_, p_217076_, p_361433_, p_217078_, p_217079_); ++ return net.neoforged.neoforge.event.EventHooks.checkSpawnPlacements(p_217075_, p_217076_, p_361433_, p_217078_, p_217079_, vanillaResult); + } + + // Neo: Added to allow for checking if an entity has a spawn placement @@ -26,10 +26,10 @@ } static { -@@ -168,5 +_,16 @@ +@@ -183,5 +_,16 @@ @FunctionalInterface public interface SpawnPredicate { - boolean test(EntityType p_217081_, ServerLevelAccessor p_217082_, MobSpawnType p_217083_, BlockPos p_217084_, RandomSource p_217085_); + boolean test(EntityType p_217081_, ServerLevelAccessor p_217082_, EntitySpawnReason p_363558_, BlockPos p_217084_, RandomSource p_217085_); + } + + /** diff --git a/patches/net/minecraft/world/entity/TamableAnimal.java.patch b/patches/net/minecraft/world/entity/TamableAnimal.java.patch index e55032dd54..5dbf80dc6b 100644 --- a/patches/net/minecraft/world/entity/TamableAnimal.java.patch +++ b/patches/net/minecraft/world/entity/TamableAnimal.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/TamableAnimal.java +++ b/net/minecraft/world/entity/TamableAnimal.java -@@ -220,11 +_,15 @@ +@@ -221,13 +_,16 @@ @Override public void die(DamageSource p_21809_) { @@ -8,12 +8,14 @@ + net.minecraft.network.chat.Component deathMessage = this.getCombatTracker().getDeathMessage(); + super.die(p_21809_); + -+ if (this.dead) - if (!this.level().isClientSide && this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES) && this.getOwner() instanceof ServerPlayer) { -- this.getOwner().sendSystemMessage(this.getCombatTracker().getDeathMessage()); -+ this.getOwner().sendSystemMessage(deathMessage); ++ if (dead) + if (this.level() instanceof ServerLevel serverlevel + && serverlevel.getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES) + && this.getOwner() instanceof ServerPlayer serverplayer) { +- serverplayer.sendSystemMessage(this.getCombatTracker().getDeathMessage()); ++ serverplayer.sendSystemMessage(deathMessage); } - +- - super.die(p_21809_); } diff --git a/patches/net/minecraft/world/entity/ai/attributes/Attributes.java.patch b/patches/net/minecraft/world/entity/ai/attributes/Attributes.java.patch index ebf3e8fe30..af4927ccd1 100644 --- a/patches/net/minecraft/world/entity/ai/attributes/Attributes.java.patch +++ b/patches/net/minecraft/world/entity/ai/attributes/Attributes.java.patch @@ -1,22 +1,21 @@ --- a/net/minecraft/world/entity/ai/attributes/Attributes.java +++ b/net/minecraft/world/entity/ai/attributes/Attributes.java -@@ -54,7 +_,8 @@ - "generic.jump_strength", new RangedAttribute("attribute.name.generic.jump_strength", 0.42F, 0.0, 32.0).setSyncable(true) +@@ -45,7 +_,7 @@ + "jump_strength", new RangedAttribute("attribute.name.jump_strength", 0.42F, 0.0, 32.0).setSyncable(true) ); public static final Holder KNOCKBACK_RESISTANCE = register( -- "generic.knockback_resistance", new RangedAttribute("attribute.name.generic.knockback_resistance", 0.0, 0.0, 1.0) -+ // Neo: Convert Knockback Resistance to percent-based for more appropriate display using IAttributeExtension. -+ "generic.knockback_resistance", new net.neoforged.neoforge.common.PercentageAttribute("attribute.name.generic.knockback_resistance", 0.0, 0.0, 1.0) +- "knockback_resistance", new RangedAttribute("attribute.name.knockback_resistance", 0.0, 0.0, 1.0) ++ "knockback_resistance", new net.neoforged.neoforge.common.PercentageAttribute("attribute.name.knockback_resistance", 0.0, 0.0, 1.0) ); - public static final Holder LUCK = register( - "generic.luck", new RangedAttribute("attribute.name.generic.luck", 0.0, -1024.0, 1024.0).setSyncable(true) -@@ -72,7 +_,8 @@ - "generic.movement_efficiency", new RangedAttribute("attribute.name.generic.movement_efficiency", 0.0, 0.0, 1.0).setSyncable(true) + public static final Holder LUCK = register("luck", new RangedAttribute("attribute.name.luck", 0.0, -1024.0, 1024.0).setSyncable(true)); + public static final Holder MAX_ABSORPTION = register( +@@ -61,7 +_,8 @@ + "movement_efficiency", new RangedAttribute("attribute.name.movement_efficiency", 0.0, 0.0, 1.0).setSyncable(true) ); public static final Holder MOVEMENT_SPEED = register( -- "generic.movement_speed", new RangedAttribute("attribute.name.generic.movement_speed", 0.7, 0.0, 1024.0).setSyncable(true) +- "movement_speed", new RangedAttribute("attribute.name.movement_speed", 0.7, 0.0, 1024.0).setSyncable(true) + // Neo: Convert Movement Speed to percent-based for more appropriate display using IAttributeExtension. Use a scale factor of 1000 since movement speed has 0.001 units. -+ "generic.movement_speed", new net.neoforged.neoforge.common.PercentageAttribute("attribute.name.generic.movement_speed", 0.7, 0.0, 1024.0, 1000).setSyncable(true) ++ "movement_speed", new net.neoforged.neoforge.common.PercentageAttribute("attribute.name.movement_speed", 0.7, 0.0, 1024.0, 1000).setSyncable(true) ); public static final Holder OXYGEN_BONUS = register( - "generic.oxygen_bonus", new RangedAttribute("attribute.name.generic.oxygen_bonus", 0.0, 0.0, 1024.0).setSyncable(true) + "oxygen_bonus", new RangedAttribute("attribute.name.oxygen_bonus", 0.0, 0.0, 1024.0).setSyncable(true) diff --git a/patches/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java.patch b/patches/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java.patch index 6497c6493e..26208739b5 100644 --- a/patches/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java.patch +++ b/patches/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java +++ b/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java -@@ -174,11 +_,12 @@ +@@ -177,11 +_,12 @@ .build(); public static AttributeSupplier getSupplier(EntityType p_22298_) { diff --git a/patches/net/minecraft/world/entity/ai/behavior/GiveGiftToHero.java.patch b/patches/net/minecraft/world/entity/ai/behavior/GiveGiftToHero.java.patch index dfe2740ab3..d88adceb0b 100644 --- a/patches/net/minecraft/world/entity/ai/behavior/GiveGiftToHero.java.patch +++ b/patches/net/minecraft/world/entity/ai/behavior/GiveGiftToHero.java.patch @@ -1,26 +1,21 @@ --- a/net/minecraft/world/entity/ai/behavior/GiveGiftToHero.java +++ b/net/minecraft/world/entity/ai/behavior/GiveGiftToHero.java -@@ -31,6 +_,8 @@ +@@ -22,6 +_,8 @@ private static final int MIN_TIME_BETWEEN_GIFTS = 600; private static final int MAX_TIME_BETWEEN_GIFTS = 6600; private static final int TIME_TO_DELAY_FOR_HEAD_TO_FINISH_TURNING = 20; + /** @deprecated Neo: use the {@link net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps#RAID_HERO_GIFTS data map} instead */ + @Deprecated - private static final Map> GIFTS = Util.make(Maps.newHashMap(), p_23020_ -> { - p_23020_.put(VillagerProfession.ARMORER, BuiltInLootTables.ARMORER_GIFT); - p_23020_.put(VillagerProfession.BUTCHER, BuiltInLootTables.BUTCHER_GIFT); -@@ -121,8 +_,12 @@ - return ImmutableList.of(new ItemStack(Items.POPPY)); + private static final Map> GIFTS = ImmutableMap.>builder() + .put(VillagerProfession.ARMORER, BuiltInLootTables.ARMORER_GIFT) + .put(VillagerProfession.BUTCHER, BuiltInLootTables.BUTCHER_GIFT) +@@ -112,7 +_,8 @@ + return BuiltInLootTables.BABY_VILLAGER_GIFT; } else { - VillagerProfession villagerprofession = p_23010_.getVillagerData().getProfession(); -- if (GIFTS.containsKey(villagerprofession)) { -- LootTable loottable = p_23010_.level().getServer().reloadableRegistries().getLootTable(GIFTS.get(villagerprofession)); -+ LootTable loottable = null; + VillagerProfession villagerprofession = p_372869_.getVillagerData().getProfession(); +- return GIFTS.getOrDefault(villagerprofession, BuiltInLootTables.UNEMPLOYED_GIFT); + var gift = net.minecraft.core.registries.BuiltInRegistries.VILLAGER_PROFESSION.wrapAsHolder(villagerprofession).getData(net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps.RAID_HERO_GIFTS); -+ if (gift != null) { -+ loottable = p_23010_.level().getServer().reloadableRegistries().getLootTable(gift.lootTable()); -+ } -+ if (loottable != null) { - LootParams lootparams = new LootParams.Builder((ServerLevel)p_23010_.level()) - .withParameter(LootContextParams.ORIGIN, p_23010_.position()) - .withParameter(LootContextParams.THIS_ENTITY, p_23010_) ++ return gift != null ? gift.lootTable() : BuiltInLootTables.UNEMPLOYED_GIFT; + } + } + diff --git a/patches/net/minecraft/world/entity/ai/behavior/StartAttacking.java.patch b/patches/net/minecraft/world/entity/ai/behavior/StartAttacking.java.patch index daa170bb51..88d24ac346 100644 --- a/patches/net/minecraft/world/entity/ai/behavior/StartAttacking.java.patch +++ b/patches/net/minecraft/world/entity/ai/behavior/StartAttacking.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/entity/ai/behavior/StartAttacking.java +++ b/net/minecraft/world/entity/ai/behavior/StartAttacking.java -@@ -30,7 +_,11 @@ - if (!p_258774_.canAttack(livingentity)) { +@@ -28,7 +_,11 @@ + if (!p_375685_.canAttack(livingentity)) { return false; } else { - p_258778_.set(livingentity); -+ net.neoforged.neoforge.event.entity.living.LivingChangeTargetEvent changeTargetEvent = net.neoforged.neoforge.common.CommonHooks.onLivingChangeTarget(p_258774_, livingentity, net.neoforged.neoforge.event.entity.living.LivingChangeTargetEvent.LivingTargetType.BEHAVIOR_TARGET); ++ net.neoforged.neoforge.event.entity.living.LivingChangeTargetEvent changeTargetEvent = net.neoforged.neoforge.common.CommonHooks.onLivingChangeTarget(p_375685_, livingentity, net.neoforged.neoforge.event.entity.living.LivingChangeTargetEvent.LivingTargetType.BEHAVIOR_TARGET); + if (changeTargetEvent.isCanceled() || changeTargetEvent.getNewAboutToBeSetTarget() == null) + return false; + diff --git a/patches/net/minecraft/world/entity/ai/behavior/Swim.java.patch b/patches/net/minecraft/world/entity/ai/behavior/Swim.java.patch index b9fd7fcb35..f1d7a4d423 100644 --- a/patches/net/minecraft/world/entity/ai/behavior/Swim.java.patch +++ b/patches/net/minecraft/world/entity/ai/behavior/Swim.java.patch @@ -3,7 +3,7 @@ @@ -14,7 +_,7 @@ } - public static boolean shouldSwim(Mob p_316787_) { + public static boolean shouldSwim(T p_316787_) { - return p_316787_.isInWater() && p_316787_.getFluidHeight(FluidTags.WATER) > p_316787_.getFluidJumpThreshold() || p_316787_.isInLava(); + return p_316787_.isInWater() && p_316787_.getFluidHeight(FluidTags.WATER) > p_316787_.getFluidJumpThreshold() || p_316787_.isInLava() || p_316787_.isInFluidType((fluidType, height) -> p_316787_.canSwimInFluidType(fluidType) && height > p_316787_.getFluidJumpThreshold()); } diff --git a/patches/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java.patch b/patches/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java.patch index a0d2d9d38f..a0ffc786d8 100644 --- a/patches/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java.patch +++ b/patches/net/minecraft/world/entity/ai/goal/BreakDoorGoal.java.patch @@ -4,8 +4,8 @@ if (!super.canUse()) { return false; } else { -- return !this.mob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) -+ return !net.neoforged.neoforge.common.CommonHooks.canEntityDestroy(this.mob.level(), this.doorPos, this.mob) +- return !getServerLevel(this.mob).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ++ return !net.neoforged.neoforge.common.CommonHooks.canEntityDestroy(getServerLevel(this.mob.level()), this.doorPos, this.mob) ? false : this.isValidDifficulty(this.mob.level().getDifficulty()) && !this.isOpen(); } diff --git a/patches/net/minecraft/world/entity/ai/goal/EatBlockGoal.java.patch b/patches/net/minecraft/world/entity/ai/goal/EatBlockGoal.java.patch index f817b98919..64b9d0f7b7 100644 --- a/patches/net/minecraft/world/entity/ai/goal/EatBlockGoal.java.patch +++ b/patches/net/minecraft/world/entity/ai/goal/EatBlockGoal.java.patch @@ -4,8 +4,8 @@ if (this.eatAnimationTick == this.adjustedTickDelay(4)) { BlockPos blockpos = this.mob.blockPosition(); if (IS_TALL_GRASS.test(this.level.getBlockState(blockpos))) { -- if (this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.level, this.mob)) { +- if (getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (net.neoforged.neoforge.event.EventHooks.canEntityGrief(getServerLevel(this.level), this.mob)) { this.level.destroyBlock(blockpos, false); } @@ -13,8 +13,8 @@ } else { BlockPos blockpos1 = blockpos.below(); if (this.level.getBlockState(blockpos1).is(Blocks.GRASS_BLOCK)) { -- if (this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.level, this.mob)) { +- if (getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (net.neoforged.neoforge.event.EventHooks.canEntityGrief(getServerLevel(this.level), this.mob)) { this.level.levelEvent(2001, blockpos1, Block.getId(Blocks.GRASS_BLOCK.defaultBlockState())); this.level.setBlock(blockpos1, Blocks.DIRT.defaultBlockState(), 2); } diff --git a/patches/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java.patch b/patches/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java.patch index 276d4f5010..ecb4345b77 100644 --- a/patches/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java.patch +++ b/patches/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java.patch @@ -4,8 +4,8 @@ @Override public boolean canUse() { -- if (!this.removerMob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (!net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.removerMob.level(), this.removerMob)) { +- if (!getServerLevel(this.removerMob).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (!net.neoforged.neoforge.event.EventHooks.canEntityGrief(getServerLevel(this.removerMob.level()), this.removerMob)) { return false; } else if (this.nextStartTick > 0) { this.nextStartTick--; diff --git a/patches/net/minecraft/world/entity/ai/navigation/PathNavigation.java.patch b/patches/net/minecraft/world/entity/ai/navigation/PathNavigation.java.patch index 8461aee220..6643b3f1ff 100644 --- a/patches/net/minecraft/world/entity/ai/navigation/PathNavigation.java.patch +++ b/patches/net/minecraft/world/entity/ai/navigation/PathNavigation.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/net/minecraft/world/entity/ai/navigation/PathNavigation.java -@@ -232,10 +_,10 @@ +@@ -249,10 +_,10 @@ Vec3 vec3 = this.getTempMobPos(); this.maxDistanceToWaypoint = this.mob.getBbWidth() > 0.75F ? this.mob.getBbWidth() / 2.0F : 0.75F - this.mob.getBbWidth() / 2.0F; Vec3i vec3i = this.path.getNextNodePos(); diff --git a/patches/net/minecraft/world/entity/ai/village/VillageSiege.java.patch b/patches/net/minecraft/world/entity/ai/village/VillageSiege.java.patch index 075cd89a91..5dc790e07c 100644 --- a/patches/net/minecraft/world/entity/ai/village/VillageSiege.java.patch +++ b/patches/net/minecraft/world/entity/ai/village/VillageSiege.java.patch @@ -16,7 +16,7 @@ Zombie zombie; try { - zombie = new Zombie(p_27017_); -+ zombie = EntityType.ZOMBIE.create(p_27017_); //Forge: Direct Initialization is deprecated, use EntityType. - zombie.finalizeSpawn(p_27017_, p_27017_.getCurrentDifficultyAt(zombie.blockPosition()), MobSpawnType.EVENT, null); ++ zombie = EntityType.ZOMBIE.create(p_27017_, EntitySpawnReason.EVENT); //Forge: Direct Initialization is deprecated, use EntityType. + zombie.finalizeSpawn(p_27017_, p_27017_.getCurrentDifficultyAt(zombie.blockPosition()), EntitySpawnReason.EVENT, null); } catch (Exception exception) { LOGGER.warn("Failed to create zombie for village siege at {}", vec3, exception); diff --git a/patches/net/minecraft/world/entity/animal/Animal.java.patch b/patches/net/minecraft/world/entity/animal/Animal.java.patch index 3885074970..7c60f97e17 100644 --- a/patches/net/minecraft/world/entity/animal/Animal.java.patch +++ b/patches/net/minecraft/world/entity/animal/Animal.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Animal.java +++ b/net/minecraft/world/entity/animal/Animal.java -@@ -201,6 +_,17 @@ +@@ -221,6 +_,17 @@ public void spawnChildFromBreeding(ServerLevel p_27564_, Animal p_27565_) { AgeableMob ageablemob = this.getBreedOffspring(p_27564_, p_27565_); diff --git a/patches/net/minecraft/world/entity/animal/Bee.java.patch b/patches/net/minecraft/world/entity/animal/Bee.java.patch index 79c82f584d..3e5e904026 100644 --- a/patches/net/minecraft/world/entity/animal/Bee.java.patch +++ b/patches/net/minecraft/world/entity/animal/Bee.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/entity/animal/Bee.java +++ b/net/minecraft/world/entity/animal/Bee.java -@@ -487,7 +_,7 @@ - return false; +@@ -498,7 +_,7 @@ + if (this.hivePos == null) { + return null; } else { - BlockEntity blockentity = this.level().getBlockEntity(this.hivePos); -- return blockentity != null && blockentity.getType() == BlockEntityType.BEEHIVE; -+ return blockentity instanceof BeehiveBlockEntity; +- return this.isTooFarAway(this.hivePos) ? null : this.level().getBlockEntity(this.hivePos, BlockEntityType.BEEHIVE).orElse(null); ++ return this.isTooFarAway(this.hivePos) ? null : this.level().getBlockEntity(this.hivePos) instanceof BeehiveBlockEntity hive ? hive : null; } } -@@ -636,8 +_,18 @@ +@@ -644,8 +_,18 @@ } @Override diff --git a/patches/net/minecraft/world/entity/animal/Cat.java.patch b/patches/net/minecraft/world/entity/animal/Cat.java.patch index 2a68e762b1..45b5cd9505 100644 --- a/patches/net/minecraft/world/entity/animal/Cat.java.patch +++ b/patches/net/minecraft/world/entity/animal/Cat.java.patch @@ -1,18 +1,17 @@ --- a/net/minecraft/world/entity/animal/Cat.java +++ b/net/minecraft/world/entity/animal/Cat.java -@@ -368,9 +_,9 @@ +@@ -373,9 +_,9 @@ } } else if (this.isFood(itemstack) && this.getHealth() < this.getMaxHealth()) { if (!this.level().isClientSide()) { - this.usePlayerItem(p_28153_, p_28154_, itemstack); -- FoodProperties foodproperties = itemstack.get(DataComponents.FOOD); -+ FoodProperties foodproperties = itemstack.getFoodProperties(this); + FoodProperties foodproperties = itemstack.get(DataComponents.FOOD); this.heal(foodproperties != null ? (float)foodproperties.nutrition() : 1.0F); + this.usePlayerItem(p_28153_, p_28154_, itemstack); + this.playEatingSound(); } - return InteractionResult.sidedSuccess(this.level().isClientSide()); -@@ -430,7 +_,7 @@ +@@ -437,7 +_,7 @@ } private void tryToTame(Player p_333858_) { diff --git a/patches/net/minecraft/world/entity/animal/Fox.java.patch b/patches/net/minecraft/world/entity/animal/Fox.java.patch index b84f34716a..c70597662c 100644 --- a/patches/net/minecraft/world/entity/animal/Fox.java.patch +++ b/patches/net/minecraft/world/entity/animal/Fox.java.patch @@ -1,16 +1,18 @@ --- a/net/minecraft/world/entity/animal/Fox.java +++ b/net/minecraft/world/entity/animal/Fox.java -@@ -677,13 +_,16 @@ +@@ -671,13 +_,18 @@ @Override protected void dropAllDeathLoot(ServerLevel p_348640_, DamageSource p_28536_) { + super.dropAllDeathLoot(p_348640_, p_28536_); + } -+ protected void dropEquipment() { // Forge: move extra drops to dropEquipment to allow them to be captured by LivingDropsEvent -+ super.dropEquipment(); ++ ++ @Override ++ protected void dropEquipment(ServerLevel p_348640_) { // Forge: move extra drops to dropEquipment to allow them to be captured by LivingDropsEvent ++ super.dropEquipment(p_348640_); ItemStack itemstack = this.getItemBySlot(EquipmentSlot.MAINHAND); if (!itemstack.isEmpty()) { - this.spawnAtLocation(itemstack); + this.spawnAtLocation(p_348640_, itemstack); this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY); } @@ -18,9 +20,9 @@ } public static boolean isPathClear(Fox p_28472_, LivingEntity p_28473_) { -@@ -842,6 +_,17 @@ +@@ -837,6 +_,17 @@ protected void breed() { - ServerLevel serverlevel = (ServerLevel)this.level; + ServerLevel serverlevel = this.level; Fox fox = (Fox)this.animal.getBreedOffspring(serverlevel, this.partner); + final net.neoforged.neoforge.event.entity.living.BabyEntitySpawnEvent event = new net.neoforged.neoforge.event.entity.living.BabyEntitySpawnEvent(animal, partner, fox); + final boolean cancelled = net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(event).isCanceled(); @@ -36,16 +38,16 @@ if (fox != null) { ServerPlayer serverplayer = this.animal.getLoveCause(); ServerPlayer serverplayer1 = this.partner.getLoveCause(); -@@ -919,7 +_,7 @@ +@@ -914,7 +_,7 @@ } protected void onReachedTarget() { -- if (Fox.this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (net.neoforged.neoforge.event.EventHooks.canEntityGrief(Fox.this.level(), Fox.this)) { +- if (getServerLevel(Fox.this.level()).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (net.neoforged.neoforge.event.EventHooks.canEntityGrief(getServerLevel(Fox.this.level()), Fox.this)) { BlockState blockstate = Fox.this.level().getBlockState(this.blockPos); if (blockstate.is(Blocks.SWEET_BERRY_BUSH)) { this.pickSweetBerries(blockstate); -@@ -978,7 +_,7 @@ +@@ -973,7 +_,7 @@ @Override public boolean canUse() { diff --git a/patches/net/minecraft/world/entity/animal/MushroomCow.java.patch b/patches/net/minecraft/world/entity/animal/MushroomCow.java.patch index fa6f17678a..373b37a15a 100644 --- a/patches/net/minecraft/world/entity/animal/MushroomCow.java.patch +++ b/patches/net/minecraft/world/entity/animal/MushroomCow.java.patch @@ -1,40 +1,23 @@ --- a/net/minecraft/world/entity/animal/MushroomCow.java +++ b/net/minecraft/world/entity/animal/MushroomCow.java -@@ -108,7 +_,7 @@ - - this.playSound(soundevent, 1.0F, 1.0F); - return InteractionResult.sidedSuccess(this.level().isClientSide); -- } else if (itemstack.is(Items.SHEARS) && this.readyForShearing()) { -+ } else if (false && itemstack.is(Items.SHEARS) && this.readyForShearing()) { // Neo: Shear logic is handled by IShearable - this.shear(SoundSource.PLAYERS); - this.gameEvent(GameEvent.SHEAR, p_28941_); - if (!this.level().isClientSide) { -@@ -165,8 +_,10 @@ - public void shear(SoundSource p_28924_) { - this.level().playSound(null, this, SoundEvents.MOOSHROOM_SHEAR, p_28924_, 1.0F, 1.0F); - if (!this.level().isClientSide()) { -+ if (!net.neoforged.neoforge.event.EventHooks.canLivingConvert(this, EntityType.COW, (timer) -> {})) return; - Cow cow = EntityType.COW.create(this.level()); - if (cow != null) { -+ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, cow); - ((ServerLevel)this.level()).sendParticles(ParticleTypes.EXPLOSION, this.getX(), this.getY(0.5), this.getZ(), 1, 0.0, 0.0, 0.0, 0.0); - this.discard(); - cow.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot()); -@@ -185,10 +_,13 @@ - this.level().addFreshEntity(cow); - - for (int i = 0; i < 5; i++) { -- this.level() -- .addFreshEntity( -- new ItemEntity(this.level(), this.getX(), this.getY(1.0), this.getZ(), new ItemStack(this.getVariant().blockState.getBlock())) -- ); +@@ -166,11 +_,19 @@ + @Override + public void shear(ServerLevel p_376375_, SoundSource p_28924_, ItemStack p_373092_) { + p_376375_.playSound(null, this, SoundEvents.MOOSHROOM_SHEAR, p_28924_, 1.0F, 1.0F); ++ if (!net.neoforged.neoforge.event.EventHooks.canLivingConvert(this, EntityType.COW, (timer) -> {})) return; + this.convertTo(EntityType.COW, ConversionParams.single(this, false, false), p_381482_ -> { ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_381482_); + p_376375_.sendParticles(ParticleTypes.EXPLOSION, this.getX(), this.getY(0.5), this.getZ(), 1, 0.0, 0.0, 0.0, 0.0); + this.dropFromShearingLootTable(p_376375_, BuiltInLootTables.SHEAR_MOOSHROOM, p_373092_, (p_381483_, p_381484_) -> { + for (int i = 0; i < p_381484_.getCount(); i++) { +- p_381483_.addFreshEntity(new ItemEntity(this.level(), this.getX(), this.getY(1.0), this.getZ(), p_381484_.copyWithCount(1))); + // Neo: Change from addFreshEntity to spawnAtLocation to ensure captureDrops can capture this, we also need to unset the default pickup delay from the item + // Vanilla uses this.getY(1.0) for the y-level, which is this.getY() + this.getBbHeight() * 1.0, so we pass the BB height as the Y-offset. -+ ItemEntity item = spawnAtLocation(new ItemStack(this.getVariant().blockState.getBlock()), this.getBbHeight()); ++ ItemEntity item = spawnAtLocation(p_381483_, p_381484_.copyWithCount(1), this.getBbHeight()); + if (item != null) { + // addFreshEntity does not incur a pickup delay, while spawnAtLocation sets the default pickup delay. + item.setNoPickUpDelay(); + } } - } - } + }); + }); diff --git a/patches/net/minecraft/world/entity/animal/Ocelot.java.patch b/patches/net/minecraft/world/entity/animal/Ocelot.java.patch index 357c44260d..6e9ec371d4 100644 --- a/patches/net/minecraft/world/entity/animal/Ocelot.java.patch +++ b/patches/net/minecraft/world/entity/animal/Ocelot.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Ocelot.java +++ b/net/minecraft/world/entity/animal/Ocelot.java -@@ -160,7 +_,7 @@ +@@ -159,7 +_,7 @@ if ((this.temptGoal == null || this.temptGoal.isRunning()) && !this.isTrusting() && this.isFood(itemstack) && p_29021_.distanceToSqr(this) < 9.0) { this.usePlayerItem(p_29021_, p_29022_, itemstack); if (!this.level().isClientSide) { diff --git a/patches/net/minecraft/world/entity/animal/Parrot.java.patch b/patches/net/minecraft/world/entity/animal/Parrot.java.patch index 0fbb41823f..ba8eca84e8 100644 --- a/patches/net/minecraft/world/entity/animal/Parrot.java.patch +++ b/patches/net/minecraft/world/entity/animal/Parrot.java.patch @@ -10,10 +10,10 @@ }; + /** @deprecated Neo: use the {@link net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps#PARROT_IMITATIONS data map} instead */ + @Deprecated - static final Map, SoundEvent> MOB_SOUND_MAP = Util.make(Maps.newHashMap(), p_326764_ -> { - p_326764_.put(EntityType.BLAZE, SoundEvents.PARROT_IMITATE_BLAZE); - p_326764_.put(EntityType.BOGGED, SoundEvents.PARROT_IMITATE_BOGGED); -@@ -257,7 +_,7 @@ + static final Map, SoundEvent> MOB_SOUND_MAP = Util.make(Maps.newHashMap(), p_379158_ -> { + p_379158_.put(EntityType.BLAZE, SoundEvents.PARROT_IMITATE_BLAZE); + p_379158_.put(EntityType.BOGGED, SoundEvents.PARROT_IMITATE_BOGGED); +@@ -261,7 +_,7 @@ } if (!this.level().isClientSide) { @@ -22,19 +22,19 @@ this.tame(p_29414_); this.level().broadcastEntityEvent(this, (byte)7); } else { -@@ -321,7 +_,10 @@ +@@ -325,7 +_,10 @@ public static SoundEvent getAmbient(Level p_218239_, RandomSource p_218240_) { if (p_218239_.getDifficulty() != Difficulty.PEACEFUL && p_218240_.nextInt(1000) == 0) { - List> list = Lists.newArrayList(MOB_SOUND_MAP.keySet()); + final var entities = new java.util.HashSet<>(MOB_SOUND_MAP.keySet()); -+ final var registry = p_218239_.registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.ENTITY_TYPE); -+ registry.getDataMap(net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps.PARROT_IMITATIONS).keySet().forEach(key -> entities.add(registry.get(key))); ++ final var registry = p_218239_.registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.ENTITY_TYPE); ++ registry.getDataMap(net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps.PARROT_IMITATIONS).keySet().forEach(key -> entities.add(registry.getValue(key))); + List> list = Lists.newArrayList(entities); return getImitatedSound(list.get(p_218240_.nextInt(list.size()))); } else { return SoundEvents.PARROT_AMBIENT; -@@ -329,7 +_,9 @@ +@@ -333,7 +_,9 @@ } private static SoundEvent getImitatedSound(EntityType p_29409_) { diff --git a/patches/net/minecraft/world/entity/animal/Pig.java.patch b/patches/net/minecraft/world/entity/animal/Pig.java.patch index 6346151346..35f07ef1d6 100644 --- a/patches/net/minecraft/world/entity/animal/Pig.java.patch +++ b/patches/net/minecraft/world/entity/animal/Pig.java.patch @@ -1,19 +1,18 @@ --- a/net/minecraft/world/entity/animal/Pig.java +++ b/net/minecraft/world/entity/animal/Pig.java -@@ -206,7 +_,7 @@ +@@ -207,13 +_,14 @@ @Override public void thunderHit(ServerLevel p_29473_, LightningBolt p_29474_) { - if (p_29473_.getDifficulty() != Difficulty.PEACEFUL) { + if (p_29473_.getDifficulty() != Difficulty.PEACEFUL && net.neoforged.neoforge.event.EventHooks.canLivingConvert(this, EntityType.ZOMBIFIED_PIGLIN, (timer) -> {})) { - ZombifiedPiglin zombifiedpiglin = EntityType.ZOMBIFIED_PIGLIN.create(p_29473_); - if (zombifiedpiglin != null) { - zombifiedpiglin.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(Items.GOLDEN_SWORD)); -@@ -219,6 +_,7 @@ + ZombifiedPiglin zombifiedpiglin = this.convertTo(EntityType.ZOMBIFIED_PIGLIN, ConversionParams.single(this, false, true), p_381485_ -> { + if (this.getMainHandItem().isEmpty()) { + p_381485_.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(Items.GOLDEN_SWORD)); } - zombifiedpiglin.setPersistenceRequired(); -+ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, zombifiedpiglin); - p_29473_.addFreshEntity(zombifiedpiglin); - this.discard(); - } else { + p_381485_.setPersistenceRequired(); ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_381485_); + }); + if (zombifiedpiglin == null) { + super.thunderHit(p_29473_, p_29474_); diff --git a/patches/net/minecraft/world/entity/animal/Rabbit.java.patch b/patches/net/minecraft/world/entity/animal/Rabbit.java.patch index 867d550ac7..987d78e676 100644 --- a/patches/net/minecraft/world/entity/animal/Rabbit.java.patch +++ b/patches/net/minecraft/world/entity/animal/Rabbit.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/entity/animal/Rabbit.java +++ b/net/minecraft/world/entity/animal/Rabbit.java -@@ -530,7 +_,7 @@ +@@ -531,7 +_,7 @@ @Override public boolean canUse() { if (this.nextStartTick <= 0) { -- if (!this.rabbit.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (!net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.rabbit.level(), this.rabbit)) { +- if (!getServerLevel(this.rabbit).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (!net.neoforged.neoforge.event.EventHooks.canEntityGrief(getServerLevel(this.rabbit.level()), this.rabbit)) { return false; } -@@ -585,7 +_,7 @@ +@@ -586,7 +_,7 @@ @Override protected boolean isValidTarget(LevelReader p_29785_, BlockPos p_29786_) { BlockState blockstate = p_29785_.getBlockState(p_29786_); diff --git a/patches/net/minecraft/world/entity/animal/Sheep.java.patch b/patches/net/minecraft/world/entity/animal/Sheep.java.patch index 4871c860c8..e22cf4c2d2 100644 --- a/patches/net/minecraft/world/entity/animal/Sheep.java.patch +++ b/patches/net/minecraft/world/entity/animal/Sheep.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/entity/animal/Sheep.java +++ b/net/minecraft/world/entity/animal/Sheep.java -@@ -212,7 +_,7 @@ +@@ -156,7 +_,7 @@ @Override public InteractionResult mobInteract(Player p_29853_, InteractionHand p_29854_) { ItemStack itemstack = p_29853_.getItemInHand(p_29854_); - if (itemstack.is(Items.SHEARS)) { + if (false && itemstack.is(Items.SHEARS)) { // Neo: Shear logic is handled by IShearable - if (!this.level().isClientSide && this.readyForShearing()) { - this.shear(SoundSource.PLAYERS); + if (this.level() instanceof ServerLevel serverlevel && this.readyForShearing()) { + this.shear(serverlevel, SoundSource.PLAYERS, itemstack); this.gameEvent(GameEvent.SHEAR, p_29853_); diff --git a/patches/net/minecraft/world/entity/animal/SnowGolem.java.patch b/patches/net/minecraft/world/entity/animal/SnowGolem.java.patch index 19b14ba776..04e835e62a 100644 --- a/patches/net/minecraft/world/entity/animal/SnowGolem.java.patch +++ b/patches/net/minecraft/world/entity/animal/SnowGolem.java.patch @@ -1,20 +1,20 @@ --- a/net/minecraft/world/entity/animal/SnowGolem.java +++ b/net/minecraft/world/entity/animal/SnowGolem.java -@@ -92,7 +_,7 @@ - this.hurt(this.damageSources().onFire(), 1.0F); +@@ -95,7 +_,7 @@ + this.hurtServer(serverlevel, this.damageSources().onFire(), 1.0F); } -- if (!this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (!net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.level(), this)) { +- if (!serverlevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (!net.neoforged.neoforge.event.EventHooks.canEntityGrief(serverlevel, this)) { return; } -@@ -127,7 +_,7 @@ +@@ -136,7 +_,7 @@ @Override protected InteractionResult mobInteract(Player p_29920_, InteractionHand p_29921_) { ItemStack itemstack = p_29920_.getItemInHand(p_29921_); - if (itemstack.is(Items.SHEARS) && this.readyForShearing()) { + if (false && itemstack.is(Items.SHEARS) && this.readyForShearing()) { // Neo: Shear logic is handled by IShearable - this.shear(SoundSource.PLAYERS); - this.gameEvent(GameEvent.SHEAR, p_29920_); - if (!this.level().isClientSide) { + if (this.level() instanceof ServerLevel serverlevel) { + this.shear(serverlevel, SoundSource.PLAYERS, itemstack); + this.gameEvent(GameEvent.SHEAR, p_29920_); diff --git a/patches/net/minecraft/world/entity/animal/Wolf.java.patch b/patches/net/minecraft/world/entity/animal/Wolf.java.patch index 5a316c46eb..e50cf8e286 100644 --- a/patches/net/minecraft/world/entity/animal/Wolf.java.patch +++ b/patches/net/minecraft/world/entity/animal/Wolf.java.patch @@ -1,29 +1,19 @@ --- a/net/minecraft/world/entity/animal/Wolf.java +++ b/net/minecraft/world/entity/animal/Wolf.java -@@ -419,10 +_,11 @@ - if (!this.level().isClientSide || this.isBaby() && this.isFood(itemstack)) { - if (this.isTame()) { - if (this.isFood(itemstack) && this.getHealth() < this.getMaxHealth()) { -- itemstack.consume(1, p_30412_); -- FoodProperties foodproperties = itemstack.get(DataComponents.FOOD); -+ FoodProperties foodproperties = itemstack.getFoodProperties(this); - float f = foodproperties != null ? (float)foodproperties.nutrition() : 1.0F; - this.heal(2.0F * f); -+ itemstack.consume(1, p_30412_); -+ this.gameEvent(GameEvent.EAT); // Neo: add EAT game event - return InteractionResult.sidedSuccess(this.level().isClientSide()); - } else { - if (item instanceof DyeItem dyeitem && this.isOwnedBy(p_30412_)) { -@@ -440,7 +_,7 @@ - this.setBodyArmorItem(itemstack.copyWithCount(1)); - itemstack.consume(1, p_30412_); - return InteractionResult.SUCCESS; -- } else if (itemstack.is(Items.SHEARS) -+ } else if (itemstack.canPerformAction(net.neoforged.neoforge.common.ItemAbilities.SHEARS_REMOVE_ARMOR) - && this.isOwnedBy(p_30412_) - && this.hasArmor() - && (!EnchantmentHelper.has(this.getBodyArmorItem(), EnchantmentEffectComponents.PREVENT_ARMOR_CHANGE) || p_30412_.isCreative())) { -@@ -488,7 +_,7 @@ +@@ -403,10 +_,11 @@ + Item item = itemstack.getItem(); + if (this.isTame()) { + if (this.isFood(itemstack) && this.getHealth() < this.getMaxHealth()) { +- this.usePlayerItem(p_30412_, p_30413_, itemstack); + FoodProperties foodproperties = itemstack.get(DataComponents.FOOD); + float f = foodproperties != null ? (float)foodproperties.nutrition() : 1.0F; + this.heal(2.0F * f); ++ this.usePlayerItem(p_30412_, p_30413_, itemstack); ++ this.gameEvent(GameEvent.EAT); // Neo: add EAT game event + return InteractionResult.SUCCESS; + } else { + if (item instanceof DyeItem dyeitem && this.isOwnedBy(p_30412_)) { +@@ -471,7 +_,7 @@ } private void tryToTame(Player p_333736_) { diff --git a/patches/net/minecraft/world/entity/animal/allay/Allay.java.patch b/patches/net/minecraft/world/entity/animal/allay/Allay.java.patch index bd58fe31d2..f0ede9df6e 100644 --- a/patches/net/minecraft/world/entity/animal/allay/Allay.java.patch +++ b/patches/net/minecraft/world/entity/animal/allay/Allay.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/world/entity/animal/allay/Allay.java +++ b/net/minecraft/world/entity/animal/allay/Allay.java -@@ -368,9 +_,9 @@ - public boolean wantsToPickUp(ItemStack p_218387_) { +@@ -369,9 +_,9 @@ + public boolean wantsToPickUp(ServerLevel p_376111_, ItemStack p_218387_) { ItemStack itemstack = this.getItemInHand(InteractionHand.MAIN_HAND); return !itemstack.isEmpty() -- && this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) +- && p_376111_.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && this.inventory.canAddItem(p_218387_) - && this.allayConsidersItemEqual(itemstack, p_218387_); + && this.allayConsidersItemEqual(itemstack, p_218387_) -+ && net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.level(), this); ++ && net.neoforged.neoforge.event.EventHooks.canEntityGrief(p_376111_, this); } private boolean allayConsidersItemEqual(ItemStack p_252278_, ItemStack p_250405_) { diff --git a/patches/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch b/patches/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch index e76537d399..d2768ffcd2 100644 --- a/patches/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch +++ b/patches/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/entity/animal/armadillo/Armadillo.java +++ b/net/minecraft/world/entity/animal/armadillo/Armadillo.java -@@ -300,7 +_,7 @@ +@@ -305,7 +_,7 @@ @Override public InteractionResult mobInteract(Player p_316559_, InteractionHand p_316119_) { ItemStack itemstack = p_316559_.getItemInHand(p_316119_); - if (itemstack.is(Items.BRUSH) && this.brushOffScute()) { + if (itemstack.canPerformAction(net.neoforged.neoforge.common.ItemAbilities.BRUSH_BRUSH) && this.brushOffScute()) { itemstack.hurtAndBreak(16, p_316559_, getSlotForHand(p_316119_)); - return InteractionResult.sidedSuccess(this.level().isClientSide); + return InteractionResult.SUCCESS; } else { diff --git a/patches/net/minecraft/world/entity/animal/camel/Camel.java.patch b/patches/net/minecraft/world/entity/animal/camel/Camel.java.patch index 9f451f4188..40ce1b83d0 100644 --- a/patches/net/minecraft/world/entity/animal/camel/Camel.java.patch +++ b/patches/net/minecraft/world/entity/animal/camel/Camel.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/camel/Camel.java +++ b/net/minecraft/world/entity/animal/camel/Camel.java -@@ -286,6 +_,7 @@ +@@ -289,6 +_,7 @@ this.dashCooldown = 55; this.setDashing(true); this.hasImpulse = true; diff --git a/patches/net/minecraft/world/entity/animal/frog/Tadpole.java.patch b/patches/net/minecraft/world/entity/animal/frog/Tadpole.java.patch index 637cf5cae4..90a3bb4745 100644 --- a/patches/net/minecraft/world/entity/animal/frog/Tadpole.java.patch +++ b/patches/net/minecraft/world/entity/animal/frog/Tadpole.java.patch @@ -1,13 +1,13 @@ --- a/net/minecraft/world/entity/animal/frog/Tadpole.java +++ b/net/minecraft/world/entity/animal/frog/Tadpole.java -@@ -225,8 +_,10 @@ +@@ -228,8 +_,10 @@ + } private void ageUp() { ++ if (!net.neoforged.neoforge.event.EventHooks.canLivingConvert(this, EntityType.FROG, (timer) -> {})) return; if (this.level() instanceof ServerLevel serverlevel) { -+ if (!net.neoforged.neoforge.event.EventHooks.canLivingConvert(this, EntityType.FROG, (timer) -> {})) return; - Frog frog = EntityType.FROG.create(this.level()); - if (frog != null) { -+ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, frog); - frog.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot()); - frog.finalizeSpawn(serverlevel, this.level().getCurrentDifficultyAt(frog.blockPosition()), MobSpawnType.CONVERSION, null); - frog.setNoAi(this.isNoAi()); + this.convertTo(EntityType.FROG, ConversionParams.single(this, false, false), p_381493_ -> { ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_381493_); + p_381493_.finalizeSpawn(serverlevel, this.level().getCurrentDifficultyAt(p_381493_.blockPosition()), EntitySpawnReason.CONVERSION, null); + p_381493_.setPersistenceRequired(); + p_381493_.fudgePositionAfterSizeChange(this.getDimensions(this.getPose())); diff --git a/patches/net/minecraft/world/entity/animal/horse/AbstractHorse.java.patch b/patches/net/minecraft/world/entity/animal/horse/AbstractHorse.java.patch index 4f8118febd..c011008d18 100644 --- a/patches/net/minecraft/world/entity/animal/horse/AbstractHorse.java.patch +++ b/patches/net/minecraft/world/entity/animal/horse/AbstractHorse.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/horse/AbstractHorse.java +++ b/net/minecraft/world/entity/animal/horse/AbstractHorse.java -@@ -396,9 +_,9 @@ +@@ -405,9 +_,9 @@ protected void playStepSound(BlockPos p_30584_, BlockState p_30585_) { if (!p_30585_.liquid()) { BlockState blockstate = this.level().getBlockState(p_30584_.above()); @@ -12,7 +12,7 @@ } if (this.isVehicle() && this.canGallop) { -@@ -816,6 +_,7 @@ +@@ -823,6 +_,7 @@ this.setDeltaMovement(vec3.x, d0, vec3.z); this.setIsJumping(true); this.hasImpulse = true; @@ -20,10 +20,10 @@ if (p_275435_.z > 0.0) { float f = Mth.sin(this.getYRot() * (float) (Math.PI / 180.0)); float f1 = Mth.cos(this.getYRot() * (float) (Math.PI / 180.0)); -@@ -1118,6 +_,11 @@ +@@ -1127,6 +_,11 @@ this.randomizeAttributes(p_30555_.getRandom()); - return super.finalizeSpawn(p_30555_, p_30556_, p_30557_, p_30558_); + return super.finalizeSpawn(p_30555_, p_30556_, p_363523_, p_30558_); + } + + // Neo: Inventory getter diff --git a/patches/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java.patch b/patches/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java.patch index e3a7684a92..ca3ab0b2c6 100644 --- a/patches/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java.patch +++ b/patches/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java.patch @@ -6,7 +6,7 @@ ServerLevel serverlevel = (ServerLevel)this.horse.level(); + // Forge: Trigger the trap in a tick task to avoid crashes when mods add goals to skeleton horses + // (MC-206338/Forge PR #7509) -+ serverlevel.getServer().tell(new net.minecraft.server.TickTask(serverlevel.getServer().getTickCount(), () -> { ++ serverlevel.getServer().schedule(new net.minecraft.server.TickTask(serverlevel.getServer().getTickCount(), () -> { + if (!this.horse.isAlive()) return; DifficultyInstance difficultyinstance = serverlevel.getCurrentDifficultyAt(this.horse.blockPosition()); this.horse.setTrap(false); diff --git a/patches/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch b/patches/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch index cfa11ac57e..8c8aa4cdca 100644 --- a/patches/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch +++ b/patches/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/sniffer/Sniffer.java +++ b/net/minecraft/world/entity/animal/sniffer/Sniffer.java -@@ -299,7 +_,7 @@ +@@ -288,7 +_,7 @@ if (this.tickCount % 10 == 0) { this.level() .playLocalSound( diff --git a/patches/net/minecraft/world/entity/boss/EnderDragonPart.java.patch b/patches/net/minecraft/world/entity/boss/EnderDragonPart.java.patch index 1eda2ad745..c00f4cdd13 100644 --- a/patches/net/minecraft/world/entity/boss/EnderDragonPart.java.patch +++ b/patches/net/minecraft/world/entity/boss/EnderDragonPart.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/boss/EnderDragonPart.java +++ b/net/minecraft/world/entity/boss/EnderDragonPart.java -@@ -13,13 +_,13 @@ +@@ -14,13 +_,13 @@ import net.minecraft.world.entity.boss.enderdragon.EnderDragon; import net.minecraft.world.item.ItemStack; diff --git a/patches/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch b/patches/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch index 5e9f360c55..b807a36c3f 100644 --- a/patches/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch +++ b/patches/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java +++ b/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -@@ -103,6 +_,14 @@ +@@ -101,6 +_,14 @@ + this.setHealth(this.getMaxHealth()); this.noPhysics = true; - this.noCulling = true; this.phaseManager = new EnderDragonPhaseManager(this); + this.setId(ENTITY_COUNTER.getAndAdd(this.subEntities.length + 1) + 1); // Forge: Fix MC-158205: Make sure part ids are successors of parent mob id + } @@ -15,49 +15,52 @@ } public void setDragonFight(EndDragonFight p_287736_) { -@@ -170,8 +_,12 @@ - return adouble; +@@ -149,8 +_,15 @@ + p_326491_.define(DATA_PHASE, EnderDragonPhase.HOVERING.getId()); } -+ @org.jetbrains.annotations.Nullable private Player unlimitedLastHurtByPlayer = null; ++ @org.jetbrains.annotations.Nullable ++ private Player unlimitedLastHurtByPlayer = null; ++ @Override public void aiStep() { + // lastHurtByPlayer is cleared after 100 ticks, capture it indefinitely in unlimitedLastHurtByPlayer for LivingExperienceDropEvent + if (this.lastHurtByPlayer != null) this.unlimitedLastHurtByPlayer = lastHurtByPlayer; + if (this.unlimitedLastHurtByPlayer != null && this.unlimitedLastHurtByPlayer.isRemoved()) this.unlimitedLastHurtByPlayer = null; ++ this.processFlappingMovement(); if (this.level().isClientSide) { this.setHealth(this.getHealth()); -@@ -475,7 +_,7 @@ +@@ -445,7 +_,7 @@ BlockPos blockpos = new BlockPos(k1, l1, i2); - BlockState blockstate = this.level().getBlockState(blockpos); + BlockState blockstate = p_376795_.getBlockState(blockpos); if (!blockstate.isAir() && !blockstate.is(BlockTags.DRAGON_TRANSPARENT)) { -- if (this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !blockstate.is(BlockTags.DRAGON_IMMUNE)) { -+ if (net.neoforged.neoforge.common.CommonHooks.canEntityDestroy(this.level(), blockpos, this) && !blockstate.is(BlockTags.DRAGON_IMMUNE)) { - flag1 = this.level().removeBlock(blockpos, false) || flag1; +- if (p_376795_.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !blockstate.is(BlockTags.DRAGON_IMMUNE)) { ++ if (net.neoforged.neoforge.common.CommonHooks.canEntityDestroy(p_376795_, blockpos, this) && !blockstate.is(BlockTags.DRAGON_IMMUNE)) { + flag1 = p_376795_.removeBlock(blockpos, false) || flag1; } else { flag = true; -@@ -569,7 +_,8 @@ +@@ -538,7 +_,8 @@ - if (this.level() instanceof ServerLevel) { - if (this.dragonDeathTime > 150 && this.dragonDeathTime % 5 == 0 && flag) { -- ExperienceOrb.award((ServerLevel)this.level(), this.position(), Mth.floor((float)i * 0.08F)); + if (this.level() instanceof ServerLevel serverlevel) { + if (this.dragonDeathTime > 150 && this.dragonDeathTime % 5 == 0 && serverlevel.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { +- ExperienceOrb.award(serverlevel, this.position(), Mth.floor((float)i * 0.08F)); + int award = net.neoforged.neoforge.event.EventHooks.getExperienceDrop(this, this.unlimitedLastHurtByPlayer, Mth.floor((float)i * 0.08F)); + ExperienceOrb.award((ServerLevel) this.level(), this.position(), award); } if (this.dragonDeathTime == 1 && !this.isSilent()) { -@@ -580,7 +_,8 @@ +@@ -549,7 +_,8 @@ this.move(MoverType.SELF, new Vec3(0.0, 0.1F, 0.0)); - if (this.dragonDeathTime == 200 && this.level() instanceof ServerLevel) { - if (flag) { -- ExperienceOrb.award((ServerLevel)this.level(), this.position(), Mth.floor((float)i * 0.2F)); + if (this.dragonDeathTime == 200 && this.level() instanceof ServerLevel serverlevel1) { + if (serverlevel1.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { +- ExperienceOrb.award(serverlevel1, this.position(), Mth.floor((float)i * 0.2F)); + int award = net.neoforged.neoforge.event.EventHooks.getExperienceDrop(this, this.unlimitedLastHurtByPlayer, Mth.floor((float)i * 0.2F)); + ExperienceOrb.award((ServerLevel) this.level(), this.position(), award); } if (this.dragonFight != null) { -@@ -912,8 +_,19 @@ +@@ -860,8 +_,19 @@ } @Override diff --git a/patches/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch b/patches/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch index a2b0f70b58..5e036c641e 100644 --- a/patches/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch +++ b/patches/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch @@ -1,24 +1,24 @@ --- a/net/minecraft/world/entity/boss/wither/WitherBoss.java +++ b/net/minecraft/world/entity/boss/wither/WitherBoss.java -@@ -322,7 +_,7 @@ +@@ -320,7 +_,7 @@ if (this.destroyBlocksTick > 0) { this.destroyBlocksTick--; -- if (this.destroyBlocksTick == 0 && this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (this.destroyBlocksTick == 0 && net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.level(), this)) { +- if (this.destroyBlocksTick == 0 && p_376675_.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (this.destroyBlocksTick == 0 && net.neoforged.neoforge.event.EventHooks.canEntityGrief(p_376675_, this)) { boolean flag = false; int l = Mth.floor(this.getBbWidth() / 2.0F + 1.0F); int i1 = Mth.floor(this.getBbHeight()); -@@ -331,7 +_,7 @@ +@@ -329,7 +_,7 @@ this.getBlockX() - l, this.getBlockY(), this.getBlockZ() - l, this.getBlockX() + l, this.getBlockY() + i1, this.getBlockZ() + l )) { - BlockState blockstate = this.level().getBlockState(blockpos); + BlockState blockstate = p_376675_.getBlockState(blockpos); - if (canDestroy(blockstate)) { + if (blockstate.canEntityDestroy(this.level(), blockpos, this) && net.neoforged.neoforge.event.EventHooks.onEntityDestroyBlock(this, blockpos, blockstate)) { - flag = this.level().destroyBlock(blockpos, true, this) || flag; + flag = p_376675_.destroyBlock(blockpos, true, this) || flag; } } -@@ -350,6 +_,10 @@ +@@ -348,6 +_,10 @@ } } @@ -29,7 +29,7 @@ public static boolean canDestroy(BlockState p_31492_) { return !p_31492_.isAir() && !p_31492_.is(BlockTags.WITHER_IMMUNE); } -@@ -495,6 +_,7 @@ +@@ -493,6 +_,7 @@ @Override public void checkDespawn() { diff --git a/patches/net/minecraft/world/entity/decoration/ArmorStand.java.patch b/patches/net/minecraft/world/entity/decoration/ArmorStand.java.patch deleted file mode 100644 index d99faa6be3..0000000000 --- a/patches/net/minecraft/world/entity/decoration/ArmorStand.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/entity/decoration/ArmorStand.java -+++ b/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -73,7 +_,7 @@ - public static final EntityDataAccessor DATA_LEFT_LEG_POSE = SynchedEntityData.defineId(ArmorStand.class, EntityDataSerializers.ROTATIONS); - public static final EntityDataAccessor DATA_RIGHT_LEG_POSE = SynchedEntityData.defineId(ArmorStand.class, EntityDataSerializers.ROTATIONS); - private static final Predicate RIDABLE_MINECARTS = p_31582_ -> p_31582_ instanceof AbstractMinecart -- && ((AbstractMinecart)p_31582_).getMinecartType() == AbstractMinecart.Type.RIDEABLE; -+ && ((AbstractMinecart)p_31582_).canBeRidden(); - private final NonNullList handItems = NonNullList.withSize(2, ItemStack.EMPTY); - private final NonNullList armorItems = NonNullList.withSize(4, ItemStack.EMPTY); - private boolean invisible; diff --git a/patches/net/minecraft/world/entity/decoration/HangingEntity.java.patch b/patches/net/minecraft/world/entity/decoration/HangingEntity.java.patch index 91ec6e8b64..830741b8a3 100644 --- a/patches/net/minecraft/world/entity/decoration/HangingEntity.java.patch +++ b/patches/net/minecraft/world/entity/decoration/HangingEntity.java.patch @@ -1,13 +1,11 @@ --- a/net/minecraft/world/entity/decoration/HangingEntity.java +++ b/net/minecraft/world/entity/decoration/HangingEntity.java -@@ -57,8 +_,8 @@ +@@ -58,7 +_,7 @@ if (!this.level().noCollision(this)) { return false; } else { -- boolean flag = BlockPos.betweenClosedStream(this.calculateSupportBox()).allMatch(p_352810_ -> { -- BlockState blockstate = this.level().getBlockState(p_352810_); -+ boolean flag = BlockPos.betweenClosedStream(this.calculateSupportBox()).filter(pos -> !net.minecraft.world.level.block.Block.canSupportCenter(this.level(), pos, this.direction)).allMatch(p_350100_ -> { -+ BlockState blockstate = this.level().getBlockState(p_350100_); +- boolean flag = BlockPos.betweenClosedStream(this.calculateSupportBox()).allMatch(p_381503_ -> { ++ boolean flag = BlockPos.betweenClosedStream(this.calculateSupportBox()).filter(pos -> !net.minecraft.world.level.block.Block.canSupportCenter(this.level(), pos, this.direction)).allMatch(p_381503_ -> { + BlockState blockstate = this.level().getBlockState(p_381503_); return blockstate.isSolid() || DiodeBlock.isDiode(blockstate); }); - return !flag ? false : this.level().getEntities(this, this.getBoundingBox(), HANGING_ENTITY).isEmpty(); diff --git a/patches/net/minecraft/world/entity/decoration/ItemFrame.java.patch b/patches/net/minecraft/world/entity/decoration/ItemFrame.java.patch index 6500489e01..788a8be1de 100644 --- a/patches/net/minecraft/world/entity/decoration/ItemFrame.java.patch +++ b/patches/net/minecraft/world/entity/decoration/ItemFrame.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/net/minecraft/world/entity/decoration/ItemFrame.java -@@ -212,7 +_,7 @@ +@@ -225,7 +_,7 @@ private void removeFramedMap(ItemStack p_31811_) { MapId mapid = this.getFramedMapId(p_31811_); if (mapid != null) { @@ -8,4 +8,4 @@ + MapItemSavedData mapitemsaveddata = MapItem.getSavedData(p_31811_, this.level()); if (mapitemsaveddata != null) { mapitemsaveddata.removedFromFrame(this.pos, this.getId()); - mapitemsaveddata.setDirty(true); + } diff --git a/patches/net/minecraft/world/entity/item/FallingBlockEntity.java.patch b/patches/net/minecraft/world/entity/item/FallingBlockEntity.java.patch index c8eae9d0bb..a8174886eb 100644 --- a/patches/net/minecraft/world/entity/item/FallingBlockEntity.java.patch +++ b/patches/net/minecraft/world/entity/item/FallingBlockEntity.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/net/minecraft/world/entity/item/FallingBlockEntity.java -@@ -138,7 +_,7 @@ - if (!this.level().isClientSide && (this.isAlive() || this.forceTickAfterTeleportToDuplicate)) { +@@ -148,7 +_,7 @@ + if (this.level() instanceof ServerLevel serverlevel && (this.isAlive() || this.forceTickAfterTeleportToDuplicate)) { BlockPos blockpos = this.blockPosition(); boolean flag = this.blockState.getBlock() instanceof ConcretePowderBlock; - boolean flag1 = flag && this.level().getFluidState(blockpos).is(FluidTags.WATER); @@ -9,7 +9,7 @@ double d0 = this.getDeltaMovement().lengthSqr(); if (flag && d0 > 1.0) { BlockHitResult blockhitresult = this.level() -@@ -147,7 +_,7 @@ +@@ -157,7 +_,7 @@ new Vec3(this.xo, this.yo, this.zo), this.position(), ClipContext.Block.COLLIDER, ClipContext.Fluid.SOURCE_ONLY, this ) ); diff --git a/patches/net/minecraft/world/entity/item/ItemEntity.java.patch b/patches/net/minecraft/world/entity/item/ItemEntity.java.patch index 71d2564a7f..0b105e1548 100644 --- a/patches/net/minecraft/world/entity/item/ItemEntity.java.patch +++ b/patches/net/minecraft/world/entity/item/ItemEntity.java.patch @@ -45,8 +45,8 @@ if (this.isInWater() && this.getFluidHeight(FluidTags.WATER) > 0.1F) { this.setUnderwaterMovement(); } else if (this.isInLava() && this.getFluidHeight(FluidTags.LAVA) > 0.1F) { -@@ -153,7 +_,8 @@ - this.move(MoverType.SELF, this.getDeltaMovement()); +@@ -154,7 +_,8 @@ + this.applyEffectsFromBlocks(); float f = 0.98F; if (this.onGround()) { - f = this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getFriction() * 0.98F; @@ -55,7 +55,7 @@ } this.setDeltaMovement(this.getDeltaMovement().multiply((double)f, 0.98, (double)f)); -@@ -185,7 +_,15 @@ +@@ -186,7 +_,15 @@ } } @@ -72,16 +72,16 @@ this.discard(); } } -@@ -282,7 +_,7 @@ - this.health = (int)((float)this.health - p_32014_); - this.gameEvent(GameEvent.ENTITY_DAMAGE, p_32013_.getEntity()); +@@ -294,7 +_,7 @@ + this.health = (int)((float)this.health - p_376562_); + this.gameEvent(GameEvent.ENTITY_DAMAGE, p_376452_.getEntity()); if (this.health <= 0) { - this.getItem().onDestroyed(this); -+ this.getItem().onDestroyed(this, p_32013_); ++ this.getItem().onDestroyed(this, p_376452_); this.discard(); } -@@ -295,6 +_,7 @@ +@@ -312,6 +_,7 @@ p_32050_.putShort("Health", (short)this.health); p_32050_.putShort("Age", (short)this.age); p_32050_.putShort("PickupDelay", (short)this.pickupDelay); @@ -89,7 +89,7 @@ if (this.thrower != null) { p_32050_.putUUID("Thrower", this.thrower); } -@@ -315,6 +_,9 @@ +@@ -332,6 +_,9 @@ if (p_32034_.contains("PickupDelay")) { this.pickupDelay = p_32034_.getShort("PickupDelay"); } @@ -99,7 +99,7 @@ if (p_32034_.hasUUID("Owner")) { this.target = p_32034_.getUUID("Owner"); -@@ -343,7 +_,22 @@ +@@ -360,7 +_,22 @@ ItemStack itemstack = this.getItem(); Item item = itemstack.getItem(); int i = itemstack.getCount(); @@ -123,7 +123,7 @@ p_32040_.take(this, i); if (itemstack.isEmpty()) { this.discard(); -@@ -398,6 +_,15 @@ +@@ -415,6 +_,15 @@ this.target = p_266724_; } @@ -139,7 +139,7 @@ public void setThrower(Entity p_306324_) { this.thrower = p_306324_.getUUID(); this.cachedThrower = p_306324_; -@@ -437,7 +_,7 @@ +@@ -454,7 +_,7 @@ public void makeFakeItem() { this.setNeverPickUp(); @@ -147,4 +147,4 @@ + this.age = getItem().getEntityLifespan(this.level()) - 1; } - public float getSpin(float p_32009_) { + public static float getSpin(float p_32009_, float p_361295_) { diff --git a/patches/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch b/patches/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch index 688628b355..02972fce45 100644 --- a/patches/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch +++ b/patches/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/AbstractSkeleton.java +++ b/net/minecraft/world/entity/monster/AbstractSkeleton.java -@@ -157,7 +_,7 @@ +@@ -161,7 +_,7 @@ if (this.level() != null && !this.level().isClientSide) { this.goalSelector.removeGoal(this.meleeGoal); this.goalSelector.removeGoal(this.bowGoal); @@ -9,7 +9,7 @@ if (itemstack.is(Items.BOW)) { int i = this.getHardAttackInterval(); if (this.level().getDifficulty() != Difficulty.HARD) { -@@ -182,9 +_,11 @@ +@@ -186,9 +_,11 @@ @Override public void performRangedAttack(LivingEntity p_32141_, float p_32142_) { diff --git a/patches/net/minecraft/world/entity/monster/Bogged.java.patch b/patches/net/minecraft/world/entity/monster/Bogged.java.patch index c77e1925c1..11982e8674 100644 --- a/patches/net/minecraft/world/entity/monster/Bogged.java.patch +++ b/patches/net/minecraft/world/entity/monster/Bogged.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/entity/monster/Bogged.java +++ b/net/minecraft/world/entity/monster/Bogged.java -@@ -74,7 +_,7 @@ +@@ -70,7 +_,7 @@ @Override protected InteractionResult mobInteract(Player p_330736_, InteractionHand p_331786_) { ItemStack itemstack = p_330736_.getItemInHand(p_331786_); - if (itemstack.is(Items.SHEARS) && this.readyForShearing()) { + if (false && itemstack.is(Items.SHEARS) && this.readyForShearing()) { // Neo: Shear logic is handled by IShearable - this.shear(SoundSource.PLAYERS); - this.gameEvent(GameEvent.SHEAR, p_330736_); - if (!this.level().isClientSide) { + if (this.level() instanceof ServerLevel serverlevel) { + this.shear(serverlevel, SoundSource.PLAYERS, itemstack); + this.gameEvent(GameEvent.SHEAR, p_330736_); diff --git a/patches/net/minecraft/world/entity/monster/EnderMan.java.patch b/patches/net/minecraft/world/entity/monster/EnderMan.java.patch index a46e783702..7ef7212218 100644 --- a/patches/net/minecraft/world/entity/monster/EnderMan.java.patch +++ b/patches/net/minecraft/world/entity/monster/EnderMan.java.patch @@ -16,16 +16,17 @@ } @Override -@@ -214,7 +_,7 @@ +@@ -213,7 +_,8 @@ + } + + boolean isBeingStaredBy(Player p_380267_) { +- return this.isLookingAtMe(p_380267_, 0.025, true, false, LivingEntity.PLAYER_NOT_WEARING_DISGUISE_ITEM, new DoubleSupplier[]{this::getEyeY}); ++ return this.isLookingAtMe(p_380267_, 0.025, true, false, LivingEntity.PLAYER_NOT_WEARING_DISGUISE_ITEM_FOR_TARGET, new DoubleSupplier[]{this::getEyeY}) && ++ !net.neoforged.neoforge.common.CommonHooks.shouldSuppressEnderManAnger(this, p_380267_); + } - boolean isLookingAtMe(Player p_32535_) { - ItemStack itemstack = p_32535_.getInventory().armor.get(3); -- if (itemstack.is(Blocks.CARVED_PUMPKIN.asItem())) { -+ if (net.neoforged.neoforge.common.CommonHooks.shouldSuppressEnderManAnger(this, p_32535_, itemstack)) { - return false; - } else { - Vec3 vec3 = p_32535_.getViewVector(1.0F).normalize(); -@@ -301,8 +_,10 @@ + @Override +@@ -291,8 +_,10 @@ boolean flag = blockstate.blocksMotion(); boolean flag1 = blockstate.getFluidState().is(FluidTags.WATER); if (flag && !flag1) { @@ -37,16 +38,16 @@ if (flag2) { this.level().gameEvent(GameEvent.TELEPORT, vec3, GameEvent.Context.of(this)); if (!this.isSilent()) { -@@ -459,7 +_,7 @@ +@@ -449,7 +_,7 @@ if (this.enderman.getCarriedBlock() == null) { return false; } else { -- return !this.enderman.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) -+ return !net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.enderman.level(), this.enderman) +- return !getServerLevel(this.enderman).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ++ return !net.neoforged.neoforge.event.EventHooks.canEntityGrief(getServerLevel(this.enderman.level()), this.enderman) ? false : this.enderman.getRandom().nextInt(reducedTickDelay(2000)) == 0; } -@@ -479,7 +_,7 @@ +@@ -469,7 +_,7 @@ BlockState blockstate2 = this.enderman.getCarriedBlock(); if (blockstate2 != null) { blockstate2 = Block.updateFromNeighbourShapes(blockstate2, this.enderman.level(), blockpos); @@ -55,7 +56,7 @@ level.setBlock(blockpos, blockstate2, 3); level.gameEvent(GameEvent.BLOCK_PLACE, blockpos, GameEvent.Context.of(this.enderman, blockstate2)); this.enderman.setCarriedBlock(null); -@@ -491,6 +_,7 @@ +@@ -481,6 +_,7 @@ return p_32562_.isAir() && !p_32563_.isAir() && !p_32563_.is(Blocks.BEDROCK) @@ -63,12 +64,12 @@ && p_32563_.isCollisionShapeFullBlock(p_32559_, p_32564_) && p_32561_.canSurvive(p_32559_, p_32560_) && p_32559_.getEntities(this.enderman, AABB.unitCubeFromLowerCorner(Vec3.atLowerCornerOf(p_32560_))).isEmpty(); -@@ -602,7 +_,7 @@ +@@ -592,7 +_,7 @@ if (this.enderman.getCarriedBlock() != null) { return false; } else { -- return !this.enderman.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) -+ return !net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.enderman.level(), this.enderman) +- return !getServerLevel(this.enderman).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ++ return !net.neoforged.neoforge.event.EventHooks.canEntityGrief(getServerLevel(this.enderman.level()), this.enderman) ? false : this.enderman.getRandom().nextInt(reducedTickDelay(20)) == 0; } diff --git a/patches/net/minecraft/world/entity/monster/Evoker.java.patch b/patches/net/minecraft/world/entity/monster/Evoker.java.patch index a0a972ccac..06281a6dab 100644 --- a/patches/net/minecraft/world/entity/monster/Evoker.java.patch +++ b/patches/net/minecraft/world/entity/monster/Evoker.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/entity/monster/Evoker.java +++ b/net/minecraft/world/entity/monster/Evoker.java -@@ -305,7 +_,7 @@ - return false; - } else if (Evoker.this.tickCount < this.nextAttackTickCount) { - return false; -- } else if (!Evoker.this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ } else if (!net.neoforged.neoforge.event.EventHooks.canEntityGrief(Evoker.this.level(), Evoker.this)) { +@@ -306,7 +_,7 @@ return false; } else { - List list = Evoker.this.level() + ServerLevel serverlevel = getServerLevel(Evoker.this.level()); +- if (!serverlevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (!net.neoforged.neoforge.event.EventHooks.canEntityGrief(serverlevel, Evoker.this)) { + return false; + } else { + List list = serverlevel.getNearbyEntities( diff --git a/patches/net/minecraft/world/entity/monster/Husk.java.patch b/patches/net/minecraft/world/entity/monster/Husk.java.patch index f36b13b010..44bb6a9ace 100644 --- a/patches/net/minecraft/world/entity/monster/Husk.java.patch +++ b/patches/net/minecraft/world/entity/monster/Husk.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Husk.java +++ b/net/minecraft/world/entity/monster/Husk.java -@@ -70,6 +_,7 @@ +@@ -71,6 +_,7 @@ @Override protected void doUnderWaterConversion() { diff --git a/patches/net/minecraft/world/entity/monster/Monster.java.patch b/patches/net/minecraft/world/entity/monster/Monster.java.patch index 48606282bc..87f0f303cf 100644 --- a/patches/net/minecraft/world/entity/monster/Monster.java.patch +++ b/patches/net/minecraft/world/entity/monster/Monster.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Monster.java +++ b/net/minecraft/world/entity/monster/Monster.java -@@ -136,11 +_,11 @@ +@@ -137,11 +_,11 @@ @Override public ItemStack getProjectile(ItemStack p_33038_) { if (p_33038_.getItem() instanceof ProjectileWeaponItem) { diff --git a/patches/net/minecraft/world/entity/monster/Pillager.java.patch b/patches/net/minecraft/world/entity/monster/Pillager.java.patch index f08cd904f2..ea74e23dd8 100644 --- a/patches/net/minecraft/world/entity/monster/Pillager.java.patch +++ b/patches/net/minecraft/world/entity/monster/Pillager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Pillager.java +++ b/net/minecraft/world/entity/monster/Pillager.java -@@ -116,7 +_,7 @@ +@@ -119,7 +_,7 @@ public AbstractIllager.IllagerArmPose getArmPose() { if (this.isChargingCrossbow()) { return AbstractIllager.IllagerArmPose.CROSSBOW_CHARGE; diff --git a/patches/net/minecraft/world/entity/monster/Ravager.java.patch b/patches/net/minecraft/world/entity/monster/Ravager.java.patch index f22f60a281..aabe0a1c02 100644 --- a/patches/net/minecraft/world/entity/monster/Ravager.java.patch +++ b/patches/net/minecraft/world/entity/monster/Ravager.java.patch @@ -1,11 +1,20 @@ --- a/net/minecraft/world/entity/monster/Ravager.java +++ b/net/minecraft/world/entity/monster/Ravager.java -@@ -134,7 +_,7 @@ - this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(Mth.lerp(0.1, d1, d0)); - } +@@ -144,7 +_,7 @@ -- if (this.horizontalCollision && this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (this.horizontalCollision && net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.level(), this)) { + if (this.level() instanceof ServerLevel serverlevel + && this.horizontalCollision +- && serverlevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ && net.neoforged.neoforge.event.EventHooks.canEntityGrief(serverlevel, this)) { boolean flag = false; AABB aabb = this.getBoundingBox().inflate(0.2); +@@ -227,7 +_,7 @@ + private void roar() { + if (this.isAlive()) { + if (this.level() instanceof ServerLevel serverlevel) { +- Predicate predicate = serverlevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) ++ Predicate predicate = net.neoforged.neoforge.event.EventHooks.canEntityGrief(serverlevel, this) + ? ROAR_TARGET_WITH_GRIEFING + : ROAR_TARGET_WITHOUT_GRIEFING; + diff --git a/patches/net/minecraft/world/entity/monster/Shulker.java.patch b/patches/net/minecraft/world/entity/monster/Shulker.java.patch index f7260e87d4..7cef3df234 100644 --- a/patches/net/minecraft/world/entity/monster/Shulker.java.patch +++ b/patches/net/minecraft/world/entity/monster/Shulker.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Shulker.java +++ b/net/minecraft/world/entity/monster/Shulker.java -@@ -392,6 +_,12 @@ +@@ -395,6 +_,12 @@ && this.level().noCollision(this, new AABB(blockpos1).deflate(1.0E-6))) { Direction direction = this.findAttachableSurface(blockpos1); if (direction != null) { diff --git a/patches/net/minecraft/world/entity/monster/Silverfish.java.patch b/patches/net/minecraft/world/entity/monster/Silverfish.java.patch index 41ef0fa648..01211fe0cd 100644 --- a/patches/net/minecraft/world/entity/monster/Silverfish.java.patch +++ b/patches/net/minecraft/world/entity/monster/Silverfish.java.patch @@ -1,20 +1,20 @@ --- a/net/minecraft/world/entity/monster/Silverfish.java +++ b/net/minecraft/world/entity/monster/Silverfish.java -@@ -140,7 +_,7 @@ +@@ -143,7 +_,7 @@ return false; } else { RandomSource randomsource = this.mob.getRandom(); -- if (this.mob.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && randomsource.nextInt(reducedTickDelay(10)) == 0) { -+ if (net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.mob.level(), this.mob) && randomsource.nextInt(reducedTickDelay(10)) == 0) { +- if (getServerLevel(this.mob).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && randomsource.nextInt(reducedTickDelay(10)) == 0) { ++ if (net.neoforged.neoforge.event.EventHooks.canEntityGrief(getServerLevel(this.mob.level()), this.mob) && randomsource.nextInt(reducedTickDelay(10)) == 0) { this.selectedDirection = Direction.getRandom(randomsource); BlockPos blockpos = BlockPos.containing(this.mob.getX(), this.mob.getY() + 0.5, this.mob.getZ()).relative(this.selectedDirection); BlockState blockstate = this.mob.level().getBlockState(blockpos); -@@ -211,7 +_,7 @@ +@@ -214,7 +_,7 @@ BlockState blockstate = level.getBlockState(blockpos1); Block block = blockstate.getBlock(); if (block instanceof InfestedBlock) { -- if (level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (net.neoforged.neoforge.event.EventHooks.canEntityGrief(level, this.silverfish)) { +- if (getServerLevel(level).getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (net.neoforged.neoforge.event.EventHooks.canEntityGrief(getServerLevel(level), this.silverfish)) { level.destroyBlock(blockpos1, true, this.silverfish); } else { level.setBlock(blockpos1, ((InfestedBlock)block).hostStateByInfested(level.getBlockState(blockpos1)), 3); diff --git a/patches/net/minecraft/world/entity/monster/Skeleton.java.patch b/patches/net/minecraft/world/entity/monster/Skeleton.java.patch index 499e41ec19..2b3815fc32 100644 --- a/patches/net/minecraft/world/entity/monster/Skeleton.java.patch +++ b/patches/net/minecraft/world/entity/monster/Skeleton.java.patch @@ -1,13 +1,12 @@ --- a/net/minecraft/world/entity/monster/Skeleton.java +++ b/net/minecraft/world/entity/monster/Skeleton.java -@@ -86,7 +_,9 @@ +@@ -89,7 +_,9 @@ } protected void doFreezeConversion() { -- this.convertTo(EntityType.STRAY, true); + if (!net.neoforged.neoforge.event.EventHooks.canLivingConvert(this, EntityType.STRAY, (timer) -> this.conversionTime = timer)) return; -+ Stray stray = this.convertTo(EntityType.STRAY, true); -+ if (stray != null) net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, stray); - if (!this.isSilent()) { - this.level().levelEvent(null, 1048, this.blockPosition(), 0); - } + this.convertTo(EntityType.STRAY, ConversionParams.single(this, true, true), p_381508_ -> { ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_381508_); + if (!this.isSilent()) { + this.level().levelEvent(null, 1048, this.blockPosition(), 0); + } diff --git a/patches/net/minecraft/world/entity/monster/Slime.java.patch b/patches/net/minecraft/world/entity/monster/Slime.java.patch index 27fde65da4..7f975fbff1 100644 --- a/patches/net/minecraft/world/entity/monster/Slime.java.patch +++ b/patches/net/minecraft/world/entity/monster/Slime.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Slime.java +++ b/net/minecraft/world/entity/monster/Slime.java -@@ -139,6 +_,8 @@ +@@ -146,6 +_,8 @@ float f = this.getDimensions(this.getPose()).width() * 2.0F; float f1 = f / 2.0F; @@ -9,31 +9,33 @@ for (int i = 0; (float)i < f * 16.0F; i++) { float f2 = this.random.nextFloat() * (float) (Math.PI * 2); float f3 = this.random.nextFloat() * 0.5F + 0.5F; -@@ -204,6 +_,8 @@ - int j = i / 2; +@@ -210,15 +_,24 @@ int k = 2 + this.random.nextInt(3); + PlayerTeam playerteam = this.getTeam(); + var children = new java.util.ArrayList(); // Neo: Children list for MobSplitEvent. + ++ this.preventConversionSpawns = true; for (int l = 0; l < k; l++) { float f2 = ((float)(l % 2) - 0.5F) * f1; float f3 = ((float)(l / 2) - 0.5F) * f1; -@@ -218,8 +_,13 @@ - slime.setInvulnerable(this.isInvulnerable()); - slime.setSize(j, true); - slime.moveTo(this.getX() + (double)f2, this.getY() + 0.5, this.getZ() + (double)f3, this.random.nextFloat() * 360.0F, 0.0F); -- this.level().addFreshEntity(slime); -+ -+ children.add(slime); // Neo: Record the slime until after event firing. - } +- this.convertTo( ++ Slime slime = this.convertTo( + this.getType(), new ConversionParams(ConversionType.SPLIT_ON_DEATH, false, false, playerteam), EntitySpawnReason.TRIGGERED, p_381514_ -> { + p_381514_.setSize(j, true); + p_381514_.moveTo(this.getX() + (double)f2, this.getY() + 0.5, this.getZ() + (double)f3, this.random.nextFloat() * 360.0F, 0.0F); + } + ); ++ children.add(slime); // Neo: Record the slime until after event firing. + } ++ this.preventConversionSpawns = false; + + if (!net.neoforged.neoforge.event.EventHooks.onMobSplit(this, children).isCanceled()) { + children.forEach(this.level()::addFreshEntity); } } -@@ -334,6 +_,7 @@ +@@ -327,6 +_,7 @@ Vec3 vec3 = this.getDeltaMovement(); this.setDeltaMovement(vec3.x, (double)this.getJumpPower(), vec3.z); this.hasImpulse = true; @@ -41,7 +43,7 @@ } @Nullable -@@ -363,6 +_,12 @@ +@@ -358,6 +_,12 @@ public EntityDimensions getDefaultDimensions(Pose p_316359_) { return super.getDefaultDimensions(p_316359_).scale((float)this.getSize()); } diff --git a/patches/net/minecraft/world/entity/monster/Zombie.java.patch b/patches/net/minecraft/world/entity/monster/Zombie.java.patch index 01af2edaa6..08f332ee7f 100644 --- a/patches/net/minecraft/world/entity/monster/Zombie.java.patch +++ b/patches/net/minecraft/world/entity/monster/Zombie.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Zombie.java +++ b/net/minecraft/world/entity/monster/Zombie.java -@@ -259,6 +_,7 @@ +@@ -257,6 +_,7 @@ } protected void doUnderWaterConversion() { @@ -8,15 +8,27 @@ this.convertToZombieType(EntityType.DROWNED); if (!this.isSilent()) { this.level().levelEvent(null, 1040, this.blockPosition(), 0); -@@ -270,6 +_,7 @@ - if (zombie != null) { - zombie.handleAttributes(zombie.level().getCurrentDifficultyAt(zombie.blockPosition()).getSpecialMultiplier()); - zombie.setCanBreakDoors(zombie.supportsBreakDoorGoal() && this.canBreakDoors()); -+ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, zombie); - } +@@ -267,7 +_,10 @@ + this.convertTo( + p_34311_, + ConversionParams.single(this, true, true), +- p_381517_ -> p_381517_.handleAttributes(p_381517_.level().getCurrentDifficultyAt(p_381517_.blockPosition()).getSpecialMultiplier()) ++ p_381517_ -> { ++ p_381517_.handleAttributes(p_381517_.level().getCurrentDifficultyAt(p_381517_.blockPosition()).getSpecialMultiplier()); ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_381517_); ++ } + ); } -@@ -406,7 +_,7 @@ +@@ -287,6 +_,7 @@ + p_370686_.setGossips(p_371444_.getGossips().store(NbtOps.INSTANCE)); + p_370686_.setTradeOffers(p_371444_.getOffers().copy()); + p_370686_.setVillagerXp(p_371444_.getVillagerXp()); ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(p_371444_, p_370686_); + if (!this.isSilent()) { + p_371466_.levelEvent(null, 1026, this.blockPosition(), 0); + } +@@ -437,7 +_,7 @@ @Override public boolean killedEntity(ServerLevel p_219160_, LivingEntity p_219161_) { boolean flag = super.killedEntity(p_219160_, p_219161_); @@ -25,11 +37,3 @@ if (p_219160_.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) { return flag; } -@@ -423,6 +_,7 @@ - zombievillager.setGossips(villager.getGossips().store(NbtOps.INSTANCE)); - zombievillager.setTradeOffers(villager.getOffers().copy()); - zombievillager.setVillagerXp(villager.getVillagerXp()); -+ net.neoforged.neoforge.event.EventHooks.onLivingConvert(p_219161_, zombievillager); - if (!this.isSilent()) { - p_219160_.levelEvent(null, 1026, this.blockPosition(), 0); - } diff --git a/patches/net/minecraft/world/entity/monster/ZombieVillager.java.patch b/patches/net/minecraft/world/entity/monster/ZombieVillager.java.patch index 08521a528a..bf52e0c706 100644 --- a/patches/net/minecraft/world/entity/monster/ZombieVillager.java.patch +++ b/patches/net/minecraft/world/entity/monster/ZombieVillager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/ZombieVillager.java +++ b/net/minecraft/world/entity/monster/ZombieVillager.java -@@ -141,7 +_,7 @@ +@@ -143,7 +_,7 @@ if (!this.level().isClientSide && this.isAlive() && this.isConverting()) { int i = this.getConversionProgress(); this.villagerConversionTime -= i; @@ -9,11 +9,12 @@ this.finishConversion((ServerLevel)this.level()); } } -@@ -246,6 +_,7 @@ - if (!this.isSilent()) { - p_34399_.levelEvent(null, 1027, this.blockPosition(), 0); +@@ -250,6 +_,8 @@ + if (!this.isSilent()) { + p_34399_.levelEvent(null, 1027, this.blockPosition(), 0); + } ++ ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_375894_); } -+ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, villager); - } + ); } - diff --git a/patches/net/minecraft/world/entity/monster/creaking/Creaking.java.patch b/patches/net/minecraft/world/entity/monster/creaking/Creaking.java.patch new file mode 100644 index 0000000000..8718946d79 --- /dev/null +++ b/patches/net/minecraft/world/entity/monster/creaking/Creaking.java.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/world/entity/monster/creaking/Creaking.java ++++ b/net/minecraft/world/entity/monster/creaking/Creaking.java +@@ -230,7 +_,8 @@ + + return true; + } else { +- Predicate predicate = this.isActive() ? LivingEntity.PLAYER_NOT_WEARING_DISGUISE_ITEM : p_380174_ -> true; ++ // Neo: provide entity being looked at to disguise check ++ java.util.function.BiPredicate predicate = this.isActive() ? LivingEntity.PLAYER_NOT_WEARING_DISGUISE_ITEM_FOR_TARGET : (p_380174_, target) -> true; + + for (Player player : list) { + if (!player.isCreative() diff --git a/patches/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch b/patches/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch index 14a4f5a41d..73ff0b6eaf 100644 --- a/patches/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch +++ b/patches/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch @@ -1,19 +1,27 @@ --- a/net/minecraft/world/entity/monster/hoglin/Hoglin.java +++ b/net/minecraft/world/entity/monster/hoglin/Hoglin.java -@@ -161,7 +_,7 @@ +@@ -166,7 +_,7 @@ HoglinAi.updateActivity(this); if (this.isConverting()) { this.timeInOverworld++; - if (this.timeInOverworld > 300) { + if (this.timeInOverworld > 300 && net.neoforged.neoforge.event.EventHooks.canLivingConvert(this, EntityType.ZOGLIN, (timer) -> this.timeInOverworld = timer)) { this.makeSound(SoundEvents.HOGLIN_CONVERTED_TO_ZOMBIFIED); - this.finishConversion((ServerLevel)this.level()); + this.finishConversion(); } -@@ -259,6 +_,7 @@ - Zoglin zoglin = this.convertTo(EntityType.ZOGLIN, true); - if (zoglin != null) { - zoglin.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0)); -+ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, zoglin); - } +@@ -264,9 +_,12 @@ + + private void finishConversion() { + this.convertTo( +- EntityType.ZOGLIN, +- ConversionParams.single(this, true, false), +- p_371903_ -> p_371903_.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0)) ++ EntityType.ZOGLIN, ++ ConversionParams.single(this, true, false), ++ p_371903_ -> { ++ p_371903_.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0)); ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_371903_); ++ } + ); } diff --git a/patches/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java.patch b/patches/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java.patch index 36ab4f9ccd..d33c44975b 100644 --- a/patches/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java.patch +++ b/patches/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java.patch @@ -1,19 +1,23 @@ --- a/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java +++ b/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java -@@ -82,7 +_,7 @@ +@@ -84,7 +_,7 @@ this.timeInOverworld = 0; } - if (this.timeInOverworld > 300) { + if (this.timeInOverworld > 300 && net.neoforged.neoforge.event.EventHooks.canLivingConvert(this, EntityType.ZOMBIFIED_PIGLIN, (timer) -> this.timeInOverworld = timer)) { this.playConvertedSound(); - this.finishConversion((ServerLevel)this.level()); - } -@@ -96,6 +_,7 @@ - ZombifiedPiglin zombifiedpiglin = this.convertTo(EntityType.ZOMBIFIED_PIGLIN, true); - if (zombifiedpiglin != null) { - zombifiedpiglin.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0)); -+ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, zombifiedpiglin); + this.finishConversion(p_376586_); } +@@ -103,7 +_,10 @@ + this.convertTo( + EntityType.ZOMBIFIED_PIGLIN, + ConversionParams.single(this, true, true), +- p_371722_ -> p_371722_.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0)) ++ p_371722_ -> { ++ p_371722_.addEffect(new MobEffectInstance(MobEffects.CONFUSION, 200, 0)); ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_371722_); ++ } + ); } diff --git a/patches/net/minecraft/world/entity/monster/piglin/Piglin.java.patch b/patches/net/minecraft/world/entity/monster/piglin/Piglin.java.patch index 8bb786c6e0..a0419dc894 100644 --- a/patches/net/minecraft/world/entity/monster/piglin/Piglin.java.patch +++ b/patches/net/minecraft/world/entity/monster/piglin/Piglin.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/entity/monster/piglin/Piglin.java +++ b/net/minecraft/world/entity/monster/piglin/Piglin.java -@@ -349,7 +_,7 @@ +@@ -355,7 +_,7 @@ } else if (this.isChargingCrossbow()) { return PiglinArmPose.CROSSBOW_CHARGE; } else { -- return this.isAggressive() && this.isHolding(Items.CROSSBOW) ? PiglinArmPose.CROSSBOW_HOLD : PiglinArmPose.DEFAULT; +- return this.isHolding(Items.CROSSBOW) && CrossbowItem.isCharged(this.getWeaponItem()) ? PiglinArmPose.CROSSBOW_HOLD : PiglinArmPose.DEFAULT; + return this.isAggressive() && this.isHolding(is -> is.getItem() instanceof net.minecraft.world.item.CrossbowItem) ? PiglinArmPose.CROSSBOW_HOLD : PiglinArmPose.DEFAULT; } } -@@ -390,7 +_,7 @@ +@@ -392,7 +_,7 @@ } protected void holdInOffHand(ItemStack p_34786_) { @@ -18,12 +18,12 @@ this.setItemSlot(EquipmentSlot.OFFHAND, p_34786_); this.setGuaranteedDrop(EquipmentSlot.OFFHAND); } else { -@@ -400,7 +_,7 @@ +@@ -402,7 +_,7 @@ @Override - public boolean wantsToPickUp(ItemStack p_34777_) { -- return this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && this.canPickUpLoot() && PiglinAi.wantsToPickup(this, p_34777_); -+ return net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.level(), this) && this.canPickUpLoot() && PiglinAi.wantsToPickup(this, p_34777_); + public boolean wantsToPickUp(ServerLevel p_376232_, ItemStack p_34777_) { +- return p_376232_.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && this.canPickUpLoot() && PiglinAi.wantsToPickup(this, p_34777_); ++ return net.neoforged.neoforge.event.EventHooks.canEntityGrief(p_376232_, this) && this.canPickUpLoot() && PiglinAi.wantsToPickup(this, p_34777_); } protected boolean canReplaceCurrentItem(ItemStack p_34788_) { diff --git a/patches/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch b/patches/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch index 3aa8dcc2a5..6aa8151c99 100644 --- a/patches/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch +++ b/patches/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/piglin/PiglinAi.java +++ b/net/minecraft/world/entity/monster/piglin/PiglinAi.java -@@ -377,7 +_,7 @@ +@@ -375,7 +_,7 @@ ItemStack itemstack = p_34868_.getItemInHand(InteractionHand.OFF_HAND); p_34868_.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY); if (p_34868_.isAdult()) { @@ -9,7 +9,7 @@ if (p_34869_ && flag) { throwItems(p_34868_, getBarterResponseItems(p_34868_)); } else if (!flag) { -@@ -461,7 +_,7 @@ +@@ -459,7 +_,7 @@ return false; } else if (isAdmiringDisabled(p_34858_) && p_34858_.getBrain().hasMemoryValue(MemoryModuleType.ATTACK_TARGET)) { return false; @@ -18,7 +18,7 @@ return isNotHoldingLovedItemInOffHand(p_34858_); } else { boolean flag = p_34858_.canAddToInventory(p_34859_); -@@ -551,7 +_,7 @@ +@@ -549,7 +_,7 @@ } protected static boolean canAdmire(Piglin p_34910_, ItemStack p_34911_) { @@ -26,17 +26,17 @@ + return !isAdmiringDisabled(p_34910_) && !isAdmiringItem(p_34910_) && p_34910_.isAdult() && p_34911_.isPiglinCurrency(); } - protected static void wasHurtBy(Piglin p_34838_, LivingEntity p_34839_) { -@@ -641,7 +_,7 @@ - public static boolean isWearingGold(LivingEntity p_34809_) { - for (ItemStack itemstack : p_34809_.getArmorAndBodyArmorSlots()) { - Item item = itemstack.getItem(); -- if (item instanceof ArmorItem && ((ArmorItem)item).getMaterial().is(ArmorMaterials.GOLD)) { -+ if (itemstack.makesPiglinsNeutral(p_34809_)) { + protected static void wasHurtBy(ServerLevel p_376829_, Piglin p_34838_, LivingEntity p_34839_) { +@@ -638,7 +_,7 @@ + + public static boolean isWearingSafeArmor(LivingEntity p_371788_) { + for (ItemStack itemstack : p_371788_.getArmorAndBodyArmorSlots()) { +- if (itemstack.is(ItemTags.PIGLIN_SAFE_ARMOR)) { ++ if (itemstack.makesPiglinsNeutral(p_371788_)) { return true; } } -@@ -792,7 +_,7 @@ +@@ -790,7 +_,7 @@ } private static boolean hasCrossbow(LivingEntity p_34919_) { diff --git a/patches/net/minecraft/world/entity/monster/piglin/StopHoldingItemIfNoLongerAdmiring.java.patch b/patches/net/minecraft/world/entity/monster/piglin/StopHoldingItemIfNoLongerAdmiring.java.patch index 29b127e428..62dfc9f67e 100644 --- a/patches/net/minecraft/world/entity/monster/piglin/StopHoldingItemIfNoLongerAdmiring.java.patch +++ b/patches/net/minecraft/world/entity/monster/piglin/StopHoldingItemIfNoLongerAdmiring.java.patch @@ -3,9 +3,9 @@ @@ -11,7 +_,7 @@ public static BehaviorControl create() { return BehaviorBuilder.create( - p_259197_ -> p_259197_.group(p_259197_.absent(MemoryModuleType.ADMIRING_ITEM)).apply(p_259197_, p_259512_ -> (p_352826_, p_352827_, p_352828_) -> { -- if (!p_352827_.getOffhandItem().isEmpty() && !p_352827_.getOffhandItem().is(Items.SHIELD)) { -+ if (!p_352827_.getOffhandItem().isEmpty() && !p_352827_.getOffhandItem().canPerformAction(net.neoforged.neoforge.common.ItemAbilities.SHIELD_BLOCK)) { - PiglinAi.stopHoldingOffHandItem(p_352827_, true); + p_259197_ -> p_259197_.group(p_259197_.absent(MemoryModuleType.ADMIRING_ITEM)).apply(p_259197_, p_259512_ -> (p_381534_, p_381535_, p_381536_) -> { +- if (!p_381535_.getOffhandItem().isEmpty() && !p_381535_.getOffhandItem().is(Items.SHIELD)) { ++ if (!p_381535_.getOffhandItem().isEmpty() && !p_381535_.getOffhandItem().canPerformAction(net.neoforged.neoforge.common.ItemAbilities.SHIELD_BLOCK)) { + PiglinAi.stopHoldingOffHandItem(p_381534_, p_381535_, true); return true; } else { diff --git a/patches/net/minecraft/world/entity/npc/AbstractVillager.java.patch b/patches/net/minecraft/world/entity/npc/AbstractVillager.java.patch index 043791fc34..961d41fffc 100644 --- a/patches/net/minecraft/world/entity/npc/AbstractVillager.java.patch +++ b/patches/net/minecraft/world/entity/npc/AbstractVillager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/net/minecraft/world/entity/npc/AbstractVillager.java -@@ -127,6 +_,7 @@ +@@ -129,6 +_,7 @@ if (this.tradingPlayer instanceof ServerPlayer) { CriteriaTriggers.TRADE.trigger((ServerPlayer)this.tradingPlayer, this, p_35274_.getResult()); } @@ -8,7 +8,7 @@ } protected abstract void rewardTradeXp(MerchantOffer p_35299_); -@@ -183,13 +_,6 @@ +@@ -185,13 +_,6 @@ } this.readInventoryFromTag(p_35290_, this.registryAccess()); @@ -16,9 +16,9 @@ - - @Nullable - @Override -- public Entity changeDimension(DimensionTransition p_350994_) { +- public Entity teleport(TeleportTransition p_379715_) { - this.stopTrading(); -- return super.changeDimension(p_350994_); +- return super.teleport(p_379715_); } protected void stopTrading() { diff --git a/patches/net/minecraft/world/entity/npc/CatSpawner.java.patch b/patches/net/minecraft/world/entity/npc/CatSpawner.java.patch index c0cbf518d6..f15338a740 100644 --- a/patches/net/minecraft/world/entity/npc/CatSpawner.java.patch +++ b/patches/net/minecraft/world/entity/npc/CatSpawner.java.patch @@ -5,7 +5,7 @@ return 0; } else { + cat.moveTo(p_35334_, 0.0F, 0.0F); // Fix MC-147659: Some witch huts spawn the incorrect cat - cat.finalizeSpawn(p_35335_, p_35335_.getCurrentDifficultyAt(p_35334_), MobSpawnType.NATURAL, null); + cat.finalizeSpawn(p_35335_, p_35335_.getCurrentDifficultyAt(p_35334_), EntitySpawnReason.NATURAL, null); - cat.moveTo(p_35334_, 0.0F, 0.0F); p_35335_.addFreshEntityWithPassengers(cat); return 1; diff --git a/patches/net/minecraft/world/entity/npc/Villager.java.patch b/patches/net/minecraft/world/entity/npc/Villager.java.patch index f206fb91fd..308d4a20d0 100644 --- a/patches/net/minecraft/world/entity/npc/Villager.java.patch +++ b/patches/net/minecraft/world/entity/npc/Villager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/npc/Villager.java +++ b/net/minecraft/world/entity/npc/Villager.java -@@ -322,7 +_,7 @@ +@@ -313,7 +_,7 @@ @Override public InteractionResult mobInteract(Player p_35472_, InteractionHand p_35473_) { ItemStack itemstack = p_35472_.getItemInHand(p_35473_); @@ -9,7 +9,7 @@ return super.mobInteract(p_35472_, p_35473_); } else if (this.isBaby()) { this.setUnhappy(); -@@ -742,8 +_,9 @@ +@@ -719,8 +_,9 @@ @Override protected Component getTypeName() { @@ -20,32 +20,28 @@ ); } -@@ -799,7 +_,7 @@ +@@ -781,10 +_,11 @@ @Override public void thunderHit(ServerLevel p_35409_, LightningBolt p_35410_) { - if (p_35409_.getDifficulty() != Difficulty.PEACEFUL) { + if (p_35409_.getDifficulty() != Difficulty.PEACEFUL && net.neoforged.neoforge.event.EventHooks.canLivingConvert(this, EntityType.WITCH, (timer) -> {})) { LOGGER.info("Villager {} was struck by lightning {}.", this, p_35410_); - Witch witch = EntityType.WITCH.create(p_35409_); - if (witch != null) { -@@ -812,6 +_,7 @@ - } - - witch.setPersistenceRequired(); -+ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, witch); - p_35409_.addFreshEntityWithPassengers(witch); + Witch witch = this.convertTo(EntityType.WITCH, ConversionParams.single(this, false, false), p_381540_ -> { + p_381540_.finalizeSpawn(p_35409_, p_35409_.getCurrentDifficultyAt(p_381540_.blockPosition()), EntitySpawnReason.CONVERSION, null); ++ net.neoforged.neoforge.event.EventHooks.onLivingConvert(this, p_381540_); + p_381540_.setPersistenceRequired(); this.releaseAllPois(); - this.discard(); -@@ -831,7 +_,10 @@ + }); +@@ -804,7 +_,10 @@ @Override - public boolean wantsToPickUp(ItemStack p_35543_) { + public boolean wantsToPickUp(ServerLevel p_376823_, ItemStack p_35543_) { Item item = p_35543_.getItem(); -- return (WANTED_ITEMS.contains(item) || this.getVillagerData().getProfession().requestedItems().contains(item)) -+ // Neo: Patched so that Farmer Villagers will pick up SpecialPlantable items. Also fixes MC-274244 by making "minecraft:villager_plantable_seeds" tagged items also be picked up by Farmer Villagers to be planted later. -+ boolean isFarmerDesiredSeed = (p_35543_.is(ItemTags.VILLAGER_PLANTABLE_SEEDS) || (p_35543_.getItem() instanceof net.neoforged.neoforge.common.SpecialPlantable specialPlantable && specialPlantable.villagerCanPlantItem(this))) +- return (p_35543_.is(ItemTags.VILLAGER_PICKS_UP) || this.getVillagerData().getProfession().requestedItems().contains(item)) ++ // Neo: Allow Farmer Villagers to pick up SpecialPlantable items. ++ boolean isFarmerDesiredSeed = (p_35543_.getItem() instanceof net.neoforged.neoforge.common.SpecialPlantable specialPlantable && specialPlantable.villagerCanPlantItem(this)) + && this.getVillagerData().getProfession().secondaryPoi().stream().anyMatch(secondaryPoi -> secondaryPoi.defaultBlockState().is(net.neoforged.neoforge.common.Tags.Blocks.VILLAGER_FARMLANDS)); -+ return (WANTED_ITEMS.contains(item) || this.getVillagerData().getProfession().requestedItems().contains(item) || isFarmerDesiredSeed) ++ return (p_35543_.is(ItemTags.VILLAGER_PICKS_UP) || this.getVillagerData().getProfession().requestedItems().contains(item) || isFarmerDesiredSeed) && this.getInventory().canAddItem(p_35543_); } diff --git a/patches/net/minecraft/world/entity/player/Inventory.java.patch b/patches/net/minecraft/world/entity/player/Inventory.java.patch index 661a168207..17c929ae65 100644 --- a/patches/net/minecraft/world/entity/player/Inventory.java.patch +++ b/patches/net/minecraft/world/entity/player/Inventory.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/player/Inventory.java +++ b/net/minecraft/world/entity/player/Inventory.java -@@ -133,7 +_,7 @@ +@@ -132,7 +_,7 @@ for (int k = 0; k < 9; k++) { int l = (this.selected + k) % 9; @@ -9,7 +9,7 @@ return l; } } -@@ -214,11 +_,15 @@ +@@ -204,11 +_,15 @@ } public void tick() { @@ -26,7 +26,7 @@ } } } -@@ -268,6 +_,8 @@ +@@ -258,6 +_,8 @@ } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Adding item to inventory"); CrashReportCategory crashreportcategory = crashreport.addCategory("Item being added"); diff --git a/patches/net/minecraft/world/entity/player/Player.java.patch b/patches/net/minecraft/world/entity/player/Player.java.patch index b56eec23b3..a4bdc8c832 100644 --- a/patches/net/minecraft/world/entity/player/Player.java.patch +++ b/patches/net/minecraft/world/entity/player/Player.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/player/Player.java +++ b/net/minecraft/world/entity/player/Player.java -@@ -113,7 +_,8 @@ +@@ -117,7 +_,8 @@ import net.minecraft.world.scores.Team; import org.slf4j.Logger; @@ -10,7 +10,7 @@ private static final Logger LOGGER = LogUtils.getLogger(); public static final HumanoidArm DEFAULT_MAIN_HAND = HumanoidArm.RIGHT; public static final int DEFAULT_MODEL_CUSTOMIZATION = 0; -@@ -193,6 +_,10 @@ +@@ -197,6 +_,10 @@ public Entity currentExplosionCause; private boolean ignoreFallDamageFromCurrentImpulse; private int currentImpulseContextResetGraceTime; @@ -21,7 +21,7 @@ public Player(Level p_250508_, BlockPos p_250289_, float p_251702_, GameProfile p_252153_) { super(EntityType.PLAYER, p_250508_); -@@ -229,7 +_,8 @@ +@@ -233,7 +_,8 @@ .add(Attributes.SUBMERGED_MINING_SPEED) .add(Attributes.SNEAKING_SPEED) .add(Attributes.MINING_EFFICIENCY) @@ -31,7 +31,7 @@ } @Override -@@ -245,6 +_,7 @@ +@@ -249,6 +_,7 @@ @Override public void tick() { @@ -39,7 +39,7 @@ this.noPhysics = this.isSpectator(); if (this.isSpectator()) { this.setOnGround(false); -@@ -260,7 +_,7 @@ +@@ -264,7 +_,7 @@ this.sleepCounter = 100; } @@ -48,20 +48,20 @@ this.stopSleepInBed(false, true); } } else if (this.sleepCounter > 0) { -@@ -291,7 +_,11 @@ +@@ -295,7 +_,11 @@ } if (!this.isSleeping()) { - this.awardStat(Stats.TIME_SINCE_REST); + // Neo: Advance TIME_SINCE_REST if (a) vanilla daytime handling in effect, or (b) days are shorter, or (c) dayTime has ticked, or (d) dayTime advances are off and we need to ignore day length -+ if (level().getDayTimeFraction() < 0 || level().getDayTimeFraction() >= 1 || lastDayTimeTick != level().getDayTime() || !level().getGameRules().getRule(GameRules.RULE_DAYLIGHT).get()) { ++ if (level().getDayTimeFraction() < 0 || level().getDayTimeFraction() >= 1 || lastDayTimeTick != level().getDayTime() || !serverplayer.serverLevel().getGameRules().getRule(GameRules.RULE_DAYLIGHT).get()) { + lastDayTimeTick = level().getDayTime(); + this.awardStat(Stats.TIME_SINCE_REST); + } } } -@@ -318,6 +_,7 @@ +@@ -325,6 +_,7 @@ if (this.currentImpulseContextResetGraceTime > 0) { this.currentImpulseContextResetGraceTime--; } @@ -69,7 +69,7 @@ } @Override -@@ -397,6 +_,10 @@ +@@ -427,6 +_,10 @@ } protected void updatePlayerPose() { @@ -80,7 +80,7 @@ if (this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.SWIMMING)) { Pose pose; if (this.isFallFlying()) { -@@ -630,6 +_,7 @@ +@@ -654,6 +_,7 @@ @Override public void die(DamageSource p_36152_) { @@ -88,7 +88,7 @@ super.die(p_36152_); this.reapplyPosition(); if (!this.isSpectator() && this.level() instanceof ServerLevel serverlevel) { -@@ -684,7 +_,7 @@ +@@ -711,7 +_,7 @@ @Nullable public ItemEntity drop(ItemStack p_36177_, boolean p_36178_) { @@ -97,20 +97,23 @@ } @Nullable -@@ -726,7 +_,12 @@ - } +@@ -723,7 +_,15 @@ + return null; } -+ @Deprecated //Use location sensitive version below ++ /** ++ * @deprecated Neo: {@link #getDestroySpeed(BlockState, BlockPos)} instead ++ */ ++ @Deprecated public float getDestroySpeed(BlockState p_36282_) { -+ return getDigSpeed(p_36282_, null); ++ return getDestroySpeed(p_36282_, null); + } + -+ public float getDigSpeed(BlockState p_36282_, @Nullable BlockPos pos) { ++ public float getDestroySpeed(BlockState p_36282_, @Nullable BlockPos pos) { float f = this.inventory.getDestroySpeed(p_36282_); if (f > 1.0F) { f += (float)this.getAttributeValue(Attributes.MINING_EFFICIENCY); -@@ -754,13 +_,19 @@ +@@ -752,13 +_,19 @@ f /= 5.0F; } @@ -130,18 +133,17 @@ @Override public void readAdditionalSaveData(CompoundTag p_36215_) { super.readAdditionalSaveData(p_36215_); -@@ -872,7 +_,9 @@ - this.removeEntitiesOnShoulder(); - } - -- if (p_36154_.scalesWithDifficulty()) { -+ p_36155_ = Math.max(0.0F, p_36154_.type().scaling().getScalingFunction().scaleDamage(p_36154_, this, p_36155_, this.level().getDifficulty())); -+ -+ if (false && p_36154_.scalesWithDifficulty()) { - if (this.level().getDifficulty() == Difficulty.PEACEFUL) { - p_36155_ = 0.0F; +@@ -867,7 +_,8 @@ + return false; + } else { + this.removeEntitiesOnShoulder(); +- if (p_376171_.scalesWithDifficulty()) { ++ p_376389_ = Math.max(0.0F, p_376171_.type().scaling().getScalingFunction().scaleDamage(p_376171_, this, p_376389_, this.level().getDifficulty())); ++ if (false && p_376171_.scalesWithDifficulty()) { + if (p_376451_.getDifficulty() == Difficulty.PEACEFUL) { + p_376389_ = 0.0F; } -@@ -926,7 +_,7 @@ +@@ -922,7 +_,7 @@ @Override protected void hurtCurrentlyUsedShield(float p_36383_) { @@ -150,7 +152,7 @@ if (!this.level().isClientSide) { this.awardStat(Stats.ITEM_USED.get(this.useItem.getItem())); } -@@ -934,7 +_,13 @@ +@@ -930,7 +_,13 @@ if (p_36383_ >= 3.0F) { int i = 1 + Mth.floor(p_36383_); InteractionHand interactionhand = this.getUsedItemHand(); @@ -165,10 +167,10 @@ if (this.useItem.isEmpty()) { if (interactionhand == InteractionHand.MAIN_HAND) { this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY); -@@ -952,11 +_,14 @@ +@@ -948,11 +_,14 @@ @Override - protected void actuallyHurt(DamageSource p_36312_, float p_36313_) { - if (!this.isInvulnerableTo(p_36312_)) { + protected void actuallyHurt(ServerLevel p_376500_, DamageSource p_36312_, float p_36313_) { + if (!this.isInvulnerableTo(p_376500_, p_36312_)) { - p_36313_ = this.getDamageAfterArmorAbsorb(p_36312_, p_36313_); - p_36313_ = this.getDamageAfterMagicAbsorb(p_36312_, p_36313_); - float f1 = Math.max(p_36313_ - this.getAbsorptionAmount(), 0.0F); @@ -185,7 +187,7 @@ if (f > 0.0F && f < 3.4028235E37F) { this.awardStat(Stats.DAMAGE_ABSORBED, Math.round(f * 10.0F)); } -@@ -970,7 +_,9 @@ +@@ -966,7 +_,9 @@ } this.gameEvent(GameEvent.ENTITY_DAMAGE); @@ -195,7 +197,7 @@ } } -@@ -1014,6 +_,8 @@ +@@ -1010,6 +_,8 @@ return InteractionResult.PASS; } else { @@ -204,7 +206,7 @@ ItemStack itemstack = this.getItemInHand(p_36159_); ItemStack itemstack1 = itemstack.copy(); InteractionResult interactionresult = p_36158_.interact(this, p_36159_); -@@ -1022,6 +_,9 @@ +@@ -1018,6 +_,9 @@ itemstack.setCount(itemstack1.getCount()); } @@ -214,7 +216,7 @@ return interactionresult; } else { if (!itemstack.isEmpty() && p_36158_ instanceof LivingEntity) { -@@ -1033,6 +_,7 @@ +@@ -1029,6 +_,7 @@ if (interactionresult1.consumesAction()) { this.level().gameEvent(GameEvent.ENTITY_INTERACT, p_36158_.position(), GameEvent.Context.of(this)); if (itemstack.isEmpty() && !this.abilities.instabuild) { @@ -222,7 +224,7 @@ this.setItemInHand(p_36159_, ItemStack.EMPTY); } -@@ -1062,6 +_,7 @@ +@@ -1058,6 +_,7 @@ } @Override @@ -230,7 +232,7 @@ protected Vec3 maybeBackOffFromEdge(Vec3 p_36201_, MoverType p_36202_) { float f = this.maxUpStep(); if (!this.abilities.flying -@@ -1111,6 +_,7 @@ +@@ -1107,6 +_,7 @@ } } @@ -238,7 +240,7 @@ private boolean isAboveGround(float p_341626_) { return this.onGround() || this.fallDistance < p_341626_ && !this.canFallAtLeast(0.0, 0.0, p_341626_ - this.fallDistance); } -@@ -1132,6 +_,7 @@ +@@ -1128,6 +_,7 @@ } public void attack(Entity p_36347_) { @@ -246,7 +248,7 @@ if (p_36347_.isAttackable()) { if (!p_36347_.skipAttackInteraction(this)) { float f = this.isAutoSpinAttack() ? this.autoSpinAttackDmg : (float)this.getAttributeValue(Attributes.ATTACK_DAMAGE); -@@ -1141,7 +_,6 @@ +@@ -1137,7 +_,6 @@ float f2 = this.getAttackStrengthScale(0.5F); f *= 0.2F + f2 * f2 * 0.8F; f1 *= f2; @@ -254,7 +256,7 @@ if (p_36347_.getType().is(EntityTypeTags.REDIRECTABLE_PROJECTILE) && p_36347_ instanceof Projectile projectile && projectile.deflect(ProjectileDeflection.AIM_DEFLECT, this, this, true)) { -@@ -1170,19 +_,28 @@ +@@ -1166,20 +_,31 @@ && !this.isPassenger() && p_36347_ instanceof LivingEntity && !this.isSprinting(); @@ -269,26 +271,27 @@ float f3 = f + f1; boolean flag2 = false; - double d0 = (double)(this.walkDist - this.walkDistO); -- if (flag4 && !flag1 && !flag && this.onGround() && d0 < (double)this.getSpeed()) { +- if (flag3 && !flag1 && !flag && this.onGround()) { + // Neo: Replace !flag1 (!isCriticalHit) with the logic from the CriticalHitEvent. + boolean critBlocksSweep = critEvent.isCriticalHit() && critEvent.disableSweep(); -+ if (flag4 && !critBlocksSweep && !flag && this.onGround() && d0 < (double)this.getSpeed()) { ++ if (flag3 && !critBlocksSweep && !flag && this.onGround()) { + double d0 = this.getKnownMovement().horizontalDistanceSqr(); + double d1 = (double)this.getSpeed() * 2.5; +- if (d0 < Mth.square(d1) && this.getItemInHand(InteractionHand.MAIN_HAND).is(ItemTags.SWORDS)) { + // Neo: Make sweep attacks check SWORD_SWEEP instead of instanceof SwordItem. - ItemStack itemstack1 = this.getItemInHand(InteractionHand.MAIN_HAND); -- if (itemstack1.getItem() instanceof SwordItem) { -- flag2 = true; -- } -+ flag2 = itemstack1.canPerformAction(net.neoforged.neoforge.common.ItemAbilities.SWORD_SWEEP); ++ if (d0 < Mth.square(d1) && this.getItemInHand(InteractionHand.MAIN_HAND).canPerformAction(net.neoforged.neoforge.common.ItemAbilities.SWORD_SWEEP)) { + flag2 = true; + } } -+ + + // Neo: Fire the SweepAttackEvent and overwrite the value of flag2 (the local controlling if a sweep will occur). + var sweepEvent = net.neoforged.neoforge.common.CommonHooks.fireSweepAttack(this, p_36347_, flag2); + flag2 = sweepEvent.isSweeping(); - ++ float f6 = 0.0F; if (p_36347_ instanceof LivingEntity livingentity) { -@@ -1217,11 +_,12 @@ + f6 = livingentity.getHealth(); +@@ -1213,11 +_,12 @@ for (LivingEntity livingentity2 : this.level() .getEntitiesOfClass(LivingEntity.class, p_36347_.getBoundingBox().inflate(1.0, 0.25, 1.0))) { @@ -302,7 +305,7 @@ float f5 = this.getEnchantedDamage(livingentity2, f7, damagesource) * f2; livingentity2.knockback( 0.4F, -@@ -1268,11 +_,12 @@ +@@ -1264,11 +_,12 @@ this.setLastHurtMob(p_36347_); Entity entity = p_36347_; @@ -317,7 +320,7 @@ if (this.level() instanceof ServerLevel serverlevel1) { if (entity instanceof LivingEntity livingentity3) { flag5 = itemstack.hurtEnemy(livingentity3, this); -@@ -1287,6 +_,7 @@ +@@ -1283,6 +_,7 @@ } if (itemstack.isEmpty()) { @@ -325,7 +328,7 @@ if (itemstack == this.getMainHandItem()) { this.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY); } else { -@@ -1311,6 +_,7 @@ +@@ -1307,6 +_,7 @@ .playSound(null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_NODAMAGE, this.getSoundSource(), 1.0F, 1.0F); } } @@ -333,15 +336,6 @@ } } } -@@ -1325,7 +_,7 @@ - } - - public void disableShield() { -- this.getCooldowns().addCooldown(Items.SHIELD, 100); -+ this.getCooldowns().addCooldown(this.getUseItem().getItem(), 100); - this.stopUsingItem(); - this.level().broadcastEntityEvent(this, (byte)30); - } @@ -1391,6 +_,7 @@ } @@ -350,7 +344,7 @@ super.stopSleeping(); if (this.level() instanceof ServerLevel && p_36227_) { ((ServerLevel)this.level()).updateSleepingPlayerList(); -@@ -1503,7 +_,8 @@ +@@ -1496,7 +_,8 @@ @Override public boolean causeFallDamage(float p_150093_, float p_150094_, DamageSource p_150095_) { @@ -360,16 +354,7 @@ return false; } else { if (p_150093_ >= 2.0F) { -@@ -1535,7 +_,7 @@ - public boolean tryToStartFallFlying() { - if (!this.onGround() && !this.isFallFlying() && !this.isInWater() && !this.hasEffect(MobEffects.LEVITATION)) { - ItemStack itemstack = this.getItemBySlot(EquipmentSlot.CHEST); -- if (itemstack.is(Items.ELYTRA) && ElytraItem.isFlyEnabled(itemstack)) { -+ if (itemstack.canElytraFly(this)) { - this.startFallFlying(); - return true; - } -@@ -1564,13 +_,13 @@ +@@ -1555,13 +_,13 @@ protected void playStepSound(BlockPos p_282121_, BlockState p_282194_) { if (this.isInWater()) { this.waterSwimSound(); @@ -385,7 +370,7 @@ } else { super.playStepSound(blockpos, blockstate); } -@@ -1601,6 +_,10 @@ +@@ -1592,6 +_,10 @@ } public void giveExperiencePoints(int p_36291_) { @@ -396,7 +381,7 @@ this.increaseScore(p_36291_); this.experienceProgress = this.experienceProgress + (float)p_36291_ / (float)this.getXpNeededForNextLevel(); this.totalExperience = Mth.clamp(this.totalExperience + p_36291_, 0, Integer.MAX_VALUE); -@@ -1628,7 +_,7 @@ +@@ -1619,7 +_,7 @@ } public void onEnchantmentPerformed(ItemStack p_36172_, int p_36173_) { @@ -405,7 +390,7 @@ if (this.experienceLevel < 0) { this.experienceLevel = 0; this.experienceProgress = 0.0F; -@@ -1639,6 +_,10 @@ +@@ -1630,6 +_,10 @@ } public void giveExperienceLevels(int p_36276_) { @@ -413,10 +398,10 @@ + if (net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(event).isCanceled()) return; + p_36276_ = event.getLevels(); + - this.experienceLevel += p_36276_; + this.experienceLevel = IntMath.saturatedAdd(this.experienceLevel, p_36276_); if (this.experienceLevel < 0) { this.experienceLevel = 0; -@@ -1847,7 +_,11 @@ +@@ -1833,7 +_,11 @@ @Override public Component getDisplayName() { @@ -429,7 +414,7 @@ return this.decorateDisplayNameComponent(mutablecomponent); } -@@ -2009,21 +_,21 @@ +@@ -1997,21 +_,21 @@ if (!(p_36349_.getItem() instanceof ProjectileWeaponItem)) { return ItemStack.EMPTY; } else { @@ -456,19 +441,7 @@ } } } -@@ -2047,7 +_,10 @@ - } - - if (!this.level().isClientSide()) { -- this.getInventory().add(optional.get().copy()); -+ ItemStack container = optional.get().copy(); -+ if (!getInventory().add(container)) { -+ drop(container, false); -+ } - } - } - -@@ -2201,5 +_,41 @@ +@@ -2172,5 +_,41 @@ public Component getMessage() { return this.message; } diff --git a/patches/net/minecraft/world/entity/projectile/AbstractArrow.java.patch b/patches/net/minecraft/world/entity/projectile/AbstractArrow.java.patch index 38e7f69f2b..f84027025e 100644 --- a/patches/net/minecraft/world/entity/projectile/AbstractArrow.java.patch +++ b/patches/net/minecraft/world/entity/projectile/AbstractArrow.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/AbstractArrow.java +++ b/net/minecraft/world/entity/projectile/AbstractArrow.java -@@ -188,7 +_,7 @@ +@@ -189,7 +_,7 @@ this.shakeTime--; } @@ -9,14 +9,20 @@ this.clearFire(); } -@@ -224,7 +_,9 @@ - } - } +@@ -269,11 +_,15 @@ -- if (hitresult != null && !flag) { -+ if (hitresult != null && hitresult.getType() != HitResult.Type.MISS && !flag) { -+ if (net.neoforged.neoforge.event.EventHooks.onProjectileImpact(this, hitresult)) + if (entityhitresult == null) { + if (this.isAlive() && p_371761_.getType() != HitResult.Type.MISS) { ++ if (net.neoforged.neoforge.event.EventHooks.onProjectileImpact(this, p_371761_)) + break; - ProjectileDeflection projectiledeflection = this.hitTargetOrDeflectSelf(hitresult); + this.hitTargetOrDeflectSelf(p_371761_); this.hasImpulse = true; - if (projectiledeflection != ProjectileDeflection.NONE) { + } + break; +- } else if (this.isAlive() && !this.noPhysics) { ++ } else if (this.isAlive() && !this.noPhysics && entityhitresult.getType() != HitResult.Type.MISS) { ++ if (net.neoforged.neoforge.event.EventHooks.onProjectileImpact(this, entityhitresult)) ++ break; + ProjectileDeflection projectiledeflection = this.hitTargetOrDeflectSelf(entityhitresult); + this.hasImpulse = true; + if (this.getPierceLevel() > 0 && projectiledeflection == ProjectileDeflection.NONE) { diff --git a/patches/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java.patch b/patches/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java.patch index 44a57f04bc..e90d9725f3 100644 --- a/patches/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java.patch +++ b/patches/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java.patch @@ -1,11 +1,21 @@ --- a/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java +++ b/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java -@@ -78,7 +_,7 @@ - } - +@@ -76,7 +_,8 @@ + if (this.level().isClientSide || (entity == null || !entity.isRemoved()) && this.level().hasChunkAt(this.blockPosition())) { HitResult hitresult = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity, this.getClipType()); + Vec3 vec3; - if (hitresult.getType() != HitResult.Type.MISS) { -+ if (hitresult.getType() != HitResult.Type.MISS && !net.neoforged.neoforge.event.EventHooks.onProjectileImpact(this, hitresult)) { ++ boolean impacted = hitresult.getType() != HitResult.Type.MISS && !net.neoforged.neoforge.event.EventHooks.onProjectileImpact(this, hitresult); ++ if (impacted) { + vec3 = hitresult.getLocation(); + } else { + vec3 = this.position().add(this.getDeltaMovement()); +@@ -90,7 +_,7 @@ + this.igniteForSeconds(1.0F); + } + +- if (hitresult.getType() != HitResult.Type.MISS && this.isAlive()) { ++ if (hitresult.getType() != HitResult.Type.MISS && this.isAlive() && impacted) { this.hitTargetOrDeflectSelf(hitresult); } diff --git a/patches/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch b/patches/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch index 930e57708d..68e0563672 100644 --- a/patches/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch +++ b/patches/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java +++ b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java -@@ -177,6 +_,13 @@ +@@ -182,6 +_,13 @@ } } @@ -11,6 +11,6 @@ + } + } + - private void explode() { - this.level().broadcastEntityEvent(this, (byte)17); + private void explode(ServerLevel p_376529_) { + p_376529_.broadcastEntityEvent(this, (byte)17); this.gameEvent(GameEvent.EXPLODE, this.getOwner()); diff --git a/patches/net/minecraft/world/entity/projectile/FishingHook.java.patch b/patches/net/minecraft/world/entity/projectile/FishingHook.java.patch index aadfd8768b..1a83a15f1e 100644 --- a/patches/net/minecraft/world/entity/projectile/FishingHook.java.patch +++ b/patches/net/minecraft/world/entity/projectile/FishingHook.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/FishingHook.java +++ b/net/minecraft/world/entity/projectile/FishingHook.java -@@ -240,8 +_,8 @@ +@@ -245,8 +_,8 @@ private boolean shouldStopFishing(Player p_37137_) { ItemStack itemstack = p_37137_.getMainHandItem(); ItemStack itemstack1 = p_37137_.getOffhandItem(); @@ -11,7 +11,7 @@ if (!p_37137_.isRemoved() && p_37137_.isAlive() && (flag || flag1) && !(this.distanceToSqr(p_37137_) > 1024.0)) { return false; } else { -@@ -252,7 +_,7 @@ +@@ -257,7 +_,7 @@ private void checkCollision() { HitResult hitresult = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); @@ -20,7 +20,7 @@ } @Override -@@ -441,6 +_,7 @@ +@@ -446,6 +_,7 @@ Player player = this.getPlayerOwner(); if (!this.level().isClientSide && player != null && !this.shouldStopFishing(player)) { int i = 0; @@ -28,7 +28,7 @@ if (this.hookedIn != null) { this.pullEntity(this.hookedIn); CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer)player, p_37157_, this, Collections.emptyList()); -@@ -451,10 +_,17 @@ +@@ -456,10 +_,17 @@ .withParameter(LootContextParams.ORIGIN, this.position()) .withParameter(LootContextParams.TOOL, p_37157_) .withParameter(LootContextParams.THIS_ENTITY, this) @@ -46,7 +46,7 @@ CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer)player, p_37157_, this, list); for (ItemStack itemstack : list) { -@@ -480,6 +_,7 @@ +@@ -485,6 +_,7 @@ } this.discard(); diff --git a/patches/net/minecraft/world/entity/projectile/LargeFireball.java.patch b/patches/net/minecraft/world/entity/projectile/LargeFireball.java.patch index f9dc490f9c..ca9675d4f1 100644 --- a/patches/net/minecraft/world/entity/projectile/LargeFireball.java.patch +++ b/patches/net/minecraft/world/entity/projectile/LargeFireball.java.patch @@ -3,10 +3,10 @@ @@ -29,7 +_,8 @@ protected void onHit(HitResult p_37218_) { super.onHit(p_37218_); - if (!this.level().isClientSide) { -- boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); + if (this.level() instanceof ServerLevel serverlevel) { +- boolean flag = serverlevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); + // TODO 1.19.3: The creation of Level.ExplosionInteraction means this code path will fire EntityMobGriefingEvent twice. Should we try and fix it? -SS -+ boolean flag = net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.level(), this.getOwner()); ++ boolean flag = net.neoforged.neoforge.event.EventHooks.canEntityGrief(serverlevel, this.getOwner()); this.level().explode(this, this.getX(), this.getY(), this.getZ(), (float)this.explosionPower, flag, Level.ExplosionInteraction.MOB); this.discard(); } diff --git a/patches/net/minecraft/world/entity/projectile/Projectile.java.patch b/patches/net/minecraft/world/entity/projectile/Projectile.java.patch index 5309585dd0..b772c7043c 100644 --- a/patches/net/minecraft/world/entity/projectile/Projectile.java.patch +++ b/patches/net/minecraft/world/entity/projectile/Projectile.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/entity/projectile/Projectile.java +++ b/net/minecraft/world/entity/projectile/Projectile.java -@@ -284,7 +_,7 @@ +@@ -375,7 +_,7 @@ Entity entity = this.getOwner(); return entity instanceof Player - ? entity.mayInteract(p_150167_, p_150168_) -- : entity == null || p_150167_.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); -+ : entity == null || net.neoforged.neoforge.event.EventHooks.canEntityGrief(p_150167_, entity); + ? entity.mayInteract(p_376318_, p_150168_) +- : entity == null || p_376318_.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); ++ : entity == null || net.neoforged.neoforge.event.EventHooks.canEntityGrief(p_376318_, entity); } - public boolean mayBreak(Level p_307481_) { + public boolean mayBreak(ServerLevel p_376471_) { diff --git a/patches/net/minecraft/world/entity/projectile/ProjectileUtil.java.patch b/patches/net/minecraft/world/entity/projectile/ProjectileUtil.java.patch index 0a939444db..19a4a507c2 100644 --- a/patches/net/minecraft/world/entity/projectile/ProjectileUtil.java.patch +++ b/patches/net/minecraft/world/entity/projectile/ProjectileUtil.java.patch @@ -9,7 +9,7 @@ if (d0 == 0.0) { entity = entity1; vec3 = vec31; -@@ -153,8 +_,13 @@ +@@ -155,8 +_,13 @@ } } diff --git a/patches/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch b/patches/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch index d78a8d8f20..471a8a36e3 100644 --- a/patches/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch +++ b/patches/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/entity/projectile/ShulkerBullet.java +++ b/net/minecraft/world/entity/projectile/ShulkerBullet.java -@@ -218,7 +_,7 @@ - } +@@ -228,7 +_,7 @@ + this.handlePortal(); + } - HitResult hitresult = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); -- if (hitresult.getType() != HitResult.Type.MISS) { -+ if (hitresult.getType() != HitResult.Type.MISS && !net.neoforged.neoforge.event.EventHooks.onProjectileImpact(this, hitresult)) { - this.hitTargetOrDeflectSelf(hitresult); - } +- if (hitresult != null && this.isAlive() && hitresult.getType() != HitResult.Type.MISS) { ++ if (hitresult != null && this.isAlive() && hitresult.getType() != HitResult.Type.MISS && !net.neoforged.neoforge.event.EventHooks.onProjectileImpact(this, hitresult)) { + this.hitTargetOrDeflectSelf(hitresult); } + diff --git a/patches/net/minecraft/world/entity/projectile/SmallFireball.java.patch b/patches/net/minecraft/world/entity/projectile/SmallFireball.java.patch index 5f4cf7048f..2a65c9d0c1 100644 --- a/patches/net/minecraft/world/entity/projectile/SmallFireball.java.patch +++ b/patches/net/minecraft/world/entity/projectile/SmallFireball.java.patch @@ -2,10 +2,10 @@ +++ b/net/minecraft/world/entity/projectile/SmallFireball.java @@ -51,7 +_,7 @@ super.onHitBlock(p_37384_); - if (!this.level().isClientSide) { + if (this.level() instanceof ServerLevel serverlevel) { Entity entity = this.getOwner(); -- if (!(entity instanceof Mob) || this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (!(entity instanceof Mob) || net.neoforged.neoforge.event.EventHooks.canEntityGrief(this.level(), entity)) { +- if (!(entity instanceof Mob) || serverlevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (!(entity instanceof Mob) || net.neoforged.neoforge.event.EventHooks.canEntityGrief(serverlevel, entity)) { BlockPos blockpos = p_37384_.getBlockPos().relative(p_37384_.getDirection()); if (this.level().isEmptyBlock(blockpos)) { this.level().setBlockAndUpdate(blockpos, BaseFireBlock.getState(this.level(), blockpos)); diff --git a/patches/net/minecraft/world/entity/projectile/ThrowableProjectile.java.patch b/patches/net/minecraft/world/entity/projectile/ThrowableProjectile.java.patch index 8db754738d..0f2f4b2c73 100644 --- a/patches/net/minecraft/world/entity/projectile/ThrowableProjectile.java.patch +++ b/patches/net/minecraft/world/entity/projectile/ThrowableProjectile.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/entity/projectile/ThrowableProjectile.java +++ b/net/minecraft/world/entity/projectile/ThrowableProjectile.java -@@ -42,7 +_,7 @@ - public void tick() { - super.tick(); +@@ -48,7 +_,7 @@ + this.applyInertia(); HitResult hitresult = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); + Vec3 vec3; - if (hitresult.getType() != HitResult.Type.MISS) { + if (hitresult.getType() != HitResult.Type.MISS && !net.neoforged.neoforge.event.EventHooks.onProjectileImpact(this, hitresult)) { - this.hitTargetOrDeflectSelf(hitresult); - } - + vec3 = hitresult.getLocation(); + } else { + vec3 = this.position().add(this.getDeltaMovement()); diff --git a/patches/net/minecraft/world/entity/projectile/ThrownEnderpearl.java.patch b/patches/net/minecraft/world/entity/projectile/ThrownEnderpearl.java.patch index 483428eed1..81b0d29e99 100644 --- a/patches/net/minecraft/world/entity/projectile/ThrownEnderpearl.java.patch +++ b/patches/net/minecraft/world/entity/projectile/ThrownEnderpearl.java.patch @@ -1,28 +1,31 @@ --- a/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +++ b/net/minecraft/world/entity/projectile/ThrownEnderpearl.java -@@ -66,6 +_,8 @@ - +@@ -126,6 +_,8 @@ + Vec3 vec3 = this.oldPosition(); if (entity instanceof ServerPlayer serverplayer) { if (serverplayer.connection.isAcceptingMessages()) { + net.neoforged.neoforge.event.entity.EntityTeleportEvent.EnderPearl event = net.neoforged.neoforge.event.EventHooks.onEnderPearlLand(serverplayer, this.getX(), this.getY(), this.getZ(), this, 5.0F, p_37504_); + if (!event.isCanceled()) { // Don't indent to lower patch size if (this.random.nextFloat() < 0.05F && serverlevel.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING)) { - Endermite endermite = EntityType.ENDERMITE.create(serverlevel); + Endermite endermite = EntityType.ENDERMITE.create(serverlevel, EntitySpawnReason.TRIGGERED); if (endermite != null) { -@@ -76,13 +_,14 @@ +@@ -140,16 +_,17 @@ - entity.changeDimension( - new DimensionTransition( -- serverlevel, this.position(), entity.getDeltaMovement(), entity.getYRot(), entity.getXRot(), DimensionTransition.DO_NOTHING -+ serverlevel, event.getTarget(), entity.getDeltaMovement(), entity.getYRot(), entity.getXRot(), DimensionTransition.DO_NOTHING + ServerPlayer serverplayer1 = serverplayer.teleport( + new TeleportTransition( +- serverlevel, vec3, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.ROTATION, Relative.DELTA), TeleportTransition.DO_NOTHING ++ serverlevel, event.getTarget(), entity.getDeltaMovement(), entity.getYRot(), entity.getXRot(), TeleportTransition.DO_NOTHING ) ); - entity.resetFallDistance(); - serverplayer.resetCurrentImpulseContext(); -- entity.hurt(this.damageSources().fall(), 5.0F); -+ entity.hurt(this.damageSources().fall(), event.getAttackDamage()); - this.playSound(serverlevel, this.position()); + if (serverplayer1 != null) { + serverplayer1.resetFallDistance(); + serverplayer1.resetCurrentImpulseContext(); +- serverplayer1.hurtServer(serverplayer.serverLevel(), this.damageSources().enderPearl(), 5.0F); ++ serverplayer1.hurtServer(serverplayer.serverLevel(), this.damageSources().fall(), event.getAttackDamage()); + } + + this.playSound(serverlevel, vec3); + } //Forge: End } } else { - entity.changeDimension( + Entity entity1 = entity.teleport( diff --git a/patches/net/minecraft/world/entity/raid/Raid.java.patch b/patches/net/minecraft/world/entity/raid/Raid.java.patch index 2175381fab..1518312f9e 100644 --- a/patches/net/minecraft/world/entity/raid/Raid.java.patch +++ b/patches/net/minecraft/world/entity/raid/Raid.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/entity/raid/Raid.java +++ b/net/minecraft/world/entity/raid/Raid.java -@@ -503,7 +_,7 @@ +@@ -493,7 +_,7 @@ int k = 0; for (int l = 0; l < j; l++) { -- Raider raider = raid$raidertype.entityType.create(this.level); -+ Raider raider = raid$raidertype.entityTypeSupplier.get().create(this.level); +- Raider raider = raid$raidertype.entityType.create(this.level, EntitySpawnReason.EVENT); ++ Raider raider = raid$raidertype.entityTypeSupplier.get().create(this.level, EntitySpawnReason.EVENT); if (raider == null) { break; } -@@ -515,7 +_,7 @@ +@@ -505,7 +_,7 @@ } this.joinRaid(i, raider, p_37756_, false); @@ -17,8 +17,8 @@ + if (raid$raidertype.entityTypeSupplier.get() == EntityType.RAVAGER) { Raider raider1 = null; if (i == this.getNumGroups(Difficulty.NORMAL)) { - raider1 = EntityType.PILLAGER.create(this.level); -@@ -834,7 +_,7 @@ + raider1 = EntityType.PILLAGER.create(this.level, EntitySpawnReason.EVENT); +@@ -828,7 +_,7 @@ } } @@ -27,7 +27,7 @@ VINDICATOR(EntityType.VINDICATOR, new int[]{0, 0, 2, 0, 1, 4, 2, 5}), EVOKER(EntityType.EVOKER, new int[]{0, 0, 0, 0, 0, 1, 1, 2}), PILLAGER(EntityType.PILLAGER, new int[]{0, 4, 3, 3, 4, 4, 4, 2}), -@@ -842,12 +_,26 @@ +@@ -836,12 +_,26 @@ RAVAGER(EntityType.RAVAGER, new int[]{0, 0, 0, 1, 0, 1, 0, 2}); static final Raid.RaiderType[] VALUES = values(); diff --git a/patches/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch b/patches/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch new file mode 100644 index 0000000000..c389491313 --- /dev/null +++ b/patches/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch @@ -0,0 +1,65 @@ +--- a/net/minecraft/world/entity/vehicle/AbstractBoat.java ++++ b/net/minecraft/world/entity/vehicle/AbstractBoat.java +@@ -45,7 +_,7 @@ + import net.minecraft.world.phys.shapes.Shapes; + import net.minecraft.world.phys.shapes.VoxelShape; + +-public abstract class AbstractBoat extends VehicleEntity implements Leashable { ++public abstract class AbstractBoat extends VehicleEntity implements Leashable, net.neoforged.neoforge.common.extensions.IAbstractBoatExtension { + private static final EntityDataAccessor DATA_ID_PADDLE_LEFT = SynchedEntityData.defineId(AbstractBoat.class, EntityDataSerializers.BOOLEAN); + private static final EntityDataAccessor DATA_ID_PADDLE_RIGHT = SynchedEntityData.defineId(AbstractBoat.class, EntityDataSerializers.BOOLEAN); + private static final EntityDataAccessor DATA_ID_BUBBLE_TIME = SynchedEntityData.defineId(AbstractBoat.class, EntityDataSerializers.INT); +@@ -478,7 +_,7 @@ + for (int i2 = i1; i2 < j1; i2++) { + blockpos$mutableblockpos.set(l1, k1, i2); + FluidState fluidstate = this.level().getFluidState(blockpos$mutableblockpos); +- if (fluidstate.is(FluidTags.WATER)) { ++ if (this.canBoatInFluid(fluidstate)) { + f = Math.max(f, fluidstate.getHeight(this.level(), blockpos$mutableblockpos)); + } + +@@ -524,7 +_,7 @@ + voxelshape, + BooleanOp.AND + )) { +- f += blockstate.getBlock().getFriction(); ++ f += blockstate.getFriction(this.level(), blockpos$mutableblockpos, this); + k1++; + } + } +@@ -553,7 +_,7 @@ + for (int i2 = i1; i2 < j1; i2++) { + blockpos$mutableblockpos.set(k1, l1, i2); + FluidState fluidstate = this.level().getFluidState(blockpos$mutableblockpos); +- if (fluidstate.is(FluidTags.WATER)) { ++ if (this.canBoatInFluid(fluidstate)) { + float f = (float)l1 + fluidstate.getHeight(this.level(), blockpos$mutableblockpos); + this.waterLevel = Math.max((double)f, this.waterLevel); + flag |= aabb.minY < (double)f; +@@ -583,7 +_,7 @@ + for (int i2 = i1; i2 < j1; i2++) { + blockpos$mutableblockpos.set(k1, l1, i2); + FluidState fluidstate = this.level().getFluidState(blockpos$mutableblockpos); +- if (fluidstate.is(FluidTags.WATER) ++ if (this.canBoatInFluid(fluidstate) + && d0 < (double)((float)blockpos$mutableblockpos.getY() + fluidstate.getHeight(this.level(), blockpos$mutableblockpos))) { + if (!fluidstate.isSource()) { + return AbstractBoat.Status.UNDER_FLOWING_WATER; +@@ -790,7 +_,7 @@ + if (!this.isPassenger()) { + if (p_376924_) { + this.resetFallDistance(); +- } else if (!this.level().getFluidState(this.blockPosition().below()).is(FluidTags.WATER) && p_376661_ < 0.0) { ++ } else if (!this.canBoatInFluid(this.level().getFluidState(this.blockPosition().below())) && p_376661_ < 0.0) { + this.fallDistance -= (float)p_376661_; + } + } +@@ -814,7 +_,7 @@ + + @Override + protected boolean canAddPassenger(Entity p_376443_) { +- return this.getPassengers().size() < this.getMaxPassengers() && !this.isEyeInFluid(FluidTags.WATER); ++ return this.getPassengers().size() < this.getMaxPassengers() && !this.canBoatInFluid(this.getEyeInFluidType()); + } + + protected int getMaxPassengers() { diff --git a/patches/net/minecraft/world/entity/vehicle/AbstractMinecart.java.patch b/patches/net/minecraft/world/entity/vehicle/AbstractMinecart.java.patch index 283ba48c69..ec083fc217 100644 --- a/patches/net/minecraft/world/entity/vehicle/AbstractMinecart.java.patch +++ b/patches/net/minecraft/world/entity/vehicle/AbstractMinecart.java.patch @@ -1,307 +1,78 @@ --- a/net/minecraft/world/entity/vehicle/AbstractMinecart.java +++ b/net/minecraft/world/entity/vehicle/AbstractMinecart.java -@@ -45,7 +_,7 @@ - import net.minecraft.world.phys.AABB; - import net.minecraft.world.phys.Vec3; - --public abstract class AbstractMinecart extends VehicleEntity { -+public abstract class AbstractMinecart extends VehicleEntity implements net.neoforged.neoforge.common.extensions.IAbstractMinecartExtension { - private static final Vec3 LOWERED_PASSENGER_ATTACHMENT = new Vec3(0.0, 0.0, 0.0); - private static final EntityDataAccessor DATA_ID_DISPLAY_BLOCK = SynchedEntityData.defineId(AbstractMinecart.class, EntityDataSerializers.INT); +@@ -49,7 +_,7 @@ private static final EntityDataAccessor DATA_ID_DISPLAY_OFFSET = SynchedEntityData.defineId(AbstractMinecart.class, EntityDataSerializers.INT); -@@ -63,6 +_,7 @@ - private double lerpYRot; - private double lerpXRot; - private Vec3 targetDeltaMovement = Vec3.ZERO; -+ private boolean canBePushed = true; - private static final Map> EXITS = Util.make(Maps.newEnumMap(RailShape.class), p_38135_ -> { - Vec3i vec3i = Direction.WEST.getNormal(); - Vec3i vec3i1 = Direction.EAST.getNormal(); -@@ -83,6 +_,7 @@ - p_38135_.put(RailShape.NORTH_WEST, Pair.of(vec3i2, vec3i)); - p_38135_.put(RailShape.NORTH_EAST, Pair.of(vec3i2, vec3i1)); - }); -+ private static net.neoforged.neoforge.common.IMinecartCollisionHandler COLLISIONS = null; - - protected AbstractMinecart(EntityType p_38087_, Level p_38088_) { - super(p_38087_, p_38088_); -@@ -97,6 +_,14 @@ - this.zo = p_38094_; - } - -+ public net.neoforged.neoforge.common.IMinecartCollisionHandler getCollisionHandler() { -+ return COLLISIONS; -+ } -+ -+ public static void registerCollisionHandler(@Nullable net.neoforged.neoforge.common.IMinecartCollisionHandler handler) { -+ COLLISIONS = handler; -+ } -+ - public static AbstractMinecart createMinecart( - ServerLevel p_305794_, - double p_38121_, -@@ -139,7 +_,7 @@ - - @Override - public boolean isPushable() { -- return true; -+ return canBePushed; - } - - @Override -@@ -271,9 +_,9 @@ - BlockPos blockpos = new BlockPos(i, j, k); - BlockState blockstate = this.level().getBlockState(blockpos); - this.onRails = BaseRailBlock.isRail(blockstate); -- if (this.onRails) { -+ if (canUseRail() && this.onRails) { - this.moveAlongTrack(blockpos, blockstate); -- if (blockstate.is(Blocks.ACTIVATOR_RAIL)) { -+ if (blockstate.getBlock() instanceof PoweredRailBlock && ((PoweredRailBlock) blockstate.getBlock()).isActivatorRail()) { - this.activateMinecart(i, j, k, blockstate.getValue(PoweredRailBlock.POWERED)); - } - } else { -@@ -298,8 +_,11 @@ - } - - this.setRot(this.getYRot(), this.getXRot()); -- if (this.getMinecartType() == AbstractMinecart.Type.RIDEABLE && this.getDeltaMovement().horizontalDistanceSqr() > 0.01) { -- List list = this.level().getEntities(this, this.getBoundingBox().inflate(0.2F, 0.0, 0.2F), EntitySelector.pushableBy(this)); -+ AABB box; -+ if (getCollisionHandler() != null) box = getCollisionHandler().getMinecartCollisionBox(this); -+ else box = this.getBoundingBox().inflate(0.2F, 0.0D, 0.2F); -+ if (canBeRidden() && this.getDeltaMovement().horizontalDistanceSqr() > 0.01D) { -+ List list = this.level().getEntities(this, box, EntitySelector.pushableBy(this)); - if (!list.isEmpty()) { - for (Entity entity1 : list) { - if (!(entity1 instanceof Player) -@@ -314,7 +_,7 @@ - } - } - } else { -- for (Entity entity : this.level().getEntities(this, this.getBoundingBox().inflate(0.2F, 0.0, 0.2F))) { -+ for(Entity entity : this.level().getEntities(this, box)) { - if (!this.hasPassenger(entity) && entity.isPushable() && entity instanceof AbstractMinecart) { - entity.push(this); - } -@@ -339,16 +_,23 @@ - } - - protected void comeOffTrack() { -- double d0 = this.getMaxSpeed(); -+ double d0 = this.onGround() ? this.getMaxSpeed() : getMaxSpeedAirLateral(); - Vec3 vec3 = this.getDeltaMovement(); - this.setDeltaMovement(Mth.clamp(vec3.x, -d0, d0), vec3.y, Mth.clamp(vec3.z, -d0, d0)); - if (this.onGround()) { - this.setDeltaMovement(this.getDeltaMovement().scale(0.5)); - } - -+ if (getMaxSpeedAirVertical() > 0 && getDeltaMovement().y > getMaxSpeedAirVertical()) { -+ if(Math.abs(getDeltaMovement().x) < 0.3f && Math.abs(getDeltaMovement().z) < 0.3f) -+ setDeltaMovement(new Vec3(getDeltaMovement().x, 0.15f, getDeltaMovement().z)); -+ else -+ setDeltaMovement(new Vec3(getDeltaMovement().x, getMaxSpeedAirVertical(), getDeltaMovement().z)); -+ } -+ - this.move(MoverType.SELF, this.getDeltaMovement()); - if (!this.onGround()) { -- this.setDeltaMovement(this.getDeltaMovement().scale(0.95)); -+ this.setDeltaMovement(this.getDeltaMovement().scale(getDragAir())); - } - } - -@@ -361,18 +_,19 @@ - d1 = (double)p_38156_.getY(); - boolean flag = false; - boolean flag1 = false; -- if (p_38157_.is(Blocks.POWERED_RAIL)) { -+ BaseRailBlock baserailblock = (BaseRailBlock) p_38157_.getBlock(); -+ if (baserailblock instanceof PoweredRailBlock && !((PoweredRailBlock) baserailblock).isActivatorRail()) { - flag = p_38157_.getValue(PoweredRailBlock.POWERED); - flag1 = !flag; - } - -- double d3 = 0.0078125; -+ double d3 = getSlopeAdjustment(); - if (this.isInWater()) { - d3 *= 0.2; - } - - Vec3 vec31 = this.getDeltaMovement(); -- RailShape railshape = p_38157_.getValue(((BaseRailBlock)p_38157_.getBlock()).getShapeProperty()); -+ RailShape railshape = ((BaseRailBlock)p_38157_.getBlock()).getRailDirection(p_38157_, this.level(), p_38156_, this); - switch (railshape) { - case ASCENDING_EAST: - this.setDeltaMovement(vec31.add(-d3, 0.0, 0.0)); -@@ -418,7 +_,7 @@ - } - } - -- if (flag1) { -+ if (flag1 && shouldDoRailFunctions()) { - double d22 = this.getDeltaMovement().horizontalDistance(); - if (d22 < 0.03) { - this.setDeltaMovement(Vec3.ZERO); -@@ -447,10 +_,7 @@ - d0 = d23 + d4 * d14; - d2 = d10 + d5 * d14; - this.setPos(d0, d1, d2); -- double d24 = this.isVehicle() ? 0.75 : 1.0; -- double d25 = this.getMaxSpeed(); -- vec31 = this.getDeltaMovement(); -- this.move(MoverType.SELF, new Vec3(Mth.clamp(d24 * vec31.x, -d25, d25), 0.0, Mth.clamp(d24 * vec31.z, -d25, d25))); -+ this.moveMinecartOnRail(p_38156_); - if (vec3i.getY() != 0 && Mth.floor(this.getX()) - p_38156_.getX() == vec3i.getX() && Mth.floor(this.getZ()) - p_38156_.getZ() == vec3i.getZ()) { - this.setPos(this.getX(), this.getY() + (double)vec3i.getY(), this.getZ()); - } else if (vec3i1.getY() != 0 && Mth.floor(this.getX()) - p_38156_.getX() == vec3i1.getX() && Mth.floor(this.getZ()) - p_38156_.getZ() == vec3i1.getZ() -@@ -480,7 +_,10 @@ - this.setDeltaMovement(d26 * (double)(j - p_38156_.getX()), vec35.y, d26 * (double)(i - p_38156_.getZ())); - } - -- if (flag) { -+ if (shouldDoRailFunctions()) -+ baserailblock.onMinecartPass(p_38157_, level(), p_38156_, this); -+ -+ if (flag && shouldDoRailFunctions()) { - Vec3 vec36 = this.getDeltaMovement(); - double d27 = vec36.horizontalDistance(); - if (d27 > 0.01) { -@@ -544,7 +_,7 @@ - - BlockState blockstate = this.level().getBlockState(new BlockPos(i, j, k)); - if (BaseRailBlock.isRail(blockstate)) { -- RailShape railshape = blockstate.getValue(((BaseRailBlock)blockstate.getBlock()).getShapeProperty()); -+ RailShape railshape = ((BaseRailBlock)blockstate.getBlock()).getRailDirection(blockstate, this.level(), new BlockPos(i, j, k), this); - p_38098_ = (double)j; - if (railshape.isAscending()) { - p_38098_ = (double)(j + 1); -@@ -583,7 +_,7 @@ - - BlockState blockstate = this.level().getBlockState(new BlockPos(i, j, k)); - if (BaseRailBlock.isRail(blockstate)) { + private static final EntityDataAccessor DATA_ID_CUSTOM_DISPLAY = SynchedEntityData.defineId(AbstractMinecart.class, EntityDataSerializers.BOOLEAN); + private static final ImmutableMap> POSE_DISMOUNT_HEIGHTS = ImmutableMap.of( +- Pose.STANDING, ImmutableList.of(0, 1, -1), Pose.CROUCHING, ImmutableList.of(0, 1, -1), Pose.SWIMMING, ImmutableList.of(0, 1) ++ Pose.STANDING, ImmutableList.of(0, 1, -1), Pose.CROUCHING, ImmutableList.of(0, 1, -1), Pose.SWIMMING, ImmutableList.of(0, 1) + ); + protected static final float WATER_SLOWDOWN_FACTOR = 0.95F; + private boolean onRails; +@@ -100,14 +_,14 @@ + + @Nullable + public static T createMinecart( +- Level p_366408_, +- double p_38121_, +- double p_38122_, +- double p_38123_, +- EntityType p_374583_, +- EntitySpawnReason p_374412_, +- ItemStack p_305892_, +- @Nullable Player p_306203_ ++ Level p_366408_, ++ double p_38121_, ++ double p_38122_, ++ double p_38123_, ++ EntityType p_374583_, ++ EntitySpawnReason p_374412_, ++ ItemStack p_305892_, ++ @Nullable Player p_306203_ + ) { + T t = (T)p_374583_.create(p_366408_, p_374412_); + if (t != null) { +@@ -180,10 +_,10 @@ + for (int[] aint1 : aint) { + blockpos$mutableblockpos.set(blockpos.getX() + aint1[0], blockpos.getY() + i, blockpos.getZ() + aint1[1]); + double d0 = this.level() +- .getBlockFloorHeight( +- DismountHelper.nonClimbableShape(this.level(), blockpos$mutableblockpos), +- () -> DismountHelper.nonClimbableShape(this.level(), blockpos$mutableblockpos.below()) +- ); ++ .getBlockFloorHeight( ++ DismountHelper.nonClimbableShape(this.level(), blockpos$mutableblockpos), ++ () -> DismountHelper.nonClimbableShape(this.level(), blockpos$mutableblockpos.below()) ++ ); + if (DismountHelper.isBlockFloorValid(d0)) { + AABB aabb = new AABB((double)(-f), 0.0, (double)(-f), (double)f, (double)entitydimensions.height(), (double)f); + Vec3 vec3 = Vec3.upFromBottomCenterOf(blockpos$mutableblockpos, d0); +@@ -203,7 +_,7 @@ + double d2 = (double)p_38145_.getDimensions(pose1).height(); + int j = Mth.ceil(d1 - (double)blockpos$mutableblockpos.getY() + d2); + double d3 = DismountHelper.findCeilingFrom( +- blockpos$mutableblockpos, j, p_381557_ -> this.level().getBlockState(p_381557_).getCollisionShape(this.level(), p_381557_) ++ blockpos$mutableblockpos, j, p_381557_ -> this.level().getBlockState(p_381557_).getCollisionShape(this.level(), p_381557_) + ); + if (d1 + d2 <= d3) { + p_38145_.setPose(pose1); +@@ -420,8 +_,8 @@ + + public Vec3 getRedstoneDirection(BlockPos p_361470_) { + BlockState blockstate = this.level().getBlockState(p_361470_); +- if (blockstate.is(Blocks.POWERED_RAIL) && blockstate.getValue(PoweredRailBlock.POWERED)) { - RailShape railshape = blockstate.getValue(((BaseRailBlock)blockstate.getBlock()).getShapeProperty()); -+ RailShape railshape = ((BaseRailBlock)blockstate.getBlock()).getRailDirection(blockstate, this.level(), new BlockPos(i, j, k), this); - Pair pair = exits(railshape); - Vec3i vec3i = pair.getFirst(); - Vec3i vec3i1 = pair.getSecond(); -@@ -647,6 +_,10 @@ - - @Override - public void push(Entity p_38165_) { -+ if (getCollisionHandler() != null) { -+ getCollisionHandler().onEntityCollision(this, p_38165_); -+ return; -+ } - if (!this.level().isClientSide) { - if (!p_38165_.noPhysics && !this.noPhysics) { - if (!this.hasPassenger(p_38165_)) { -@@ -685,13 +_,11 @@ - - Vec3 vec32 = this.getDeltaMovement(); - Vec3 vec33 = p_38165_.getDeltaMovement(); -- if (((AbstractMinecart)p_38165_).getMinecartType() == AbstractMinecart.Type.FURNACE -- && this.getMinecartType() != AbstractMinecart.Type.FURNACE) { -+ if (((AbstractMinecart)p_38165_).isPoweredCart() && !this.isPoweredCart()) { - this.setDeltaMovement(vec32.multiply(0.2, 1.0, 0.2)); - this.push(vec33.x - d0, 0.0, vec33.z - d1); - p_38165_.setDeltaMovement(vec33.multiply(0.95, 1.0, 0.95)); -- } else if (((AbstractMinecart)p_38165_).getMinecartType() != AbstractMinecart.Type.FURNACE -- && this.getMinecartType() == AbstractMinecart.Type.FURNACE) { -+ } else if (!((AbstractMinecart)p_38165_).isPoweredCart() && this.isPoweredCart()) { - p_38165_.setDeltaMovement(vec33.multiply(0.2, 1.0, 0.2)); - p_38165_.push(vec32.x + d0, 0.0, vec32.z + d1); - this.setDeltaMovement(vec32.multiply(0.95, 1.0, 0.95)); -@@ -789,6 +_,93 @@ - - public void setCustomDisplay(boolean p_38139_) { - this.getEntityData().set(DATA_ID_CUSTOM_DISPLAY, p_38139_); -+ } -+ -+ // Neo: Controls whether a Minecrart is allowed on Rails or not -+ private boolean canUseRail = true; -+ -+ @Override -+ public boolean canUseRail() { -+ return canUseRail; -+ } -+ -+ @Override -+ public void setCanUseRail(boolean value) { -+ this.canUseRail = value; -+ } -+ -+ // Neo: Controls the rail speed cap -+ private float currentSpeedCapOnRail = getMaxCartSpeedOnRail(); -+ -+ @Override -+ public float getCurrentCartSpeedCapOnRail() { -+ return currentSpeedCapOnRail; -+ } -+ -+ @Override -+ public void setCurrentCartSpeedCapOnRail(float value) { -+ currentSpeedCapOnRail = Math.min(value, getMaxCartSpeedOnRail()); -+ } -+ -+ @Override -+ public double getMaxSpeedWithRail() { //Non-default because getMaximumSpeed is protected -+ if (!canUseRail()) return getMaxSpeed(); -+ BlockPos pos = this.getCurrentRailPosition(); -+ BlockState state = this.level().getBlockState(pos); -+ if (!state.is(BlockTags.RAILS)) return getMaxSpeed(); -+ -+ float railMaxSpeed = ((BaseRailBlock)state.getBlock()).getRailMaxSpeed(state, this.level(), pos, this); -+ return Math.min(railMaxSpeed, getCurrentCartSpeedCapOnRail()); -+ } -+ -+ // Neo: Controls the horizontal air speed cap -+ @org.jetbrains.annotations.Nullable -+ private Float maxSpeedAirLateral = null; -+ -+ @Override -+ public float getMaxSpeedAirLateral() { -+ return maxSpeedAirLateral == null ? (float) this.getMaxSpeed() : maxSpeedAirLateral; -+ } -+ -+ @Override -+ public void setMaxSpeedAirLateral(float value) { -+ maxSpeedAirLateral = value; -+ } -+ -+ // Neo: Controls the vertical air speed cap -+ private float maxSpeedAirVertical = DEFAULT_MAX_SPEED_AIR_VERTICAL; -+ -+ @Override -+ public float getMaxSpeedAirVertical() { -+ return maxSpeedAirVertical; -+ } -+ -+ @Override -+ public void setMaxSpeedAirVertical(float value) { -+ maxSpeedAirVertical = value; -+ } -+ -+ // Neo: Controls the drag effect when Minecart is in air -+ private double dragAir = DEFAULT_AIR_DRAG; -+ -+ @Override -+ public double getDragAir() { -+ return dragAir; -+ } -+ -+ @Override -+ public void setDragAir(double value) { -+ dragAir = value; -+ } -+ -+ // Neo: Applies the movement speed to the Minecart -+ @Override -+ public void moveMinecartOnRail(BlockPos pos) { //Non-default because getMaximumSpeed is protected -+ AbstractMinecart mc = this; -+ double d24 = mc.isVehicle() ? 0.75D : 1.0D; -+ double d25 = mc.getMaxSpeedWithRail(); -+ Vec3 vec3d1 = mc.getDeltaMovement(); -+ mc.move(MoverType.SELF, new Vec3(Mth.clamp(d24 * vec3d1.x, -d25, d25), 0.0D, Mth.clamp(d24 * vec3d1.z, -d25, d25))); - } - - @Override ++ if (blockstate.getBlock() instanceof PoweredRailBlock poweredRail && !poweredRail.isActivatorRail() && blockstate.getValue(PoweredRailBlock.POWERED)) { ++ RailShape railshape = ((BaseRailBlock)blockstate.getBlock()).getRailDirection(blockstate, this.level(), p_361470_, this); + if (railshape == RailShape.EAST_WEST) { + if (this.isRedstoneConductor(p_361470_.west())) { + return new Vec3(1.0, 0.0, 0.0); +@@ -531,7 +_,7 @@ + + Vec3 vec3 = new Vec3(d0, 0.0, d1).normalize(); + Vec3 vec31 = new Vec3((double)Mth.cos(this.getYRot() * (float) (Math.PI / 180.0)), 0.0, (double)Mth.sin(this.getYRot() * (float) (Math.PI / 180.0))) +- .normalize(); ++ .normalize(); + double d2 = Math.abs(vec3.dot(vec31)); + if (!(d2 < 0.8F) || useExperimentalMovement(this.level())) { + Vec3 vec32 = this.getDeltaMovement(); diff --git a/patches/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch b/patches/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch index cec5eec538..15d33613e4 100644 --- a/patches/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch +++ b/patches/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java +++ b/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java -@@ -95,6 +_,8 @@ +@@ -93,6 +_,8 @@ @Override public InteractionResult interact(Player p_38232_, InteractionHand p_38233_) { diff --git a/patches/net/minecraft/world/entity/vehicle/Boat.java.patch b/patches/net/minecraft/world/entity/vehicle/Boat.java.patch deleted file mode 100644 index fbd6f23a2c..0000000000 --- a/patches/net/minecraft/world/entity/vehicle/Boat.java.patch +++ /dev/null @@ -1,193 +0,0 @@ ---- a/net/minecraft/world/entity/vehicle/Boat.java -+++ b/net/minecraft/world/entity/vehicle/Boat.java -@@ -52,7 +_,7 @@ - import net.minecraft.world.phys.shapes.Shapes; - import net.minecraft.world.phys.shapes.VoxelShape; - --public class Boat extends VehicleEntity implements Leashable, VariantHolder { -+public class Boat extends VehicleEntity implements Leashable, VariantHolder, net.neoforged.neoforge.common.extensions.IBoatExtension { - private static final EntityDataAccessor DATA_ID_TYPE = SynchedEntityData.defineId(Boat.class, EntityDataSerializers.INT); - private static final EntityDataAccessor DATA_ID_PADDLE_LEFT = SynchedEntityData.defineId(Boat.class, EntityDataSerializers.BOOLEAN); - private static final EntityDataAccessor DATA_ID_PADDLE_RIGHT = SynchedEntityData.defineId(Boat.class, EntityDataSerializers.BOOLEAN); -@@ -157,7 +_,7 @@ - } - } - -- return new Vec3(0.0, this.getVariant() == Boat.Type.BAMBOO ? (double)(p_295933_.height() * 0.8888889F) : (double)(p_295933_.height() / 3.0F), (double)f) -+ return new Vec3(0.0, this.getVariant().isRaft() ? (double)(p_295933_.height() * 0.8888889F) : (double)(p_295933_.height() / 3.0F), (double)f) - .yRot(-this.getYRot() * (float) (Math.PI / 180.0)); - } - -@@ -212,7 +_,8 @@ - case DARK_OAK -> Items.DARK_OAK_BOAT; - case MANGROVE -> Items.MANGROVE_BOAT; - case BAMBOO -> Items.BAMBOO_RAFT; -- default -> Items.OAK_BOAT; -+ case OAK -> Items.OAK_BOAT; -+ default -> this.getVariant().boatItem.get(); - }; - } - -@@ -498,7 +_,7 @@ - for (int i2 = i1; i2 < j1; i2++) { - blockpos$mutableblockpos.set(l1, k1, i2); - FluidState fluidstate = this.level().getFluidState(blockpos$mutableblockpos); -- if (fluidstate.is(FluidTags.WATER)) { -+ if (this.canBoatInFluid(fluidstate)) { - f = Math.max(f, fluidstate.getHeight(this.level(), blockpos$mutableblockpos)); - } - -@@ -544,7 +_,7 @@ - voxelshape, - BooleanOp.AND - )) { -- f += blockstate.getBlock().getFriction(); -+ f += blockstate.getFriction(this.level(), blockpos$mutableblockpos, this); - k1++; - } - } -@@ -573,7 +_,7 @@ - for (int i2 = i1; i2 < j1; i2++) { - blockpos$mutableblockpos.set(k1, l1, i2); - FluidState fluidstate = this.level().getFluidState(blockpos$mutableblockpos); -- if (fluidstate.is(FluidTags.WATER)) { -+ if (this.canBoatInFluid(fluidstate)) { - float f = (float)l1 + fluidstate.getHeight(this.level(), blockpos$mutableblockpos); - this.waterLevel = Math.max((double)f, this.waterLevel); - flag |= aabb.minY < (double)f; -@@ -603,7 +_,7 @@ - for (int i2 = i1; i2 < j1; i2++) { - blockpos$mutableblockpos.set(k1, l1, i2); - FluidState fluidstate = this.level().getFluidState(blockpos$mutableblockpos); -- if (fluidstate.is(FluidTags.WATER) -+ if (this.canBoatInFluid(fluidstate) - && d0 < (double)((float)blockpos$mutableblockpos.getY() + fluidstate.getHeight(this.level(), blockpos$mutableblockpos))) { - if (!fluidstate.isSource()) { - return Boat.Status.UNDER_FLOWING_WATER; -@@ -832,14 +_,15 @@ - } - - for (int j = 0; j < 2; j++) { -- this.spawnAtLocation(Items.STICK); -+ // Neo: allow dropping material-specific sticks instead of just generic wooden sticks -+ this.spawnAtLocation(this.getVariant().getSticks()); - } - } - } - } - - this.resetFallDistance(); -- } else if (!this.level().getFluidState(this.blockPosition().below()).is(FluidTags.WATER) && p_38307_ < 0.0) { -+ } else if (!this.canBoatInFluid(this.level().getFluidState(this.blockPosition().below())) && p_38307_ < 0.0D) { - this.fallDistance -= (float)p_38307_; - } - } -@@ -871,7 +_,7 @@ - - @Override - protected boolean canAddPassenger(Entity p_38390_) { -- return this.getPassengers().size() < this.getMaxPassengers() && !this.isEyeInFluid(FluidTags.WATER); -+ return this.getPassengers().size() < this.getMaxPassengers() && !this.canBoatInFluid(this.getEyeInFluidType()); - } - - protected int getMaxPassengers() { -@@ -914,7 +_,9 @@ - IN_AIR; - } - -- public static enum Type implements StringRepresentable { -+ @net.neoforged.fml.common.asm.enumextension.NamedEnum(1) -+ @net.neoforged.fml.common.asm.enumextension.NetworkedEnum(net.neoforged.fml.common.asm.enumextension.NetworkedEnum.NetworkCheck.CLIENTBOUND) -+ public static enum Type implements StringRepresentable, net.neoforged.fml.common.asm.enumextension.IExtensibleEnum { - OAK(Blocks.OAK_PLANKS, "oak"), - SPRUCE(Blocks.SPRUCE_PLANKS, "spruce"), - BIRCH(Blocks.BIRCH_PLANKS, "birch"), -@@ -923,16 +_,59 @@ - CHERRY(Blocks.CHERRY_PLANKS, "cherry"), - DARK_OAK(Blocks.DARK_OAK_PLANKS, "dark_oak"), - MANGROVE(Blocks.MANGROVE_PLANKS, "mangrove"), -- BAMBOO(Blocks.BAMBOO_PLANKS, "bamboo"); -+ BAMBOO(Blocks.BAMBOO_PLANKS, "bamboo", true); - - private final String name; -+ /** @deprecated Neo: Will be {@link Blocks#AIR} for modded boat types, use {@link #planksSupplier} instead */ -+ @Deprecated - private final Block planks; -+ private final java.util.function.Supplier planksSupplier; -+ final java.util.function.Supplier boatItem; -+ final java.util.function.Supplier chestBoatItem; -+ private final java.util.function.Supplier stickItem; -+ private final boolean raft; - public static final StringRepresentable.EnumCodec CODEC = StringRepresentable.fromEnum(Boat.Type::values); - private static final IntFunction BY_ID = ByIdMap.continuous(Enum::ordinal, values(), ByIdMap.OutOfBoundsStrategy.ZERO); - -+ @net.neoforged.fml.common.asm.enumextension.ReservedConstructor - private Type(Block p_38427_, String p_38428_) { -+ this(p_38427_, p_38428_, false); -+ } -+ -+ @net.neoforged.fml.common.asm.enumextension.ReservedConstructor -+ private Type(Block p_38427_, String p_38428_, boolean raft) { - this.name = p_38428_; - this.planks = p_38427_; -+ this.planksSupplier = () -> p_38427_; -+ this.boatItem = () -> Items.AIR; -+ this.chestBoatItem = () -> Items.AIR; -+ this.stickItem = () -> Items.STICK; -+ this.raft = raft; -+ } -+ -+ /** -+ * @param planks A supplier of the block to be dropped when the boat is destroyed by fall damage -+ * @param name The name of this boat type -+ * @param boatItem A supplier of the item to be dropped when a normal boat or raft of this type is picked up -+ * @param chestBoatItem A supplier of the item to be dropped when a chest boat or raft of this type is picked up -+ * @param stickItem A supplier of the stick item to be dropped when the boat is destroyed by fall damage -+ * @param raft Whether this boat type is a "standard" boat or a raft -+ */ -+ private Type( -+ java.util.function.Supplier planks, -+ String name, -+ java.util.function.Supplier boatItem, -+ java.util.function.Supplier chestBoatItem, -+ java.util.function.Supplier stickItem, -+ boolean raft -+ ) { -+ this.name = name; -+ this.planks = Blocks.AIR; -+ this.planksSupplier = planks; -+ this.boatItem = boatItem; -+ this.chestBoatItem = chestBoatItem; -+ this.stickItem = stickItem; -+ this.raft = raft; - } - - @Override -@@ -945,7 +_,15 @@ - } - - public Block getPlanks() { -- return this.planks; -+ return this.planksSupplier.get(); -+ } -+ -+ public Item getSticks() { -+ return this.stickItem.get(); -+ } -+ -+ public boolean isRaft() { -+ return this.raft; - } - - @Override -@@ -959,6 +_,10 @@ - - public static Boat.Type byName(String p_38433_) { - return CODEC.byName(p_38433_, OAK); -+ } -+ -+ public static net.neoforged.fml.common.asm.enumextension.ExtensionInfo getExtensionInfo() { -+ return net.neoforged.fml.common.asm.enumextension.ExtensionInfo.nonExtended(Boat.Type.class); - } - } - } diff --git a/patches/net/minecraft/world/entity/vehicle/ChestBoat.java.patch b/patches/net/minecraft/world/entity/vehicle/ChestBoat.java.patch deleted file mode 100644 index 97fcd4d1aa..0000000000 --- a/patches/net/minecraft/world/entity/vehicle/ChestBoat.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/net/minecraft/world/entity/vehicle/ChestBoat.java -+++ b/net/minecraft/world/entity/vehicle/ChestBoat.java -@@ -122,7 +_,8 @@ - case DARK_OAK -> Items.DARK_OAK_CHEST_BOAT; - case MANGROVE -> Items.MANGROVE_CHEST_BOAT; - case BAMBOO -> Items.BAMBOO_CHEST_RAFT; -- default -> Items.OAK_CHEST_BOAT; -+ case OAK -> Items.OAK_CHEST_BOAT; -+ default -> this.getVariant().chestBoatItem.get(); - }; - } - diff --git a/patches/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch b/patches/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch index 43ebd7d918..1b7edd673f 100644 --- a/patches/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch +++ b/patches/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/world/entity/vehicle/ContainerEntity.java +++ b/net/minecraft/world/entity/vehicle/ContainerEntity.java -@@ -107,6 +_,9 @@ +@@ -105,6 +_,9 @@ - this.setLootTable(null); + this.setContainerLootTable(null); LootParams.Builder lootparams$builder = new LootParams.Builder((ServerLevel)this.level()).withParameter(LootContextParams.ORIGIN, this.position()); + // Neo: set the chest to attacking_entity for loot context. + if (this instanceof AbstractMinecartContainer entityContainer) diff --git a/patches/net/minecraft/world/entity/vehicle/Minecart.java.patch b/patches/net/minecraft/world/entity/vehicle/Minecart.java.patch index dcdbc9be2f..8a977d39af 100644 --- a/patches/net/minecraft/world/entity/vehicle/Minecart.java.patch +++ b/patches/net/minecraft/world/entity/vehicle/Minecart.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/entity/vehicle/Minecart.java +++ b/net/minecraft/world/entity/vehicle/Minecart.java -@@ -19,6 +_,8 @@ +@@ -22,6 +_,8 @@ @Override public InteractionResult interact(Player p_38483_, InteractionHand p_38484_) { + InteractionResult ret = super.interact(p_38483_, p_38484_); + if (ret.consumesAction()) return ret; - if (p_38483_.isSecondaryUseActive()) { - return InteractionResult.PASS; - } else if (this.isVehicle()) { + if (!p_38483_.isSecondaryUseActive() && !this.isVehicle() && (this.level().isClientSide || p_38483_.startRiding(this))) { + this.playerRotationOffset = this.rotationOffset; + if (!this.level().isClientSide) { diff --git a/patches/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch b/patches/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch index fa2e6954e2..febb3543af 100644 --- a/patches/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch +++ b/patches/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java +++ b/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java -@@ -85,6 +_,8 @@ +@@ -82,6 +_,8 @@ @Override public InteractionResult interact(Player p_38522_, InteractionHand p_38523_) { diff --git a/patches/net/minecraft/world/entity/vehicle/MinecartFurnace.java.patch b/patches/net/minecraft/world/entity/vehicle/MinecartFurnace.java.patch index 2d4d876d57..08ca00da50 100644 --- a/patches/net/minecraft/world/entity/vehicle/MinecartFurnace.java.patch +++ b/patches/net/minecraft/world/entity/vehicle/MinecartFurnace.java.patch @@ -1,23 +1,11 @@ --- a/net/minecraft/world/entity/vehicle/MinecartFurnace.java +++ b/net/minecraft/world/entity/vehicle/MinecartFurnace.java -@@ -116,6 +_,8 @@ +@@ -104,6 +_,8 @@ @Override public InteractionResult interact(Player p_38562_, InteractionHand p_38563_) { + InteractionResult ret = super.interact(p_38562_, p_38563_); + if (ret.consumesAction()) return ret; ItemStack itemstack = p_38562_.getItemInHand(p_38563_); - if (INGREDIENT.test(itemstack) && this.fuel + 3600 <= 32000) { + if (itemstack.is(ItemTags.FURNACE_MINECART_FUEL) && this.fuel + 3600 <= 32000) { itemstack.consume(1, p_38562_); -@@ -128,6 +_,11 @@ - } - - return InteractionResult.sidedSuccess(this.level().isClientSide); -+ } -+ -+ @Override -+ public float getMaxCartSpeedOnRail() { -+ return 0.2f; - } - - @Override diff --git a/patches/net/minecraft/world/entity/vehicle/MinecartSpawner.java.patch b/patches/net/minecraft/world/entity/vehicle/MinecartSpawner.java.patch index 4a73b0baf6..253ad729aa 100644 --- a/patches/net/minecraft/world/entity/vehicle/MinecartSpawner.java.patch +++ b/patches/net/minecraft/world/entity/vehicle/MinecartSpawner.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/MinecartSpawner.java +++ b/net/minecraft/world/entity/vehicle/MinecartSpawner.java -@@ -17,6 +_,11 @@ +@@ -18,6 +_,11 @@ public void broadcastEvent(Level p_150342_, BlockPos p_150343_, int p_150344_) { p_150342_.broadcastEntityEvent(MinecartSpawner.this, (byte)p_150344_); } diff --git a/patches/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java.patch b/patches/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java.patch new file mode 100644 index 0000000000..999ad24235 --- /dev/null +++ b/patches/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java.patch @@ -0,0 +1,57 @@ +--- a/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java ++++ b/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java +@@ -170,7 +_,7 @@ + + public void adjustToRails(BlockPos p_360495_, BlockState p_362772_, boolean p_366683_) { + if (BaseRailBlock.isRail(p_362772_)) { +- RailShape railshape = p_362772_.getValue(((BaseRailBlock)p_362772_.getBlock()).getShapeProperty()); ++ RailShape railshape = ((BaseRailBlock)p_362772_.getBlock()).getRailDirection(p_362772_, this.level(), p_360495_, this.minecart); + Pair pair = AbstractMinecart.exits(railshape); + Vec3 vec3 = new Vec3(pair.getFirst()).scale(0.5); + Vec3 vec31 = new Vec3(pair.getSecond()).scale(0.5); +@@ -258,11 +_,11 @@ + if (flag) { + this.minecart.resetFallDistance(); + this.minecart.setOldPosAndRot(); +- if (blockstate.is(Blocks.ACTIVATOR_RAIL)) { ++ if (blockstate.getBlock() instanceof PoweredRailBlock poweredRail && poweredRail.isActivatorRail()) { + this.minecart.activateMinecart(blockpos.getX(), blockpos.getY(), blockpos.getZ(), blockstate.getValue(PoweredRailBlock.POWERED)); + } + +- RailShape railshape = blockstate.getValue(((BaseRailBlock)blockstate.getBlock()).getShapeProperty()); ++ RailShape railshape = ((BaseRailBlock)blockstate.getBlock()).getRailDirection(blockstate, this.level(), blockpos, this.minecart);; + Vec3 vec31 = this.calculateTrackSpeed(p_376236_, vec3.horizontal(), newminecartbehavior$trackiteration, blockpos, blockstate, railshape); + if (newminecartbehavior$trackiteration.firstIteration) { + newminecartbehavior$trackiteration.movementLeft = vec31.horizontalDistance(); +@@ -393,7 +_,7 @@ + } + + private Vec3 calculateHaltTrackSpeed(Vec3 p_360517_, BlockState p_362923_) { +- if (p_362923_.is(Blocks.POWERED_RAIL) && !p_362923_.getValue(PoweredRailBlock.POWERED)) { ++ if (p_362923_.getBlock() instanceof PoweredRailBlock poweredRail && !poweredRail.isActivatorRail() && !p_362923_.getValue(PoweredRailBlock.POWERED)) { + return p_360517_.length() < 0.03 ? Vec3.ZERO : p_360517_.scale(0.5); + } else { + return p_360517_; +@@ -401,7 +_,7 @@ + } + + private Vec3 calculateBoostTrackSpeed(Vec3 p_363053_, BlockPos p_361792_, BlockState p_361859_) { +- if (p_361859_.is(Blocks.POWERED_RAIL) && p_361859_.getValue(PoweredRailBlock.POWERED)) { ++ if (p_361859_.getBlock() instanceof PoweredRailBlock poweredRail && !poweredRail.isActivatorRail() && p_361859_.getValue(PoweredRailBlock.POWERED)) { + if (p_363053_.length() > 0.01) { + return p_363053_.normalize().scale(p_363053_.length() + 0.06); + } else { +@@ -450,10 +_,11 @@ + } + + this.minecart.move(MoverType.SELF, vec36.subtract(vec3)); +- BlockState blockstate = this.level().getBlockState(BlockPos.containing(vec36)); ++ BlockPos railPos = BlockPos.containing(vec36); ++ BlockState blockstate = this.level().getBlockState(railPos); + if (flag) { + if (BaseRailBlock.isRail(blockstate)) { +- RailShape railshape = blockstate.getValue(((BaseRailBlock)blockstate.getBlock()).getShapeProperty()); ++ RailShape railshape = ((BaseRailBlock)blockstate.getBlock()).getRailDirection(blockstate, this.level(), railPos, this.minecart);; + if (this.restAtVShape(p_361660_, railshape)) { + return 0.0; + } diff --git a/patches/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java.patch b/patches/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java.patch new file mode 100644 index 0000000000..0e5d4fb6b5 --- /dev/null +++ b/patches/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java.patch @@ -0,0 +1,55 @@ +--- a/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java ++++ b/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java +@@ -97,7 +_,7 @@ + this.minecart.setOnRails($$4); + if ($$4) { + this.moveAlongTrack(serverlevel); +- if (blockstate.is(Blocks.ACTIVATOR_RAIL)) { ++ if (blockstate.getBlock() instanceof PoweredRailBlock poweredRail && poweredRail.isActivatorRail()) { + this.minecart.activateMinecart(blockpos.getX(), blockpos.getY(), blockpos.getZ(), blockstate.getValue(PoweredRailBlock.POWERED)); + } + } else { +@@ -149,7 +_,7 @@ + d1 = (double)blockpos.getY(); + boolean flag = false; + boolean flag1 = false; +- if (blockstate.is(Blocks.POWERED_RAIL)) { ++ if (blockstate.getBlock() instanceof PoweredRailBlock poweredRail && !poweredRail.isActivatorRail()) { + flag = blockstate.getValue(PoweredRailBlock.POWERED); + flag1 = !flag; + } +@@ -160,7 +_,7 @@ + } + + Vec3 vec31 = this.getDeltaMovement(); +- RailShape railshape = blockstate.getValue(((BaseRailBlock)blockstate.getBlock()).getShapeProperty()); ++ RailShape railshape = ((BaseRailBlock)blockstate.getBlock()).getRailDirection(blockstate, this.level(), blockpos, this.minecart);; + switch (railshape) { + case ASCENDING_EAST: + this.setDeltaMovement(vec31.add(-d3, 0.0, 0.0)); +@@ -318,9 +_,10 @@ + j--; + } + +- BlockState blockstate = this.level().getBlockState(new BlockPos(i, j, k)); ++ BlockPos railPos = new BlockPos(i, j, k); ++ BlockState blockstate = this.level().getBlockState(railPos); + if (BaseRailBlock.isRail(blockstate)) { +- RailShape railshape = blockstate.getValue(((BaseRailBlock)blockstate.getBlock()).getShapeProperty()); ++ RailShape railshape = ((BaseRailBlock)blockstate.getBlock()).getRailDirection(blockstate, this.level(), railPos, this.minecart); + p_363435_ = (double)j; + if (railshape.isSlope()) { + p_363435_ = (double)(j + 1); +@@ -357,9 +_,10 @@ + j--; + } + +- BlockState blockstate = this.level().getBlockState(new BlockPos(i, j, k)); ++ BlockPos railPos = new BlockPos(i, j, k); ++ BlockState blockstate = this.level().getBlockState(railPos); + if (BaseRailBlock.isRail(blockstate)) { +- RailShape railshape = blockstate.getValue(((BaseRailBlock)blockstate.getBlock()).getShapeProperty()); ++ RailShape railshape = ((BaseRailBlock)blockstate.getBlock()).getRailDirection(blockstate, this.level(), railPos, this.minecart); + Pair pair = AbstractMinecart.exits(railshape); + Vec3i vec3i = pair.getFirst(); + Vec3i vec3i1 = pair.getSecond(); diff --git a/patches/net/minecraft/world/food/FoodProperties.java.patch b/patches/net/minecraft/world/food/FoodProperties.java.patch deleted file mode 100644 index feb3b0712a..0000000000 --- a/patches/net/minecraft/world/food/FoodProperties.java.patch +++ /dev/null @@ -1,67 +0,0 @@ ---- a/net/minecraft/world/food/FoodProperties.java -+++ b/net/minecraft/world/food/FoodProperties.java -@@ -49,6 +_,22 @@ - return (int)(this.eatSeconds * 20.0F); - } - -+ public boolean equals(Object otherObject) {// Neo: Fix MC-272643 -+ if(otherObject == this) return true; -+ if (!(otherObject instanceof FoodProperties other)) return false; -+ boolean ans = nutrition == other.nutrition && -+ saturation == other.saturation && -+ canAlwaysEat == other.canAlwaysEat && -+ eatSeconds == other.eatSeconds; -+ if (!ans) return false; -+ if (!effects.equals(other.effects)) return false; -+ ItemStack selfContainer = usingConvertsTo.orElse(null); -+ ItemStack otherContainer = other.usingConvertsTo.orElse(null); -+ if (selfContainer == otherContainer) return true; -+ if (selfContainer == null || otherContainer == null) return false; -+ return selfContainer.getCount() == otherContainer.getCount() && ItemStack.isSameItemSameComponents(selfContainer, otherContainer); -+ } -+ - public static class Builder { - private int nutrition; - private float saturationModifier; -@@ -77,11 +_,18 @@ - return this; - } - -+ // Neo: Use supplier method instead -+ @Deprecated - public FoodProperties.Builder effect(MobEffectInstance p_38763_, float p_38764_) { - this.effects.add(new FoodProperties.PossibleEffect(p_38763_, p_38764_)); - return this; - } - -+ public FoodProperties.Builder effect(java.util.function.Supplier effectIn, float probability) { -+ this.effects.add(new FoodProperties.PossibleEffect(effectIn, probability)); -+ return this; -+ } -+ - public FoodProperties.Builder usingConvertsTo(ItemLike p_347650_) { - this.usingConvertsTo = Optional.of(new ItemStack(p_347650_)); - return this; -@@ -93,7 +_,7 @@ - } - } - -- public static record PossibleEffect(MobEffectInstance effect, float probability) { -+ public static record PossibleEffect(java.util.function.Supplier effectSupplier, float probability) { - public static final Codec CODEC = RecordCodecBuilder.create( - p_337893_ -> p_337893_.group( - MobEffectInstance.CODEC.fieldOf("effect").forGetter(FoodProperties.PossibleEffect::effect), -@@ -109,8 +_,12 @@ - FoodProperties.PossibleEffect::new - ); - -+ private PossibleEffect(MobEffectInstance effect, float probability) { -+ this(() -> effect, probability); -+ } -+ - public MobEffectInstance effect() { -- return new MobEffectInstance(this.effect); -+ return new MobEffectInstance(this.effectSupplier.get()); - } - } - } diff --git a/patches/net/minecraft/world/inventory/AbstractContainerMenu.java.patch b/patches/net/minecraft/world/inventory/AbstractContainerMenu.java.patch index 5840b2258f..d23a1d7689 100644 --- a/patches/net/minecraft/world/inventory/AbstractContainerMenu.java.patch +++ b/patches/net/minecraft/world/inventory/AbstractContainerMenu.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/net/minecraft/world/inventory/AbstractContainerMenu.java -@@ -511,6 +_,11 @@ +@@ -559,6 +_,11 @@ } private boolean tryItemClickBehaviourOverride(Player p_249615_, ClickAction p_250300_, Slot p_249384_, ItemStack p_251073_, ItemStack p_252026_) { diff --git a/patches/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch b/patches/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch index aa475430e7..9581ed49d1 100644 --- a/patches/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch +++ b/patches/net/minecraft/world/inventory/AbstractFurnaceMenu.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/inventory/AbstractFurnaceMenu.java +++ b/net/minecraft/world/inventory/AbstractFurnaceMenu.java -@@ -167,7 +_,7 @@ +@@ -142,7 +_,7 @@ } protected boolean isFuel(ItemStack p_38989_) { -- return AbstractFurnaceBlockEntity.isFuel(p_38989_); -+ return p_38989_.getBurnTime(this.recipeType) > 0; +- return this.level.fuelValues().isFuel(p_38989_); ++ return p_38989_.getBurnTime(this.recipeType, this.level.fuelValues()) > 0; } public float getBurnProgress() { diff --git a/patches/net/minecraft/world/inventory/AnvilMenu.java.patch b/patches/net/minecraft/world/inventory/AnvilMenu.java.patch index 255c825995..f8446bf46c 100644 --- a/patches/net/minecraft/world/inventory/AnvilMenu.java.patch +++ b/patches/net/minecraft/world/inventory/AnvilMenu.java.patch @@ -6,11 +6,11 @@ + float breakChance = net.neoforged.neoforge.common.CommonHooks.onAnvilRepair(p_150474_, p_150475_, AnvilMenu.this.inputSlots.getItem(0), AnvilMenu.this.inputSlots.getItem(1)); + - this.inputSlots.setItem(0, ItemStack.EMPTY); if (this.repairItemCountCost > 0) { ItemStack itemstack = this.inputSlots.getItem(1); + if (!itemstack.isEmpty() && itemstack.getCount() > this.repairItemCountCost) { @@ -95,7 +_,7 @@ - this.cost.set(0); + this.inputSlots.setItem(0, ItemStack.EMPTY); this.access.execute((p_150479_, p_150480_) -> { BlockState blockstate = p_150479_.getBlockState(p_150480_); - if (!p_150474_.hasInfiniteMaterials() && blockstate.is(BlockTags.ANVIL) && p_150474_.getRandom().nextFloat() < 0.12F) { @@ -18,7 +18,7 @@ BlockState blockstate1 = AnvilBlock.damage(blockstate); if (blockstate1 == null) { p_150479_.removeBlock(p_150480_, false); -@@ -124,8 +_,10 @@ +@@ -125,8 +_,10 @@ j += (long)itemstack.getOrDefault(DataComponents.REPAIR_COST, Integer.valueOf(0)).intValue() + (long)itemstack2.getOrDefault(DataComponents.REPAIR_COST, Integer.valueOf(0)).intValue(); this.repairItemCountCost = 0; @@ -27,10 +27,10 @@ if (!itemstack2.isEmpty()) { - boolean flag = itemstack2.has(DataComponents.STORED_ENCHANTMENTS); + flag = itemstack2.has(DataComponents.STORED_ENCHANTMENTS); - if (itemstack1.isDamageableItem() && itemstack1.getItem().isValidRepairItem(itemstack, itemstack2)) { + if (itemstack1.isDamageableItem() && itemstack.isValidRepairItem(itemstack2)) { int l2 = Math.min(itemstack1.getDamageValue(), itemstack1.getMaxDamage() / 4); if (l2 <= 0) { -@@ -176,8 +_,10 @@ +@@ -177,8 +_,10 @@ int j2 = entry.getIntValue(); j2 = i2 == j2 ? j2 + 1 : Math.max(j2, i2); Enchantment enchantment = holder.value(); @@ -43,15 +43,15 @@ flag1 = true; } -@@ -228,6 +_,7 @@ +@@ -229,6 +_,7 @@ i += k; itemstack1.remove(DataComponents.CUSTOM_NAME); } + if (flag && !itemstack1.isBookEnchantable(itemstack2)) itemstack1 = ItemStack.EMPTY; - int k2 = (int)Mth.clamp(j + (long)i, 0L, 2147483647L); + int k2 = i <= 0 ? 0 : (int)Mth.clamp(j + (long)i, 0L, 2147483647L); this.cost.set(k2); -@@ -297,5 +_,12 @@ +@@ -302,5 +_,12 @@ public int getCost() { return this.cost.get(); diff --git a/patches/net/minecraft/world/inventory/BeaconMenu.java.patch b/patches/net/minecraft/world/inventory/BeaconMenu.java.patch index 8df10e8f26..9c42af6e5a 100644 --- a/patches/net/minecraft/world/inventory/BeaconMenu.java.patch +++ b/patches/net/minecraft/world/inventory/BeaconMenu.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/BeaconMenu.java +++ b/net/minecraft/world/inventory/BeaconMenu.java -@@ -98,10 +_,8 @@ +@@ -87,10 +_,8 @@ } slot.onQuickCraft(itemstack1, itemstack); diff --git a/patches/net/minecraft/world/inventory/BrewingStandMenu.java.patch b/patches/net/minecraft/world/inventory/BrewingStandMenu.java.patch index 9b9d7142ef..f562eb3218 100644 --- a/patches/net/minecraft/world/inventory/BrewingStandMenu.java.patch +++ b/patches/net/minecraft/world/inventory/BrewingStandMenu.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/BrewingStandMenu.java +++ b/net/minecraft/world/inventory/BrewingStandMenu.java -@@ -41,9 +_,9 @@ +@@ -42,9 +_,9 @@ this.brewingStand = p_39095_; this.brewingStandData = p_39096_; PotionBrewing potionbrewing = p_39094_.player.level().potionBrewing(); @@ -13,7 +13,7 @@ this.ingredientSlot = this.addSlot(new BrewingStandMenu.IngredientsSlot(potionbrewing, p_39095_, 3, 79, 17)); this.addSlot(new BrewingStandMenu.FuelSlot(p_39095_, 4, 17, 17)); this.addDataSlots(p_39096_); -@@ -81,7 +_,7 @@ +@@ -73,7 +_,7 @@ if (!this.moveItemStackTo(itemstack1, 3, 4, false)) { return ItemStack.EMPTY; } @@ -22,7 +22,7 @@ if (!this.moveItemStackTo(itemstack1, 0, 3, false)) { return ItemStack.EMPTY; } -@@ -158,13 +_,20 @@ +@@ -150,13 +_,20 @@ } static class PotionSlot extends Slot { @@ -44,7 +44,7 @@ } @Override -@@ -176,14 +_,20 @@ +@@ -168,14 +_,20 @@ public void onTake(Player p_150499_, ItemStack p_150500_) { Optional> optional = p_150500_.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY).potion(); if (optional.isPresent() && p_150499_ instanceof ServerPlayer serverplayer) { diff --git a/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch b/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch index 817bb84ff8..a60216de04 100644 --- a/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch +++ b/patches/net/minecraft/world/inventory/EnchantmentMenu.java.patch @@ -9,10 +9,10 @@ } @Override -@@ -101,23 +_,24 @@ +@@ -91,23 +_,24 @@ if (!itemstack.isEmpty() && itemstack.isEnchantable()) { this.access.execute((p_344366_, p_344367_) -> { - IdMap> idmap = p_344366_.registryAccess().registryOrThrow(Registries.ENCHANTMENT).asHolderIdMap(); + IdMap> idmap = p_344366_.registryAccess().lookupOrThrow(Registries.ENCHANTMENT).asHolderIdMap(); - int j = 0; + float j = 0; @@ -37,7 +37,7 @@ } for (int l = 0; l < 3; l++) { -@@ -163,14 +_,10 @@ +@@ -153,14 +_,10 @@ List list = this.getEnchantmentList(p_347276_.registryAccess(), itemstack, p_39466_, this.costs[p_39466_]); if (!list.isEmpty()) { p_39465_.onEnchantmentPerformed(itemstack, i); @@ -56,7 +56,7 @@ itemstack1.consume(i, p_39465_); if (itemstack1.isEmpty()) { -@@ -249,7 +_,7 @@ +@@ -239,7 +_,7 @@ if (!this.moveItemStackTo(itemstack1, 2, 38, true)) { return ItemStack.EMPTY; } diff --git a/patches/net/minecraft/world/inventory/GrindstoneMenu.java.patch b/patches/net/minecraft/world/inventory/GrindstoneMenu.java.patch index 9c769897c2..fce1cf6462 100644 --- a/patches/net/minecraft/world/inventory/GrindstoneMenu.java.patch +++ b/patches/net/minecraft/world/inventory/GrindstoneMenu.java.patch @@ -37,10 +37,10 @@ private int getExperienceAmount(Level p_39632_) { + if (xp > -1) return xp; - int l = 0; - l += this.getExperienceFromItem(GrindstoneMenu.this.repairSlots.getItem(0)); - l += this.getExperienceFromItem(GrindstoneMenu.this.repairSlots.getItem(1)); -@@ -125,6 +_,8 @@ + int i = 0; + i += this.getExperienceFromItem(GrindstoneMenu.this.repairSlots.getItem(0)); + i += this.getExperienceFromItem(GrindstoneMenu.this.repairSlots.getItem(1)); +@@ -116,6 +_,8 @@ } private void createResult() { @@ -49,7 +49,7 @@ this.resultSlots.setItem(0, this.computeResult(this.repairSlots.getItem(0), this.repairSlots.getItem(1))); this.broadcastChanges(); } -@@ -155,7 +_,7 @@ +@@ -146,7 +_,7 @@ int k = p_332686_.getMaxDamage() - p_332686_.getDamageValue(); int l = j + k + i * 5 / 100; int i1 = 1; @@ -58,7 +58,7 @@ if (p_332723_.getMaxStackSize() < 2 || !ItemStack.matches(p_332723_, p_332686_)) { return ItemStack.EMPTY; } -@@ -167,6 +_,7 @@ +@@ -158,6 +_,7 @@ if (itemstack.isDamageableItem()) { itemstack.set(DataComponents.MAX_DAMAGE, i); itemstack.setDamageValue(Math.max(i - l, 0)); diff --git a/patches/net/minecraft/world/inventory/RecipeBookMenu.java.patch b/patches/net/minecraft/world/inventory/RecipeBookMenu.java.patch deleted file mode 100644 index c9e4cd5ce6..0000000000 --- a/patches/net/minecraft/world/inventory/RecipeBookMenu.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/net/minecraft/world/inventory/RecipeBookMenu.java -+++ b/net/minecraft/world/inventory/RecipeBookMenu.java -@@ -43,6 +_,10 @@ - - public abstract int getSize(); - -+ public java.util.List getRecipeBookCategories() { -+ return net.minecraft.client.RecipeBookCategories.getCategories(this.getRecipeBookType()); -+ } -+ - public abstract RecipeBookType getRecipeBookType(); - - public abstract boolean shouldMoveToInventory(int p_150635_); diff --git a/patches/net/minecraft/world/inventory/ResultSlot.java.patch b/patches/net/minecraft/world/inventory/ResultSlot.java.patch index 19f87b4820..4f84a5e0a2 100644 --- a/patches/net/minecraft/world/inventory/ResultSlot.java.patch +++ b/patches/net/minecraft/world/inventory/ResultSlot.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/ResultSlot.java +++ b/net/minecraft/world/inventory/ResultSlot.java -@@ -47,6 +_,7 @@ +@@ -51,6 +_,7 @@ protected void checkTakeAchievements(ItemStack p_40185_) { if (this.removeCount > 0) { p_40185_.onCraftedBy(this.player.level(), this.player, this.removeCount); @@ -8,12 +8,12 @@ } if (this.container instanceof RecipeCraftingHolder recipecraftingholder) { -@@ -63,7 +_,9 @@ +@@ -86,7 +_,9 @@ CraftingInput craftinginput = craftinginput$positioned.input(); int i = craftinginput$positioned.left(); int j = craftinginput$positioned.top(); + net.neoforged.neoforge.common.CommonHooks.setCraftingPlayer(p_150638_); - NonNullList nonnulllist = p_150638_.level().getRecipeManager().getRemainingItemsFor(RecipeType.CRAFTING, craftinginput, p_150638_.level()); + NonNullList nonnulllist = this.getRemainingItems(craftinginput, p_150638_.level()); + net.neoforged.neoforge.common.CommonHooks.setCraftingPlayer(null); for (int k = 0; k < craftinginput.height(); k++) { diff --git a/patches/net/minecraft/world/item/ArmorItem.java.patch b/patches/net/minecraft/world/item/ArmorItem.java.patch deleted file mode 100644 index 5f30afe02d..0000000000 --- a/patches/net/minecraft/world/item/ArmorItem.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/item/ArmorItem.java -+++ b/net/minecraft/world/item/ArmorItem.java -@@ -49,6 +_,8 @@ - } else { - LivingEntity livingentity = list.get(0); - EquipmentSlot equipmentslot = livingentity.getEquipmentSlotForItem(p_40400_); -+ // Neo: Respect IItemExtension#canEquip in dispenseArmor -+ if (!p_40400_.canEquip(equipmentslot, livingentity)) return false; - ItemStack itemstack = p_40400_.split(1); - livingentity.setItemSlot(equipmentslot, itemstack); - if (livingentity instanceof Mob) { diff --git a/patches/net/minecraft/world/item/AxeItem.java.patch b/patches/net/minecraft/world/item/AxeItem.java.patch index 9f9732d1ac..1edab2016b 100644 --- a/patches/net/minecraft/world/item/AxeItem.java.patch +++ b/patches/net/minecraft/world/item/AxeItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/AxeItem.java +++ b/net/minecraft/world/item/AxeItem.java -@@ -60,7 +_,7 @@ +@@ -62,7 +_,7 @@ if (playerHasShieldUseIntent(p_40529_)) { return InteractionResult.PASS; } else { @@ -9,7 +9,7 @@ if (optional.isEmpty()) { return InteractionResult.PASS; } else { -@@ -85,20 +_,19 @@ +@@ -87,20 +_,19 @@ return p_345141_.getHand().equals(InteractionHand.MAIN_HAND) && player.getOffhandItem().is(Items.SHIELD) && !player.isSecondaryUseActive(); } @@ -34,7 +34,7 @@ if (optional2.isPresent()) { p_308922_.playSound(p_309192_, p_308899_, SoundEvents.AXE_WAX_OFF, SoundSource.BLOCKS, 1.0F, 1.0F); p_308922_.levelEvent(p_309192_, 3004, p_308899_, 0); -@@ -110,8 +_,19 @@ +@@ -112,8 +_,19 @@ } } @@ -46,7 +46,7 @@ + private Optional getStripped(BlockState p_150691_) { return Optional.ofNullable(STRIPPABLES.get(p_150691_.getBlock())) - .map(p_150689_ -> p_150689_.defaultBlockState().setValue(RotatedPillarBlock.AXIS, p_150691_.getValue(RotatedPillarBlock.AXIS))); + .map(p_360012_ -> p_360012_.defaultBlockState().setValue(RotatedPillarBlock.AXIS, p_150691_.getValue(RotatedPillarBlock.AXIS))); + } + + @Override diff --git a/patches/net/minecraft/world/item/BlockItem.java.patch b/patches/net/minecraft/world/item/BlockItem.java.patch index eed7cf8eb1..95447e9649 100644 --- a/patches/net/minecraft/world/item/BlockItem.java.patch +++ b/patches/net/minecraft/world/item/BlockItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/BlockItem.java +++ b/net/minecraft/world/item/BlockItem.java -@@ -82,11 +_,11 @@ +@@ -79,11 +_,11 @@ } } @@ -14,33 +14,18 @@ SoundSource.BLOCKS, (soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F -@@ -99,10 +_,16 @@ +@@ -96,8 +_,14 @@ } } + @Deprecated //Forge: Use more sensitive version {@link BlockItem#getPlaceSound(BlockState, IBlockReader, BlockPos, Entity) } protected SoundEvent getPlaceSound(BlockState p_40588_) { return p_40588_.getSoundType().getPlaceSound(); - } - ++ } ++ + //Forge: Sensitive version of BlockItem#getPlaceSound + protected SoundEvent getPlaceSound(BlockState state, Level world, BlockPos pos, Player entity) { + return state.getSoundType(world, pos, entity).getPlaceSound(); -+ } -+ - @Nullable - public BlockPlaceContext updatePlacementContext(BlockPlaceContext p_40609_) { - return p_40609_; -@@ -193,6 +_,12 @@ - - public void registerBlocks(Map p_40607_, Item p_40608_) { - p_40607_.put(this.getBlock(), p_40608_); -+ } -+ -+ /** @deprecated Neo: To be removed without replacement since registry replacement is not a feature anymore. */ -+ @Deprecated(forRemoval = true, since = "1.21.1") -+ public void removeFromBlockToItemMap(Map blockToItemMap, Item itemIn) { -+ blockToItemMap.remove(this.getBlock()); } - @Override + @Nullable diff --git a/patches/net/minecraft/world/item/BowItem.java.patch b/patches/net/minecraft/world/item/BowItem.java.patch index 88e532ec9c..0264038cb5 100644 --- a/patches/net/minecraft/world/item/BowItem.java.patch +++ b/patches/net/minecraft/world/item/BowItem.java.patch @@ -1,22 +1,22 @@ --- a/net/minecraft/world/item/BowItem.java +++ b/net/minecraft/world/item/BowItem.java -@@ -28,6 +_,8 @@ - ItemStack itemstack = player.getProjectile(p_40667_); - if (!itemstack.isEmpty()) { +@@ -32,6 +_,8 @@ + return false; + } else { int i = this.getUseDuration(p_40667_, p_40669_) - p_40670_; + i = net.neoforged.neoforge.event.EventHooks.onArrowLoose(p_40667_, p_40668_, player, i, !itemstack.isEmpty()); -+ if (i < 0) return; ++ if (i < 0) return false; float f = getPowerForTime(i); - if (!((double)f < 0.1)) { - List list = draw(p_40667_, itemstack, player); -@@ -82,6 +_,10 @@ - public InteractionResultHolder use(Level p_40672_, Player p_40673_, InteractionHand p_40674_) { + if ((double)f < 0.1) { + return false; +@@ -89,6 +_,10 @@ + public InteractionResult use(Level p_40672_, Player p_40673_, InteractionHand p_40674_) { ItemStack itemstack = p_40673_.getItemInHand(p_40674_); boolean flag = !p_40673_.getProjectile(itemstack).isEmpty(); + -+ InteractionResultHolder ret = net.neoforged.neoforge.event.EventHooks.onArrowNock(itemstack, p_40672_, p_40673_, p_40674_, flag); ++ InteractionResult ret = net.neoforged.neoforge.event.EventHooks.onArrowNock(itemstack, p_40672_, p_40673_, p_40674_, flag); + if (ret != null) return ret; + if (!p_40673_.hasInfiniteMaterials() && !flag) { - return InteractionResultHolder.fail(itemstack); + return InteractionResult.FAIL; } else { diff --git a/patches/net/minecraft/world/item/BrushItem.java.patch b/patches/net/minecraft/world/item/BrushItem.java.patch index 34e228180c..7b051f9c2b 100644 --- a/patches/net/minecraft/world/item/BrushItem.java.patch +++ b/patches/net/minecraft/world/item/BrushItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/BrushItem.java +++ b/net/minecraft/world/item/BrushItem.java -@@ -142,4 +_,9 @@ +@@ -143,4 +_,9 @@ }; } } diff --git a/patches/net/minecraft/world/item/BucketItem.java.patch b/patches/net/minecraft/world/item/BucketItem.java.patch index c87fec7ce4..911b51c960 100644 --- a/patches/net/minecraft/world/item/BucketItem.java.patch +++ b/patches/net/minecraft/world/item/BucketItem.java.patch @@ -10,7 +10,7 @@ ItemStack itemstack2 = ItemUtils.createFilledResult(itemstack, p_40704_, itemstack3); if (!p_40703_.isClientSide) { @@ -72,8 +_,8 @@ - return InteractionResultHolder.fail(itemstack); + return InteractionResult.FAIL; } else { BlockState blockstate = p_40703_.getBlockState(blockpos); - BlockPos blockpos2 = blockstate.getBlock() instanceof LiquidBlockContainer && this.content == Fluids.WATER ? blockpos : blockpos1; diff --git a/patches/net/minecraft/world/item/BundleItem.java.patch b/patches/net/minecraft/world/item/BundleItem.java.patch index 945917f07c..ff5bc70598 100644 --- a/patches/net/minecraft/world/item/BundleItem.java.patch +++ b/patches/net/minecraft/world/item/BundleItem.java.patch @@ -1,19 +1,19 @@ --- a/net/minecraft/world/item/BundleItem.java +++ b/net/minecraft/world/item/BundleItem.java -@@ -38,7 +_,7 @@ - +@@ -61,7 +_,7 @@ @Override public boolean overrideStackedOnOther(ItemStack p_150733_, Slot p_150734_, ClickAction p_150735_, Player p_150736_) { -- if (p_150735_ != ClickAction.SECONDARY) { -+ if (p_150733_.getCount() != 1 || p_150735_ != ClickAction.SECONDARY) { + BundleContents bundlecontents = p_150733_.get(DataComponents.BUNDLE_CONTENTS); +- if (bundlecontents == null) { ++ if (bundlecontents == null || p_150733_.getCount() != 1) { return false; } else { - BundleContents bundlecontents = p_150733_.get(DataComponents.BUNDLE_CONTENTS); -@@ -71,6 +_,7 @@ + ItemStack itemstack = p_150734_.getItem(); +@@ -100,6 +_,7 @@ public boolean overrideOtherStackedOnMe( ItemStack p_150742_, ItemStack p_150743_, Slot p_150744_, ClickAction p_150745_, Player p_150746_, SlotAccess p_150747_ ) { + if (p_150742_.getCount() != 1) return false; - if (p_150745_ == ClickAction.SECONDARY && p_150744_.allowModification(p_150746_)) { - BundleContents bundlecontents = p_150742_.get(DataComponents.BUNDLE_CONTENTS); - if (bundlecontents == null) { + if (p_150745_ == ClickAction.PRIMARY && p_150743_.isEmpty()) { + toggleSelectedItem(p_150742_, -1); + return false; diff --git a/patches/net/minecraft/world/item/ChorusFruitItem.java.patch b/patches/net/minecraft/world/item/ChorusFruitItem.java.patch deleted file mode 100644 index 1080f1730c..0000000000 --- a/patches/net/minecraft/world/item/ChorusFruitItem.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/net/minecraft/world/item/ChorusFruitItem.java -+++ b/net/minecraft/world/item/ChorusFruitItem.java -@@ -34,7 +_,9 @@ - } - - Vec3 vec3 = p_40714_.position(); -- if (p_40714_.randomTeleport(d0, d1, d2, true)) { -+ net.neoforged.neoforge.event.entity.EntityTeleportEvent.ChorusFruit event = net.neoforged.neoforge.event.EventHooks.onChorusFruitTeleport(p_40714_, d0, d1, d2); -+ if (event.isCanceled()) return itemstack; -+ if (p_40714_.randomTeleport(event.getTargetX(), event.getTargetY(), event.getTargetZ(), true)) { - p_40713_.gameEvent(GameEvent.TELEPORT, vec3, GameEvent.Context.of(p_40714_)); - SoundSource soundsource; - SoundEvent soundevent; diff --git a/patches/net/minecraft/world/item/CrossbowItem.java.patch b/patches/net/minecraft/world/item/CrossbowItem.java.patch index b21064d1c6..6cb5f7be7d 100644 --- a/patches/net/minecraft/world/item/CrossbowItem.java.patch +++ b/patches/net/minecraft/world/item/CrossbowItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/CrossbowItem.java +++ b/net/minecraft/world/item/CrossbowItem.java -@@ -181,6 +_,7 @@ +@@ -184,6 +_,7 @@ Level p_40888_, LivingEntity p_40889_, InteractionHand p_40890_, ItemStack p_40891_, float p_40892_, float p_40893_, @Nullable LivingEntity p_331602_ ) { if (p_40888_ instanceof ServerLevel serverlevel) { diff --git a/patches/net/minecraft/world/item/DyeColor.java.patch b/patches/net/minecraft/world/item/DyeColor.java.patch index 641da94185..ff5a295142 100644 --- a/patches/net/minecraft/world/item/DyeColor.java.patch +++ b/patches/net/minecraft/world/item/DyeColor.java.patch @@ -15,7 +15,7 @@ this.textColor = p_41051_; + this.dyesTag = net.minecraft.tags.ItemTags.create(net.minecraft.resources.ResourceLocation.fromNamespaceAndPath("c", "dyes/" + p_41047_)); + this.dyedTag = net.minecraft.tags.ItemTags.create(net.minecraft.resources.ResourceLocation.fromNamespaceAndPath("c", "dyed/" + p_41047_)); - this.textureDiffuseColor = FastColor.ARGB32.opaque(p_41048_); + this.textureDiffuseColor = ARGB.opaque(p_41048_); this.fireworkColor = p_41050_; } @@ -102,5 +_,35 @@ diff --git a/patches/net/minecraft/world/item/ElytraItem.java.patch b/patches/net/minecraft/world/item/ElytraItem.java.patch deleted file mode 100644 index 7dedbef32a..0000000000 --- a/patches/net/minecraft/world/item/ElytraItem.java.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- a/net/minecraft/world/item/ElytraItem.java -+++ b/net/minecraft/world/item/ElytraItem.java -@@ -31,6 +_,25 @@ - } - - @Override -+ public boolean canElytraFly(ItemStack stack, net.minecraft.world.entity.LivingEntity entity) { -+ return ElytraItem.isFlyEnabled(stack); -+ } -+ -+ @Override -+ public boolean elytraFlightTick(ItemStack stack, net.minecraft.world.entity.LivingEntity entity, int flightTicks) { -+ if (!entity.level().isClientSide) { -+ int nextFlightTick = flightTicks + 1; -+ if (nextFlightTick % 10 == 0) { -+ if (nextFlightTick % 20 == 0) { -+ stack.hurtAndBreak(1, entity, net.minecraft.world.entity.EquipmentSlot.CHEST); -+ } -+ entity.gameEvent(net.minecraft.world.level.gameevent.GameEvent.ELYTRA_GLIDE); -+ } -+ } -+ return true; -+ } -+ -+ @Override - public Holder getEquipSound() { - return SoundEvents.ARMOR_EQUIP_ELYTRA; - } diff --git a/patches/net/minecraft/world/item/FishingRodItem.java.patch b/patches/net/minecraft/world/item/FishingRodItem.java.patch index 250a7e3a03..7bad48b3a4 100644 --- a/patches/net/minecraft/world/item/FishingRodItem.java.patch +++ b/patches/net/minecraft/world/item/FishingRodItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/FishingRodItem.java +++ b/net/minecraft/world/item/FishingRodItem.java -@@ -24,7 +_,11 @@ +@@ -25,7 +_,11 @@ if (p_41291_.fishing != null) { if (!p_41290_.isClientSide) { int i = p_41291_.fishing.retrieve(itemstack); @@ -12,10 +12,10 @@ } p_41290_.playSound( -@@ -65,5 +_,10 @@ - @Override - public int getEnchantmentValue() { - return 1; +@@ -61,5 +_,10 @@ + } + + return InteractionResult.SUCCESS; + } + + @Override diff --git a/patches/net/minecraft/world/item/FlintAndSteelItem.java.patch b/patches/net/minecraft/world/item/FlintAndSteelItem.java.patch index 3a550060cb..aac6bbeee3 100644 --- a/patches/net/minecraft/world/item/FlintAndSteelItem.java.patch +++ b/patches/net/minecraft/world/item/FlintAndSteelItem.java.patch @@ -21,7 +21,7 @@ p_41297_.getItemInHand().hurtAndBreak(1, player, LivingEntity.getSlotForHand(p_41297_.getHand())); @@ -56,5 +_,10 @@ - return InteractionResult.sidedSuccess(level.isClientSide()); + return InteractionResult.SUCCESS; } + } + diff --git a/patches/net/minecraft/world/item/HoneyBottleItem.java.patch b/patches/net/minecraft/world/item/HoneyBottleItem.java.patch deleted file mode 100644 index ae550d2576..0000000000 --- a/patches/net/minecraft/world/item/HoneyBottleItem.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/item/HoneyBottleItem.java -+++ b/net/minecraft/world/item/HoneyBottleItem.java -@@ -28,7 +_,7 @@ - } - - if (!p_41349_.isClientSide) { -- p_41350_.removeEffect(MobEffects.POISON); -+ p_41350_.removeEffectsCuredBy(net.neoforged.neoforge.common.EffectCures.HONEY); - } - - if (p_41348_.isEmpty()) { diff --git a/patches/net/minecraft/world/item/Item.java.patch b/patches/net/minecraft/world/item/Item.java.patch index 4054c635cd..85a8aab6d7 100644 --- a/patches/net/minecraft/world/item/Item.java.patch +++ b/patches/net/minecraft/world/item/Item.java.patch @@ -1,19 +1,25 @@ --- a/net/minecraft/world/item/Item.java +++ b/net/minecraft/world/item/Item.java -@@ -56,9 +_,9 @@ +@@ -70,7 +_,7 @@ import net.minecraft.world.phys.Vec3; import org.slf4j.Logger; -public class Item implements FeatureElement, ItemLike { +public class Item implements FeatureElement, ItemLike, net.neoforged.neoforge.common.extensions.IItemExtension { + public static final Codec> CODEC = BuiltInRegistries.ITEM + .holderByNameCodec() + .validate( +@@ -79,7 +_,7 @@ + : DataResult.success(p_381630_) + ); private static final Logger LOGGER = LogUtils.getLogger(); - public static final Map BY_BLOCK = Maps.newHashMap(); + public static final Map BY_BLOCK = net.neoforged.neoforge.registries.GameData.getBlockItemMap(); public static final ResourceLocation BASE_ATTACK_DAMAGE_ID = ResourceLocation.withDefaultNamespace("base_attack_damage"); public static final ResourceLocation BASE_ATTACK_SPEED_ID = ResourceLocation.withDefaultNamespace("base_attack_speed"); public static final int DEFAULT_MAX_STACK_SIZE = 64; -@@ -89,12 +_,13 @@ - this.components = p_41383_.buildAndValidateComponents(); +@@ -110,7 +_,7 @@ + this.components = p_41383_.buildAndValidateComponents(Component.translatable(this.descriptionId), p_41383_.effectiveModel()); this.craftingRemainingItem = p_41383_.craftingRemainingItem; this.requiredFeatures = p_41383_.requiredFeatures; - if (SharedConstants.IS_RUNNING_IN_IDE) { @@ -21,13 +27,7 @@ String s = this.getClass().getSimpleName(); if (!s.endsWith("Item")) { LOGGER.error("Item classes should end with Item and {} doesn't.", s); - } - } -+ this.canRepair = p_41383_.canRepair; - } - - @Deprecated -@@ -106,6 +_,15 @@ +@@ -127,6 +_,15 @@ return this.components; } @@ -37,13 +37,13 @@ + if (!net.neoforged.neoforge.internal.RegistrationEvents.canModifyComponents()) throw new IllegalStateException("Default components cannot be modified now!"); + var builder = DataComponentMap.builder().addAll(components); + patch.entrySet().forEach(entry -> builder.set((DataComponentType)entry.getKey(), entry.getValue().orElse(null))); -+ components = Properties.COMPONENT_INTERNER.intern(Properties.validateComponents(builder.build())); ++ components = Properties.validateComponents(builder.build()); + } + public int getDefaultMaxStackSize() { return this.components.getOrDefault(DataComponents.MAX_STACK_SIZE, 1); } -@@ -113,6 +_,8 @@ +@@ -134,6 +_,8 @@ public void onUseTick(Level p_41428_, LivingEntity p_41429_, ItemStack p_41430_, int p_41431_) { } @@ -52,25 +52,7 @@ public void onDestroyed(ItemEntity p_150887_) { } -@@ -139,7 +_,7 @@ - - public InteractionResultHolder use(Level p_41432_, Player p_41433_, InteractionHand p_41434_) { - ItemStack itemstack = p_41433_.getItemInHand(p_41434_); -- FoodProperties foodproperties = itemstack.get(DataComponents.FOOD); -+ FoodProperties foodproperties = itemstack.getFoodProperties(p_41433_); - if (foodproperties != null) { - if (p_41433_.canEat(foodproperties.canAlwaysEat())) { - p_41433_.startUsingItem(p_41434_); -@@ -153,7 +_,7 @@ - } - - public ItemStack finishUsingItem(ItemStack p_41409_, Level p_41410_, LivingEntity p_41411_) { -- FoodProperties foodproperties = p_41409_.get(DataComponents.FOOD); -+ FoodProperties foodproperties = p_41409_.getFoodProperties(p_41411_); - return foodproperties != null ? p_41411_.eat(p_41410_, p_41409_, foodproperties) : p_41409_; - } - -@@ -162,12 +_,13 @@ +@@ -181,12 +_,13 @@ } public int getBarWidth(ItemStack p_150900_) { @@ -86,109 +68,49 @@ return Mth.hsvToRgb(f / 3.0F, 1.0F, 1.0F); } -@@ -240,10 +_,12 @@ - } - - @Nullable -+ @Deprecated // Use ItemStack sensitive version. - public final Item getCraftingRemainingItem() { - return this.craftingRemainingItem; +@@ -243,6 +_,7 @@ + return BuiltInRegistries.ITEM.wrapAsHolder(this).getRegisteredName(); } + @Deprecated // Use ItemStack sensitive version. - public boolean hasCraftingRemainingItem() { - return this.craftingRemainingItem != null; + public final ItemStack getCraftingRemainder() { + return this.craftingRemainingItem == null ? ItemStack.EMPTY : new ItemStack(this.craftingRemainingItem); } -@@ -267,7 +_,7 @@ - } - - public int getUseDuration(ItemStack p_41454_, LivingEntity p_344979_) { -- FoodProperties foodproperties = p_41454_.get(DataComponents.FOOD); -+ FoodProperties foodproperties = p_41454_.getFoodProperties(null); - return foodproperties != null ? foodproperties.eatDurationTicks() : 0; - } - -@@ -299,6 +_,8 @@ - return p_41436_.clip(new ClipContext(vec3, vec31, ClipContext.Block.OUTLINE, p_41438_, p_41437_)); - } - -+ /** @deprecated Neo: Use ItemStack sensitive version. */ -+ @Deprecated - public int getEnchantmentValue() { - return 0; - } -@@ -307,13 +_,23 @@ - return false; - } - -+ /** -+ * @deprecated Neo: Use {@link Item#getDefaultAttributeModifiers(ItemStack)} -+ */ - @Deprecated - public ItemAttributeModifiers getDefaultAttributeModifiers() { - return ItemAttributeModifiers.EMPTY; +@@ -302,7 +_,12 @@ } -+ protected final boolean canRepair; -+ -+ @Override -+ public boolean isRepairable(ItemStack stack) { -+ return canRepair && isDamageable(stack); -+ } -+ public boolean useOnRelease(ItemStack p_41464_) { - return false; + return p_41464_.getItem() == Items.CROSSBOW; ++ } ++ ++ @Override ++ public boolean isRepairable(ItemStack stack) { ++ return stack.has(DataComponents.REPAIRABLE) && isDamageable(stack); } public ItemStack getDefaultInstance() { -@@ -341,13 +_,22 @@ +@@ -322,7 +_,7 @@ return this.requiredFeatures; } - public static class Properties { -+ /** -+ * Neo: Allowing mods to define client behavior for their Items -+ * @deprecated Use {@link net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent} instead -+ */ -+ @Deprecated(forRemoval = true, since = "1.21") -+ public void initializeClient(java.util.function.Consumer consumer) { -+ } -+ + public static class Properties implements net.neoforged.neoforge.common.extensions.IItemPropertiesExtensions { - private static final Interner COMPONENT_INTERNER = Interners.newStrongInterner(); - @Nullable - private DataComponentMap.Builder components; - @Nullable - Item craftingRemainingItem; - FeatureFlagSet requiredFeatures = FeatureFlags.VANILLA_SET; -+ private boolean canRepair = true; - - public Item.Properties food(FoodProperties p_41490_) { - return this.component(DataComponents.FOOD, p_41490_); -@@ -381,12 +_,18 @@ - return this.component(DataComponents.JUKEBOX_PLAYABLE, new JukeboxPlayable(new EitherHolder<>(p_350862_), true)); - } - -+ public Item.Properties setNoRepair() { -+ canRepair = false; -+ return this; -+ } -+ - public Item.Properties requiredFeatures(FeatureFlag... p_250948_) { - this.requiredFeatures = FeatureFlags.REGISTRY.subset(p_250948_); - return this; + private static final DependantName BLOCK_DESCRIPTION_ID = p_371954_ -> Util.makeDescriptionId("block", p_371954_.location()); + private static final DependantName ITEM_DESCRIPTION_ID = p_371511_ -> Util.makeDescriptionId("item", p_371511_.location()); + private final DataComponentMap.Builder components = DataComponentMap.builder().addAll(DataComponents.COMMON_ITEM_COMPONENTS); +@@ -438,6 +_,7 @@ } public Item.Properties component(DataComponentType p_330871_, T p_330323_) { + net.neoforged.neoforge.common.CommonHooks.validateComponent(p_330323_); - if (this.components == null) { - this.components = DataComponentMap.builder().addAll(DataComponents.COMMON_ITEM_COMPONENTS); - } -@@ -401,6 +_,10 @@ + this.components.set(p_330871_, p_330323_); + return this; + } +@@ -448,6 +_,10 @@ - DataComponentMap buildAndValidateComponents() { - DataComponentMap datacomponentmap = this.buildComponents(); + DataComponentMap buildAndValidateComponents(Component p_371796_, ResourceLocation p_371450_) { + DataComponentMap datacomponentmap = this.components.set(DataComponents.ITEM_NAME, p_371796_).set(DataComponents.ITEM_MODEL, p_371450_).build(); + return validateComponents(datacomponentmap); + } + @@ -196,7 +118,7 @@ if (datacomponentmap.has(DataComponents.DAMAGE) && datacomponentmap.getOrDefault(DataComponents.MAX_STACK_SIZE, 1) > 1) { throw new IllegalStateException("Item cannot have both durability and be stackable"); } else { -@@ -441,6 +_,14 @@ +@@ -484,6 +_,14 @@ @Nullable MapItemSavedData mapData(MapId p_339670_); @@ -211,7 +133,7 @@ static Item.TooltipContext of(@Nullable final Level p_339599_) { return p_339599_ == null ? EMPTY : new Item.TooltipContext() { @Override -@@ -456,6 +_,11 @@ +@@ -499,6 +_,11 @@ @Override public MapItemSavedData mapData(MapId p_339628_) { return p_339599_.getMapData(p_339628_); diff --git a/patches/net/minecraft/world/item/ItemStack.java.patch b/patches/net/minecraft/world/item/ItemStack.java.patch index 7f753b99da..6842e3538e 100644 --- a/patches/net/minecraft/world/item/ItemStack.java.patch +++ b/patches/net/minecraft/world/item/ItemStack.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/item/ItemStack.java +++ b/net/minecraft/world/item/ItemStack.java -@@ -92,7 +_,7 @@ +@@ -97,7 +_,7 @@ import org.apache.commons.lang3.mutable.MutableBoolean; import org.slf4j.Logger; -public final class ItemStack implements DataComponentHolder { +public final class ItemStack implements DataComponentHolder, net.neoforged.neoforge.common.extensions.IItemStackExtension, net.neoforged.neoforge.common.MutableDataComponentHolder { - public static final Codec> ITEM_NON_AIR_CODEC = BuiltInRegistries.ITEM - .holderByNameCodec() - .validate( -@@ -234,6 +_,10 @@ + public static final Codec CODEC = Codec.lazyInitialized( + () -> RecordCodecBuilder.create( + p_381569_ -> p_381569_.group( +@@ -233,6 +_,10 @@ return !this.isEmpty() ? this.components.asPatch() : DataComponentPatch.EMPTY; } @@ -20,7 +20,7 @@ public ItemStack(ItemLike p_41599_) { this(p_41599_, 1); } -@@ -339,7 +_,7 @@ +@@ -338,7 +_,7 @@ } public boolean is(Holder p_220166_) { @@ -29,19 +29,20 @@ } public boolean is(HolderSet p_298683_) { -@@ -351,13 +_,26 @@ +@@ -350,13 +_,27 @@ } public InteractionResult useOn(UseOnContext p_41662_) { + var e = net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.entity.player.UseItemOnBlockEvent(p_41662_, net.neoforged.neoforge.event.entity.player.UseItemOnBlockEvent.UsePhase.ITEM_AFTER_BLOCK)); -+ if (e.isCanceled()) return e.getCancellationResult().result(); ++ if (e.isCanceled()) return e.getCancellationResult(); + if (!p_41662_.getLevel().isClientSide) return net.neoforged.neoforge.common.CommonHooks.onPlaceItemIntoWorld(p_41662_); + return onItemUse(p_41662_, (c) -> getItem().useOn(p_41662_)); + } + ++ @Override + public InteractionResult onItemUseFirst(UseOnContext p_41662_) { + var e = net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.entity.player.UseItemOnBlockEvent(p_41662_, net.neoforged.neoforge.event.entity.player.UseItemOnBlockEvent.UsePhase.ITEM_BEFORE_BLOCK)); -+ if (e.isCanceled()) return e.getCancellationResult().result(); ++ if (e.isCanceled()) return e.getCancellationResult(); + return onItemUse(p_41662_, (c) -> getItem().onItemUseFirst(this, p_41662_)); + } + @@ -54,10 +55,10 @@ Item item = this.getItem(); - InteractionResult interactionresult = item.useOn(p_41662_); + InteractionResult interactionresult = callback.apply(p_41662_); - if (player != null && interactionresult.indicateItemUse()) { - player.awardStat(Stats.ITEM_USED.get(item)); - } -@@ -382,7 +_,8 @@ + if (player != null + && interactionresult instanceof InteractionResult.Success interactionresult$success + && interactionresult$success.wasItemInteraction()) { +@@ -410,7 +_,8 @@ if (this.isEmpty()) { throw new IllegalStateException("Cannot encode empty ItemStack"); } else { @@ -67,7 +68,7 @@ } } -@@ -390,7 +_,8 @@ +@@ -418,7 +_,8 @@ if (this.isEmpty()) { throw new IllegalStateException("Cannot encode empty ItemStack"); } else { @@ -77,7 +78,7 @@ } } -@@ -399,7 +_,7 @@ +@@ -427,7 +_,7 @@ } public int getMaxStackSize() { @@ -86,7 +87,7 @@ } public boolean isStackable() { -@@ -411,23 +_,28 @@ +@@ -439,19 +_,19 @@ } public boolean isDamaged() { @@ -109,28 +110,46 @@ + return this.getItem().getMaxDamage(this); } + public boolean isBroken() { +@@ -463,6 +_,11 @@ + } + public void hurtAndBreak(int p_220158_, ServerLevel p_346256_, @Nullable ServerPlayer p_220160_, Consumer p_348596_) { + this.hurtAndBreak(p_220158_, p_346256_, (LivingEntity) p_220160_, p_348596_); + } + + public void hurtAndBreak(int p_220158_, ServerLevel p_346256_, @Nullable LivingEntity p_220160_, Consumer p_348596_) { - if (this.isDamageableItem()) { -+ p_220158_ = getItem().damageItem(this, p_220158_, p_220160_, p_348596_); - if (p_220160_ == null || !p_220160_.hasInfiniteMaterials()) { - if (p_220158_ > 0) { - p_220158_ = EnchantmentHelper.processDurabilityChange(p_346256_, this, p_220158_); -@@ -436,8 +_,8 @@ - } - } ++ p_220158_ = getItem().damageItem(this, p_220158_, p_220160_, p_348596_); + int i = this.processDurabilityChange(p_220158_, p_346256_, p_220160_); + if (i != 0) { + this.applyDamage(this.getDamageValue() + i, p_220160_, p_348596_); +@@ -470,6 +_,10 @@ + } -- if (p_220160_ != null && p_220158_ != 0) { -- CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(p_220160_, this, this.getDamageValue() + p_220158_); -+ if (p_220160_ instanceof ServerPlayer sp && p_220158_ != 0) { -+ CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(sp, this, this.getDamageValue() + p_220158_); - } + private int processDurabilityChange(int p_361290_, ServerLevel p_361409_, @Nullable ServerPlayer p_364940_) { ++ return processDurabilityChange(p_361290_, p_361409_, (LivingEntity) p_364940_); ++ } ++ ++ private int processDurabilityChange(int p_361290_, ServerLevel p_361409_, @Nullable LivingEntity p_364940_) { + if (!this.isDamageableItem()) { + return 0; + } else if (p_364940_ != null && p_364940_.hasInfiniteMaterials()) { +@@ -480,8 +_,12 @@ + } - int i = this.getDamageValue() + p_220158_; -@@ -456,7 +_,7 @@ + private void applyDamage(int p_361754_, @Nullable ServerPlayer p_364853_, Consumer p_360895_) { +- if (p_364853_ != null) { +- CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(p_364853_, this, p_361754_); ++ applyDamage(p_361754_, (LivingEntity) p_364853_, p_360895_); ++ } ++ ++ private void applyDamage(int p_361754_, @Nullable LivingEntity p_364853_, Consumer p_360895_) { ++ if (p_364853_ instanceof ServerPlayer serverPlayer) { ++ CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(serverPlayer, this, p_361754_); + } + + this.setDamageValue(p_361754_); +@@ -510,7 +_,7 @@ this.hurtAndBreak( p_41623_, serverlevel, @@ -139,16 +158,16 @@ p_348383_ -> p_41624_.onEquippedItemBroken(p_348383_, p_319898_) ); } -@@ -728,7 +_,7 @@ - return List.of(); - } else { - List list = Lists.newArrayList(); -- MutableComponent mutablecomponent = Component.empty().append(this.getHoverName()).withStyle(this.getRarity().color()); -+ MutableComponent mutablecomponent = Component.empty().append(this.getHoverName()).withStyle(this.getRarity().getStyleModifier()); - if (this.has(DataComponents.CUSTOM_NAME)) { - mutablecomponent.withStyle(ChatFormatting.ITALIC); - } -@@ -752,7 +_,9 @@ +@@ -785,7 +_,7 @@ + } + + public Component getStyledHoverName() { +- MutableComponent mutablecomponent = Component.empty().append(this.getHoverName()).withStyle(this.getRarity().color()); ++ MutableComponent mutablecomponent = Component.empty().append(this.getHoverName()).withStyle(this.getRarity().getStyleModifier()); + if (this.has(DataComponents.CUSTOM_NAME)) { + mutablecomponent.withStyle(ChatFormatting.ITALIC); + } +@@ -826,7 +_,9 @@ this.addToTooltip(DataComponents.ENCHANTMENTS, p_339637_, consumer, p_41653_); this.addToTooltip(DataComponents.DYED_COLOR, p_339637_, consumer, p_41653_); this.addToTooltip(DataComponents.LORE, p_339637_, consumer, p_41653_); @@ -157,9 +176,9 @@ + net.neoforged.neoforge.common.util.AttributeUtil.addAttributeTooltips(this, consumer, + net.neoforged.neoforge.common.util.AttributeTooltipContext.of(p_41652_, p_339637_, p_41653_)); this.addToTooltip(DataComponents.UNBREAKABLE, p_339637_, consumer, p_41653_); - AdventureModePredicate adventuremodepredicate = this.get(DataComponents.CAN_BREAK); - if (adventuremodepredicate != null && adventuremodepredicate.showInTooltip()) { -@@ -784,10 +_,15 @@ + this.addToTooltip(DataComponents.OMINOUS_BOTTLE_AMPLIFIER, p_339637_, consumer, p_41653_); + this.addToTooltip(DataComponents.SUSPICIOUS_STEW_EFFECTS, p_339637_, consumer, p_41653_); +@@ -860,10 +_,15 @@ list.add(DISABLED_ITEM_TOOLTIP); } @@ -175,7 +194,7 @@ private void addAttributeTooltips(Consumer p_330796_, @Nullable Player p_330530_) { ItemAttributeModifiers itemattributemodifiers = this.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY); if (itemattributemodifiers.showInTooltip()) { -@@ -897,6 +_,17 @@ +@@ -973,6 +_,17 @@ return !this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY).isEmpty(); } @@ -193,50 +212,34 @@ public ItemEnchantments getEnchantments() { return this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY); } -@@ -922,6 +_,12 @@ +@@ -998,14 +_,26 @@ } public void forEachModifier(EquipmentSlotGroup p_348610_, BiConsumer, AttributeModifier> p_348516_) { + // Neo: Reflect real attribute modifiers when doing iteration + this.getAttributeModifiers().forEach(p_348610_, p_348516_); -+ + if (false) { + // Start disabled vanilla code -+ ItemAttributeModifiers itemattributemodifiers = this.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY); - if (!itemattributemodifiers.modifiers().isEmpty()) { - itemattributemodifiers.forEach(p_348610_, p_348516_); -@@ -929,10 +_,19 @@ - this.getItem().getDefaultAttributeModifiers().forEach(p_348610_, p_348516_); - } - + itemattributemodifiers.forEach(p_348610_, p_348516_); + // end disabled vanilla code + } -+ EnchantmentHelper.forEachModifier(this, p_348610_, p_348516_); } public void forEachModifier(EquipmentSlot p_332001_, BiConsumer, AttributeModifier> p_330882_) { + // Neo: Reflect real attribute modifiers when doing iteration + this.getAttributeModifiers().forEach(p_332001_, p_330882_); -+ + if (false) { + // Start disabled vanilla code -+ ItemAttributeModifiers itemattributemodifiers = this.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY); - if (!itemattributemodifiers.modifiers().isEmpty()) { - itemattributemodifiers.forEach(p_332001_, p_330882_); -@@ -940,6 +_,9 @@ - this.getItem().getDefaultAttributeModifiers().forEach(p_332001_, p_330882_); - } - + itemattributemodifiers.forEach(p_332001_, p_330882_); + // end disabled vanilla code + } -+ EnchantmentHelper.forEachModifier(this, p_332001_, p_330882_); } -@@ -951,7 +_,7 @@ +@@ -1017,7 +_,7 @@ MutableComponent mutablecomponent1 = ComponentUtils.wrapInSquareBrackets(mutablecomponent); if (!this.isEmpty()) { @@ -245,7 +248,7 @@ .withStyle(p_220170_ -> p_220170_.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new HoverEvent.ItemStackInfo(this)))); } -@@ -1014,6 +_,8 @@ +@@ -1085,6 +_,8 @@ this.getItem().onUseTick(p_41732_, p_41733_, this, p_41734_); } @@ -254,11 +257,11 @@ public void onDestroyed(ItemEntity p_150925_) { this.getItem().onDestroyed(p_150925_); } -@@ -1031,6 +_,7 @@ +@@ -1094,6 +_,7 @@ } public boolean canBeHurtBy(DamageSource p_335431_) { + if (!getItem().canBeHurtBy(this, p_335431_)) return false; - return !this.has(DataComponents.FIRE_RESISTANT) || !p_335431_.is(DamageTypeTags.IS_FIRE); + DamageResistant damageresistant = this.get(DataComponents.DAMAGE_RESISTANT); + return damageresistant == null || !damageresistant.isResistantTo(p_335431_); } - } diff --git a/patches/net/minecraft/world/item/ItemUseAnimation.java.patch b/patches/net/minecraft/world/item/ItemUseAnimation.java.patch new file mode 100644 index 0000000000..bae3e76080 --- /dev/null +++ b/patches/net/minecraft/world/item/ItemUseAnimation.java.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/world/item/ItemUseAnimation.java ++++ b/net/minecraft/world/item/ItemUseAnimation.java +@@ -8,7 +_,10 @@ + import net.minecraft.util.ByIdMap; + import net.minecraft.util.StringRepresentable; + +-public enum ItemUseAnimation implements StringRepresentable { ++@net.neoforged.fml.common.asm.enumextension.IndexedEnum ++@net.neoforged.fml.common.asm.enumextension.NamedEnum(1) ++@net.neoforged.fml.common.asm.enumextension.NetworkedEnum(net.neoforged.fml.common.asm.enumextension.NetworkedEnum.NetworkCheck.BIDIRECTIONAL) ++public enum ItemUseAnimation implements StringRepresentable, net.neoforged.fml.common.asm.enumextension.IExtensibleEnum { + NONE(0, "none"), + EAT(1, "eat"), + DRINK(2, "drink"), +@@ -38,5 +_,9 @@ + @Override + public String getSerializedName() { + return this.name; ++ } ++ ++ public static net.neoforged.fml.common.asm.enumextension.ExtensionInfo getExtensionInfo() { ++ return net.neoforged.fml.common.asm.enumextension.ExtensionInfo.nonExtended(ItemUseAnimation.class); + } + } diff --git a/patches/net/minecraft/world/item/Items.java.patch b/patches/net/minecraft/world/item/Items.java.patch index 5967553b88..98327eb50c 100644 --- a/patches/net/minecraft/world/item/Items.java.patch +++ b/patches/net/minecraft/world/item/Items.java.patch @@ -1,32 +1,27 @@ --- a/net/minecraft/world/item/Items.java +++ b/net/minecraft/world/item/Items.java -@@ -2092,11 +_,25 @@ +@@ -2326,11 +_,19 @@ } public static Item registerBlock(Block p_252092_, Block... p_248886_) { -- BlockItem blockitem = new BlockItem(p_252092_, new Item.Properties()); -+ BlockItem blockitem = new BlockItem(p_252092_, new Item.Properties()) { -+ @Override -+ public void registerBlocks(java.util.Map map, Item self) { -+ super.registerBlocks(map, self); -+ for (Block b : p_248886_) { -+ map.put(b, self); -+ } -+ } - +- Item item = registerBlock(p_252092_); +- - for (Block block : p_248886_) { -- Item.BY_BLOCK.put(block, blockitem); +- Item.BY_BLOCK.put(block, item); - } -+ /** @deprecated Neo: To be removed without replacement since registry replacement is not a feature anymore. */ -+ @Deprecated(forRemoval = true, since = "1.21.1") -+ @Override -+ public void removeFromBlockToItemMap(java.util.Map map, Item self) { -+ super.removeFromBlockToItemMap(map, self); -+ for (Block b : p_248886_) { -+ map.remove(b); -+ } -+ } -+ }; ++ Item item = registerItem( ++ blockIdToItemId(p_252092_.builtInRegistryHolder().key()), ++ p -> new BlockItem(p_252092_, p) { ++ @Override ++ public void registerBlocks(java.util.Map map, Item self) { ++ super.registerBlocks(map, self); ++ for (Block block : p_248886_) { ++ map.put(block, self); ++ } ++ } ++ }, ++ new Item.Properties().useBlockDescriptionPrefix() ++ ); - return registerBlock(blockitem); + return item; } diff --git a/patches/net/minecraft/world/item/MapItem.java.patch b/patches/net/minecraft/world/item/MapItem.java.patch index 159280f4f4..f5c15dc15d 100644 --- a/patches/net/minecraft/world/item/MapItem.java.patch +++ b/patches/net/minecraft/world/item/MapItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/MapItem.java +++ b/net/minecraft/world/item/MapItem.java -@@ -57,6 +_,16 @@ +@@ -56,6 +_,16 @@ @Nullable public static MapItemSavedData getSavedData(ItemStack p_42854_, Level p_42855_) { diff --git a/patches/net/minecraft/world/item/MilkBucketItem.java.patch b/patches/net/minecraft/world/item/MilkBucketItem.java.patch deleted file mode 100644 index 416fad27ba..0000000000 --- a/patches/net/minecraft/world/item/MilkBucketItem.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/item/MilkBucketItem.java -+++ b/net/minecraft/world/item/MilkBucketItem.java -@@ -24,7 +_,7 @@ - } - - if (!p_42924_.isClientSide) { -- p_42925_.removeAllEffects(); -+ p_42925_.removeEffectsCuredBy(net.neoforged.neoforge.common.EffectCures.MILK); - } - - if (p_42925_ instanceof Player player) { diff --git a/patches/net/minecraft/world/item/MinecartItem.java.patch b/patches/net/minecraft/world/item/MinecartItem.java.patch index a28feeaef1..da2d05fb93 100644 --- a/patches/net/minecraft/world/item/MinecartItem.java.patch +++ b/patches/net/minecraft/world/item/MinecartItem.java.patch @@ -1,29 +1,11 @@ --- a/net/minecraft/world/item/MinecartItem.java +++ b/net/minecraft/world/item/MinecartItem.java -@@ -33,7 +_,7 @@ - BlockPos blockpos = p_302448_.pos().relative(direction); - BlockState blockstate = serverlevel.getBlockState(blockpos); +@@ -34,7 +_,7 @@ + } else { + ItemStack itemstack = p_42943_.getItemInHand(); RailShape railshape = blockstate.getBlock() instanceof BaseRailBlock - ? blockstate.getValue(((BaseRailBlock)blockstate.getBlock()).getShapeProperty()) -+ ? ((BaseRailBlock)blockstate.getBlock()).getRailDirection(blockstate, serverlevel, blockpos, null) - : RailShape.NORTH_SOUTH; - double d3; - if (blockstate.is(BlockTags.RAILS)) { -@@ -49,7 +_,7 @@ - - BlockState blockstate1 = serverlevel.getBlockState(blockpos.below()); - RailShape railshape1 = blockstate1.getBlock() instanceof BaseRailBlock -- ? blockstate1.getValue(((BaseRailBlock)blockstate1.getBlock()).getShapeProperty()) -+ ? ((BaseRailBlock)blockstate1.getBlock()).getRailDirection(blockstate1, serverlevel, blockpos.below(), null) - : RailShape.NORTH_SOUTH; - if (direction != Direction.DOWN && railshape1.isAscending()) { - d3 = -0.4; -@@ -90,7 +_,7 @@ - ItemStack itemstack = p_42943_.getItemInHand(); - if (level instanceof ServerLevel serverlevel) { - RailShape railshape = blockstate.getBlock() instanceof BaseRailBlock -- ? blockstate.getValue(((BaseRailBlock)blockstate.getBlock()).getShapeProperty()) + ? ((BaseRailBlock)blockstate.getBlock()).getRailDirection(blockstate, level, blockpos, null) - : RailShape.NORTH_SOUTH; - double d0 = 0.0; - if (railshape.isAscending()) { + : RailShape.NORTH_SOUTH; + double d0 = 0.0; + if (railshape.isSlope()) { diff --git a/patches/net/minecraft/world/item/PickaxeItem.java.patch b/patches/net/minecraft/world/item/PickaxeItem.java.patch index f6f3418534..52ad2444bf 100644 --- a/patches/net/minecraft/world/item/PickaxeItem.java.patch +++ b/patches/net/minecraft/world/item/PickaxeItem.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/world/item/PickaxeItem.java +++ b/net/minecraft/world/item/PickaxeItem.java @@ -6,4 +_,9 @@ - public PickaxeItem(Tier p_42961_, Item.Properties p_42964_) { - super(p_42961_, BlockTags.MINEABLE_WITH_PICKAXE, p_42964_); + public PickaxeItem(ToolMaterial p_362209_, float p_364146_, float p_361793_, Item.Properties p_42964_) { + super(p_362209_, BlockTags.MINEABLE_WITH_PICKAXE, p_364146_, p_361793_, p_42964_); } + + @Override diff --git a/patches/net/minecraft/world/item/ProjectileWeaponItem.java.patch b/patches/net/minecraft/world/item/ProjectileWeaponItem.java.patch index 06d8d4276e..9747fe189d 100644 --- a/patches/net/minecraft/world/item/ProjectileWeaponItem.java.patch +++ b/patches/net/minecraft/world/item/ProjectileWeaponItem.java.patch @@ -43,7 +43,7 @@ public static ItemStack getHeldProjectile(LivingEntity p_43011_, Predicate p_43012_) { if (p_43012_.test(p_43011_.getItemInHand(InteractionHand.OFF_HAND))) { return p_43011_.getItemInHand(InteractionHand.OFF_HAND); -@@ -92,7 +_,7 @@ +@@ -91,7 +_,7 @@ abstractarrow.setCritArrow(true); } @@ -52,7 +52,7 @@ } protected static List draw(ItemStack p_331565_, ItemStack p_330406_, LivingEntity p_330823_) { -@@ -115,7 +_,8 @@ +@@ -114,7 +_,8 @@ } protected static ItemStack useAmmo(ItemStack p_331207_, ItemStack p_331434_, LivingEntity p_330302_, boolean p_330934_) { @@ -62,7 +62,7 @@ ? EnchantmentHelper.processAmmoUse(serverlevel, p_331207_, p_331434_, 1) : 0; if (i > p_331434_.getCount()) { -@@ -132,5 +_,20 @@ +@@ -131,5 +_,20 @@ return itemstack; } diff --git a/patches/net/minecraft/world/item/ShearsItem.java.patch b/patches/net/minecraft/world/item/ShearsItem.java.patch index 6f0ad827e7..1ce63f102e 100644 --- a/patches/net/minecraft/world/item/ShearsItem.java.patch +++ b/patches/net/minecraft/world/item/ShearsItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/ShearsItem.java +++ b/net/minecraft/world/item/ShearsItem.java -@@ -54,20 +_,57 @@ +@@ -59,20 +_,57 @@ || p_43080_.is(BlockTags.WOOL); } @@ -19,9 +19,9 @@ + // Call onSheared on both sides (mirrors vanilla shear()) + List drops = target.onSheared(player, stack, entity.level(), pos); + // Spawn drops on the server side using spawnShearedDrop to retain vanilla mob-specific behavior -+ if (!isClient) { ++ if (entity.level() instanceof net.minecraft.server.level.ServerLevel serverLevel) { + for(ItemStack drop : drops) { -+ target.spawnShearedDrop(entity.level(), pos, drop); ++ target.spawnShearedDrop(serverLevel, pos, drop); + } + } + // Call GameEvent.SHEAR on both sides @@ -31,7 +31,7 @@ + stack.hurtAndBreak(1, player, LivingEntity.getSlotForHand(hand)); + } + // Return sided success if the entity was shearable -+ return InteractionResult.sidedSuccess(isClient); ++ return InteractionResult.SUCCESS; + } + } + return InteractionResult.PASS; diff --git a/patches/net/minecraft/world/item/ShieldItem.java.patch b/patches/net/minecraft/world/item/ShieldItem.java.patch index e22dccf461..812ecb68f1 100644 --- a/patches/net/minecraft/world/item/ShieldItem.java.patch +++ b/patches/net/minecraft/world/item/ShieldItem.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/world/item/ShieldItem.java +++ b/net/minecraft/world/item/ShieldItem.java -@@ -58,4 +_,9 @@ - public EquipmentSlot getEquipmentSlot() { - return EquipmentSlot.OFFHAND; +@@ -43,4 +_,9 @@ + p_43100_.startUsingItem(p_43101_); + return InteractionResult.CONSUME; } + + @Override diff --git a/patches/net/minecraft/world/item/SpawnEggItem.java.patch b/patches/net/minecraft/world/item/SpawnEggItem.java.patch index 039545cc2e..b3a50e656b 100644 --- a/patches/net/minecraft/world/item/SpawnEggItem.java.patch +++ b/patches/net/minecraft/world/item/SpawnEggItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/SpawnEggItem.java +++ b/net/minecraft/world/item/SpawnEggItem.java -@@ -42,11 +_,14 @@ +@@ -41,11 +_,14 @@ private final int highlightColor; private final EntityType defaultType; @@ -15,7 +15,7 @@ BY_ID.put(p_43207_, this); } -@@ -134,6 +_,8 @@ +@@ -133,6 +_,8 @@ @Nullable public static SpawnEggItem byId(@Nullable EntityType p_43214_) { @@ -24,7 +24,7 @@ return BY_ID.get(p_43214_); } -@@ -143,12 +_,12 @@ +@@ -142,12 +_,12 @@ public EntityType getType(ItemStack p_330335_) { CustomData customdata = p_330335_.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY); @@ -39,7 +39,7 @@ } public Optional spawnOffspringFromSpawnEgg( -@@ -179,5 +_,9 @@ +@@ -178,5 +_,9 @@ } } } diff --git a/patches/net/minecraft/world/item/StandingAndWallBlockItem.java.patch b/patches/net/minecraft/world/item/StandingAndWallBlockItem.java.patch deleted file mode 100644 index c119b7fac0..0000000000 --- a/patches/net/minecraft/world/item/StandingAndWallBlockItem.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/net/minecraft/world/item/StandingAndWallBlockItem.java -+++ b/net/minecraft/world/item/StandingAndWallBlockItem.java -@@ -50,4 +_,11 @@ - super.registerBlocks(p_43252_, p_43253_); - p_43252_.put(this.wallBlock, p_43253_); - } -+ -+ /** @deprecated Neo: To be removed without replacement since registry replacement is not a feature anymore. */ -+ @Deprecated(forRemoval = true, since = "1.21.1") -+ public void removeFromBlockToItemMap(Map blockToItemMap, Item itemIn) { -+ super.removeFromBlockToItemMap(blockToItemMap, itemIn); -+ blockToItemMap.remove(this.wallBlock); -+ } - } diff --git a/patches/net/minecraft/world/item/SwordItem.java.patch b/patches/net/minecraft/world/item/SwordItem.java.patch index bcff559cf7..d7c8b39eb1 100644 --- a/patches/net/minecraft/world/item/SwordItem.java.patch +++ b/patches/net/minecraft/world/item/SwordItem.java.patch @@ -1,32 +1,20 @@ --- a/net/minecraft/world/item/SwordItem.java +++ b/net/minecraft/world/item/SwordItem.java -@@ -21,11 +_,25 @@ - super(p_43269_, p_43272_.component(DataComponents.TOOL, createToolProperties())); +@@ -12,6 +_,13 @@ + super(p_361460_.applySwordProperties(p_43272_, p_362481_, p_364182_)); } + /** -+ * Neo: Allow modded Swords to set exactly what Tool data component to use for their sword. ++ * Neo: Allow modded Swords to set exactly what properties to use for their sword. + */ -+ public SwordItem(Tier tier, Item.Properties properties, Tool toolComponentData) { -+ super(tier, properties.component(DataComponents.TOOL, toolComponentData)); ++ public SwordItem(Item.Properties properties) { ++ super(properties); + } + - public static Tool createToolProperties() { - return new Tool(List.of(Tool.Rule.minesAndDrops(List.of(Blocks.COBWEB), 15.0F), Tool.Rule.overrideSpeed(BlockTags.SWORD_EFFICIENT, 1.5F)), 1.0F, 2); - } - - public static ItemAttributeModifiers createAttributes(Tier p_330371_, int p_331976_, float p_332104_) { -+ return createAttributes(p_330371_, (float)p_331976_, p_332104_); -+ } -+ -+ /** -+ * Neo: Method overload to allow giving a float for damage instead of an int. -+ */ -+ public static ItemAttributeModifiers createAttributes(Tier p_330371_, float p_331976_, float p_332104_) { - return ItemAttributeModifiers.builder() - .add( - Attributes.ATTACK_DAMAGE, -@@ -55,5 +_,10 @@ + @Override + public boolean canAttackBlock(BlockState p_43291_, Level p_43292_, BlockPos p_43293_, Player p_43294_) { + return !p_43294_.isCreative(); +@@ -25,5 +_,10 @@ @Override public void postHurtEnemy(ItemStack p_345553_, LivingEntity p_345771_, LivingEntity p_346282_) { p_345553_.hurtAndBreak(1, p_346282_, EquipmentSlot.MAINHAND); diff --git a/patches/net/minecraft/world/item/Tiers.java.patch b/patches/net/minecraft/world/item/Tiers.java.patch deleted file mode 100644 index 48dc1da1b8..0000000000 --- a/patches/net/minecraft/world/item/Tiers.java.patch +++ /dev/null @@ -1,9 +0,0 @@ ---- a/net/minecraft/world/item/Tiers.java -+++ b/net/minecraft/world/item/Tiers.java -@@ -61,4 +_,6 @@ - public Ingredient getRepairIngredient() { - return this.repairIngredient.get(); - } -+ -+ @org.jetbrains.annotations.Nullable public net.minecraft.tags.TagKey getTag() { return net.neoforged.neoforge.common.CommonHooks.getTagFromVanillaTier(this); } - } diff --git a/patches/net/minecraft/world/item/TridentItem.java.patch b/patches/net/minecraft/world/item/TridentItem.java.patch index 1f32d6ec83..5cd4365e49 100644 --- a/patches/net/minecraft/world/item/TridentItem.java.patch +++ b/patches/net/minecraft/world/item/TridentItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/TridentItem.java +++ b/net/minecraft/world/item/TridentItem.java -@@ -160,4 +_,9 @@ +@@ -161,4 +_,9 @@ throwntrident.pickup = AbstractArrow.Pickup.ALLOWED; return throwntrident; } diff --git a/patches/net/minecraft/world/item/UseAnim.java.patch b/patches/net/minecraft/world/item/UseAnim.java.patch deleted file mode 100644 index 3f78819ea3..0000000000 --- a/patches/net/minecraft/world/item/UseAnim.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/net/minecraft/world/item/UseAnim.java -+++ b/net/minecraft/world/item/UseAnim.java -@@ -10,5 +_,10 @@ - CROSSBOW, - SPYGLASS, - TOOT_HORN, -- BRUSH; -+ BRUSH, -+ /** -+ * Items with custom arm animation should return this in `Item#getUseAnimation` -+ * to prevent vanilla from also trying to animate same item -+ */ -+ CUSTOM - } diff --git a/patches/net/minecraft/world/item/alchemy/PotionContents.java.patch b/patches/net/minecraft/world/item/alchemy/PotionContents.java.patch index 90c51e7d35..f5c53ac620 100644 --- a/patches/net/minecraft/world/item/alchemy/PotionContents.java.patch +++ b/patches/net/minecraft/world/item/alchemy/PotionContents.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/alchemy/PotionContents.java +++ b/net/minecraft/world/item/alchemy/PotionContents.java -@@ -173,6 +_,10 @@ +@@ -201,6 +_,10 @@ p_331296_.accept(CommonComponents.EMPTY); p_331296_.accept(Component.translatable("potion.whenDrank").withStyle(ChatFormatting.DARK_PURPLE)); diff --git a/patches/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java.patch b/patches/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java.patch new file mode 100644 index 0000000000..4e1c2927dc --- /dev/null +++ b/patches/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java ++++ b/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java +@@ -56,7 +_,9 @@ + } + + Vec3 vec3 = p_366884_.position(); +- if (p_366884_.randomTeleport(d0, d1, d2, true)) { ++ var event = net.neoforged.neoforge.event.EventHooks.onItemConsumptionTeleport(p_366884_, p_366476_, d0, d1, d2); ++ if (event.isCanceled()) return false; ++ if (p_366884_.randomTeleport(event.getTargetX(), event.getTargetY(), event.getTargetZ(), true)) { + p_366648_.gameEvent(GameEvent.TELEPORT, vec3, GameEvent.Context.of(p_366884_)); + SoundSource soundsource; + SoundEvent soundevent; diff --git a/patches/net/minecraft/world/item/crafting/AbstractCookingRecipe.java.patch b/patches/net/minecraft/world/item/crafting/AbstractCookingRecipe.java.patch new file mode 100644 index 0000000000..305a1d580b --- /dev/null +++ b/patches/net/minecraft/world/item/crafting/AbstractCookingRecipe.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/item/crafting/AbstractCookingRecipe.java ++++ b/net/minecraft/world/item/crafting/AbstractCookingRecipe.java +@@ -75,7 +_,7 @@ + Codec.STRING.optionalFieldOf("group", "").forGetter(SingleItemRecipe::group), + CookingBookCategory.CODEC.fieldOf("category").orElse(CookingBookCategory.MISC).forGetter(AbstractCookingRecipe::category), + Ingredient.CODEC.fieldOf("ingredient").forGetter(SingleItemRecipe::input), +- ItemStack.STRICT_SINGLE_ITEM_CODEC.fieldOf("result").forGetter(SingleItemRecipe::result), ++ ItemStack.CODEC.fieldOf("result").forGetter(SingleItemRecipe::result), + Codec.FLOAT.fieldOf("experience").orElse(0.0F).forGetter(AbstractCookingRecipe::experience), + Codec.INT.fieldOf("cookingtime").orElse(p_379669_).forGetter(AbstractCookingRecipe::cookingTime) + ) diff --git a/patches/net/minecraft/world/item/crafting/BannerDuplicateRecipe.java.patch b/patches/net/minecraft/world/item/crafting/BannerDuplicateRecipe.java.patch index 7628e93377..2a92e339c3 100644 --- a/patches/net/minecraft/world/item/crafting/BannerDuplicateRecipe.java.patch +++ b/patches/net/minecraft/world/item/crafting/BannerDuplicateRecipe.java.patch @@ -1,13 +1,11 @@ --- a/net/minecraft/world/item/crafting/BannerDuplicateRecipe.java +++ b/net/minecraft/world/item/crafting/BannerDuplicateRecipe.java -@@ -79,8 +_,8 @@ +@@ -84,7 +_,7 @@ for (int i = 0; i < nonnulllist.size(); i++) { ItemStack itemstack = p_345377_.getItem(i); if (!itemstack.isEmpty()) { -- if (itemstack.getItem().hasCraftingRemainingItem()) { -- nonnulllist.set(i, new ItemStack(itemstack.getItem().getCraftingRemainingItem())); -+ if (itemstack.hasCraftingRemainingItem()) { -+ nonnulllist.set(i, itemstack.getCraftingRemainingItem()); +- ItemStack itemstack1 = itemstack.getItem().getCraftingRemainder(); ++ ItemStack itemstack1 = itemstack.getCraftingRemainder(); + if (!itemstack1.isEmpty()) { + nonnulllist.set(i, itemstack1); } else if (!itemstack.getOrDefault(DataComponents.BANNER_PATTERNS, BannerPatternLayers.EMPTY).layers().isEmpty()) { - nonnulllist.set(i, itemstack.copyWithCount(1)); - } diff --git a/patches/net/minecraft/world/item/crafting/BookCloningRecipe.java.patch b/patches/net/minecraft/world/item/crafting/BookCloningRecipe.java.patch index d801583d1e..ccfed826ab 100644 --- a/patches/net/minecraft/world/item/crafting/BookCloningRecipe.java.patch +++ b/patches/net/minecraft/world/item/crafting/BookCloningRecipe.java.patch @@ -1,13 +1,11 @@ --- a/net/minecraft/world/item/crafting/BookCloningRecipe.java +++ b/net/minecraft/world/item/crafting/BookCloningRecipe.java -@@ -83,8 +_,8 @@ +@@ -88,7 +_,7 @@ for (int i = 0; i < nonnulllist.size(); i++) { ItemStack itemstack = p_344763_.getItem(i); -- if (itemstack.getItem().hasCraftingRemainingItem()) { -- nonnulllist.set(i, new ItemStack(itemstack.getItem().getCraftingRemainingItem())); -+ if (itemstack.hasCraftingRemainingItem()) { -+ nonnulllist.set(i, itemstack.getCraftingRemainingItem()); +- ItemStack itemstack1 = itemstack.getItem().getCraftingRemainder(); ++ ItemStack itemstack1 = itemstack.getCraftingRemainder(); + if (!itemstack1.isEmpty()) { + nonnulllist.set(i, itemstack1); } else if (itemstack.getItem() instanceof WrittenBookItem) { - nonnulllist.set(i, itemstack.copyWithCount(1)); - break; diff --git a/patches/net/minecraft/world/item/crafting/CraftingRecipe.java.patch b/patches/net/minecraft/world/item/crafting/CraftingRecipe.java.patch new file mode 100644 index 0000000000..7ba401edc6 --- /dev/null +++ b/patches/net/minecraft/world/item/crafting/CraftingRecipe.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/item/crafting/CraftingRecipe.java ++++ b/net/minecraft/world/item/crafting/CraftingRecipe.java +@@ -23,7 +_,7 @@ + NonNullList nonnulllist = NonNullList.withSize(p_380223_.size(), ItemStack.EMPTY); + + for (int i = 0; i < nonnulllist.size(); i++) { +- Item item = p_380223_.getItem(i).getItem(); ++ ItemStack item = p_380223_.getItem(i); + nonnulllist.set(i, item.getCraftingRemainder()); + } + diff --git a/patches/net/minecraft/world/item/crafting/Ingredient.java.patch b/patches/net/minecraft/world/item/crafting/Ingredient.java.patch index 9699025400..f80d5c47b2 100644 --- a/patches/net/minecraft/world/item/crafting/Ingredient.java.patch +++ b/patches/net/minecraft/world/item/crafting/Ingredient.java.patch @@ -1,127 +1,71 @@ --- a/net/minecraft/world/item/crafting/Ingredient.java +++ b/net/minecraft/world/item/crafting/Ingredient.java -@@ -29,15 +_,54 @@ +@@ -24,18 +_,20 @@ + import net.minecraft.world.level.ItemLike; public final class Ingredient implements Predicate { - public static final Ingredient EMPTY = new Ingredient(Stream.empty()); -- public static final StreamCodec CONTENTS_STREAM_CODEC = ItemStack.LIST_STREAM_CODEC -- .map(p_319730_ -> fromValues(p_319730_.stream().map(Ingredient.ItemValue::new)), p_319731_ -> Arrays.asList(p_319731_.getItems())); -+ public static final StreamCodec CONTENTS_STREAM_CODEC = new StreamCodec<>() { -+ private static final StreamCodec CUSTOM_INGREDIENT_CODEC = net.minecraft.network.codec.ByteBufCodecs.registry(net.neoforged.neoforge.registries.NeoForgeRegistries.Keys.INGREDIENT_TYPES) -+ .dispatch(c -> c.getType(), t -> t.streamCodec()); -+ -+ @Override -+ public void encode(RegistryFriendlyByteBuf buf, Ingredient ingredient) { -+ if (ingredient.isSimple()) { -+ ItemStack.LIST_STREAM_CODEC.encode(buf, Arrays.asList(ingredient.getItems())); -+ } else { -+ buf.writeVarInt(-1); -+ CUSTOM_INGREDIENT_CODEC.encode(buf, ingredient.customIngredient); -+ } -+ } -+ -+ @Override -+ public Ingredient decode(RegistryFriendlyByteBuf buf) { -+ var size = buf.readVarInt(); -+ if (size == -1) { -+ return new Ingredient(CUSTOM_INGREDIENT_CODEC.decode(buf)); -+ } -+ return fromValues(Stream.generate(() -> ItemStack.STREAM_CODEC.decode(buf)).limit(size).map(Ingredient.ItemValue::new)); -+ } -+ }; - private final Ingredient.Value[] values; +- public static final StreamCodec CONTENTS_STREAM_CODEC = ByteBufCodecs.holderSet(Registries.ITEM) +- .map(Ingredient::new, p_360055_ -> p_360055_.values); +- public static final StreamCodec> OPTIONAL_CONTENTS_STREAM_CODEC = ByteBufCodecs.holderSet(Registries.ITEM) ++ public static final StreamCodec CONTENTS_STREAM_CODEC = net.neoforged.neoforge.common.crafting.IngredientCodecs.streamCodec(ByteBufCodecs.holderSet(Registries.ITEM) ++ .map(Ingredient::new, p_360055_ -> p_360055_.getValuesForSync())); ++ public static final StreamCodec> OPTIONAL_CONTENTS_STREAM_CODEC = net.neoforged.neoforge.common.crafting.IngredientCodecs.optionalStreamCodec(ByteBufCodecs.holderSet(Registries.ITEM) + .map( + p_360058_ -> p_360058_.size() == 0 ? Optional.empty() : Optional.of(new Ingredient((HolderSet)p_360058_)), +- p_360056_ -> p_360056_.map(p_360062_ -> p_360062_.values).orElse(HolderSet.direct()) +- ); ++ p_360056_ -> p_360056_.map(p_360062_ -> p_360062_.getValuesForSync()).orElse(HolderSet.direct()) ++ )); + public static final Codec> NON_AIR_HOLDER_SET_CODEC = HolderSetCodec.create(Registries.ITEM, Item.CODEC, false); +- public static final Codec CODEC = ExtraCodecs.nonEmptyHolderSet(NON_AIR_HOLDER_SET_CODEC).xmap(Ingredient::new, p_360061_ -> p_360061_.values); ++ public static final Codec CODEC = net.neoforged.neoforge.common.crafting.IngredientCodecs.codec(ExtraCodecs.nonEmptyHolderSet(NON_AIR_HOLDER_SET_CODEC).xmap(Ingredient::new, p_360061_ -> p_360061_.values)); + private final HolderSet values; @Nullable - private ItemStack[] itemStacks; - @Nullable - private IntList stackingIds; -- public static final Codec CODEC = codec(true); -- public static final Codec CODEC_NONEMPTY = codec(false); + private List> items; + @Nullable + private net.neoforged.neoforge.common.crafting.ICustomIngredient customIngredient = null; -+ -+ /** -+ * This codec allows both the {@code {...}} and {@code [{...}, {...}, ...]} syntax. -+ * {@code []} is allowed for empty ingredients, and will only match empty stacks. -+ */ -+ public static final Codec CODEC = net.neoforged.neoforge.common.crafting.CraftingHelper.makeIngredientCodec(true); -+ /** -+ * Same as {@link #CODEC} except that empty ingredients ({@code []}) are not allowed. -+ */ -+ public static final Codec CODEC_NONEMPTY = net.neoforged.neoforge.common.crafting.CraftingHelper.makeIngredientCodec(false); -+ /** -+ * This is a codec that only allows the {@code {...}} syntax. -+ * Array ingredients are serialized using the CompoundIngredient custom ingredient type: -+ * {@code { "type": "neoforge:compound", "ingredients": [{...}, {...}, ...] }}. -+ */ -+ public static final com.mojang.serialization.MapCodec MAP_CODEC_NONEMPTY = net.neoforged.neoforge.common.crafting.CraftingHelper.makeIngredientMapCodec(); -+ public static final Codec> LIST_CODEC = MAP_CODEC_NONEMPTY.codec().listOf(); -+ public static final Codec> LIST_CODEC_NONEMPTY = LIST_CODEC.validate(list -> list.isEmpty() ? DataResult.error(() -> "Item array cannot be empty, at least one item must be defined") : DataResult.success(list)); - private Ingredient(Stream p_43907_) { - this.values = p_43907_.toArray(Ingredient.Value[]::new); -@@ -47,9 +_,19 @@ - this.values = p_301044_; + private Ingredient(HolderSet p_365027_) { + p_365027_.unwrap().ifRight(p_360057_ -> { +@@ -48,19 +_,31 @@ + this.values = p_365027_; } + public Ingredient(net.neoforged.neoforge.common.crafting.ICustomIngredient customIngredient) { -+ this(new Value[0]); ++ this.values = HolderSet.empty(); + this.customIngredient = customIngredient; + } + - public ItemStack[] getItems() { - if (this.itemStacks == null) { -- this.itemStacks = Arrays.stream(this.values).flatMap(p_43916_ -> p_43916_.getItems().stream()).distinct().toArray(ItemStack[]::new); -+ // Neo: vanilla used Stream.distinct() here which has basically no effect as ItemStack does not override hashCode() and equals(). -+ // Using ItemStackLinkedSet::createTypeAndComponentsSet instead for a real distinct result. -+ final Stream stream = this.customIngredient == null -+ ? Arrays.stream(this.values).flatMap(value -> value.getItems().stream()) -+ : this.customIngredient.getItems(); -+ this.itemStacks = stream.collect(java.util.stream.Collectors.toCollection(net.minecraft.world.item.ItemStackLinkedSet::createTypeAndComponentsSet)).toArray(ItemStack[]::new); + public static boolean testOptionalIngredient(Optional p_362504_, ItemStack p_363604_) { + return p_362504_.map(p_360060_ -> p_360060_.test(p_363604_)).orElseGet(p_363604_::isEmpty); + } + + public List> items() { + if (this.items == null) { +- this.items = ImmutableList.copyOf(this.values); ++ if (this.customIngredient != null) { ++ this.items = this.customIngredient.items().toList(); ++ } else { ++ this.items = ImmutableList.copyOf(this.values); ++ } } - return this.itemStacks; -@@ -58,6 +_,8 @@ - public boolean test(@Nullable ItemStack p_43914_) { - if (p_43914_ == null) { - return false; -+ } else if (this.customIngredient != null) { -+ return this.customIngredient.test(p_43914_); - } else if (this.isEmpty()) { - return p_43914_.isEmpty(); - } else { -@@ -86,13 +_,65 @@ - return this.stackingIds; + return this.items; } -+ /** -+ * Returns {@code true} if this ingredient is explicitly chosen to be empty, i.e. using {@code []}. -+ */ - public boolean isEmpty() { -- return this.values.length == 0; -+ return this.values.length == 0 && !isCustom(); -+ } -+ -+ /** -+ * Returns {@code true} if this ingredient has an empty stack list. -+ * Unlike {@link #isEmpty()}, this will catch "accidentally empty" ingredients, -+ * for example a tag ingredient that has an empty tag. -+ */ -+ public boolean hasNoItems() { -+ ItemStack[] items = getItems(); -+ if (items.length == 0) -+ return true; -+ if (items.length == 1) { -+ // If we potentially added a barrier due to the ingredient being an empty tag, try and check if it is the stack we added -+ ItemStack item = items[0]; -+ return item.getItem() == net.minecraft.world.item.Items.BARRIER && item.getHoverName() instanceof net.minecraft.network.chat.MutableComponent hoverName && hoverName.getString().startsWith("Empty Tag: "); + public boolean test(ItemStack p_43914_) { ++ if (this.customIngredient != null) { ++ return this.customIngredient.test(p_43914_); + } -+ return false; - } + List> list = this.items(); + + for (int i = 0; i < list.size(); i++) { +@@ -74,7 +_,49 @@ @Override public boolean equals(Object p_301003_) { -- return p_301003_ instanceof Ingredient ingredient ? Arrays.equals((Object[])this.values, (Object[])ingredient.values) : false; -+ return p_301003_ instanceof Ingredient ingredient ? java.util.Objects.equals(this.customIngredient, ingredient.customIngredient) && Arrays.equals((Object[])this.values, (Object[])ingredient.values) : false; +- return p_301003_ instanceof Ingredient ingredient ? Objects.equals(this.values, ingredient.values) : false; ++ return p_301003_ instanceof Ingredient ingredient ? java.util.Objects.equals(this.customIngredient, ingredient.customIngredient) && Objects.equals(this.values, ingredient.values) : false; + } + + @Override @@ -129,20 +73,30 @@ + if (this.customIngredient != null) { + return this.customIngredient.hashCode(); + } -+ return Arrays.hashCode(this.values); ++ return this.values.hashCode(); + } + + /** -+ * Retrieves the underlying values of this ingredient. -+ * If this is a {@linkplain #isCustom custom ingredient}, an exception is thrown. -+ */ -+ public Value[] getValues() { ++ * Retrieves the underlying values of this ingredient. ++ * If this is a {@linkplain #isCustom custom ingredient}, an exception is thrown. ++ */ ++ public HolderSet getValues() { + if (isCustom()) { + throw new IllegalStateException("Cannot retrieve values from custom ingredient!"); + } + return this.values; + } + ++ /** ++ * Retrieves the holder set to use for syncing {@linkplain #isSimple() simple} ingredients ++ */ ++ private HolderSet getValuesForSync() { ++ if (isCustom()) { ++ return HolderSet.direct(this.items()); ++ } ++ return this.values; ++ } ++ + public boolean isSimple() { + return this.customIngredient == null || this.customIngredient.isSimple(); + } @@ -156,79 +110,14 @@ + return this.customIngredient != null; } - public static Ingredient fromValues(Stream p_43939_) { -@@ -120,6 +_,7 @@ - return fromValues(Stream.of(new Ingredient.TagValue(p_204133_))); + public static Ingredient of(ItemLike p_364285_) { +@@ -94,6 +_,9 @@ } -+ @Deprecated // Neo: We take over the codec creation entirely to support custom ingredients - see CraftingHelper - private static Codec codec(boolean p_301074_) { - Codec codec = Codec.list(Ingredient.Value.CODEC) - .comapFlatMap( -@@ -144,10 +_,11 @@ - } - - public static record ItemValue(ItemStack item) implements Ingredient.Value { -- static final Codec CODEC = RecordCodecBuilder.create( -+ static final com.mojang.serialization.MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec( - p_330109_ -> p_330109_.group(ItemStack.SIMPLE_ITEM_CODEC.fieldOf("item").forGetter(p_300919_ -> p_300919_.item)) - .apply(p_330109_, Ingredient.ItemValue::new) - ); -+ static final Codec CODEC = MAP_CODEC.codec(); - - @Override - public boolean equals(Object p_301316_) { -@@ -156,6 +_,12 @@ - : ingredient$itemvalue.item.getItem().equals(this.item.getItem()) && ingredient$itemvalue.item.getCount() == this.item.getCount(); - } - -+ // Neo: Add a hashCode() implementation that matches equals() -+ @Override -+ public int hashCode() { -+ return 31 * item.getItem().hashCode() + item.getCount(); + public SlotDisplay display() { ++ if (this.customIngredient != null) { ++ return this.customIngredient.display(); + } -+ - @Override - public Collection getItems() { - return Collections.singleton(this.item); -@@ -163,10 +_,11 @@ - } - - public static record TagValue(TagKey tag) implements Ingredient.Value { -- static final Codec CODEC = RecordCodecBuilder.create( -+ static final com.mojang.serialization.MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec( - p_301118_ -> p_301118_.group(TagKey.codec(Registries.ITEM).fieldOf("tag").forGetter(p_301154_ -> p_301154_.tag)) - .apply(p_301118_, Ingredient.TagValue::new) - ); -+ static final Codec CODEC = MAP_CODEC.codec(); - - @Override - public boolean equals(Object p_301162_) { -@@ -181,12 +_,18 @@ - list.add(new ItemStack(holder)); - } - -+ if (list.isEmpty()) { -+ net.minecraft.world.item.ItemStack itemStack = new net.minecraft.world.item.ItemStack(net.minecraft.world.level.block.Blocks.BARRIER); -+ itemStack.set(net.minecraft.core.component.DataComponents.CUSTOM_NAME, net.minecraft.network.chat.Component.literal("Empty Tag: " + this.tag.location())); -+ list.add(itemStack); -+ } - return list; - } - } - -+ // Neo: Do not extend this interface. For custom ingredient behaviors see ICustomIngredient. - public interface Value { -- Codec CODEC = Codec.xor(Ingredient.ItemValue.CODEC, Ingredient.TagValue.CODEC) -+ com.mojang.serialization.MapCodec MAP_CODEC = net.neoforged.neoforge.common.util.NeoForgeExtraCodecs.xor(Ingredient.ItemValue.MAP_CODEC, Ingredient.TagValue.MAP_CODEC) - .xmap(p_300956_ -> p_300956_.map(p_300932_ -> p_300932_, p_301313_ -> p_301313_), p_301304_ -> { - if (p_301304_ instanceof Ingredient.TagValue ingredient$tagvalue) { - return Either.right(ingredient$tagvalue); -@@ -196,6 +_,7 @@ - throw new UnsupportedOperationException("This is neither an item value nor a tag value."); - } - }); -+ Codec CODEC = MAP_CODEC.codec(); - - Collection getItems(); - } + return (SlotDisplay)this.values + .unwrap() + .map(SlotDisplay.TagSlotDisplay::new, p_380837_ -> new SlotDisplay.Composite(p_380837_.stream().map(Ingredient::displayForSingleItem).toList())); diff --git a/patches/net/minecraft/world/item/crafting/Recipe.java.patch b/patches/net/minecraft/world/item/crafting/Recipe.java.patch index 4c7128f14c..7a084590af 100644 --- a/patches/net/minecraft/world/item/crafting/Recipe.java.patch +++ b/patches/net/minecraft/world/item/crafting/Recipe.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/crafting/Recipe.java +++ b/net/minecraft/world/item/crafting/Recipe.java -@@ -15,6 +_,7 @@ +@@ -14,6 +_,7 @@ public interface Recipe { Codec> CODEC = BuiltInRegistries.RECIPE_SERIALIZER.byNameCodec().dispatch(Recipe::getSerializer, RecipeSerializer::codec); @@ -8,23 +8,3 @@ StreamCodec> STREAM_CODEC = ByteBufCodecs.registry(Registries.RECIPE_SERIALIZER) .dispatch(Recipe::getSerializer, RecipeSerializer::streamCodec); -@@ -30,9 +_,9 @@ - NonNullList nonnulllist = NonNullList.withSize(p_345383_.size(), ItemStack.EMPTY); - - for (int i = 0; i < nonnulllist.size(); i++) { -- Item item = p_345383_.getItem(i).getItem(); -+ ItemStack item = p_345383_.getItem(i); - if (item.hasCraftingRemainingItem()) { -- nonnulllist.set(i, new ItemStack(item.getCraftingRemainingItem())); -+ nonnulllist.set(i, item.getCraftingRemainingItem()); - } - } - -@@ -65,6 +_,6 @@ - - default boolean isIncomplete() { - NonNullList nonnulllist = this.getIngredients(); -- return nonnulllist.isEmpty() || nonnulllist.stream().anyMatch(p_151268_ -> p_151268_.getItems().length == 0); -+ return nonnulllist.isEmpty() || nonnulllist.stream().anyMatch(Ingredient::hasNoItems); - } - } diff --git a/patches/net/minecraft/world/item/crafting/RecipeManager.java.patch b/patches/net/minecraft/world/item/crafting/RecipeManager.java.patch deleted file mode 100644 index c4f01d12d0..0000000000 --- a/patches/net/minecraft/world/item/crafting/RecipeManager.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- a/net/minecraft/world/item/crafting/RecipeManager.java -+++ b/net/minecraft/world/item/crafting/RecipeManager.java -@@ -50,16 +_,22 @@ - this.hasErrors = false; - Builder, RecipeHolder> builder = ImmutableMultimap.builder(); - com.google.common.collect.ImmutableMap.Builder> builder1 = ImmutableMap.builder(); -- RegistryOps registryops = this.registries.createSerializationContext(JsonOps.INSTANCE); -+ RegistryOps registryops = this.makeConditionalOps(); // Neo: add condition context - - for (Entry entry : p_44037_.entrySet()) { - ResourceLocation resourcelocation = entry.getKey(); -+ if (resourcelocation.getPath().startsWith("_")) continue; //Forge: filter anything beginning with "_" as it's used for metadata. - - try { -- Recipe recipe = Recipe.CODEC.parse(registryops, entry.getValue()).getOrThrow(JsonParseException::new); -+ var decoded = Recipe.CONDITIONAL_CODEC.parse(registryops, entry.getValue()).getOrThrow(JsonParseException::new); -+ decoded.ifPresentOrElse(r -> { -+ Recipe recipe = r.carrier(); - RecipeHolder recipeholder = new RecipeHolder<>(resourcelocation, recipe); - builder.put(recipe.getType(), recipeholder); - builder1.put(resourcelocation, recipeholder); -+ }, () -> { -+ LOGGER.debug("Skipping loading recipe {} as its conditions were not met", resourcelocation); -+ }); - } catch (IllegalArgumentException | JsonParseException jsonparseexception) { - LOGGER.error("Parsing error loading recipe {}", resourcelocation, jsonparseexception); - } diff --git a/patches/net/minecraft/world/item/crafting/RepairItemRecipe.java.patch b/patches/net/minecraft/world/item/crafting/RepairItemRecipe.java.patch index 5838660aab..91780eb1f2 100644 --- a/patches/net/minecraft/world/item/crafting/RepairItemRecipe.java.patch +++ b/patches/net/minecraft/world/item/crafting/RepairItemRecipe.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/crafting/RepairItemRecipe.java +++ b/net/minecraft/world/item/crafting/RepairItemRecipe.java -@@ -47,7 +_,9 @@ +@@ -46,7 +_,9 @@ && p_336139_.has(DataComponents.MAX_DAMAGE) && p_335795_.has(DataComponents.MAX_DAMAGE) && p_336139_.has(DataComponents.DAMAGE) diff --git a/patches/net/minecraft/world/item/crafting/ShapedRecipe.java.patch b/patches/net/minecraft/world/item/crafting/ShapedRecipe.java.patch deleted file mode 100644 index 520c71a87f..0000000000 --- a/patches/net/minecraft/world/item/crafting/ShapedRecipe.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/item/crafting/ShapedRecipe.java -+++ b/net/minecraft/world/item/crafting/ShapedRecipe.java -@@ -84,7 +_,7 @@ - @Override - public boolean isIncomplete() { - NonNullList nonnulllist = this.getIngredients(); -- return nonnulllist.isEmpty() || nonnulllist.stream().filter(p_151277_ -> !p_151277_.isEmpty()).anyMatch(p_151273_ -> p_151273_.getItems().length == 0); -+ return nonnulllist.isEmpty() || nonnulllist.stream().filter(p_151277_ -> !p_151277_.isEmpty()).anyMatch(Ingredient::hasNoItems); - } - - public static class Serializer implements RecipeSerializer { diff --git a/patches/net/minecraft/world/item/crafting/ShapedRecipePattern.java.patch b/patches/net/minecraft/world/item/crafting/ShapedRecipePattern.java.patch index 9d6f735dea..cd823dd075 100644 --- a/patches/net/minecraft/world/item/crafting/ShapedRecipePattern.java.patch +++ b/patches/net/minecraft/world/item/crafting/ShapedRecipePattern.java.patch @@ -1,11 +1,12 @@ --- a/net/minecraft/world/item/crafting/ShapedRecipePattern.java +++ b/net/minecraft/world/item/crafting/ShapedRecipePattern.java -@@ -20,7 +_,30 @@ +@@ -21,8 +_,31 @@ import net.minecraft.world.item.ItemStack; public final class ShapedRecipePattern { + /** @deprecated Neo: use {@link #getMaxWidth} and {@link #getMaxHeight} */ @Deprecated private static final int MAX_SIZE = 3; + public static final char EMPTY_SLOT = ' '; + static int maxWidth = 3; + static int maxHeight = 3; + @@ -31,7 +32,7 @@ public static final MapCodec MAP_CODEC = ShapedRecipePattern.Data.MAP_CODEC .flatXmap( ShapedRecipePattern::unpack, -@@ -214,16 +_,16 @@ +@@ -206,16 +_,16 @@ public static record Data(Map key, List pattern) { private static final Codec> PATTERN_CODEC = Codec.STRING.listOf().comapFlatMap(p_312085_ -> { diff --git a/patches/net/minecraft/world/item/crafting/ShapelessRecipe.java.patch b/patches/net/minecraft/world/item/crafting/ShapelessRecipe.java.patch index 67d0abb76e..9e0f171250 100644 --- a/patches/net/minecraft/world/item/crafting/ShapelessRecipe.java.patch +++ b/patches/net/minecraft/world/item/crafting/ShapelessRecipe.java.patch @@ -1,21 +1,21 @@ --- a/net/minecraft/world/item/crafting/ShapelessRecipe.java +++ b/net/minecraft/world/item/crafting/ShapelessRecipe.java -@@ -18,12 +_,14 @@ - final CraftingBookCategory category; - final ItemStack result; - final NonNullList ingredients; +@@ -24,12 +_,14 @@ + final List ingredients; + @Nullable + private PlacementInfo placementInfo; + private final boolean isSimple; - public ShapelessRecipe(String p_249640_, CraftingBookCategory p_249390_, ItemStack p_252071_, NonNullList p_250689_) { + public ShapelessRecipe(String p_249640_, CraftingBookCategory p_249390_, ItemStack p_252071_, List p_361103_) { this.group = p_249640_; this.category = p_249390_; this.result = p_252071_; - this.ingredients = p_250689_; -+ this.isSimple = p_250689_.stream().allMatch(Ingredient::isSimple); + this.ingredients = p_361103_; ++ this.isSimple = p_361103_.stream().allMatch(Ingredient::isSimple); } @Override -@@ -54,6 +_,12 @@ +@@ -59,6 +_,12 @@ public boolean matches(CraftingInput p_346123_, Level p_44263_) { if (p_346123_.ingredientCount() != this.ingredients.size()) { return false; @@ -28,19 +28,12 @@ } else { return p_346123_.size() == 1 && this.ingredients.size() == 1 ? this.ingredients.getFirst().test(p_346123_.getItem(0)) -@@ -81,12 +_,12 @@ - .fieldOf("ingredients") - .flatXmap( - p_301021_ -> { -- Ingredient[] aingredient = p_301021_.stream().filter(p_300883_ -> !p_300883_.isEmpty()).toArray(Ingredient[]::new); -+ Ingredient[] aingredient = p_301021_.toArray(Ingredient[]::new); // Neo skip the empty check and immediately create the array. - if (aingredient.length == 0) { - return DataResult.error(() -> "No ingredients for shapeless recipe"); - } else { -- return aingredient.length > 9 -- ? DataResult.error(() -> "Too many ingredients for shapeless recipe") -+ return aingredient.length > ShapedRecipePattern.maxHeight * ShapedRecipePattern.maxWidth -+ ? DataResult.error(() -> "Too many ingredients for shapeless recipe. The maximum is: %s".formatted(ShapedRecipePattern.maxHeight * ShapedRecipePattern.maxWidth)) - : DataResult.success(NonNullList.of(Ingredient.EMPTY, aingredient)); - } - }, +@@ -87,7 +_,7 @@ + Codec.STRING.optionalFieldOf("group", "").forGetter(p_301127_ -> p_301127_.group), + CraftingBookCategory.CODEC.fieldOf("category").orElse(CraftingBookCategory.MISC).forGetter(p_301133_ -> p_301133_.category), + ItemStack.STRICT_CODEC.fieldOf("result").forGetter(p_301142_ -> p_301142_.result), +- Ingredient.CODEC.listOf(1, 9).fieldOf("ingredients").forGetter(p_360071_ -> p_360071_.ingredients) ++ Codec.lazyInitialized(() -> Ingredient.CODEC.listOf(1, ShapedRecipePattern.maxHeight * ShapedRecipePattern.maxWidth)).fieldOf("ingredients").forGetter(p_360071_ -> p_360071_.ingredients) + ) + .apply(p_360072_, ShapelessRecipe::new) + ); diff --git a/patches/net/minecraft/world/item/crafting/ShulkerBoxColoring.java.patch b/patches/net/minecraft/world/item/crafting/ShulkerBoxColoring.java.patch deleted file mode 100644 index 8ad7cc1c6d..0000000000 --- a/patches/net/minecraft/world/item/crafting/ShulkerBoxColoring.java.patch +++ /dev/null @@ -1,38 +0,0 @@ ---- a/net/minecraft/world/item/crafting/ShulkerBoxColoring.java -+++ b/net/minecraft/world/item/crafting/ShulkerBoxColoring.java -@@ -24,7 +_,7 @@ - if (Block.byItem(itemstack.getItem()) instanceof ShulkerBoxBlock) { - i++; - } else { -- if (!(itemstack.getItem() instanceof DyeItem)) { -+ if (!itemstack.is(net.neoforged.neoforge.common.Tags.Items.DYES)) { - return false; - } - -@@ -42,7 +_,7 @@ - - public ItemStack assemble(CraftingInput p_346433_, HolderLookup.Provider p_335717_) { - ItemStack itemstack = ItemStack.EMPTY; -- DyeItem dyeitem = (DyeItem)Items.WHITE_DYE; -+ net.minecraft.world.item.DyeColor dyecolor = net.minecraft.world.item.DyeColor.WHITE; - - for (int i = 0; i < p_346433_.size(); i++) { - ItemStack itemstack1 = p_346433_.getItem(i); -@@ -50,13 +_,14 @@ - Item item = itemstack1.getItem(); - if (Block.byItem(item) instanceof ShulkerBoxBlock) { - itemstack = itemstack1; -- } else if (item instanceof DyeItem) { -- dyeitem = (DyeItem)item; -+ } else { -+ net.minecraft.world.item.DyeColor tmp = net.minecraft.world.item.DyeColor.getColor(itemstack1); -+ if (tmp != null) dyecolor = tmp; - } - } - } - -- Block block = ShulkerBoxBlock.getBlockByColor(dyeitem.getDyeColor()); -+ Block block = ShulkerBoxBlock.getBlockByColor(dyecolor); - return itemstack.transmuteCopy(block, 1); - } - diff --git a/patches/net/minecraft/world/item/crafting/SimpleCookingSerializer.java.patch b/patches/net/minecraft/world/item/crafting/SimpleCookingSerializer.java.patch deleted file mode 100644 index 090c3de77e..0000000000 --- a/patches/net/minecraft/world/item/crafting/SimpleCookingSerializer.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/item/crafting/SimpleCookingSerializer.java -+++ b/net/minecraft/world/item/crafting/SimpleCookingSerializer.java -@@ -20,7 +_,7 @@ - Codec.STRING.optionalFieldOf("group", "").forGetter(p_300832_ -> p_300832_.group), - CookingBookCategory.CODEC.fieldOf("category").orElse(CookingBookCategory.MISC).forGetter(p_300828_ -> p_300828_.category), - Ingredient.CODEC_NONEMPTY.fieldOf("ingredient").forGetter(p_300833_ -> p_300833_.ingredient), -- ItemStack.STRICT_SINGLE_ITEM_CODEC.fieldOf("result").forGetter(p_300827_ -> p_300827_.result), -+ ItemStack.CODEC.fieldOf("result").forGetter(p_300827_ -> p_300827_.result), - Codec.FLOAT.fieldOf("experience").orElse(0.0F).forGetter(p_300826_ -> p_300826_.experience), - Codec.INT.fieldOf("cookingtime").orElse(p_44331_).forGetter(p_300834_ -> p_300834_.cookingTime) - ) diff --git a/patches/net/minecraft/world/item/crafting/SmithingTransformRecipe.java.patch b/patches/net/minecraft/world/item/crafting/SmithingTransformRecipe.java.patch deleted file mode 100644 index fbf57bcd12..0000000000 --- a/patches/net/minecraft/world/item/crafting/SmithingTransformRecipe.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/item/crafting/SmithingTransformRecipe.java -+++ b/net/minecraft/world/item/crafting/SmithingTransformRecipe.java -@@ -60,7 +_,7 @@ - - @Override - public boolean isIncomplete() { -- return Stream.of(this.template, this.base, this.addition).anyMatch(Ingredient::isEmpty); -+ return Stream.of(this.template, this.base, this.addition).anyMatch(Ingredient::hasNoItems); - } - - public static class Serializer implements RecipeSerializer { diff --git a/patches/net/minecraft/world/item/crafting/SmithingTrimRecipe.java.patch b/patches/net/minecraft/world/item/crafting/SmithingTrimRecipe.java.patch deleted file mode 100644 index e2e5dadbda..0000000000 --- a/patches/net/minecraft/world/item/crafting/SmithingTrimRecipe.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/item/crafting/SmithingTrimRecipe.java -+++ b/net/minecraft/world/item/crafting/SmithingTrimRecipe.java -@@ -89,7 +_,7 @@ - - @Override - public boolean isIncomplete() { -- return Stream.of(this.template, this.base, this.addition).anyMatch(Ingredient::isEmpty); -+ return Stream.of(this.template, this.base, this.addition).anyMatch(Ingredient::hasNoItems); - } - - public static class Serializer implements RecipeSerializer { diff --git a/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch b/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch index 86a3a016cf..be865c9992 100644 --- a/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch +++ b/patches/net/minecraft/world/item/enchantment/Enchantment.java.patch @@ -43,7 +43,7 @@ public boolean canEnchant(ItemStack p_44689_) { return this.definition.supportedItems().contains(p_44689_.getItemHolder()); } -@@ -504,12 +_,26 @@ +@@ -511,12 +_,26 @@ return new Enchantment.Builder(p_345873_); } @@ -70,7 +70,7 @@ public Builder(Enchantment.EnchantmentDefinition p_345317_) { this.definition = p_345317_; } -@@ -562,6 +_,16 @@ +@@ -569,6 +_,16 @@ return this; } @@ -87,7 +87,7 @@ private List getEffectsList(DataComponentType> p_344770_) { return (List)this.effectLists.computeIfAbsent(p_344770_, p_346247_ -> { ArrayList arraylist = new ArrayList<>(); -@@ -572,7 +_,9 @@ +@@ -579,7 +_,9 @@ public Enchantment build(ResourceLocation p_344988_) { return new Enchantment( diff --git a/patches/net/minecraft/world/item/enchantment/EnchantmentHelper.java.patch b/patches/net/minecraft/world/item/enchantment/EnchantmentHelper.java.patch index f04fd8c5f6..3fee255d5d 100644 --- a/patches/net/minecraft/world/item/enchantment/EnchantmentHelper.java.patch +++ b/patches/net/minecraft/world/item/enchantment/EnchantmentHelper.java.patch @@ -20,7 +20,7 @@ ItemEnchantments itemenchantments = p_44845_.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY); return itemenchantments.getLevel(p_346179_); } -@@ -122,6 +_,12 @@ +@@ -128,6 +_,12 @@ public static void runIterationOnItem(ItemStack p_345425_, EnchantmentHelper.EnchantmentVisitor p_345023_) { ItemEnchantments itemenchantments = p_345425_.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY); @@ -33,7 +33,7 @@ for (Entry> entry : itemenchantments.entrySet()) { p_345023_.accept(entry.getKey(), entry.getIntValue()); } -@@ -132,6 +_,10 @@ +@@ -138,6 +_,10 @@ ) { if (!p_44852_.isEmpty()) { ItemEnchantments itemenchantments = p_44852_.get(DataComponents.ENCHANTMENTS); @@ -44,7 +44,7 @@ if (itemenchantments != null && !itemenchantments.isEmpty()) { EnchantedItemInUse enchantediteminuse = new EnchantedItemInUse(p_44852_, p_345566_, p_345792_); -@@ -417,6 +_,12 @@ +@@ -438,6 +_,12 @@ public static boolean hasTag(ItemStack p_345665_, TagKey p_345928_) { ItemEnchantments itemenchantments = p_345665_.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY); @@ -57,25 +57,7 @@ for (Entry> entry : itemenchantments.entrySet()) { Holder holder = entry.getKey(); if (holder.is(p_345928_)) { -@@ -484,7 +_,7 @@ - - public static int getEnchantmentCost(RandomSource p_220288_, int p_220289_, int p_220290_, ItemStack p_220291_) { - Item item = p_220291_.getItem(); -- int i = item.getEnchantmentValue(); -+ int i = p_220291_.getEnchantmentValue(); - if (i <= 0) { - return 0; - } else { -@@ -529,7 +_,7 @@ - public static List selectEnchantment(RandomSource p_220298_, ItemStack p_220299_, int p_220300_, Stream> p_346061_) { - List list = Lists.newArrayList(); - Item item = p_220299_.getItem(); -- int i = item.getEnchantmentValue(); -+ int i = p_220299_.getEnchantmentValue(); - if (i <= 0) { - return list; - } else { -@@ -575,7 +_,9 @@ +@@ -594,7 +_,9 @@ public static List getAvailableEnchantmentResults(int p_44818_, ItemStack p_44819_, Stream> p_345348_) { List list = Lists.newArrayList(); boolean flag = p_44819_.is(Items.BOOK); diff --git a/patches/net/minecraft/world/level/BaseSpawner.java.patch b/patches/net/minecraft/world/level/BaseSpawner.java.patch index 05af8829aa..6a423f6cca 100644 --- a/patches/net/minecraft/world/level/BaseSpawner.java.patch +++ b/patches/net/minecraft/world/level/BaseSpawner.java.patch @@ -9,27 +9,28 @@ public static final String SPAWN_DATA_TAG = "SpawnData"; private static final Logger LOGGER = LogUtils.getLogger(); private static final int EVENT_SPAWN = 1; -@@ -151,15 +_,14 @@ +@@ -151,16 +_,14 @@ entity.moveTo(entity.getX(), entity.getY(), entity.getZ(), randomsource.nextFloat() * 360.0F, 0.0F); if (entity instanceof Mob mob) { -- if (spawndata.getCustomSpawnRules().isEmpty() && !mob.checkSpawnRules(p_151312_, MobSpawnType.SPAWNER) +- if (spawndata.getCustomSpawnRules().isEmpty() && !mob.checkSpawnRules(p_151312_, EntitySpawnReason.SPAWNER) - || !mob.checkSpawnObstruction(p_151312_)) { -+ if (!net.neoforged.neoforge.event.EventHooks.checkSpawnPositionSpawner(mob, p_151312_, MobSpawnType.SPAWNER, spawndata, this)) { ++ if (!net.neoforged.neoforge.event.EventHooks.checkSpawnPositionSpawner(mob, p_151312_, EntitySpawnReason.SPAWNER, spawndata, this)) { continue; } boolean flag1 = spawndata.getEntityToSpawn().size() == 1 && spawndata.getEntityToSpawn().contains("id", 8); - if (flag1) { -- ((Mob)entity).finalizeSpawn(p_151312_, p_151312_.getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.SPAWNER, null); +- ((Mob)entity) +- .finalizeSpawn(p_151312_, p_151312_.getCurrentDifficultyAt(entity.blockPosition()), EntitySpawnReason.SPAWNER, null); - } + // Neo: Patch in FinalizeSpawn for spawners so it may be fired unconditionally, instead of only when vanilla would normally call it. + // The local flag1 is the conditions under which the spawner will normally call Mob#finalizeSpawn. -+ net.neoforged.neoforge.event.EventHooks.finalizeMobSpawnSpawner(mob, p_151312_, p_151312_.getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.SPAWNER, null, this, flag1); ++ net.neoforged.neoforge.event.EventHooks.finalizeMobSpawnSpawner(mob, p_151312_, p_151312_.getCurrentDifficultyAt(entity.blockPosition()), EntitySpawnReason.SPAWNER, null, this, flag1); spawndata.getEquipment().ifPresent(mob::equip); } -@@ -308,5 +_,12 @@ +@@ -309,5 +_,12 @@ public double getoSpin() { return this.oSpin; diff --git a/patches/net/minecraft/world/level/BlockGetter.java.patch b/patches/net/minecraft/world/level/BlockGetter.java.patch index c04b9cc5cf..60f517c0ab 100644 --- a/patches/net/minecraft/world/level/BlockGetter.java.patch +++ b/patches/net/minecraft/world/level/BlockGetter.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/level/BlockGetter.java +++ b/net/minecraft/world/level/BlockGetter.java -@@ -18,7 +_,7 @@ +@@ -20,7 +_,7 @@ import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.VoxelShape; -public interface BlockGetter extends LevelHeightAccessor { +public interface BlockGetter extends LevelHeightAccessor, net.neoforged.neoforge.common.extensions.IBlockGetterExtension { - @Nullable - BlockEntity getBlockEntity(BlockPos p_45570_); + int MAX_BLOCK_ITERATIONS_ALONG_TRAVEL = 16; -@@ -32,7 +_,7 @@ + @Nullable +@@ -36,7 +_,7 @@ FluidState getFluidState(BlockPos p_45569_); default int getLightEmission(BlockPos p_45572_) { @@ -17,4 +17,4 @@ + return this.getBlockState(p_45572_).getLightEmission(this, p_45572_); } - default int getMaxLightLevel() { + default Stream getBlockStates(AABB p_45557_) { diff --git a/patches/net/minecraft/world/level/Explosion.java.patch b/patches/net/minecraft/world/level/Explosion.java.patch deleted file mode 100644 index 285a7530f6..0000000000 --- a/patches/net/minecraft/world/level/Explosion.java.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/net/minecraft/world/level/Explosion.java -+++ b/net/minecraft/world/level/Explosion.java -@@ -269,6 +_,7 @@ - int j2 = Mth.floor(this.z - (double)f2 - 1.0); - int j1 = Mth.floor(this.z + (double)f2 + 1.0); - List list = this.level.getEntities(this.source, new AABB((double)k1, (double)i2, (double)j2, (double)l1, (double)i1, (double)j1)); -+ net.neoforged.neoforge.event.EventHooks.onExplosionDetonate(this.level, this, list, f2); - Vec3 vec3 = new Vec3(this.x, this.y, this.z); - - for (Entity entity : list) { -@@ -299,6 +_,7 @@ - d7 *= d10; - d9 *= d10; - Vec3 vec31 = new Vec3(d5, d7, d9); -+ vec31 = net.neoforged.neoforge.event.EventHooks.getExplosionKnockback(this.level, this, entity, vec31); - entity.setDeltaMovement(entity.getDeltaMovement().add(vec31)); - if (entity instanceof Player) { - Player player = (Player)entity; diff --git a/patches/net/minecraft/world/level/Level.java.patch b/patches/net/minecraft/world/level/Level.java.patch index c2328b4f8b..00df1925bc 100644 --- a/patches/net/minecraft/world/level/Level.java.patch +++ b/patches/net/minecraft/world/level/Level.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java -@@ -76,7 +_,7 @@ +@@ -78,7 +_,7 @@ import net.minecraft.world.phys.Vec3; import net.minecraft.world.scores.Scoreboard; @@ -9,7 +9,7 @@ public static final Codec> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION); public static final ResourceKey OVERWORLD = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("overworld")); public static final ResourceKey NETHER = ResourceKey.create(Registries.DIMENSION, ResourceLocation.withDefaultNamespace("the_nether")); -@@ -114,6 +_,11 @@ +@@ -115,6 +_,11 @@ private final RegistryAccess registryAccess; private final DamageSources damageSources; private long subTickCount; @@ -21,7 +21,7 @@ protected Level( WritableLevelData p_270739_, -@@ -216,11 +_,40 @@ +@@ -215,11 +_,36 @@ } else { LevelChunk levelchunk = this.getChunkAt(p_46605_); Block block = p_46606_.getBlock(); @@ -32,10 +32,6 @@ + blockSnapshot = net.neoforged.neoforge.common.util.BlockSnapshot.create(this.dimension, this, p_46605_, p_46607_); + this.capturedBlockSnapshots.add(blockSnapshot); + } -+ -+ BlockState old = getBlockState(p_46605_); -+ int oldLight = old.getLightEmission(this, p_46605_); -+ int oldOpacity = old.getLightBlock(this, p_46605_); + BlockState blockstate = levelchunk.setBlockState(p_46605_, p_46606_, (p_46607_ & 64) != 0); if (blockstate == null) { @@ -62,7 +58,7 @@ if (blockstate1 == p_46606_) { if (blockstate != blockstate1) { this.setBlocksDirty(p_46605_, blockstate, blockstate1); -@@ -247,9 +_,8 @@ +@@ -246,9 +_,8 @@ } this.onBlockStateChange(p_46605_, blockstate, blockstate1); @@ -73,15 +69,15 @@ } } } -@@ -301,6 +_,7 @@ +@@ -300,6 +_,7 @@ } public void updateNeighborsAt(BlockPos p_46673_, Block p_46674_) { + net.neoforged.neoforge.event.EventHooks.onNeighborNotify(this, p_46673_, this.getBlockState(p_46673_), java.util.EnumSet.allOf(Direction.class), false).isCanceled(); } - public void updateNeighborsAtExceptFromFacing(BlockPos p_46591_, Block p_46592_, Direction p_46593_) { -@@ -489,10 +_,26 @@ + public void updateNeighborsAt(BlockPos p_365514_, Block p_364886_, @Nullable Orientation p_363337_) { +@@ -491,10 +_,26 @@ (this.tickingBlockEntities ? this.pendingBlockEntityTickers : this.blockEntityTickers).add(p_151526_); } @@ -94,7 +90,7 @@ + } + protected void tickBlockEntities() { - ProfilerFiller profilerfiller = this.getProfiler(); + ProfilerFiller profilerfiller = Profiler.get(); profilerfiller.push("blockEntities"); + if (!this.pendingFreshBlockEntities.isEmpty()) { + this.freshBlockEntities.addAll(this.pendingFreshBlockEntities); @@ -108,7 +104,7 @@ if (!this.pendingBlockEntityTickers.isEmpty()) { this.blockEntityTickers.addAll(this.pendingBlockEntityTickers); this.pendingBlockEntityTickers.clear(); -@@ -516,12 +_,19 @@ +@@ -518,12 +_,19 @@ public void guardEntityTick(Consumer p_46654_, T p_46655_) { try { @@ -128,24 +124,7 @@ } } -@@ -670,7 +_,7 @@ - Explosion.BlockInteraction explosion$blockinteraction = switch (p_312265_) { - case NONE -> Explosion.BlockInteraction.KEEP; - case BLOCK -> this.getDestroyType(GameRules.RULE_BLOCK_EXPLOSION_DROP_DECAY); -- case MOB -> this.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) -+ case MOB -> net.neoforged.neoforge.event.EventHooks.canEntityGrief(this, p_311934_) - ? this.getDestroyType(GameRules.RULE_MOB_EXPLOSION_DROP_DECAY) - : Explosion.BlockInteraction.KEEP; - case TNT -> this.getDestroyType(GameRules.RULE_TNT_EXPLOSION_DROP_DECAY); -@@ -691,6 +_,7 @@ - p_312060_, - p_320283_ - ); -+ if (net.neoforged.neoforge.event.EventHooks.onExplosionStart(this, explosion)) return explosion; - explosion.explode(); - explosion.finalizeExplosion(p_312145_); - return explosion; -@@ -725,6 +_,7 @@ +@@ -673,6 +_,7 @@ if (!this.isOutsideBuildHeight(p_46748_)) { this.getChunkAt(p_46748_).removeBlockEntity(p_46748_); } @@ -153,7 +132,7 @@ } public boolean isLoaded(BlockPos p_46750_) { -@@ -803,6 +_,7 @@ +@@ -751,6 +_,7 @@ list.add(p_151522_); } @@ -161,7 +140,7 @@ if (p_151522_ instanceof EnderDragon) { for (EnderDragonPart enderdragonpart : ((EnderDragon)p_151522_).getSubEntities()) { if (p_151522_ != p_46536_ && p_46538_.test(enderdragonpart)) { -@@ -811,6 +_,11 @@ +@@ -759,6 +_,11 @@ } } }); @@ -173,7 +152,7 @@ return list; } -@@ -837,6 +_,8 @@ +@@ -785,6 +_,8 @@ } } @@ -182,7 +161,7 @@ if (p_261454_ instanceof EnderDragon enderdragon) { for (EnderDragonPart enderdragonpart : enderdragon.getSubEntities()) { T t = p_261885_.tryCast(enderdragonpart); -@@ -851,6 +_,15 @@ +@@ -799,6 +_,15 @@ return AbortableIterationConsumer.Continuation.CONTINUE; }); @@ -198,7 +177,7 @@ } @Nullable -@@ -979,16 +_,15 @@ +@@ -922,16 +_,15 @@ public abstract Scoreboard getScoreboard(); public void updateNeighbourForOutputSignal(BlockPos p_46718_, Block p_46719_) { @@ -208,7 +187,7 @@ if (this.hasChunkAt(blockpos)) { BlockState blockstate = this.getBlockState(blockpos); - if (blockstate.is(Blocks.COMPARATOR)) { -- this.neighborChanged(blockstate, blockpos, p_46719_, p_46718_, false); +- this.neighborChanged(blockstate, blockpos, p_46719_, null, false); - } else if (blockstate.isRedstoneConductor(this, blockpos)) { + blockstate.onNeighborChange(this, blockpos, p_46718_); + if (blockstate.isRedstoneConductor(this, blockpos)) { @@ -216,10 +195,10 @@ blockstate = this.getBlockState(blockpos); - if (blockstate.is(Blocks.COMPARATOR)) { + if (blockstate.getWeakChanges(this, blockpos)) { - this.neighborChanged(blockstate, blockpos, p_46719_, p_46718_, false); + this.neighborChanged(blockstate, blockpos, p_46719_, null, false); } } -@@ -1078,6 +_,18 @@ +@@ -1013,6 +_,18 @@ return this.biomeManager; } @@ -238,7 +217,7 @@ public final boolean isDebug() { return this.isDebug; } -@@ -1118,5 +_,38 @@ +@@ -1055,5 +_,38 @@ public String getSerializedName() { return this.id; } diff --git a/patches/net/minecraft/world/level/LevelSettings.java.patch b/patches/net/minecraft/world/level/LevelSettings.java.patch index e7ca7e313f..086a722d3a 100644 --- a/patches/net/minecraft/world/level/LevelSettings.java.patch +++ b/patches/net/minecraft/world/level/LevelSettings.java.patch @@ -26,14 +26,14 @@ @@ -33,7 +_,8 @@ p_46925_.get("Difficulty").asNumber().map(p_46928_ -> Difficulty.byId(p_46928_.byteValue())).result().orElse(Difficulty.NORMAL), p_46925_.get("allowCommands").asBoolean(gametype == GameType.CREATIVE), - new GameRules(p_46925_.get("GameRules")), + new GameRules(p_251697_.enabledFeatures(), p_46925_.get("GameRules")), - p_251697_ + p_251697_, + net.neoforged.neoforge.common.CommonHooks.parseLifecycle(p_46925_.get("forgeLifecycle").asString("stable")) ); } -@@ -66,20 +_,27 @@ +@@ -66,15 +_,15 @@ } public LevelSettings withGameType(GameType p_46923_) { @@ -43,7 +43,6 @@ public LevelSettings withDifficulty(Difficulty p_46919_) { - return new LevelSettings(this.levelName, this.gameType, this.hardcore, p_46919_, this.allowCommands, this.gameRules, this.dataConfiguration); -+ net.neoforged.neoforge.common.CommonHooks.onDifficultyChange(p_46919_, this.difficulty); + return new LevelSettings(this.levelName, this.gameType, this.hardcore, p_46919_, this.allowCommands, this.gameRules, this.dataConfiguration, this.lifecycle); } @@ -53,14 +52,20 @@ } public LevelSettings copy() { - return new LevelSettings( -- this.levelName, this.gameType, this.hardcore, this.difficulty, this.allowCommands, this.gameRules.copy(), this.dataConfiguration -+ this.levelName, this.gameType, this.hardcore, this.difficulty, this.allowCommands, this.gameRules.copy(), this.dataConfiguration, this.lifecycle +@@ -85,7 +_,16 @@ + this.difficulty, + this.allowCommands, + this.gameRules.copy(this.dataConfiguration.enabledFeatures()), +- this.dataConfiguration ++ this.dataConfiguration, ++ this.lifecycle ); + } ++ + public LevelSettings withLifecycle(com.mojang.serialization.Lifecycle lifecycle) { + return new LevelSettings(this.levelName, this.gameType, this.hardcore, this.difficulty, this.allowCommands, this.gameRules, this.dataConfiguration, lifecycle); + } ++ + public com.mojang.serialization.Lifecycle getLifecycle() { + return this.lifecycle; } diff --git a/patches/net/minecraft/world/level/NaturalSpawner.java.patch b/patches/net/minecraft/world/level/NaturalSpawner.java.patch index 53f0facd7e..396218218b 100644 --- a/patches/net/minecraft/world/level/NaturalSpawner.java.patch +++ b/patches/net/minecraft/world/level/NaturalSpawner.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/NaturalSpawner.java +++ b/net/minecraft/world/level/NaturalSpawner.java -@@ -45,6 +_,7 @@ +@@ -49,6 +_,7 @@ import net.minecraft.world.phys.Vec3; import org.slf4j.Logger; @@ -8,7 +8,7 @@ public final class NaturalSpawner { private static final Logger LOGGER = LogUtils.getLogger(); private static final int MIN_SPAWN_DISTANCE = 24; -@@ -69,7 +_,7 @@ +@@ -73,7 +_,7 @@ continue; } @@ -17,7 +17,7 @@ if (mobcategory != MobCategory.MISC) { BlockPos blockpos = entity.blockPosition(); p_186527_.query( -@@ -199,7 +_,7 @@ +@@ -214,7 +_,7 @@ l1++; p_47040_.addFreshEntityWithPassengers(mob); p_47044_.run(mob, p_47041_); @@ -26,16 +26,16 @@ return; } -@@ -272,7 +_,7 @@ +@@ -287,7 +_,7 @@ return p_46994_ > (double)(p_46993_.getType().getCategory().getDespawnDistance() * p_46993_.getType().getCategory().getDespawnDistance()) && p_46993_.removeWhenFarAway(p_46994_) ? false -- : p_46993_.checkSpawnRules(p_46992_, MobSpawnType.NATURAL) && p_46993_.checkSpawnObstruction(p_46992_); -+ : net.neoforged.neoforge.event.EventHooks.checkSpawnPosition(p_46993_, p_46992_, MobSpawnType.NATURAL); +- : p_46993_.checkSpawnRules(p_46992_, EntitySpawnReason.NATURAL) && p_46993_.checkSpawnObstruction(p_46992_); ++ : net.neoforged.neoforge.event.EventHooks.checkSpawnPosition(p_46993_, p_46992_, EntitySpawnReason.NATURAL); } private static Optional getRandomSpawnMobAt( -@@ -303,9 +_,14 @@ +@@ -318,9 +_,14 @@ BlockPos p_220448_, @Nullable Holder p_220449_ ) { @@ -44,7 +44,7 @@ - : p_220446_.getMobsAt(p_220449_ != null ? p_220449_ : p_220444_.getBiome(p_220448_), p_220445_, p_220447_, p_220448_); + // Forge: Add in potential spawns, and replace hardcoded nether fortress mob list + if (isInNetherFortressBounds(p_220448_, p_220444_, p_220447_, p_220445_)) { -+ var monsterSpawns = p_220445_.registryAccess().registryOrThrow(Registries.STRUCTURE).getOrThrow(BuiltinStructures.FORTRESS).spawnOverrides().get(MobCategory.MONSTER); ++ var monsterSpawns = p_220445_.registryAccess().lookupOrThrow(Registries.STRUCTURE).getValueOrThrow(BuiltinStructures.FORTRESS).spawnOverrides().get(MobCategory.MONSTER); + if (monsterSpawns != null) { // structure modifiers can clear the spawn overrides + return net.neoforged.neoforge.event.EventHooks.getPotentialSpawns(p_220444_, p_220447_, p_220448_, monsterSpawns.spawns()); + } @@ -53,13 +53,13 @@ } public static boolean isInNetherFortressBounds(BlockPos p_220456_, ServerLevel p_220457_, MobCategory p_220458_, StructureManager p_220459_) { -@@ -392,8 +_,7 @@ +@@ -407,8 +_,7 @@ entity.moveTo(d0, (double)blockpos.getY(), d1, p_220454_.nextFloat() * 360.0F, 0.0F); if (entity instanceof Mob mob -- && mob.checkSpawnRules(p_220451_, MobSpawnType.CHUNK_GENERATION) +- && mob.checkSpawnRules(p_220451_, EntitySpawnReason.CHUNK_GENERATION) - && mob.checkSpawnObstruction(p_220451_)) { -+ && net.neoforged.neoforge.event.EventHooks.checkSpawnPosition(mob, p_220451_, MobSpawnType.CHUNK_GENERATION)) { ++ && net.neoforged.neoforge.event.EventHooks.checkSpawnPosition(mob, p_220451_, EntitySpawnReason.CHUNK_GENERATION)) { spawngroupdata = mob.finalizeSpawn( - p_220451_, p_220451_.getCurrentDifficultyAt(mob.blockPosition()), MobSpawnType.CHUNK_GENERATION, spawngroupdata + p_220451_, p_220451_.getCurrentDifficultyAt(mob.blockPosition()), EntitySpawnReason.CHUNK_GENERATION, spawngroupdata ); diff --git a/patches/net/minecraft/world/level/ServerExplosion.java.patch b/patches/net/minecraft/world/level/ServerExplosion.java.patch new file mode 100644 index 0000000000..de66d59d95 --- /dev/null +++ b/patches/net/minecraft/world/level/ServerExplosion.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/world/level/ServerExplosion.java ++++ b/net/minecraft/world/level/ServerExplosion.java +@@ -174,7 +_,9 @@ + int i1 = Mth.floor(this.center.z - (double)f - 1.0); + int j1 = Mth.floor(this.center.z + (double)f + 1.0); + +- for (Entity entity : this.level.getEntities(this.source, new AABB((double)i, (double)k, (double)i1, (double)j, (double)l, (double)j1))) { ++ List list = this.level.getEntities(this.source, new AABB((double)i, (double)k, (double)i1, (double)j, (double)l, (double)j1)); ++ net.neoforged.neoforge.event.EventHooks.onExplosionDetonate(this.level, this, list, f); ++ for (Entity entity : list) { + if (!entity.ignoreExplosion(this)) { + double d0 = Math.sqrt(entity.distanceToSqr(this.center)) / (double)f; + if (d0 <= 1.0) { +@@ -205,6 +_,7 @@ + d2 *= d6; + d3 *= d6; + Vec3 vec3 = new Vec3(d1, d2, d3); ++ vec3 = net.neoforged.neoforge.event.EventHooks.getExplosionKnockback(this.level, this, entity, vec3); + entity.setDeltaMovement(entity.getDeltaMovement().add(vec3)); + if (entity instanceof Player) { + Player player = (Player)entity; diff --git a/patches/net/minecraft/world/level/biome/Biome.java.patch b/patches/net/minecraft/world/level/biome/Biome.java.patch index 756ca8a329..54c553a09a 100644 --- a/patches/net/minecraft/world/level/biome/Biome.java.patch +++ b/patches/net/minecraft/world/level/biome/Biome.java.patch @@ -40,7 +40,7 @@ } public boolean hasPrecipitation() { -@@ -191,7 +_,7 @@ +@@ -188,7 +_,7 @@ } public BiomeGenerationSettings getGenerationSettings() { @@ -49,7 +49,7 @@ } public int getFogColor() { -@@ -414,5 +_,32 @@ +@@ -411,5 +_,32 @@ public String getSerializedName() { return this.name; } diff --git a/patches/net/minecraft/world/level/biome/BiomeGenerationSettings.java.patch b/patches/net/minecraft/world/level/biome/BiomeGenerationSettings.java.patch deleted file mode 100644 index a9325c1bf1..0000000000 --- a/patches/net/minecraft/world/level/biome/BiomeGenerationSettings.java.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- a/net/minecraft/world/level/biome/BiomeGenerationSettings.java -+++ b/net/minecraft/world/level/biome/BiomeGenerationSettings.java -@@ -50,6 +_,7 @@ - .apply(p_186655_, BiomeGenerationSettings::new) - ); - private final Map>> carvers; -+ private final java.util.Set carversView; - private final List> features; - private final Supplier>> flowerFeatures; - private final Supplier> featureSet; -@@ -66,10 +_,15 @@ - .collect(ImmutableList.toImmutableList()) - ); - this.featureSet = Suppliers.memoize(() -> p_186651_.stream().flatMap(HolderSet::stream).map(Holder::value).collect(Collectors.toSet())); -+ this.carversView = java.util.Collections.unmodifiableSet(carvers.keySet()); - } - - public Iterable>> getCarvers(GenerationStep.Carving p_204188_) { - return Objects.requireNonNullElseGet(this.carvers.get(p_204188_), List::of); -+ } -+ -+ public java.util.Set getCarvingStages() { -+ return this.carversView; - } - - public List> getFlowerFeatures() { diff --git a/patches/net/minecraft/world/level/block/AttachedStemBlock.java.patch b/patches/net/minecraft/world/level/block/AttachedStemBlock.java.patch index 85788acd54..df3eaddebc 100644 --- a/patches/net/minecraft/world/level/block/AttachedStemBlock.java.patch +++ b/patches/net/minecraft/world/level/block/AttachedStemBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/AttachedStemBlock.java +++ b/net/minecraft/world/level/block/AttachedStemBlock.java -@@ -84,7 +_,7 @@ +@@ -94,7 +_,7 @@ @Override protected boolean mayPlaceOn(BlockState p_48863_, BlockGetter p_48864_, BlockPos p_48865_) { diff --git a/patches/net/minecraft/world/level/block/BambooSaplingBlock.java.patch b/patches/net/minecraft/world/level/block/BambooSaplingBlock.java.patch index cce4907ae0..f3b8f17dd2 100644 --- a/patches/net/minecraft/world/level/block/BambooSaplingBlock.java.patch +++ b/patches/net/minecraft/world/level/block/BambooSaplingBlock.java.patch @@ -9,7 +9,7 @@ return p_48987_.getBlockState(p_48988_.below()).is(BlockTags.BAMBOO_PLANTABLE_ON); } -@@ -88,7 +_,7 @@ +@@ -95,7 +_,7 @@ @Override protected float getDestroyProgress(BlockState p_48981_, Player p_48982_, BlockGetter p_48983_, BlockPos p_48984_) { diff --git a/patches/net/minecraft/world/level/block/BambooStalkBlock.java.patch b/patches/net/minecraft/world/level/block/BambooStalkBlock.java.patch index efaeb2b815..91d4635c7e 100644 --- a/patches/net/minecraft/world/level/block/BambooStalkBlock.java.patch +++ b/patches/net/minecraft/world/level/block/BambooStalkBlock.java.patch @@ -33,7 +33,7 @@ return p_262154_.getBlockState(p_261493_.below()).is(BlockTags.BAMBOO_PLANTABLE_ON); } -@@ -193,7 +_,7 @@ +@@ -198,7 +_,7 @@ @Override protected float getDestroyProgress(BlockState p_261691_, Player p_262171_, BlockGetter p_261621_, BlockPos p_261500_) { diff --git a/patches/net/minecraft/world/level/block/BaseFireBlock.java.patch b/patches/net/minecraft/world/level/block/BaseFireBlock.java.patch index c4bc4e334f..ade6a8b9df 100644 --- a/patches/net/minecraft/world/level/block/BaseFireBlock.java.patch +++ b/patches/net/minecraft/world/level/block/BaseFireBlock.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/world/level/block/BaseFireBlock.java +++ b/net/minecraft/world/level/block/BaseFireBlock.java -@@ -143,6 +_,7 @@ +@@ -152,6 +_,7 @@ if (!p_49282_.is(p_49279_.getBlock())) { if (inPortalDimension(p_49280_)) { Optional optional = PortalShape.findEmptyPortalShape(p_49280_, p_49281_, Direction.Axis.X); + optional = net.neoforged.neoforge.event.EventHooks.onTrySpawnPortal(p_49280_, p_49281_, optional); if (optional.isPresent()) { - optional.get().createPortalBlocks(); + optional.get().createPortalBlocks(p_49280_); return; -@@ -185,7 +_,7 @@ +@@ -194,7 +_,7 @@ boolean flag = false; for (Direction direction : Direction.values()) { diff --git a/patches/net/minecraft/world/level/block/BaseRailBlock.java.patch b/patches/net/minecraft/world/level/block/BaseRailBlock.java.patch index af4fb513e8..cf64085b38 100644 --- a/patches/net/minecraft/world/level/block/BaseRailBlock.java.patch +++ b/patches/net/minecraft/world/level/block/BaseRailBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/BaseRailBlock.java +++ b/net/minecraft/world/level/block/BaseRailBlock.java -@@ -20,7 +_,7 @@ +@@ -23,7 +_,7 @@ import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; @@ -9,33 +9,43 @@ protected static final VoxelShape FLAT_AABB = Block.box(0.0, 0.0, 0.0, 16.0, 2.0, 16.0); protected static final VoxelShape HALF_BLOCK_AABB = Block.box(0.0, 0.0, 0.0, 16.0, 8.0, 16.0); public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; -@@ -49,6 +_,7 @@ +@@ -51,7 +_,7 @@ + @Override protected VoxelShape getShape(BlockState p_49403_, BlockGetter p_49404_, BlockPos p_49405_, CollisionContext p_49406_) { - RailShape railshape = p_49403_.is(this) ? p_49403_.getValue(this.getShapeProperty()) : null; -+ RailShape railShape2 = p_49403_.is(this) ? getRailDirection(p_49403_, p_49404_, p_49405_, null) : null; - return railshape != null && railshape.isAscending() ? HALF_BLOCK_AABB : FLAT_AABB; +- RailShape railshape = p_49403_.is(this) ? p_49403_.getValue(this.getShapeProperty()) : null; ++ RailShape railshape = p_49403_.is(this) ? getRailDirection(p_49403_, p_49404_, p_49405_, null) : null; + return railshape != null && railshape.isSlope() ? HALF_BLOCK_AABB : FLAT_AABB; } -@@ -76,7 +_,7 @@ +@@ -79,7 +_,7 @@ @Override - protected void neighborChanged(BlockState p_49377_, Level p_49378_, BlockPos p_49379_, Block p_49380_, BlockPos p_49381_, boolean p_49382_) { + protected void neighborChanged(BlockState p_49377_, Level p_49378_, BlockPos p_49379_, Block p_49380_, @Nullable Orientation p_361387_, boolean p_49382_) { if (!p_49378_.isClientSide && p_49378_.getBlockState(p_49379_).is(this)) { - RailShape railshape = p_49377_.getValue(this.getShapeProperty()); + RailShape railshape = getRailDirection(p_49377_, p_49378_, p_49379_, null); if (shouldBeRemoved(p_49379_, p_49378_, railshape)) { dropResources(p_49377_, p_49378_, p_49379_); p_49378_.removeBlock(p_49379_, p_49382_); -@@ -121,7 +_,7 @@ +@@ -115,7 +_,7 @@ + if (p_49368_.isClientSide) { + return p_49370_; + } else { +- RailShape railshape = p_49370_.getValue(this.getShapeProperty()); ++ RailShape railshape = getRailDirection(p_49370_, p_49368_, p_49369_, null); + return new RailState(p_49368_, p_49369_, p_49370_).place(p_49368_.hasNeighborSignal(p_49369_), p_49371_, railshape).getState(); + } + } +@@ -124,7 +_,7 @@ protected void onRemove(BlockState p_49384_, Level p_49385_, BlockPos p_49386_, BlockState p_49387_, boolean p_49388_) { if (!p_49388_) { super.onRemove(p_49384_, p_49385_, p_49386_, p_49387_, p_49388_); -- if (p_49384_.getValue(this.getShapeProperty()).isAscending()) { -+ if (getRailDirection(p_49384_, p_49385_, p_49386_, null).isAscending()) { +- if (p_49384_.getValue(this.getShapeProperty()).isSlope()) { ++ if (getRailDirection(p_49384_, p_49385_, p_49386_, null).isSlope()) { p_49385_.updateNeighborsAt(p_49386_.above(), this); } -@@ -142,6 +_,11 @@ +@@ -145,6 +_,11 @@ return blockstate.setValue(this.getShapeProperty(), flag1 ? RailShape.EAST_WEST : RailShape.NORTH_SOUTH).setValue(WATERLOGGED, Boolean.valueOf(flag)); } @@ -47,7 +57,7 @@ public abstract Property getShapeProperty(); @Override -@@ -158,5 +_,15 @@ +@@ -168,5 +_,15 @@ @Override protected FluidState getFluidState(BlockState p_152158_) { return p_152158_.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(p_152158_); @@ -55,7 +65,7 @@ + + @Override + public boolean isFlexibleRail(BlockState state, BlockGetter world, BlockPos pos) { -+ return !this.isStraight; ++ return !this.isStraight; + } + + @Override diff --git a/patches/net/minecraft/world/level/block/BeehiveBlock.java.patch b/patches/net/minecraft/world/level/block/BeehiveBlock.java.patch index 5e59b85a4c..8f858d24fb 100644 --- a/patches/net/minecraft/world/level/block/BeehiveBlock.java.patch +++ b/patches/net/minecraft/world/level/block/BeehiveBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/BeehiveBlock.java +++ b/net/minecraft/world/level/block/BeehiveBlock.java -@@ -126,7 +_,7 @@ +@@ -142,7 +_,7 @@ boolean flag = false; if (i >= 5) { Item item = p_316844_.getItem(); diff --git a/patches/net/minecraft/world/level/block/BigDripleafBlock.java.patch b/patches/net/minecraft/world/level/block/BigDripleafBlock.java.patch index 909353cec3..a95895aa63 100644 --- a/patches/net/minecraft/world/level/block/BigDripleafBlock.java.patch +++ b/patches/net/minecraft/world/level/block/BigDripleafBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/BigDripleafBlock.java +++ b/net/minecraft/world/level/block/BigDripleafBlock.java -@@ -146,6 +_,8 @@ +@@ -148,6 +_,8 @@ protected boolean canSurvive(BlockState p_152289_, LevelReader p_152290_, BlockPos p_152291_) { BlockPos blockpos = p_152291_.below(); BlockState blockstate = p_152290_.getBlockState(blockpos); diff --git a/patches/net/minecraft/world/level/block/Block.java.patch b/patches/net/minecraft/world/level/block/Block.java.patch index ca575a2ee2..652a468069 100644 --- a/patches/net/minecraft/world/level/block/Block.java.patch +++ b/patches/net/minecraft/world/level/block/Block.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/Block.java +++ b/net/minecraft/world/level/block/Block.java -@@ -61,11 +_,11 @@ +@@ -60,11 +_,11 @@ import net.minecraft.world.phys.shapes.VoxelShape; import org.slf4j.Logger; @@ -14,7 +14,7 @@ private static final LoadingCache SHAPE_FULL_BLOCK_CACHE = CacheBuilder.newBuilder() .maximumSize(512L) .weakKeys() -@@ -186,7 +_,7 @@ +@@ -182,7 +_,7 @@ this.createBlockStateDefinition(builder); this.stateDefinition = builder.create(Block::defaultBlockState, BlockState::new); this.registerDefaultState(this.stateDefinition.any()); @@ -23,16 +23,30 @@ String s = this.getClass().getSimpleName(); if (!s.endsWith("Block")) { LOGGER.error("Block classes should end with Block and {} doesn't.", s); -@@ -208,6 +_,8 @@ - BlockState blockstate = p_152446_.getBlockState(p_152449_); - if (p_152445_.skipRendering(blockstate, p_152448_)) { +@@ -200,12 +_,22 @@ + || p_152464_.is(BlockTags.SHULKER_BOXES); + } + ++ /** ++ * @deprecated Neo: use overload with level context instead ++ */ ++ @Deprecated + public static boolean shouldRenderFace(BlockState p_152445_, BlockState p_361252_, Direction p_152448_) { ++ return shouldRenderFace(net.minecraft.world.level.EmptyBlockGetter.INSTANCE, BlockPos.ZERO, p_152445_, p_361252_, p_152448_); ++ } ++ ++ public static boolean shouldRenderFace(BlockGetter level, BlockPos pos, BlockState p_152445_, BlockState p_361252_, Direction p_152448_) { + VoxelShape voxelshape = p_361252_.getFaceOcclusionShape(p_152448_.getOpposite()); + if (voxelshape == Shapes.block()) { return false; -+ } else if (blockstate.hidesNeighborFace(p_152446_, p_152449_, p_152445_, p_152448_.getOpposite()) && p_152445_.supportsExternalFaceHiding()) { + } else if (p_152445_.skipRendering(p_361252_, p_152448_)) { + return false; ++ } else if (p_361252_.hidesNeighborFace(level, pos.relative(p_152448_), p_152445_, p_152448_.getOpposite()) && p_152445_.supportsExternalFaceHiding()) { + return false; - } else if (blockstate.canOcclude()) { - Block.BlockStatePairKey block$blockstatepairkey = new Block.BlockStatePairKey(p_152445_, blockstate, p_152448_); - Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap = OCCLUSION_CACHE.get(); -@@ -281,24 +_,30 @@ + } else if (voxelshape == Shapes.empty()) { + return true; + } else { +@@ -278,24 +_,30 @@ public static void dropResources(BlockState p_49951_, Level p_49952_, BlockPos p_49953_) { if (p_49952_ instanceof ServerLevel) { @@ -67,15 +81,16 @@ } } -@@ -326,19 +_,26 @@ +@@ -323,20 +_,26 @@ } private static void popResource(Level p_152441_, Supplier p_152442_, ItemStack p_152443_) { -- if (!p_152441_.isClientSide && !p_152443_.isEmpty() && p_152441_.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) { -+ if (!p_152441_.isClientSide && !p_152443_.isEmpty() && p_152441_.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS) && !p_152441_.restoringBlockSnapshots) { +- if (p_152441_ instanceof ServerLevel serverlevel && !p_152443_.isEmpty() && serverlevel.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) { ++ if (p_152441_ instanceof ServerLevel serverLevel && !p_152443_.isEmpty() && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS) && !p_152441_.restoringBlockSnapshots) { ItemEntity itementity = p_152442_.get(); itementity.setDefaultPickUpDelay(); - p_152441_.addFreshEntity(itementity); +- return; + // Neo: Add drops to the captured list if capturing is enabled. + if (capturedDrops != null) { + capturedDrops.add(itementity); @@ -97,9 +112,9 @@ public float getExplosionResistance() { return this.explosionResistance; } -@@ -385,8 +_,10 @@ +@@ -375,8 +_,10 @@ - public void updateEntityAfterFallOn(BlockGetter p_49821_, Entity p_49822_) { + public void updateEntityMovementAfterFallOn(BlockGetter p_49821_, Entity p_49822_) { p_49822_.setDeltaMovement(p_49822_.getDeltaMovement().multiply(1.0, 0.0, 1.0)); + p_49822_.setDeltaMovement(p_49822_.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D)); } @@ -108,7 +123,7 @@ public ItemStack getCloneItemStack(LevelReader p_304395_, BlockPos p_49824_, BlockState p_49825_) { return new ItemStack(this); } -@@ -420,6 +_,7 @@ +@@ -410,6 +_,7 @@ public void handlePrecipitation(BlockState p_152450_, Level p_152451_, BlockPos p_152452_, Biome.Precipitation p_152453_) { } @@ -116,7 +131,7 @@ public boolean dropFromExplosion(Explosion p_49826_) { return true; } -@@ -485,6 +_,43 @@ +@@ -475,6 +_,35 @@ return this.stateDefinition.getPossibleStates().stream().collect(ImmutableMap.toImmutableMap(Function.identity(), p_152459_)); } @@ -148,14 +163,6 @@ + return drops; + } + -+ /** -+ * Neo: Allowing mods to define client behavior for their Blocks -+ * @deprecated Use {@link net.neoforged.neoforge.client.extensions.common.RegisterClientExtensionsEvent} instead -+ */ -+ @Deprecated(forRemoval = true, since = "1.21") -+ public void initializeClient(java.util.function.Consumer consumer) { -+ } -+ + /** @deprecated */ @Deprecated public Holder.Reference builtInRegistryHolder() { diff --git a/patches/net/minecraft/world/level/block/Blocks.java.patch b/patches/net/minecraft/world/level/block/Blocks.java.patch index 2985e101f2..c9befa089f 100644 --- a/patches/net/minecraft/world/level/block/Blocks.java.patch +++ b/patches/net/minecraft/world/level/block/Blocks.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/level/block/Blocks.java +++ b/net/minecraft/world/level/block/Blocks.java -@@ -754,7 +_,7 @@ - public static final Block RED_BED = register("red_bed", bed(DyeColor.RED)); - public static final Block BLACK_BED = register("black_bed", bed(DyeColor.BLACK)); +@@ -690,7 +_,7 @@ + public static final Block RED_BED = registerBed("red_bed", DyeColor.RED); + public static final Block BLACK_BED = registerBed("black_bed", DyeColor.BLACK); public static final Block POWERED_RAIL = register( -- "powered_rail", new PoweredRailBlock(BlockBehaviour.Properties.of().noCollission().strength(0.7F).sound(SoundType.METAL)) -+ "powered_rail", new PoweredRailBlock(BlockBehaviour.Properties.of().noCollission().strength(0.7F).sound(SoundType.METAL), true) +- "powered_rail", PoweredRailBlock::new, BlockBehaviour.Properties.of().noCollission().strength(0.7F).sound(SoundType.METAL) ++ "powered_rail", p_55218_ -> new PoweredRailBlock(p_55218_, true), BlockBehaviour.Properties.of().noCollission().strength(0.7F).sound(SoundType.METAL) ); public static final Block DETECTOR_RAIL = register( - "detector_rail", new DetectorRailBlock(BlockBehaviour.Properties.of().noCollission().strength(0.7F).sound(SoundType.METAL)) -@@ -7806,7 +_,8 @@ + "detector_rail", DetectorRailBlock::new, BlockBehaviour.Properties.of().noCollission().strength(0.7F).sound(SoundType.METAL) +@@ -6919,7 +_,8 @@ static { for (Block block : BuiltInRegistries.BLOCK) { for (BlockState blockstate : block.getStateDefinition().getPossibleStates()) { @@ -18,4 +18,4 @@ + //Block.BLOCK_STATE_REGISTRY.add(blockstate); blockstate.initCache(); } - + } diff --git a/patches/net/minecraft/world/level/block/BubbleColumnBlock.java.patch b/patches/net/minecraft/world/level/block/BubbleColumnBlock.java.patch index 526c55e206..37842d4270 100644 --- a/patches/net/minecraft/world/level/block/BubbleColumnBlock.java.patch +++ b/patches/net/minecraft/world/level/block/BubbleColumnBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/BubbleColumnBlock.java +++ b/net/minecraft/world/level/block/BubbleColumnBlock.java -@@ -121,10 +_,12 @@ +@@ -122,10 +_,12 @@ private static BlockState getColumnState(BlockState p_152718_) { if (p_152718_.is(Blocks.BUBBLE_COLUMN)) { return p_152718_; @@ -15,7 +15,7 @@ ? Blocks.BUBBLE_COLUMN.defaultBlockState().setValue(DRAG_DOWN, Boolean.valueOf(true)) : Blocks.WATER.defaultBlockState(); } -@@ -190,7 +_,7 @@ +@@ -200,7 +_,7 @@ @Override protected boolean canSurvive(BlockState p_50986_, LevelReader p_50987_, BlockPos p_50988_) { BlockState blockstate = p_50987_.getBlockState(p_50988_.below()); diff --git a/patches/net/minecraft/world/level/block/BushBlock.java.patch b/patches/net/minecraft/world/level/block/BushBlock.java.patch index e1321e5049..1a33073847 100644 --- a/patches/net/minecraft/world/level/block/BushBlock.java.patch +++ b/patches/net/minecraft/world/level/block/BushBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/BushBlock.java +++ b/net/minecraft/world/level/block/BushBlock.java -@@ -20,7 +_,7 @@ +@@ -21,7 +_,7 @@ protected abstract MapCodec codec(); protected boolean mayPlaceOn(BlockState p_51042_, BlockGetter p_51043_, BlockPos p_51044_) { @@ -9,7 +9,7 @@ } @Override -@@ -33,7 +_,10 @@ +@@ -43,7 +_,10 @@ @Override protected boolean canSurvive(BlockState p_51028_, LevelReader p_51029_, BlockPos p_51030_) { BlockPos blockpos = p_51030_.below(); diff --git a/patches/net/minecraft/world/level/block/CactusBlock.java.patch b/patches/net/minecraft/world/level/block/CactusBlock.java.patch index 037a99fb7c..c4a87b6942 100644 --- a/patches/net/minecraft/world/level/block/CactusBlock.java.patch +++ b/patches/net/minecraft/world/level/block/CactusBlock.java.patch @@ -25,7 +25,7 @@ } } } -@@ -99,6 +_,8 @@ +@@ -108,6 +_,8 @@ } BlockState blockstate1 = p_51154_.getBlockState(p_51155_.below()); diff --git a/patches/net/minecraft/world/level/block/CampfireBlock.java.patch b/patches/net/minecraft/world/level/block/CampfireBlock.java.patch index e81ecca378..927f77d8db 100644 --- a/patches/net/minecraft/world/level/block/CampfireBlock.java.patch +++ b/patches/net/minecraft/world/level/block/CampfireBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/CampfireBlock.java +++ b/net/minecraft/world/level/block/CampfireBlock.java -@@ -279,7 +_,7 @@ +@@ -292,7 +_,7 @@ return true; } diff --git a/patches/net/minecraft/world/level/block/ChestBlock.java.patch b/patches/net/minecraft/world/level/block/ChestBlock.java.patch index 99655a4e31..47e4ad187d 100644 --- a/patches/net/minecraft/world/level/block/ChestBlock.java.patch +++ b/patches/net/minecraft/world/level/block/ChestBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/ChestBlock.java +++ b/net/minecraft/world/level/block/ChestBlock.java -@@ -357,7 +_,8 @@ +@@ -365,7 +_,8 @@ @Override protected BlockState mirror(BlockState p_51549_, Mirror p_51550_) { diff --git a/patches/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch b/patches/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch index 7f01cbf363..c9fd63af62 100644 --- a/patches/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch +++ b/patches/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/world/level/block/ChorusFlowerBlock.java +++ b/net/minecraft/world/level/block/ChorusFlowerBlock.java -@@ -65,10 +_,13 @@ +@@ -66,10 +_,13 @@ BlockPos blockpos = p_220982_.above(); - if (p_220981_.isEmptyBlock(blockpos) && blockpos.getY() < p_220981_.getMaxBuildHeight()) { + if (p_220981_.isEmptyBlock(blockpos) && blockpos.getY() <= p_220981_.getMaxY()) { int i = p_220980_.getValue(AGE); - if (i < 5) { + if (i < 5 && net.neoforged.neoforge.common.CommonHooks.canCropGrow(p_220981_, blockpos, p_220980_, true)) { @@ -15,7 +15,7 @@ if (blockstate.is(Blocks.END_STONE)) { flag = true; } else if (blockstate.is(this.plant)) { -@@ -77,6 +_,8 @@ +@@ -78,6 +_,8 @@ for (int k = 0; k < 4; k++) { BlockState blockstate1 = p_220981_.getBlockState(p_220982_.below(j + 1)); if (!blockstate1.is(this.plant)) { @@ -24,7 +24,7 @@ if (blockstate1.is(Blocks.END_STONE)) { flag1 = true; } -@@ -123,6 +_,7 @@ +@@ -124,6 +_,7 @@ } else { this.placeDeadFlower(p_220981_, p_220982_); } @@ -32,7 +32,7 @@ } } } -@@ -159,6 +_,8 @@ +@@ -169,6 +_,8 @@ @Override protected boolean canSurvive(BlockState p_51683_, LevelReader p_51684_, BlockPos p_51685_) { BlockState blockstate = p_51684_.getBlockState(p_51685_.below()); diff --git a/patches/net/minecraft/world/level/block/ChorusPlantBlock.java.patch b/patches/net/minecraft/world/level/block/ChorusPlantBlock.java.patch index d01ed837a2..5c9b256f04 100644 --- a/patches/net/minecraft/world/level/block/ChorusPlantBlock.java.patch +++ b/patches/net/minecraft/world/level/block/ChorusPlantBlock.java.patch @@ -10,12 +10,12 @@ .trySetValue(UP, Boolean.valueOf(blockstate1.is(block) || blockstate1.is(Blocks.CHORUS_FLOWER))) .trySetValue(NORTH, Boolean.valueOf(blockstate2.is(block) || blockstate2.is(Blocks.CHORUS_FLOWER))) .trySetValue(EAST, Boolean.valueOf(blockstate3.is(block) || blockstate3.is(Blocks.CHORUS_FLOWER))) -@@ -64,6 +_,12 @@ - return super.updateShape(p_51728_, p_51729_, p_51730_, p_51731_, p_51732_, p_51733_); +@@ -73,6 +_,12 @@ + return super.updateShape(p_51728_, p_374320_, p_374500_, p_51732_, p_51729_, p_51733_, p_51730_, p_374170_); } else { boolean flag = p_51730_.is(this) || p_51730_.is(Blocks.CHORUS_FLOWER) || p_51729_ == Direction.DOWN && p_51730_.is(Blocks.END_STONE); + if (p_51729_ == Direction.DOWN) { -+ net.neoforged.neoforge.common.util.TriState soilDecision = p_51730_.canSustainPlant(p_51731_, p_51733_.relative(p_51729_), p_51729_.getOpposite(), p_51728_); ++ net.neoforged.neoforge.common.util.TriState soilDecision = p_51730_.canSustainPlant(p_374320_, p_51733_.relative(p_51729_), p_51729_.getOpposite(), p_51728_); + if (!soilDecision.isDefault()) { + flag = soilDecision.isTrue(); + } @@ -23,7 +23,7 @@ return p_51728_.setValue(PROPERTY_BY_DIRECTION.get(p_51729_), Boolean.valueOf(flag)); } } -@@ -95,6 +_,8 @@ +@@ -104,6 +_,8 @@ } } diff --git a/patches/net/minecraft/world/level/block/ComparatorBlock.java.patch b/patches/net/minecraft/world/level/block/ComparatorBlock.java.patch index c8fc89171c..82dbe7feb6 100644 --- a/patches/net/minecraft/world/level/block/ComparatorBlock.java.patch +++ b/patches/net/minecraft/world/level/block/ComparatorBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/ComparatorBlock.java +++ b/net/minecraft/world/level/block/ComparatorBlock.java -@@ -199,4 +_,16 @@ +@@ -207,4 +_,17 @@ protected void createBlockStateDefinition(StateDefinition.Builder p_51887_) { p_51887_.add(FACING, MODE, POWERED); } @@ -11,9 +11,10 @@ + } + + @Override -+ public void onNeighborChange(BlockState state, net.minecraft.world.level.LevelReader world, BlockPos pos, BlockPos neighbor) { -+ if (pos.getY() == neighbor.getY() && world instanceof Level && !((Level)world).isClientSide()) { -+ state.handleNeighborChanged((Level)world, pos, world.getBlockState(neighbor).getBlock(), neighbor, false); ++ public void onNeighborChange(BlockState state, net.minecraft.world.level.LevelReader levelReader, BlockPos pos, BlockPos neighbor) { ++ if (pos.getY() == neighbor.getY() && levelReader instanceof Level level && !levelReader.isClientSide()) { ++ // TODO porting: check this still works as expected ++ state.handleNeighborChanged(level, pos, levelReader.getBlockState(neighbor).getBlock(), null, false); + } + } } diff --git a/patches/net/minecraft/world/level/block/ComposterBlock.java.patch b/patches/net/minecraft/world/level/block/ComposterBlock.java.patch index 9a3dc8180a..5d1d96dda8 100644 --- a/patches/net/minecraft/world/level/block/ComposterBlock.java.patch +++ b/patches/net/minecraft/world/level/block/ComposterBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/ComposterBlock.java +++ b/net/minecraft/world/level/block/ComposterBlock.java -@@ -48,6 +_,8 @@ +@@ -47,6 +_,8 @@ public static final int MIN_LEVEL = 0; public static final int MAX_LEVEL = 7; public static final IntegerProperty LEVEL = BlockStateProperties.LEVEL_COMPOSTER; @@ -9,7 +9,7 @@ public static final Object2FloatMap COMPOSTABLES = new Object2FloatOpenHashMap<>(); private static final int AABB_SIDE_THICKNESS = 2; private static final VoxelShape OUTER_SHAPE = Shapes.block(); -@@ -227,6 +_,15 @@ +@@ -231,6 +_,15 @@ if (p_51978_.getValue(LEVEL) == 7) { p_51979_.scheduleTick(p_51980_, p_51978_.getBlock(), 20); } @@ -25,7 +25,7 @@ } @Override -@@ -234,7 +_,7 @@ +@@ -238,7 +_,7 @@ ItemStack p_316332_, BlockState p_316118_, Level p_316624_, BlockPos p_316660_, Player p_316715_, InteractionHand p_316472_, BlockHitResult p_316606_ ) { int i = p_316118_.getValue(LEVEL); @@ -34,7 +34,7 @@ if (i < 7 && !p_316624_.isClientSide) { BlockState blockstate = addItem(p_316715_, p_316118_, p_316624_, p_316660_, p_316332_); p_316624_.levelEvent(1500, p_316660_, p_316118_ != blockstate ? 1 : 0); -@@ -261,7 +_,7 @@ +@@ -265,7 +_,7 @@ public static BlockState insertItem(Entity p_270919_, BlockState p_270087_, ServerLevel p_270284_, ItemStack p_270253_, BlockPos p_270678_) { int i = p_270087_.getValue(LEVEL); @@ -43,7 +43,7 @@ BlockState blockstate = addItem(p_270919_, p_270087_, p_270284_, p_270678_, p_270253_); p_270253_.shrink(1); return blockstate; -@@ -292,7 +_,7 @@ +@@ -296,7 +_,7 @@ static BlockState addItem(@Nullable Entity p_270464_, BlockState p_270603_, LevelAccessor p_270151_, BlockPos p_270547_, ItemStack p_270354_) { int i = p_270603_.getValue(LEVEL); @@ -52,7 +52,7 @@ if ((i != 0 || !(f > 0.0F)) && !(p_270151_.getRandom().nextDouble() < (double)f)) { return p_270603_; } else { -@@ -392,7 +_,7 @@ +@@ -396,7 +_,7 @@ @Override public boolean canPlaceItemThroughFace(int p_52028_, ItemStack p_52029_, @Nullable Direction p_52030_) { @@ -61,7 +61,7 @@ } @Override -@@ -450,5 +_,11 @@ +@@ -454,5 +_,11 @@ ComposterBlock.empty(null, this.state, this.level, this.pos); this.changed = true; } diff --git a/patches/net/minecraft/world/level/block/ConcretePowderBlock.java.patch b/patches/net/minecraft/world/level/block/ConcretePowderBlock.java.patch index 30355c0220..9254fe666b 100644 --- a/patches/net/minecraft/world/level/block/ConcretePowderBlock.java.patch +++ b/patches/net/minecraft/world/level/block/ConcretePowderBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/ConcretePowderBlock.java +++ b/net/minecraft/world/level/block/ConcretePowderBlock.java -@@ -34,7 +_,7 @@ +@@ -36,7 +_,7 @@ @Override public void onLand(Level p_52068_, BlockPos p_52069_, BlockState p_52070_, BlockState p_52071_, FallingBlockEntity p_52072_) { @@ -9,7 +9,7 @@ p_52068_.setBlock(p_52069_, this.concrete.defaultBlockState(), 3); } } -@@ -47,20 +_,24 @@ +@@ -49,20 +_,24 @@ return shouldSolidify(blockgetter, blockpos, blockstate) ? this.concrete.defaultBlockState() : super.getStateForPlacement(p_52063_); } @@ -38,12 +38,12 @@ flag = true; break; } -@@ -76,7 +_,7 @@ - - @Override - protected BlockState updateShape(BlockState p_52074_, Direction p_52075_, BlockState p_52076_, LevelAccessor p_52077_, BlockPos p_52078_, BlockPos p_52079_) { -- return touchesLiquid(p_52077_, p_52078_) -+ return touchesLiquid(p_52077_, p_52078_, p_52074_) +@@ -87,7 +_,7 @@ + BlockState p_52076_, + RandomSource p_374119_ + ) { +- return touchesLiquid(p_374245_, p_52078_) ++ return touchesLiquid(p_374245_, p_52078_, p_52074_) ? this.concrete.defaultBlockState() - : super.updateShape(p_52074_, p_52075_, p_52076_, p_52077_, p_52078_, p_52079_); + : super.updateShape(p_52074_, p_374245_, p_374286_, p_52078_, p_52075_, p_52079_, p_52076_, p_374119_); } diff --git a/patches/net/minecraft/world/level/block/CoralBlock.java.patch b/patches/net/minecraft/world/level/block/CoralBlock.java.patch index 5a1ed63e3c..ea6a1bed14 100644 --- a/patches/net/minecraft/world/level/block/CoralBlock.java.patch +++ b/patches/net/minecraft/world/level/block/CoralBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/CoralBlock.java +++ b/net/minecraft/world/level/block/CoralBlock.java -@@ -51,9 +_,10 @@ +@@ -61,9 +_,10 @@ } protected boolean scanForWater(BlockGetter p_52135_, BlockPos p_52136_) { diff --git a/patches/net/minecraft/world/level/block/CrafterBlock.java.patch b/patches/net/minecraft/world/level/block/CrafterBlock.java.patch index ac39be323e..a80e470efc 100644 --- a/patches/net/minecraft/world/level/block/CrafterBlock.java.patch +++ b/patches/net/minecraft/world/level/block/CrafterBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/CrafterBlock.java +++ b/net/minecraft/world/level/block/CrafterBlock.java -@@ -221,6 +_,8 @@ +@@ -214,6 +_,8 @@ break; } } diff --git a/patches/net/minecraft/world/level/block/CropBlock.java.patch b/patches/net/minecraft/world/level/block/CropBlock.java.patch index e00cad5006..f947ffdb3e 100644 --- a/patches/net/minecraft/world/level/block/CropBlock.java.patch +++ b/patches/net/minecraft/world/level/block/CropBlock.java.patch @@ -62,8 +62,8 @@ @Override protected void entityInside(BlockState p_52277_, Level p_52278_, BlockPos p_52279_, Entity p_52280_) { -- if (p_52280_ instanceof Ravager && p_52278_.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (p_52280_ instanceof Ravager && net.neoforged.neoforge.event.EventHooks.canEntityGrief(p_52278_, p_52280_)) { - p_52278_.destroyBlock(p_52279_, true, p_52280_); +- if (p_52278_ instanceof ServerLevel serverlevel && p_52280_ instanceof Ravager && serverlevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (p_52278_ instanceof ServerLevel serverlevel && p_52280_ instanceof Ravager && net.neoforged.neoforge.event.EventHooks.canEntityGrief(serverlevel, p_52280_)) { + serverlevel.destroyBlock(p_52279_, true, p_52280_); } diff --git a/patches/net/minecraft/world/level/block/DetectorRailBlock.java.patch b/patches/net/minecraft/world/level/block/DetectorRailBlock.java.patch index bccb363636..0350c723b9 100644 --- a/patches/net/minecraft/world/level/block/DetectorRailBlock.java.patch +++ b/patches/net/minecraft/world/level/block/DetectorRailBlock.java.patch @@ -11,19 +11,15 @@ this.registerDefaultState( this.stateDefinition .any() -@@ -152,9 +_,9 @@ - return list.get(0).getCommandBlock().getSuccessCount(); +@@ -153,7 +_,7 @@ } -- List list1 = this.getInteractingMinecartOfType( + List list1 = this.getInteractingMinecartOfType( - p_52455_, p_52456_, AbstractMinecart.class, EntitySelector.CONTAINER_ENTITY_SELECTOR -- ); -+ List carts = this.getInteractingMinecartOfType(p_52455_, p_52456_, AbstractMinecart.class, e -> e.isAlive()); -+ if (!carts.isEmpty() && carts.get(0).getComparatorLevel() > -1) return carts.get(0).getComparatorLevel(); -+ List list1 = carts.stream().filter(EntitySelector.CONTAINER_ENTITY_SELECTOR).collect(java.util.stream.Collectors.toList()); ++ p_52455_, p_52456_, AbstractMinecart.class, EntitySelector.CONTAINER_ENTITY_SELECTOR + ); if (!list1.isEmpty()) { return AbstractContainerMenu.getRedstoneSignalFromContainer((Container)list1.get(0)); - } @@ -299,6 +_,6 @@ @Override diff --git a/patches/net/minecraft/world/level/block/DiodeBlock.java.patch b/patches/net/minecraft/world/level/block/DiodeBlock.java.patch index 13cfbf4a01..50271b6536 100644 --- a/patches/net/minecraft/world/level/block/DiodeBlock.java.patch +++ b/patches/net/minecraft/world/level/block/DiodeBlock.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/block/DiodeBlock.java +++ b/net/minecraft/world/level/block/DiodeBlock.java -@@ -173,6 +_,8 @@ +@@ -176,6 +_,8 @@ protected void updateNeighborsInFront(Level p_52581_, BlockPos p_52582_, BlockState p_52583_) { Direction direction = p_52583_.getValue(FACING); BlockPos blockpos = p_52582_.relative(direction.getOpposite()); + if (net.neoforged.neoforge.event.EventHooks.onNeighborNotify(p_52581_, p_52582_, p_52581_.getBlockState(p_52582_), java.util.EnumSet.of(direction.getOpposite()), false).isCanceled()) + return; - p_52581_.neighborChanged(blockpos, this, p_52582_); - p_52581_.updateNeighborsAtExceptFromFacing(blockpos, this, direction); - } + Orientation orientation = ExperimentalRedstoneUtils.initialOrientation(p_52581_, direction.getOpposite(), Direction.UP); + p_52581_.neighborChanged(blockpos, this, orientation); + p_52581_.updateNeighborsAtExceptFromFacing(blockpos, this, direction, orientation); diff --git a/patches/net/minecraft/world/level/block/DoorBlock.java.patch b/patches/net/minecraft/world/level/block/DoorBlock.java.patch index 2c444805ae..bd91c16f2d 100644 --- a/patches/net/minecraft/world/level/block/DoorBlock.java.patch +++ b/patches/net/minecraft/world/level/block/DoorBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/DoorBlock.java +++ b/net/minecraft/world/level/block/DoorBlock.java -@@ -119,7 +_,7 @@ +@@ -132,7 +_,7 @@ @Override public BlockState playerWillDestroy(Level p_52755_, BlockPos p_52756_, BlockState p_52757_, Player p_52758_) { diff --git a/patches/net/minecraft/world/level/block/DoublePlantBlock.java.patch b/patches/net/minecraft/world/level/block/DoublePlantBlock.java.patch index edfa73df39..b9261ddcd8 100644 --- a/patches/net/minecraft/world/level/block/DoublePlantBlock.java.patch +++ b/patches/net/minecraft/world/level/block/DoublePlantBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/DoublePlantBlock.java +++ b/net/minecraft/world/level/block/DoublePlantBlock.java -@@ -71,6 +_,7 @@ +@@ -80,6 +_,7 @@ return super.canSurvive(p_52887_, p_52888_, p_52889_); } else { BlockState blockstate = p_52888_.getBlockState(p_52889_.below()); diff --git a/patches/net/minecraft/world/level/block/FarmBlock.java.patch b/patches/net/minecraft/world/level/block/FarmBlock.java.patch index 7b5c19bf38..72f3a0e03e 100644 --- a/patches/net/minecraft/world/level/block/FarmBlock.java.patch +++ b/patches/net/minecraft/world/level/block/FarmBlock.java.patch @@ -1,18 +1,18 @@ --- a/net/minecraft/world/level/block/FarmBlock.java +++ b/net/minecraft/world/level/block/FarmBlock.java -@@ -100,10 +_,7 @@ +@@ -109,10 +_,7 @@ @Override public void fallOn(Level p_153227_, BlockState p_153228_, BlockPos p_153229_, Entity p_153230_, float p_153231_) { - if (!p_153227_.isClientSide + if (p_153227_ instanceof ServerLevel serverlevel - && p_153227_.random.nextFloat() < p_153231_ - 0.5F - && p_153230_ instanceof LivingEntity -- && (p_153230_ instanceof Player || p_153227_.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) +- && (p_153230_ instanceof Player || serverlevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) - && p_153230_.getBbWidth() * p_153230_.getBbWidth() * p_153230_.getBbHeight() > 0.512F) { -+ && net.neoforged.neoforge.common.CommonHooks.onFarmlandTrample(p_153227_, p_153229_, Blocks.DIRT.defaultBlockState(), p_153231_, p_153230_)) { // Forge: Move logic to Entity#canTrample ++ && net.neoforged.neoforge.common.CommonHooks.onFarmlandTrample(serverlevel, p_153229_, Blocks.DIRT.defaultBlockState(), p_153231_, p_153230_)) { // Forge: Move logic to Entity#canTrample turnToDirt(p_153230_, p_153228_, p_153227_, p_153229_); } -@@ -121,13 +_,14 @@ +@@ -130,13 +_,14 @@ } private static boolean isNearWater(LevelReader p_53259_, BlockPos p_53260_) { diff --git a/patches/net/minecraft/world/level/block/FenceGateBlock.java.patch b/patches/net/minecraft/world/level/block/FenceGateBlock.java.patch index e31aaf5e23..042b0ecf8c 100644 --- a/patches/net/minecraft/world/level/block/FenceGateBlock.java.patch +++ b/patches/net/minecraft/world/level/block/FenceGateBlock.java.patch @@ -1,17 +1,19 @@ --- a/net/minecraft/world/level/block/FenceGateBlock.java +++ b/net/minecraft/world/level/block/FenceGateBlock.java -@@ -31,7 +_,9 @@ +@@ -36,8 +_,10 @@ public class FenceGateBlock extends HorizontalDirectionalBlock { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( -- p_308823_ -> p_308823_.group(WoodType.CODEC.fieldOf("wood_type").forGetter(p_304842_ -> p_304842_.type), propertiesCodec()) +- p_368422_ -> p_368422_.group(WoodType.CODEC.fieldOf("wood_type").forGetter(p_304842_ -> p_304842_.type), propertiesCodec()) +- .apply(p_368422_, FenceGateBlock::new) + p_308823_ -> p_308823_.group(WoodType.CODEC.optionalFieldOf("wood_type").forGetter(p_304842_ -> java.util.Optional.ofNullable(p_304842_.type)), propertiesCodec(), + net.minecraft.sounds.SoundEvent.DIRECT_CODEC.optionalFieldOf("open_sound").forGetter(fence -> java.util.Optional.of(fence.openSound).filter(s -> fence.type == null || s != fence.type.fenceGateOpen())), + net.minecraft.sounds.SoundEvent.DIRECT_CODEC.optionalFieldOf("close_sound").forGetter(fence -> java.util.Optional.of(fence.closeSound).filter(s -> fence.type == null || s != fence.type.fenceGateClose()))) - .apply(p_308823_, FenceGateBlock::new) ++ .apply(p_308823_, FenceGateBlock::new) ); public static final BooleanProperty OPEN = BlockStateProperties.OPEN; -@@ -49,6 +_,8 @@ + public static final BooleanProperty POWERED = BlockStateProperties.POWERED; +@@ -54,6 +_,8 @@ protected static final VoxelShape X_OCCLUSION_SHAPE = Shapes.or(Block.box(7.0, 5.0, 0.0, 9.0, 16.0, 2.0), Block.box(7.0, 5.0, 14.0, 9.0, 16.0, 16.0)); protected static final VoxelShape Z_OCCLUSION_SHAPE_LOW = Shapes.or(Block.box(0.0, 2.0, 7.0, 2.0, 13.0, 9.0), Block.box(14.0, 2.0, 7.0, 16.0, 13.0, 9.0)); protected static final VoxelShape X_OCCLUSION_SHAPE_LOW = Shapes.or(Block.box(7.0, 2.0, 0.0, 9.0, 13.0, 2.0), Block.box(7.0, 2.0, 14.0, 9.0, 13.0, 16.0)); @@ -20,7 +22,7 @@ private final WoodType type; @Override -@@ -57,8 +_,17 @@ +@@ -62,8 +_,17 @@ } public FenceGateBlock(WoodType p_273340_, BlockBehaviour.Properties p_273352_) { @@ -40,7 +42,7 @@ this.registerDefaultState( this.stateDefinition .any() -@@ -169,7 +_,7 @@ +@@ -183,7 +_,7 @@ p_53366_.playSound( p_53368_, p_53367_, @@ -49,16 +51,16 @@ SoundSource.BLOCKS, 1.0F, p_53366_.getRandom().nextFloat() * 0.1F + 0.9F -@@ -186,7 +_,7 @@ - p_311813_.playSound( +@@ -202,7 +_,7 @@ + p_361116_.playSound( null, p_312680_, - flag ? this.type.fenceGateClose() : this.type.fenceGateOpen(), + flag ? closeSound : openSound, SoundSource.BLOCKS, 1.0F, - p_311813_.getRandom().nextFloat() * 0.1F + 0.9F -@@ -207,7 +_,7 @@ + p_361116_.getRandom().nextFloat() * 0.1F + 0.9F +@@ -223,7 +_,7 @@ p_53373_.playSound( null, p_53374_, diff --git a/patches/net/minecraft/world/level/block/FireBlock.java.patch b/patches/net/minecraft/world/level/block/FireBlock.java.patch index 0e6d1d834e..1b005e4d03 100644 --- a/patches/net/minecraft/world/level/block/FireBlock.java.patch +++ b/patches/net/minecraft/world/level/block/FireBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/FireBlock.java +++ b/net/minecraft/world/level/block/FireBlock.java -@@ -132,13 +_,13 @@ +@@ -141,13 +_,13 @@ protected BlockState getStateForPlacement(BlockGetter p_53471_, BlockPos p_53472_) { BlockPos blockpos = p_53472_.below(); BlockState blockstate = p_53471_.getBlockState(blockpos); @@ -16,7 +16,7 @@ } } -@@ -163,7 +_,7 @@ +@@ -172,7 +_,7 @@ } BlockState blockstate = p_221161_.getBlockState(p_221162_.below()); @@ -25,7 +25,7 @@ int i = p_221160_.getValue(AGE); if (!flag && p_221161_.isRaining() && this.isNearRain(p_221161_, p_221162_) && p_221163_.nextFloat() < 0.2F + (float)i * 0.03F) { p_221161_.removeBlock(p_221162_, false); -@@ -184,7 +_,7 @@ +@@ -193,7 +_,7 @@ return; } @@ -34,7 +34,7 @@ p_221161_.removeBlock(p_221162_, false); return; } -@@ -192,12 +_,12 @@ +@@ -201,12 +_,12 @@ boolean flag1 = p_221161_.getBiome(p_221162_).is(BiomeTags.INCREASED_FIRE_BURNOUT); int k = flag1 ? -50 : 0; @@ -53,7 +53,7 @@ BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); for (int l = -1; l <= 1; l++) { -@@ -240,33 +_,32 @@ +@@ -249,33 +_,32 @@ || p_53429_.isRainingAt(p_53430_.south()); } @@ -93,7 +93,7 @@ } } -@@ -277,7 +_,7 @@ +@@ -286,7 +_,7 @@ private boolean isValidFireLocation(BlockGetter p_53486_, BlockPos p_53487_) { for (Direction direction : Direction.values()) { @@ -102,7 +102,7 @@ return true; } } -@@ -293,7 +_,7 @@ +@@ -302,7 +_,7 @@ for (Direction direction : Direction.values()) { BlockState blockstate = p_221157_.getBlockState(p_221158_.relative(direction)); @@ -111,7 +111,7 @@ } return i; -@@ -301,6 +_,7 @@ +@@ -310,6 +_,7 @@ } @Override @@ -119,7 +119,7 @@ protected boolean canBurn(BlockState p_53489_) { return this.getIgniteOdds(p_53489_) > 0; } -@@ -321,8 +_,21 @@ +@@ -330,8 +_,21 @@ } public void setFlammable(Block p_53445_, int p_53446_, int p_53447_) { diff --git a/patches/net/minecraft/world/level/block/FlowerPotBlock.java.patch b/patches/net/minecraft/world/level/block/FlowerPotBlock.java.patch index e2a75a86fe..ce68c441bd 100644 --- a/patches/net/minecraft/world/level/block/FlowerPotBlock.java.patch +++ b/patches/net/minecraft/world/level/block/FlowerPotBlock.java.patch @@ -59,9 +59,9 @@ - p_316655_.setBlock(p_316654_, Blocks.FLOWER_POT.defaultBlockState(), 3); + p_316655_.setBlock(p_316654_, getEmptyPot().defaultBlockState(), 3); p_316655_.gameEvent(p_316338_, GameEvent.BLOCK_CHANGE, p_316654_); - return InteractionResult.sidedSuccess(p_316655_.isClientSide); + return InteractionResult.SUCCESS; } -@@ -107,11 +_,44 @@ +@@ -116,11 +_,44 @@ } public Block getPotted() { diff --git a/patches/net/minecraft/world/level/block/LeavesBlock.java.patch b/patches/net/minecraft/world/level/block/LeavesBlock.java.patch index b086bca9d6..7807a016b1 100644 --- a/patches/net/minecraft/world/level/block/LeavesBlock.java.patch +++ b/patches/net/minecraft/world/level/block/LeavesBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/LeavesBlock.java +++ b/net/minecraft/world/level/block/LeavesBlock.java -@@ -24,7 +_,7 @@ +@@ -26,7 +_,7 @@ import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; diff --git a/patches/net/minecraft/world/level/block/LiquidBlock.java.patch b/patches/net/minecraft/world/level/block/LiquidBlock.java.patch index bc1dea4969..5d6aea4b75 100644 --- a/patches/net/minecraft/world/level/block/LiquidBlock.java.patch +++ b/patches/net/minecraft/world/level/block/LiquidBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/LiquidBlock.java +++ b/net/minecraft/world/level/block/LiquidBlock.java -@@ -134,7 +_,7 @@ +@@ -137,7 +_,7 @@ @Override protected void onPlace(BlockState p_54754_, Level p_54755_, BlockPos p_54756_, BlockState p_54757_, boolean p_54758_) { @@ -9,10 +9,10 @@ p_54755_.scheduleTick(p_54756_, p_54754_.getFluidState().getType(), this.fluid.getTickDelay(p_54755_)); } } -@@ -150,11 +_,12 @@ +@@ -162,11 +_,12 @@ @Override - protected void neighborChanged(BlockState p_54709_, Level p_54710_, BlockPos p_54711_, Block p_54712_, BlockPos p_54713_, boolean p_54714_) { + protected void neighborChanged(BlockState p_54709_, Level p_54710_, BlockPos p_54711_, Block p_54712_, @Nullable Orientation p_361226_, boolean p_54714_) { - if (this.shouldSpreadLiquid(p_54710_, p_54711_, p_54709_)) { + if (!net.neoforged.neoforge.fluids.FluidInteractionRegistry.canInteract(p_54710_, p_54711_)) { p_54710_.scheduleTick(p_54711_, p_54709_.getFluidState().getType(), this.fluid.getTickDelay(p_54710_)); diff --git a/patches/net/minecraft/world/level/block/MushroomBlock.java.patch b/patches/net/minecraft/world/level/block/MushroomBlock.java.patch index a977b18527..6283cb275b 100644 --- a/patches/net/minecraft/world/level/block/MushroomBlock.java.patch +++ b/patches/net/minecraft/world/level/block/MushroomBlock.java.patch @@ -13,8 +13,8 @@ public boolean growMushroom(ServerLevel p_221774_, BlockPos p_221775_, BlockState p_221776_, RandomSource p_221777_) { Optional>> optional = p_221774_.registryAccess() - .registryOrThrow(Registries.CONFIGURED_FEATURE) - .getHolder(this.feature); + .lookupOrThrow(Registries.CONFIGURED_FEATURE) + .get(this.feature); + + // Neo: Fire the BlockGrowFeatureEvent and update the result of the Optional local with the new feature. + var event = net.neoforged.neoforge.event.EventHooks.fireBlockGrowFeature(p_221774_, p_221777_, p_221775_, optional.orElse(null)); diff --git a/patches/net/minecraft/world/level/block/NoteBlock.java.patch b/patches/net/minecraft/world/level/block/NoteBlock.java.patch index 5c0e59dbd2..9c9392dbcd 100644 --- a/patches/net/minecraft/world/level/block/NoteBlock.java.patch +++ b/patches/net/minecraft/world/level/block/NoteBlock.java.patch @@ -1,17 +1,16 @@ --- a/net/minecraft/world/level/block/NoteBlock.java +++ b/net/minecraft/world/level/block/NoteBlock.java -@@ -110,7 +_,9 @@ - if (p_316774_.isClientSide) { - return InteractionResult.SUCCESS; - } else { -- p_316441_ = p_316441_.cycle(NOTE); +@@ -122,6 +_,9 @@ + protected InteractionResult useWithoutItem(BlockState p_316441_, Level p_316774_, BlockPos p_316344_, Player p_316884_, BlockHitResult p_316631_) { + if (!p_316774_.isClientSide) { + p_316441_ = p_316441_.cycle(NOTE); + int _new = net.neoforged.neoforge.common.CommonHooks.onNoteChange(p_316774_, p_316344_, p_316441_, p_316441_.getValue(NOTE), p_316441_.cycle(NOTE).getValue(NOTE)); + if (_new == -1) return InteractionResult.FAIL; + p_316441_ = p_316441_.setValue(NOTE, _new); p_316774_.setBlock(p_316344_, p_316441_, 3); this.playNote(p_316884_, p_316441_, p_316774_, p_316344_); p_316884_.awardStat(Stats.TUNE_NOTEBLOCK); -@@ -132,6 +_,9 @@ +@@ -144,6 +_,9 @@ @Override protected boolean triggerEvent(BlockState p_55023_, Level p_55024_, BlockPos p_55025_, int p_55026_, int p_55027_) { diff --git a/patches/net/minecraft/world/level/block/PitcherCropBlock.java.patch b/patches/net/minecraft/world/level/block/PitcherCropBlock.java.patch index b38b96d495..f3be3ce25c 100644 --- a/patches/net/minecraft/world/level/block/PitcherCropBlock.java.patch +++ b/patches/net/minecraft/world/level/block/PitcherCropBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/PitcherCropBlock.java +++ b/net/minecraft/world/level/block/PitcherCropBlock.java -@@ -86,12 +_,13 @@ +@@ -93,12 +_,13 @@ @Override public boolean canSurvive(BlockState p_277671_, LevelReader p_277477_, BlockPos p_278085_) { @@ -16,7 +16,7 @@ } @Override -@@ -125,7 +_,7 @@ +@@ -132,7 +_,7 @@ @Override public void randomTick(BlockState p_277950_, ServerLevel p_277589_, BlockPos p_277937_, RandomSource p_277887_) { diff --git a/patches/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch b/patches/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch index 433f12e7c7..4ba64c1bd2 100644 --- a/patches/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch +++ b/patches/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/PointedDripstoneBlock.java +++ b/net/minecraft/world/level/block/PointedDripstoneBlock.java -@@ -184,7 +_,7 @@ +@@ -192,7 +_,7 @@ @VisibleForTesting public static void maybeTransferFluid(BlockState p_221860_, ServerLevel p_221861_, BlockPos p_221862_, float p_221863_) { @@ -9,7 +9,7 @@ if (isStalactiteStartPos(p_221860_, p_221861_, p_221862_)) { Optional optional = getFluidAboveStalactite(p_221861_, p_221862_, p_221860_); if (!optional.isEmpty()) { -@@ -193,14 +_,12 @@ +@@ -201,14 +_,12 @@ if (fluid == Fluids.WATER) { f = 0.17578125F; } else { @@ -26,7 +26,7 @@ BlockPos blockpos = findTip(p_221860_, p_221861_, p_221862_, 11, false); if (blockpos != null) { if (optional.get().sourceState.is(Blocks.MUD) && fluid == Fluids.WATER) { -@@ -411,7 +_,8 @@ +@@ -419,7 +_,8 @@ double d2 = (double)((float)(p_154073_.getY() + 1) - 0.6875F) - 0.0625; double d3 = (double)p_154073_.getZ() + 0.5 + vec3.z; Fluid fluid = getDripFluid(p_154072_, p_154075_); @@ -36,7 +36,7 @@ p_154072_.addParticle(particleoptions, d1, d2, d3, 0.0, 0.0, 0.0); } -@@ -563,7 +_,7 @@ +@@ -571,7 +_,7 @@ } private static boolean canFillCauldron(Fluid p_154159_) { diff --git a/patches/net/minecraft/world/level/block/PowderSnowBlock.java.patch b/patches/net/minecraft/world/level/block/PowderSnowBlock.java.patch index 29c7e6ca18..923d5b94e6 100644 --- a/patches/net/minecraft/world/level/block/PowderSnowBlock.java.patch +++ b/patches/net/minecraft/world/level/block/PowderSnowBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/PowderSnowBlock.java +++ b/net/minecraft/world/level/block/PowderSnowBlock.java -@@ -130,7 +_,7 @@ +@@ -126,7 +_,7 @@ if (p_154256_.getType().is(EntityTypeTags.POWDER_SNOW_WALKABLE_MOBS)) { return true; } else { diff --git a/patches/net/minecraft/world/level/block/PoweredRailBlock.java.patch b/patches/net/minecraft/world/level/block/PoweredRailBlock.java.patch index 7e5da26de1..e0a519f676 100644 --- a/patches/net/minecraft/world/level/block/PoweredRailBlock.java.patch +++ b/patches/net/minecraft/world/level/block/PoweredRailBlock.java.patch @@ -25,7 +25,7 @@ int k = p_55221_.getZ(); boolean flag = true; - RailShape railshape = p_55222_.getValue(SHAPE); -+ RailShape railshape = p_55222_.getValue(getShapeProperty()); ++ RailShape railshape = ((BaseRailBlock)p_55222_.getBlock()).getRailDirection(p_55222_, p_55220_, p_55221_, null); switch (railshape) { case NORTH_SOUTH: if (p_55223_) { @@ -56,8 +56,8 @@ if (flag1 != flag) { p_55233_.setBlock(p_55234_, p_55232_.setValue(POWERED, Boolean.valueOf(flag1)), 3); p_55233_.updateNeighborsAt(p_55234_.below(), this); -- if (p_55232_.getValue(SHAPE).isAscending()) { -+ if (p_55232_.getValue(getShapeProperty()).isAscending()) { +- if (p_55232_.getValue(SHAPE).isSlope()) { ++ if (((BaseRailBlock)p_55232_.getBlock()).getRailDirection(p_55232_, p_55233_, p_55234_, null).isSlope()) { p_55233_.updateNeighborsAt(p_55234_.above(), this); } } diff --git a/patches/net/minecraft/world/level/block/PumpkinBlock.java.patch b/patches/net/minecraft/world/level/block/PumpkinBlock.java.patch index 64546ae9af..6c99c628ff 100644 --- a/patches/net/minecraft/world/level/block/PumpkinBlock.java.patch +++ b/patches/net/minecraft/world/level/block/PumpkinBlock.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/block/PumpkinBlock.java +++ b/net/minecraft/world/level/block/PumpkinBlock.java @@ -35,7 +_,7 @@ - protected ItemInteractionResult useItemOn( + protected InteractionResult useItemOn( ItemStack p_316383_, BlockState p_316676_, Level p_316272_, BlockPos p_316484_, Player p_316367_, InteractionHand p_316216_, BlockHitResult p_316827_ ) { - if (!p_316383_.is(Items.SHEARS)) { + if (!p_316383_.canPerformAction(net.neoforged.neoforge.common.ItemAbilities.SHEARS_CARVE)) { return super.useItemOn(p_316383_, p_316676_, p_316272_, p_316484_, p_316367_, p_316216_, p_316827_); } else if (p_316272_.isClientSide) { - return ItemInteractionResult.sidedSuccess(p_316272_.isClientSide); + return InteractionResult.SUCCESS; diff --git a/patches/net/minecraft/world/level/block/RedStoneWireBlock.java.patch b/patches/net/minecraft/world/level/block/RedStoneWireBlock.java.patch index 79ce4b3f60..1e9a7cfceb 100644 --- a/patches/net/minecraft/world/level/block/RedStoneWireBlock.java.patch +++ b/patches/net/minecraft/world/level/block/RedStoneWireBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/RedStoneWireBlock.java +++ b/net/minecraft/world/level/block/RedStoneWireBlock.java -@@ -253,7 +_,7 @@ +@@ -268,7 +_,7 @@ BlockState blockstate = p_55523_.getBlockState(blockpos); if (p_55526_) { boolean flag = blockstate.getBlock() instanceof TrapDoorBlock || this.canSurviveOn(p_55523_, blockpos, blockstate); @@ -9,7 +9,7 @@ if (blockstate.isFaceSturdy(p_55523_, blockpos, p_55525_.getOpposite())) { return RedstoneSide.UP; } -@@ -262,10 +_,14 @@ +@@ -277,10 +_,14 @@ } } diff --git a/patches/net/minecraft/world/level/block/SculkSensorBlock.java.patch b/patches/net/minecraft/world/level/block/SculkSensorBlock.java.patch index 12f47c323f..5aee48d600 100644 --- a/patches/net/minecraft/world/level/block/SculkSensorBlock.java.patch +++ b/patches/net/minecraft/world/level/block/SculkSensorBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SculkSensorBlock.java +++ b/net/minecraft/world/level/block/SculkSensorBlock.java -@@ -291,8 +_,13 @@ +@@ -299,8 +_,13 @@ @Override protected void spawnAfterBreak(BlockState p_222142_, ServerLevel p_222143_, BlockPos p_222144_, ItemStack p_222145_, boolean p_222146_) { super.spawnAfterBreak(p_222142_, p_222143_, p_222144_, p_222145_, p_222146_); diff --git a/patches/net/minecraft/world/level/block/SculkShriekerBlock.java.patch b/patches/net/minecraft/world/level/block/SculkShriekerBlock.java.patch index 6f5dedbc34..646554aa30 100644 --- a/patches/net/minecraft/world/level/block/SculkShriekerBlock.java.patch +++ b/patches/net/minecraft/world/level/block/SculkShriekerBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SculkShriekerBlock.java +++ b/net/minecraft/world/level/block/SculkShriekerBlock.java -@@ -141,9 +_,14 @@ +@@ -149,9 +_,14 @@ @Override protected void spawnAfterBreak(BlockState p_222192_, ServerLevel p_222193_, BlockPos p_222194_, ItemStack p_222195_, boolean p_222196_) { super.spawnAfterBreak(p_222192_, p_222193_, p_222194_, p_222195_, p_222196_); diff --git a/patches/net/minecraft/world/level/block/SeagrassBlock.java.patch b/patches/net/minecraft/world/level/block/SeagrassBlock.java.patch index a3580320c7..f596a92bef 100644 --- a/patches/net/minecraft/world/level/block/SeagrassBlock.java.patch +++ b/patches/net/minecraft/world/level/block/SeagrassBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SeagrassBlock.java +++ b/net/minecraft/world/level/block/SeagrassBlock.java -@@ -22,7 +_,7 @@ +@@ -23,7 +_,7 @@ import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; diff --git a/patches/net/minecraft/world/level/block/SoundType.java.patch b/patches/net/minecraft/world/level/block/SoundType.java.patch index 0d3a12b6cd..92c1ab63a3 100644 --- a/patches/net/minecraft/world/level/block/SoundType.java.patch +++ b/patches/net/minecraft/world/level/block/SoundType.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SoundType.java +++ b/net/minecraft/world/level/block/SoundType.java -@@ -777,6 +_,7 @@ +@@ -789,6 +_,7 @@ private final SoundEvent hitSound; private final SoundEvent fallSound; diff --git a/patches/net/minecraft/world/level/block/SpongeBlock.java.patch b/patches/net/minecraft/world/level/block/SpongeBlock.java.patch index 69c47ae16d..ac00ddee76 100644 --- a/patches/net/minecraft/world/level/block/SpongeBlock.java.patch +++ b/patches/net/minecraft/world/level/block/SpongeBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SpongeBlock.java +++ b/net/minecraft/world/level/block/SpongeBlock.java -@@ -49,6 +_,7 @@ +@@ -51,6 +_,7 @@ } private boolean removeWaterBreadthFirstSearch(Level p_56808_, BlockPos p_56809_) { @@ -8,7 +8,7 @@ return BlockPos.breadthFirstTraversal( p_56809_, 6, -@@ -64,7 +_,7 @@ +@@ -66,7 +_,7 @@ } else { BlockState blockstate = p_56808_.getBlockState(p_294069_); FluidState fluidstate = p_56808_.getFluidState(p_294069_); diff --git a/patches/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java.patch b/patches/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java.patch index 2f24cf95b1..0c7f4162b8 100644 --- a/patches/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java.patch +++ b/patches/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java +++ b/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java -@@ -42,8 +_,10 @@ +@@ -40,8 +_,10 @@ @Override protected void randomTick(BlockState p_222508_, ServerLevel p_222509_, BlockPos p_222510_, RandomSource p_222511_) { if (!canBeGrass(p_222508_, p_222509_, p_222510_)) { diff --git a/patches/net/minecraft/world/level/block/StemBlock.java.patch b/patches/net/minecraft/world/level/block/StemBlock.java.patch index 17d8f22e5b..f8d6468063 100644 --- a/patches/net/minecraft/world/level/block/StemBlock.java.patch +++ b/patches/net/minecraft/world/level/block/StemBlock.java.patch @@ -27,7 +27,7 @@ BlockState blockstate = p_222539_.getBlockState(blockpos.below()); - if (p_222539_.getBlockState(blockpos).isAir() && (blockstate.is(Blocks.FARMLAND) || blockstate.is(BlockTags.DIRT))) { + if (p_222539_.isEmptyBlock(blockpos) && (blockstate.getBlock() instanceof net.minecraft.world.level.block.FarmBlock || blockstate.is(BlockTags.DIRT))) { - Registry registry = p_222539_.registryAccess().registryOrThrow(Registries.BLOCK); + Registry registry = p_222539_.registryAccess().lookupOrThrow(Registries.BLOCK); Optional optional = registry.getOptional(this.fruit); Optional optional1 = registry.getOptional(this.attachedStem); @@ -100,6 +_,7 @@ diff --git a/patches/net/minecraft/world/level/block/SugarCaneBlock.java.patch b/patches/net/minecraft/world/level/block/SugarCaneBlock.java.patch index 55a9cd856c..dbf788792d 100644 --- a/patches/net/minecraft/world/level/block/SugarCaneBlock.java.patch +++ b/patches/net/minecraft/world/level/block/SugarCaneBlock.java.patch @@ -16,7 +16,7 @@ } } } -@@ -83,13 +_,15 @@ +@@ -92,13 +_,15 @@ if (blockstate.is(this)) { return true; } else { diff --git a/patches/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch b/patches/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch index 934879d9b1..9abbbc3e05 100644 --- a/patches/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch +++ b/patches/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SweetBerryBushBlock.java +++ b/net/minecraft/world/level/block/SweetBerryBushBlock.java -@@ -69,9 +_,10 @@ +@@ -68,9 +_,10 @@ @Override protected void randomTick(BlockState p_222563_, ServerLevel p_222564_, BlockPos p_222565_, RandomSource p_222566_) { int i = p_222563_.getValue(AGE); diff --git a/patches/net/minecraft/world/level/block/TntBlock.java.patch b/patches/net/minecraft/world/level/block/TntBlock.java.patch index acf16ed6ab..eb50b4ce68 100644 --- a/patches/net/minecraft/world/level/block/TntBlock.java.patch +++ b/patches/net/minecraft/world/level/block/TntBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/TntBlock.java +++ b/net/minecraft/world/level/block/TntBlock.java -@@ -41,10 +_,14 @@ +@@ -43,10 +_,14 @@ } @Override @@ -16,16 +16,16 @@ p_57467_.removeBlock(p_57468_, false); } } -@@ -53,7 +_,7 @@ +@@ -55,7 +_,7 @@ @Override - protected void neighborChanged(BlockState p_57457_, Level p_57458_, BlockPos p_57459_, Block p_57460_, BlockPos p_57461_, boolean p_57462_) { + protected void neighborChanged(BlockState p_57457_, Level p_57458_, BlockPos p_57459_, Block p_57460_, @Nullable Orientation p_364510_, boolean p_57462_) { if (p_57458_.hasNeighborSignal(p_57459_)) { - explode(p_57458_, p_57459_); + onCaughtFire(p_57457_, p_57458_, p_57459_, null, null); p_57458_.removeBlock(p_57459_, false); } } -@@ -61,7 +_,7 @@ +@@ -63,7 +_,7 @@ @Override public BlockState playerWillDestroy(Level p_57445_, BlockPos p_57446_, BlockState p_57447_, Player p_57448_) { if (!p_57445_.isClientSide() && !p_57448_.isCreative() && p_57447_.getValue(UNSTABLE)) { @@ -35,7 +35,7 @@ return super.playerWillDestroy(p_57445_, p_57446_, p_57447_, p_57448_); @@ -79,10 +_,12 @@ - } + p_364953_.addFreshEntity(primedtnt); } + @Deprecated //Forge: Prefer using IForgeBlock#catchFire @@ -59,7 +59,7 @@ @@ -119,7 +_,7 @@ BlockPos blockpos = p_57431_.getBlockPos(); Entity entity = p_57432_.getOwner(); - if (p_57432_.isOnFire() && p_57432_.mayInteract(p_57429_, blockpos)) { + if (p_57432_.isOnFire() && p_57432_.mayInteract(serverlevel, blockpos)) { - explode(p_57429_, blockpos, entity instanceof LivingEntity ? (LivingEntity)entity : null); + onCaughtFire(p_57430_, p_57429_, blockpos, null, entity instanceof LivingEntity ? (LivingEntity)entity : null); p_57429_.removeBlock(blockpos, false); diff --git a/patches/net/minecraft/world/level/block/TrapDoorBlock.java.patch b/patches/net/minecraft/world/level/block/TrapDoorBlock.java.patch index 6fb22ca4cb..3ebddb6f27 100644 --- a/patches/net/minecraft/world/level/block/TrapDoorBlock.java.patch +++ b/patches/net/minecraft/world/level/block/TrapDoorBlock.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/level/block/TrapDoorBlock.java +++ b/net/minecraft/world/level/block/TrapDoorBlock.java -@@ -200,6 +_,17 @@ - return super.updateShape(p_57554_, p_57555_, p_57556_, p_57557_, p_57558_, p_57559_); +@@ -215,6 +_,17 @@ + return super.updateShape(p_57554_, p_374386_, p_374038_, p_57558_, p_57555_, p_57559_, p_57556_, p_374093_); } + // Neo: Allows Trapdoors to be climbable if any ladder, even modded ladders, is below Trapdoor diff --git a/patches/net/minecraft/world/level/block/TripWireBlock.java.patch b/patches/net/minecraft/world/level/block/TripWireBlock.java.patch index 1d1fd55985..e1bdf7fc7c 100644 --- a/patches/net/minecraft/world/level/block/TripWireBlock.java.patch +++ b/patches/net/minecraft/world/level/block/TripWireBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/TripWireBlock.java +++ b/net/minecraft/world/level/block/TripWireBlock.java -@@ -104,7 +_,7 @@ +@@ -114,7 +_,7 @@ @Override public BlockState playerWillDestroy(Level p_57615_, BlockPos p_57616_, BlockState p_57617_, Player p_57618_) { diff --git a/patches/net/minecraft/world/level/block/TripWireHookBlock.java.patch b/patches/net/minecraft/world/level/block/TripWireHookBlock.java.patch deleted file mode 100644 index f06ccb7460..0000000000 --- a/patches/net/minecraft/world/level/block/TripWireHookBlock.java.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/net/minecraft/world/level/block/TripWireHookBlock.java -+++ b/net/minecraft/world/level/block/TripWireHookBlock.java -@@ -176,8 +_,8 @@ - BlockPos blockpos2 = p_57687_.relative(direction, k); - BlockState blockstate2 = ablockstate[k]; - if (blockstate2 != null) { -+ if (!p_57686_.getBlockState(blockpos2).isAir()) { // FORGE: fix MC-129055 - p_57686_.setBlock(blockpos2, blockstate2.trySetValue(ATTACHED, Boolean.valueOf(flag2)), 3); -- if (!p_57686_.getBlockState(blockpos2).isAir()) { - } - } - } diff --git a/patches/net/minecraft/world/level/block/TurtleEggBlock.java.patch b/patches/net/minecraft/world/level/block/TurtleEggBlock.java.patch index 3f07d6855e..d3294faa4e 100644 --- a/patches/net/minecraft/world/level/block/TurtleEggBlock.java.patch +++ b/patches/net/minecraft/world/level/block/TurtleEggBlock.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/block/TurtleEggBlock.java +++ b/net/minecraft/world/level/block/TurtleEggBlock.java -@@ -171,7 +_,7 @@ +@@ -173,7 +_,7 @@ if (p_57769_ instanceof Turtle || p_57769_ instanceof Bat) { return false; } else { -- return !(p_57769_ instanceof LivingEntity) ? false : p_57769_ instanceof Player || p_57768_.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); -+ return !(p_57769_ instanceof LivingEntity) ? false : p_57769_ instanceof Player || net.neoforged.neoforge.event.EventHooks.canEntityGrief(p_57768_, p_57769_); +- return !(p_57769_ instanceof LivingEntity) ? false : p_57769_ instanceof Player || p_376510_.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); ++ return !(p_57769_ instanceof LivingEntity) ? false : p_57769_ instanceof Player || net.neoforged.neoforge.event.EventHooks.canEntityGrief(p_376510_, p_57769_); } } } diff --git a/patches/net/minecraft/world/level/block/VineBlock.java.patch b/patches/net/minecraft/world/level/block/VineBlock.java.patch index f83b32be8e..70537e1e0e 100644 --- a/patches/net/minecraft/world/level/block/VineBlock.java.patch +++ b/patches/net/minecraft/world/level/block/VineBlock.java.patch @@ -9,7 +9,7 @@ public static final MapCodec CODEC = simpleCodec(VineBlock::new); public static final BooleanProperty UP = PipeBlock.UP; public static final BooleanProperty NORTH = PipeBlock.NORTH; -@@ -183,7 +_,7 @@ +@@ -192,7 +_,7 @@ @Override protected void randomTick(BlockState p_222655_, ServerLevel p_222656_, BlockPos p_222657_, RandomSource p_222658_) { if (p_222656_.getGameRules().getBoolean(GameRules.RULE_DO_VINES_SPREAD)) { diff --git a/patches/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch index 602c72711f..03bd036ae7 100644 --- a/patches/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -@@ -60,6 +_,7 @@ - public static final int NUM_DATA_VALUES = 4; +@@ -54,6 +_,7 @@ public static final int BURN_TIME_STANDARD = 200; public static final int BURN_COOL_SPEED = 2; + public static final int UNKNOWN_LIT_DURATION = 0; + private final RecipeType recipeType; protected NonNullList items = NonNullList.withSize(3, ItemStack.EMPTY); int litTime; - int litDuration; -@@ -72,9 +_,14 @@ + int litDuration = 0; +@@ -64,9 +_,14 @@ public int get(int p_58431_) { switch (p_58431_) { case 0: @@ -24,57 +24,15 @@ case 2: return AbstractFurnaceBlockEntity.this.cookingProgress; case 3: -@@ -114,18 +_,40 @@ +@@ -106,6 +_,7 @@ ) { super(p_154991_, p_154992_, p_154993_); this.quickCheck = RecipeManager.createCheck((RecipeType)p_154994_); + this.recipeType = p_154994_; } - public static void invalidateCache() { - fuelCache = null; - } - -+ /** -+ * @deprecated Neo: get burn times by calling {@link net.neoforged.neoforge.common.extensions.IItemStackExtension#getBurnTime(RecipeType)} -+ */ -+ @Deprecated - public static Map getFuel() { - Map map = fuelCache; - if (map != null) { - return map; - } else { - Map map1 = Maps.newLinkedHashMap(); -+ buildFuels((e, time) -> e.ifRight(tag -> add(map1, tag, time)).ifLeft(item -> add(map1, item, time))); -+ fuelCache = map1; -+ return map1; -+ } -+ } -+ -+ private static void add(java.util.function.ObjIntConsumer>> consumer, ItemLike item, int time) { -+ consumer.accept(com.mojang.datafixers.util.Either.left(item.asItem()), time); -+ } -+ -+ private static void add(java.util.function.ObjIntConsumer>> consumer, TagKey tag, int time) { -+ consumer.accept(com.mojang.datafixers.util.Either.right(tag), time); -+ } -+ -+ @org.jetbrains.annotations.ApiStatus.Internal -+ public static void buildFuels(java.util.function.ObjIntConsumer>> map1) { -+ { - add(map1, Items.LAVA_BUCKET, 20000); - add(map1, Blocks.COAL_BLOCK, 16000); - add(map1, Items.BLAZE_ROD, 2400); -@@ -185,8 +_,6 @@ - add(map1, Blocks.AZALEA, 100); - add(map1, Blocks.FLOWERING_AZALEA, 100); - add(map1, Blocks.MANGROVE_ROOTS, 300); -- fuelCache = map1; -- return map1; - } - } - -@@ -226,9 +_,9 @@ + private boolean isLit() { +@@ -117,9 +_,9 @@ super.loadAdditional(p_155025_, p_323468_); this.items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); ContainerHelper.loadAllItems(p_155025_, this.items, p_323468_); @@ -84,10 +42,10 @@ + this.litTime = p_155025_.getInt("BurnTime"); + this.cookingProgress = p_155025_.getInt("CookTime"); + this.cookingTotalTime = p_155025_.getInt("CookTimeTotal"); - this.litDuration = this.getBurnDuration(this.items.get(1)); + this.litDuration = 0; CompoundTag compoundtag = p_155025_.getCompound("RecipesUsed"); -@@ -240,9 +_,9 @@ +@@ -131,9 +_,9 @@ @Override protected void saveAdditional(CompoundTag p_187452_, HolderLookup.Provider p_323656_) { super.saveAdditional(p_187452_, p_323656_); @@ -99,56 +57,25 @@ + p_187452_.putInt("CookTimeTotal", this.cookingTotalTime); ContainerHelper.saveAllItems(p_187452_, this.items, p_323656_); CompoundTag compoundtag = new CompoundTag(); - this.recipesUsed.forEach((p_187449_, p_187450_) -> compoundtag.putInt(p_187449_.toString(), p_187450_)); -@@ -269,28 +_,30 @@ - } - - int i = p_155017_.getMaxStackSize(); -- if (!p_155017_.isLit() && canBurn(p_155014_.registryAccess(), recipeholder, p_155017_.items, i)) { -+ if (!p_155017_.isLit() && canBurn(p_155014_.registryAccess(), recipeholder, p_155017_.items, i, p_155017_)) { - p_155017_.litTime = p_155017_.getBurnDuration(itemstack); + this.recipesUsed.forEach((p_380898_, p_380899_) -> compoundtag.putInt(p_380898_.location().toString(), p_380899_)); +@@ -170,11 +_,15 @@ p_155017_.litDuration = p_155017_.litTime; if (p_155017_.isLit()) { flag1 = true; -+ if (itemstack.hasCraftingRemainingItem()) -+ p_155017_.items.set(1, itemstack.getCraftingRemainingItem()); ++ var remainder = itemstack.getCraftingRemainder(); ++ if (!remainder.isEmpty()) ++ p_155017_.items.set(1, remainder); + else if (flag3) { Item item = itemstack.getItem(); itemstack.shrink(1); if (itemstack.isEmpty()) { -- Item item1 = item.getCraftingRemainingItem(); -- p_155017_.items.set(1, item1 == null ? ItemStack.EMPTY : new ItemStack(item1)); -+ p_155017_.items.set(1, itemstack.getCraftingRemainingItem()); +- p_155017_.items.set(1, item.getCraftingRemainder()); ++ p_155017_.items.set(1, item.getCraftingRemainder()); // Neo: Remainder is handled in the `if` check above. } } } - } - -- if (p_155017_.isLit() && canBurn(p_155014_.registryAccess(), recipeholder, p_155017_.items, i)) { -+ if (p_155017_.isLit() && canBurn(p_155014_.registryAccess(), recipeholder, p_155017_.items, i, p_155017_)) { - p_155017_.cookingProgress++; - if (p_155017_.cookingProgress == p_155017_.cookingTotalTime) { - p_155017_.cookingProgress = 0; - p_155017_.cookingTotalTime = getTotalCookTime(p_155014_, p_155017_); -- if (burn(p_155014_.registryAccess(), recipeholder, p_155017_.items, i)) { -+ if (burn(p_155014_.registryAccess(), recipeholder, p_155017_.items, i, p_155017_)) { - p_155017_.setRecipeUsed(recipeholder); - } - -@@ -314,9 +_,9 @@ - } - } - -- private static boolean canBurn(RegistryAccess p_266924_, @Nullable RecipeHolder p_301107_, NonNullList p_155007_, int p_155008_) { -+ private static boolean canBurn(RegistryAccess p_266924_, @Nullable RecipeHolder p_301107_, NonNullList p_155007_, int p_155008_, AbstractFurnaceBlockEntity furnace) { - if (!p_155007_.get(0).isEmpty() && p_301107_ != null) { -- ItemStack itemstack = p_301107_.value().getResultItem(p_266924_); -+ ItemStack itemstack = ((RecipeHolder) p_301107_).value().assemble(new SingleRecipeInput(furnace.getItem(0)), p_266924_); - if (itemstack.isEmpty()) { - return false; - } else { -@@ -326,9 +_,9 @@ +@@ -227,9 +_,9 @@ } else if (!ItemStack.isSameItemSameComponents(itemstack1, itemstack)) { return false; } else { @@ -160,18 +87,7 @@ } } } else { -@@ -336,15 +_,15 @@ - } - } - -- private static boolean burn(RegistryAccess p_266740_, @Nullable RecipeHolder p_300910_, NonNullList p_267073_, int p_267157_) { -- if (p_300910_ != null && canBurn(p_266740_, p_300910_, p_267073_, p_267157_)) { -+ private static boolean burn(RegistryAccess p_266740_, @Nullable RecipeHolder p_300910_, NonNullList p_267073_, int p_267157_, AbstractFurnaceBlockEntity furnace) { -+ if (p_300910_ != null && canBurn(p_266740_, p_300910_, p_267073_, p_267157_, furnace)) { - ItemStack itemstack = p_267073_.get(0); -- ItemStack itemstack1 = p_300910_.value().getResultItem(p_266740_); -+ ItemStack itemstack1 = ((RecipeHolder) p_300910_).value().assemble(new SingleRecipeInput(furnace.getItem(0)), p_266740_); - ItemStack itemstack2 = p_267073_.get(2); +@@ -251,7 +_,7 @@ if (itemstack2.isEmpty()) { p_267073_.set(2, itemstack1.copy()); } else if (ItemStack.isSameItemSameComponents(itemstack2, itemstack1)) { @@ -180,31 +96,21 @@ } if (itemstack.is(Blocks.WET_SPONGE.asItem()) && !p_267073_.get(1).isEmpty() && p_267073_.get(1).is(Items.BUCKET)) { -@@ -362,8 +_,7 @@ - if (p_58343_.isEmpty()) { - return 0; - } else { -- Item item = p_58343_.getItem(); -- return getFuel().getOrDefault(item, 0); -+ return p_58343_.getBurnTime(this.recipeType); - } +@@ -266,7 +_,7 @@ } -@@ -373,7 +_,7 @@ + protected int getBurnDuration(FuelValues p_363501_, ItemStack p_58343_) { +- return p_363501_.burnDuration(p_58343_); ++ return p_58343_.getBurnTime(this.recipeType, p_363501_); } - public static boolean isFuel(ItemStack p_58400_) { -- return getFuel().containsKey(p_58400_.getItem()); -+ return p_58400_.getBurnTime(null) > 0; - } - - @Override -@@ -431,7 +_,7 @@ + private static int getTotalCookTime(ServerLevel p_380169_, AbstractFurnaceBlockEntity p_222694_) { +@@ -329,7 +_,7 @@ return true; } else { ItemStack itemstack = this.items.get(1); -- return isFuel(p_58390_) || p_58390_.is(Items.BUCKET) && !itemstack.is(Items.BUCKET); -+ return p_58390_.getBurnTime(this.recipeType) > 0 || p_58390_.is(Items.BUCKET) && !itemstack.is(Items.BUCKET); +- return this.level.fuelValues().isFuel(p_58390_) || p_58390_.is(Items.BUCKET) && !itemstack.is(Items.BUCKET); ++ return p_58390_.getBurnTime(this.recipeType, this.level.fuelValues()) > 0 || p_58390_.is(Items.BUCKET) && !itemstack.is(Items.BUCKET); } } diff --git a/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch index 51453c55cf..16fb21f9f0 100644 --- a/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/BlockEntity.java.patch @@ -48,7 +48,7 @@ } public final CompoundTag saveWithFullMetadata(HolderLookup.Provider p_323767_) { -@@ -216,10 +_,14 @@ +@@ -217,10 +_,14 @@ public void setRemoved() { this.remove = true; @@ -63,7 +63,7 @@ } public boolean triggerEvent(int p_58889_, int p_58890_) { -@@ -246,6 +_,27 @@ +@@ -247,6 +_,27 @@ return this.type; } @@ -91,7 +91,7 @@ @Deprecated public void setBlockState(BlockState p_155251_) { this.validateBlockState(p_155251_); -@@ -325,5 +_,15 @@ +@@ -326,5 +_,15 @@ T get(DataComponentType p_338658_); T getOrDefault(DataComponentType p_338573_, T p_338734_); diff --git a/patches/net/minecraft/world/level/block/entity/BlockEntityType.java.patch b/patches/net/minecraft/world/level/block/entity/BlockEntityType.java.patch index 627986209a..77f3f48d29 100644 --- a/patches/net/minecraft/world/level/block/entity/BlockEntityType.java.patch +++ b/patches/net/minecraft/world/level/block/entity/BlockEntityType.java.patch @@ -1,14 +1,25 @@ --- a/net/minecraft/world/level/block/entity/BlockEntityType.java +++ b/net/minecraft/world/level/block/entity/BlockEntityType.java -@@ -268,6 +_,7 @@ - ); - public static final BlockEntityType VAULT = register("vault", BlockEntityType.Builder.of(VaultBlockEntity::new, Blocks.VAULT)); +@@ -229,6 +_,7 @@ + public static final BlockEntityType TRIAL_SPAWNER = register("trial_spawner", TrialSpawnerBlockEntity::new, Blocks.TRIAL_SPAWNER); + public static final BlockEntityType VAULT = register("vault", VaultBlockEntity::new, Blocks.VAULT); private final BlockEntityType.BlockEntitySupplier factory; + // Neo: This field will be modified by BlockEntityTypeAddBlocksEvent event. Please use the event to add to this field for vanilla or other mod's BlockEntityTypes. private final Set validBlocks; - private final Type dataType; private final Holder.Reference> builtInRegistryHolder = BuiltInRegistries.BLOCK_ENTITY_TYPE.createIntrusiveHolder(this); -@@ -295,6 +_,13 @@ + +@@ -253,9 +_,24 @@ + this.validBlocks = p_155260_; + } + ++ // Neo: Additional constructor for convenience. ++ public BlockEntityType(BlockEntityType.BlockEntitySupplier p_155259_, Block... p_155260_) { ++ this(p_155259_, Set.of(p_155260_)); ++ if (p_155260_.length == 0) { ++ throw new IllegalArgumentException("Block entity type instantiated without valid blocks. If this is intentional, pass Set.of() instead of an empty varag."); ++ } ++ } ++ @Nullable public T create(BlockPos p_155265_, BlockState p_155266_) { return (T)this.factory.create(p_155265_, p_155266_); diff --git a/patches/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch index 95af4ec3c3..12d0923b2f 100644 --- a/patches/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java -@@ -164,6 +_,7 @@ +@@ -165,6 +_,7 @@ } private static void doBrew(Level p_155291_, BlockPos p_155292_, NonNullList p_155293_) { @@ -8,28 +8,18 @@ ItemStack itemstack = p_155293_.get(3); PotionBrewing potionbrewing = p_155291_.potionBrewing(); -@@ -171,15 +_,17 @@ +@@ -172,8 +_,9 @@ p_155293_.set(i, potionbrewing.mix(itemstack, p_155293_.get(i))); } -- itemstack.shrink(1); -- if (itemstack.getItem().hasCraftingRemainingItem()) { -- ItemStack itemstack1 = new ItemStack(itemstack.getItem().getCraftingRemainingItem()); + net.neoforged.neoforge.event.EventHooks.onPotionBrewed(p_155293_); -+ if (itemstack.hasCraftingRemainingItem()) { -+ ItemStack itemstack1 = itemstack.getCraftingRemainingItem(); -+ itemstack.shrink(1); ++ ItemStack itemstack1 = itemstack.getCraftingRemainder(); + itemstack.shrink(1); +- ItemStack itemstack1 = itemstack.getItem().getCraftingRemainder(); + if (!itemstack1.isEmpty()) { if (itemstack.isEmpty()) { itemstack = itemstack1; - } else { - Containers.dropItemStack(p_155291_, (double)p_155292_.getX(), (double)p_155292_.getY(), (double)p_155292_.getZ(), itemstack1); - } - } -+ else itemstack.shrink(1); - - p_155293_.set(3, itemstack); - p_155291_.levelEvent(1035, p_155292_, 0); -@@ -208,13 +_,13 @@ +@@ -209,13 +_,13 @@ @Override public boolean canPlaceItem(int p_59017_, ItemStack p_59018_) { @@ -39,7 +29,7 @@ return potionbrewing.isIngredient(p_59018_); } else { return p_59017_ == 4 - ? p_59018_.is(Items.BLAZE_POWDER) + ? p_59018_.is(ItemTags.BREWING_FUEL) - : (p_59018_.is(Items.POTION) || p_59018_.is(Items.SPLASH_POTION) || p_59018_.is(Items.LINGERING_POTION) || p_59018_.is(Items.GLASS_BOTTLE)) + : (potionbrewing.isInput(p_59018_) || p_59018_.is(Items.GLASS_BOTTLE)) && this.getItem(p_59017_).isEmpty(); diff --git a/patches/net/minecraft/world/level/block/entity/FuelValues.java.patch b/patches/net/minecraft/world/level/block/entity/FuelValues.java.patch new file mode 100644 index 0000000000..b5166418b4 --- /dev/null +++ b/patches/net/minecraft/world/level/block/entity/FuelValues.java.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/world/level/block/entity/FuelValues.java ++++ b/net/minecraft/world/level/block/entity/FuelValues.java +@@ -32,6 +_,10 @@ + return Collections.unmodifiableSequencedSet(this.values.keySet()); + } + ++ /** ++ * @deprecated Neo: use {@link ItemStack#getBurnTime(net.minecraft.world.item.crafting.RecipeType, FuelValues)} instead ++ */ ++ @Deprecated + public int burnDuration(ItemStack p_362816_) { + return p_362816_.isEmpty() ? 0 : this.values.getInt(p_362816_.getItem()); + } +@@ -41,7 +_,11 @@ + } + + public static FuelValues vanillaBurnTimes(HolderLookup.Provider p_362290_, FeatureFlagSet p_364291_, int p_363365_) { +- return new FuelValues.Builder(p_362290_, p_364291_) ++ return vanillaBurnTimes(new FuelValues.Builder(p_362290_, p_364291_), p_363365_); ++ } ++ ++ public static FuelValues vanillaBurnTimes(FuelValues.Builder builder, int p_363365_) { ++ return builder + .add(Items.LAVA_BUCKET, p_363365_ * 100) + .add(Blocks.COAL_BLOCK, p_363365_ * 8 * 10) + .add(Items.BLAZE_ROD, p_363365_ * 12) diff --git a/patches/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java.patch b/patches/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java.patch new file mode 100644 index 0000000000..e3a36de823 --- /dev/null +++ b/patches/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java ++++ b/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java +@@ -255,7 +_,7 @@ + + @Override + public boolean shouldRenderFace(Direction p_59959_) { +- return Block.shouldRenderFace(this.getBlockState(), this.level.getBlockState(this.getBlockPos().relative(p_59959_)), p_59959_); ++ return Block.shouldRenderFace(this.level, this.worldPosition, this.getBlockState(), this.level.getBlockState(this.getBlockPos().relative(p_59959_)), p_59959_); + } + + public int getParticleAmount() { diff --git a/patches/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch b/patches/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch index cd80ce062a..54f0c94786 100644 --- a/patches/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch +++ b/patches/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java +++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java -@@ -43,7 +_,7 @@ +@@ -44,7 +_,7 @@ import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.CollisionContext; @@ -9,20 +9,20 @@ public static final String NORMAL_CONFIG_TAG_NAME = "normal_config"; public static final String OMINOUS_CONFIG_TAG_NAME = "ominous_config"; public static final int DETECT_PLAYER_SPAWN_BUFFER = 40; -@@ -229,9 +_,9 @@ +@@ -237,9 +_,9 @@ } boolean flag = spawndata.getEntityToSpawn().size() == 1 && spawndata.getEntityToSpawn().contains("id", 8); - if (flag) { -- mob.finalizeSpawn(p_312582_, p_312582_.getCurrentDifficultyAt(mob.blockPosition()), MobSpawnType.TRIAL_SPAWNER, null); +- mob.finalizeSpawn(p_312582_, p_312582_.getCurrentDifficultyAt(mob.blockPosition()), EntitySpawnReason.TRIAL_SPAWNER, null); - } + // Neo: Patch in FinalizeSpawn for spawners so it may be fired unconditionally, instead of only when vanilla would normally call it. + // The local flag is the conditions under which the spawner will normally call Mob#finalizeSpawn. -+ net.neoforged.neoforge.event.EventHooks.finalizeMobSpawnSpawner(mob, p_312582_, p_312582_.getCurrentDifficultyAt(mob.blockPosition()), MobSpawnType.TRIAL_SPAWNER, null, this, flag); ++ net.neoforged.neoforge.event.EventHooks.finalizeMobSpawnSpawner(mob, p_312582_, p_312582_.getCurrentDifficultyAt(mob.blockPosition()), EntitySpawnReason.TRIAL_SPAWNER, null, this, flag); mob.setPersistenceRequired(); spawndata.getEquipment().ifPresent(mob::equip); -@@ -405,5 +_,14 @@ +@@ -413,5 +_,14 @@ TrialSpawnerState getState(); void markUpdated(); diff --git a/patches/net/minecraft/world/level/block/grower/TreeGrower.java.patch b/patches/net/minecraft/world/level/block/grower/TreeGrower.java.patch index 04738fa464..bef15f255b 100644 --- a/patches/net/minecraft/world/level/block/grower/TreeGrower.java.patch +++ b/patches/net/minecraft/world/level/block/grower/TreeGrower.java.patch @@ -1,19 +1,19 @@ --- a/net/minecraft/world/level/block/grower/TreeGrower.java +++ b/net/minecraft/world/level/block/grower/TreeGrower.java -@@ -130,6 +_,9 @@ - .registryOrThrow(Registries.CONFIGURED_FEATURE) - .getHolder(resourcekey) - .orElse(null); +@@ -128,6 +_,9 @@ + ResourceKey> resourcekey = this.getConfiguredMegaFeature(p_304893_); + if (resourcekey != null) { + Holder> holder = p_304396_.registryAccess().lookupOrThrow(Registries.CONFIGURED_FEATURE).get(resourcekey).orElse(null); + var event = net.neoforged.neoforge.event.EventHooks.fireBlockGrowFeature(p_304396_, p_304893_, p_304643_, holder); + holder = event.getFeature(); + if (event.isCanceled()) return false; if (holder != null) { for (int i = 0; i >= -1; i--) { for (int j = 0; j >= -1; j--) { -@@ -163,6 +_,9 @@ - .registryOrThrow(Registries.CONFIGURED_FEATURE) - .getHolder(resourcekey1) - .orElse(null); +@@ -158,6 +_,9 @@ + return false; + } else { + Holder> holder1 = p_304396_.registryAccess().lookupOrThrow(Registries.CONFIGURED_FEATURE).get(resourcekey1).orElse(null); + var event = net.neoforged.neoforge.event.EventHooks.fireBlockGrowFeature(p_304396_, p_304893_, p_304643_, holder1); + holder1 = event.getFeature(); + if (event.isCanceled()) return false; diff --git a/patches/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch b/patches/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch index 0f685960e1..5b3568cbb0 100644 --- a/patches/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch +++ b/patches/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/piston/PistonBaseBlock.java +++ b/net/minecraft/world/level/block/piston/PistonBaseBlock.java -@@ -186,6 +_,7 @@ +@@ -189,6 +_,7 @@ } if (p_60195_ == 0) { @@ -8,7 +8,7 @@ if (!this.moveBlocks(p_60193_, p_60194_, direction, true)) { return false; } -@@ -194,6 +_,7 @@ +@@ -197,6 +_,7 @@ p_60193_.playSound(null, p_60194_, SoundEvents.PISTON_EXTEND, SoundSource.BLOCKS, 0.5F, p_60193_.random.nextFloat() * 0.25F + 0.6F); p_60193_.gameEvent(GameEvent.BLOCK_ACTIVATE, p_60194_, GameEvent.Context.of(blockstate)); } else if (p_60195_ == 1 || p_60195_ == 2) { @@ -16,7 +16,7 @@ BlockEntity blockentity = p_60193_.getBlockEntity(p_60194_.relative(direction)); if (blockentity instanceof PistonMovingBlockEntity) { ((PistonMovingBlockEntity)blockentity).finalTick(); -@@ -243,6 +_,7 @@ +@@ -246,6 +_,7 @@ p_60193_.gameEvent(GameEvent.BLOCK_DEACTIVATE, p_60194_, GameEvent.Context.of(blockstate1)); } @@ -24,7 +24,7 @@ return true; } -@@ -314,8 +_,7 @@ +@@ -315,8 +_,7 @@ BlockState blockstate1 = p_60182_.getBlockState(blockpos2); BlockEntity blockentity = blockstate1.hasBlockEntity() ? p_60182_.getBlockEntity(blockpos2) : null; dropResources(blockstate1, p_60182_, blockpos2, blockentity); @@ -34,7 +34,7 @@ if (!blockstate1.is(BlockTags.FIRE)) { p_60182_.addDestroyBlockEffect(blockpos2, blockstate1); } -@@ -387,6 +_,10 @@ +@@ -389,6 +_,10 @@ @Override protected BlockState rotate(BlockState p_60215_, Rotation p_60216_) { return p_60215_.setValue(FACING, p_60216_.rotate(p_60215_.getValue(FACING))); diff --git a/patches/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch b/patches/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch index 94bcbb53d7..70dbd39e7d 100644 --- a/patches/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch +++ b/patches/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java +++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -@@ -115,7 +_,7 @@ +@@ -116,7 +_,7 @@ List list = p_155911_.getEntities(null, PistonMath.getMovementArea(aabb, direction, d0).minmax(aabb)); if (!list.isEmpty()) { List list1 = voxelshape.toAabbs(); diff --git a/patches/net/minecraft/world/level/block/state/BlockBehaviour.java.patch b/patches/net/minecraft/world/level/block/state/BlockBehaviour.java.patch index 851387e29d..9fdd0acefe 100644 --- a/patches/net/minecraft/world/level/block/state/BlockBehaviour.java.patch +++ b/patches/net/minecraft/world/level/block/state/BlockBehaviour.java.patch @@ -1,64 +1,36 @@ --- a/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/net/minecraft/world/level/block/state/BlockBehaviour.java -@@ -111,6 +_,17 @@ - this.dynamicShape = p_60452_.dynamicShape; - this.requiredFeatures = p_60452_.requiredFeatures; - this.properties = p_60452_; -+ final ResourceKey lootTableCache = p_60452_.drops; -+ if (lootTableCache != null) { -+ this.lootTableSupplier = () -> lootTableCache; -+ } else if (p_60452_.lootTableSupplier != null) { -+ this.lootTableSupplier = p_60452_.lootTableSupplier; -+ } else { -+ this.lootTableSupplier = () -> { -+ ResourceLocation resourcelocation = BuiltInRegistries.BLOCK.getKey(this.asBlock()); -+ return ResourceKey.create(Registries.LOOT_TABLE, resourcelocation.withPrefix("blocks/")); -+ }; -+ } - } - - public BlockBehaviour.Properties properties() { -@@ -168,7 +_,7 @@ +@@ -182,7 +_,7 @@ if (!p_311951_.isAir() && p_312925_.getBlockInteraction() != Explosion.BlockInteraction.TRIGGER_BLOCK) { Block block = p_311951_.getBlock(); boolean flag = p_312925_.getIndirectSourceEntity() instanceof Player; -- if (block.dropFromExplosion(p_312925_) && p_312820_ instanceof ServerLevel serverlevel) { -+ if (p_311951_.canDropFromExplosion(p_312820_, p_312489_, p_312925_) && p_312820_ instanceof ServerLevel serverlevel) { - BlockEntity blockentity = p_311951_.hasBlockEntity() ? p_312820_.getBlockEntity(p_312489_) : null; - LootParams.Builder lootparams$builder = new LootParams.Builder(serverlevel) +- if (block.dropFromExplosion(p_312925_)) { ++ if (p_311951_.canDropFromExplosion(p_365148_, p_312489_, p_312925_)) { + BlockEntity blockentity = p_311951_.hasBlockEntity() ? p_365148_.getBlockEntity(p_312489_) : null; + LootParams.Builder lootparams$builder = new LootParams.Builder(p_365148_) .withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(p_312489_)) -@@ -183,8 +_,7 @@ +@@ -197,8 +_,7 @@ p_311951_.getDrops(lootparams$builder).forEach(p_311752_ -> p_312073_.accept(p_311752_, p_312489_)); } -- p_312820_.setBlock(p_312489_, Blocks.AIR.defaultBlockState(), 3); -- block.wasExploded(p_312820_, p_312489_, p_312925_); -+ p_311951_.onBlockExploded(p_312820_, p_312489_, p_312925_); +- p_365148_.setBlock(p_312489_, Blocks.AIR.defaultBlockState(), 3); +- block.wasExploded(p_365148_, p_312489_, p_312925_); ++ p_311951_.onBlockExploded(p_365148_, p_312489_, p_312925_); } } -@@ -335,8 +_,8 @@ +@@ -344,8 +_,8 @@ if (f == -1.0F) { return 0.0F; } else { - int i = p_60467_.hasCorrectToolForDrops(p_60466_) ? 30 : 100; - return p_60467_.getDestroySpeed(p_60466_) / f / (float)i; + int i = net.neoforged.neoforge.event.EventHooks.doPlayerHarvestCheck(p_60467_, p_60466_, p_60468_, p_60469_) ? 30 : 100; -+ return p_60467_.getDigSpeed(p_60466_, p_60469_) / f / (float)i; ++ return p_60467_.getDestroySpeed(p_60466_, p_60469_) / f / (float)i; } } -@@ -359,8 +_,7 @@ - - public final ResourceKey getLootTable() { - if (this.drops == null) { -- ResourceLocation resourcelocation = BuiltInRegistries.BLOCK.getKey(this.asBlock()); -- this.drops = ResourceKey.create(Registries.LOOT_TABLE, resourcelocation.withPrefix("blocks/")); -+ this.drops = this.lootTableSupplier.get(); - } - - return this.drops; -@@ -377,6 +_,7 @@ +@@ -389,6 +_,7 @@ return this.isRandomlyTicking; } @@ -66,21 +38,18 @@ protected SoundType getSoundType(BlockState p_320941_) { return this.soundType; } -@@ -393,6 +_,13 @@ +@@ -405,6 +_,10 @@ return this.properties.destroyTime; } + protected boolean isAir(BlockState state) { + return ((BlockStateBase)state).isAir; + } -+ -+ // Neo: Holds the loot table for this block's drops. Used for getLootTable method. -+ private final java.util.function.Supplier> lootTableSupplier; + public abstract static class BlockStateBase extends StateHolder { - private final int lightEmission; - private final boolean useShapeForLightOcclusion; -@@ -523,12 +_,14 @@ + private static final Direction[] DIRECTIONS = Direction.values(); + private static final VoxelShape[] EMPTY_OCCLUSION_SHAPES = Util.make( +@@ -561,12 +_,14 @@ return this.useShapeForLightOcclusion; } @@ -96,7 +65,7 @@ } public boolean ignitedByLava() { -@@ -541,9 +_,11 @@ +@@ -579,9 +_,11 @@ } public MapColor getMapColor(BlockGetter p_285002_, BlockPos p_285293_) { @@ -109,7 +78,7 @@ public BlockState rotate(Rotation p_60718_) { return this.getBlock().rotate(this.asState(), p_60718_); } -@@ -597,6 +_,8 @@ +@@ -635,6 +_,8 @@ } public PushReaction getPistonPushReaction() { @@ -118,17 +87,17 @@ return this.pushReaction; } -@@ -724,6 +_,9 @@ +@@ -762,6 +_,9 @@ } - public ItemInteractionResult useItemOn(ItemStack p_316374_, Level p_316651_, Player p_316623_, InteractionHand p_316469_, BlockHitResult p_316877_) { + public InteractionResult useItemOn(ItemStack p_316374_, Level p_316651_, Player p_316623_, InteractionHand p_316469_, BlockHitResult p_316877_) { + var useOnContext = new net.minecraft.world.item.context.UseOnContext(p_316651_, p_316623_, p_316469_, p_316623_.getItemInHand(p_316469_).copy(), p_316877_); + var e = net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.entity.player.UseItemOnBlockEvent(useOnContext, net.neoforged.neoforge.event.entity.player.UseItemOnBlockEvent.UsePhase.BLOCK)); + if (e.isCanceled()) return e.getCancellationResult(); return this.getBlock().useItemOn(p_316374_, this.asState(), p_316651_, p_316877_.getBlockPos(), p_316623_, p_316469_, p_316877_); } -@@ -825,6 +_,7 @@ +@@ -871,6 +_,7 @@ return this.getBlock().getSeed(this.asState(), p_60727_); } @@ -136,34 +105,12 @@ public SoundType getSoundType() { return this.getBlock().getSoundType(this.asState()); } -@@ -959,11 +_,12 @@ - PushReaction pushReaction = PushReaction.NORMAL; - boolean spawnTerrainParticles = true; - NoteBlockInstrument instrument = NoteBlockInstrument.HARP; -+ private java.util.function.Supplier> lootTableSupplier; - boolean replaceable; - BlockBehaviour.StateArgumentPredicate> isValidSpawn = (p_284893_, p_284894_, p_284895_, p_284896_) -> p_284893_.isFaceSturdy( - p_284894_, p_284895_, Direction.UP +@@ -996,7 +_,7 @@ + BlockBehaviour.StateArgumentPredicate> isValidSpawn = (p_360193_, p_360194_, p_360195_, p_360196_) -> p_360193_.isFaceSturdy( + p_360194_, p_360195_, Direction.UP ) -- && p_284893_.getLightEmission() < 14; -+ && p_284893_.getLightEmission(p_284894_, p_284895_) < 14; - BlockBehaviour.StatePredicate isRedstoneConductor = (p_284888_, p_284889_, p_284890_) -> p_284888_.isCollisionShapeFullBlock(p_284889_, p_284890_); - BlockBehaviour.StatePredicate isSuffocating = (p_284885_, p_284886_, p_284887_) -> p_284885_.blocksMotion() - && p_284885_.isCollisionShapeFullBlock(p_284886_, p_284887_); -@@ -1105,9 +_,15 @@ - return this; - } - -+ @Deprecated // FORGE: Use the variant that takes a Supplier below - public BlockBehaviour.Properties dropsLike(Block p_60917_) { -- this.drops = p_60917_.getLootTable(); -+ this.lootTableSupplier = () -> p_60917_.getLootTable(); - return this; -+ } -+ -+ public BlockBehaviour.Properties lootFrom(java.util.function.Supplier blockIn) { -+ this.lootTableSupplier = () -> blockIn.get().getLootTable(); -+ return this; - } - - public BlockBehaviour.Properties ignitedByLava() { +- && p_360193_.getLightEmission() < 14; ++ && p_360193_.getLightEmission(p_360194_, p_360195_) < 14; + BlockBehaviour.StatePredicate isRedstoneConductor = (p_360190_, p_360191_, p_360192_) -> p_360190_.isCollisionShapeFullBlock(p_360191_, p_360192_); + BlockBehaviour.StatePredicate isSuffocating = (p_360187_, p_360188_, p_360189_) -> p_360187_.blocksMotion() + && p_360187_.isCollisionShapeFullBlock(p_360188_, p_360189_); diff --git a/patches/net/minecraft/world/level/chunk/ChunkAccess.java.patch b/patches/net/minecraft/world/level/chunk/ChunkAccess.java.patch index 311f7f4973..7de81bd23b 100644 --- a/patches/net/minecraft/world/level/chunk/ChunkAccess.java.patch +++ b/patches/net/minecraft/world/level/chunk/ChunkAccess.java.patch @@ -4,16 +4,16 @@ import net.minecraft.world.ticks.TickContainerAccess; import org.slf4j.Logger; --public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiomeSource, LightChunk, StructureAccess { -+public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiomeSource, LightChunk, StructureAccess, net.neoforged.neoforge.attachment.IAttachmentHolder { +-public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, LightChunk, StructureAccess { ++public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, LightChunk, StructureAccess, net.neoforged.neoforge.attachment.IAttachmentHolder { public static final int NO_FILLED_SECTION = -1; private static final Logger LOGGER = LogUtils.getLogger(); private static final LongSet EMPTY_REFERENCE_SET = new LongOpenHashSet(); -@@ -315,10 +_,19 @@ +@@ -324,10 +_,19 @@ @Override public final void findBlockLightSources(BiConsumer p_285269_) { -- this.findBlocks(p_284897_ -> p_284897_.getLightEmission() != 0, p_285269_); +- this.findBlocks(p_360197_ -> p_360197_.getLightEmission() != 0, p_285269_); + this.findBlocks(p_284897_ -> p_284897_.hasDynamicLightEmission() || p_284897_.getLightEmission(net.minecraft.world.level.EmptyBlockGetter.INSTANCE, BlockPos.ZERO) != 0, (p_284897_, pos) -> p_284897_.getLightEmission(this, pos) != 0, p_285269_); } @@ -29,8 +29,8 @@ + public void findBlocks(Predicate p_285343_, java.util.function.BiPredicate fineFilter, BiConsumer p_285030_) { BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); - for (int i = this.getMinSection(); i < this.getMaxSection(); i++) { -@@ -330,8 +_,9 @@ + for (int i = this.getMinSectionY(); i <= this.getMaxSectionY(); i++) { +@@ -339,8 +_,9 @@ for (int k = 0; k < 16; k++) { for (int l = 0; l < 16; l++) { BlockState blockstate = levelchunksection.getBlockState(l, j, k); @@ -42,9 +42,9 @@ } } } -@@ -476,4 +_,72 @@ - - public static record TicksToSave(SerializableTickContainer blocks, SerializableTickContainer fluids) { +@@ -482,6 +_,74 @@ + public ChunkSkyLightSources getSkyLightSources() { + return this.skyLightSources; } + + // Neo: Hook in AttachmentHolder to chunks for data storage and retrieval @@ -73,14 +73,14 @@ + @Override + @Nullable + public T setData(net.neoforged.neoforge.attachment.AttachmentType type, T data) { -+ setUnsaved(true); ++ markUnsaved(); + return getAttachmentHolder().setData(type, data); + } + + @Override + @Nullable + public T removeData(net.neoforged.neoforge.attachment.AttachmentType type) { -+ setUnsaved(true); ++ markUnsaved(); + return getAttachmentHolder().removeData(type); + } + @@ -114,4 +114,6 @@ + // Neo: Allow for exposing the Level a chunk is tied to if available + @Nullable + public net.minecraft.world.level.Level getLevel() { return null; } - } + + public static record PackedTicks(List> blocks, List> fluids) { + } diff --git a/patches/net/minecraft/world/level/chunk/ImposterProtoChunk.java.patch b/patches/net/minecraft/world/level/chunk/ImposterProtoChunk.java.patch index 827439587d..6481ea0fc1 100644 --- a/patches/net/minecraft/world/level/chunk/ImposterProtoChunk.java.patch +++ b/patches/net/minecraft/world/level/chunk/ImposterProtoChunk.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/ImposterProtoChunk.java +++ b/net/minecraft/world/level/chunk/ImposterProtoChunk.java -@@ -219,6 +_,15 @@ +@@ -223,6 +_,15 @@ } @Override @@ -16,7 +16,7 @@ public TickContainerAccess getBlockTicks() { return this.allowWrites ? this.wrapped.getBlockTicks() : BlackholeTickAccess.emptyContainer(); } -@@ -291,5 +_,10 @@ +@@ -290,5 +_,10 @@ @Override public ChunkSkyLightSources getSkyLightSources() { return this.wrapped.getSkyLightSources(); diff --git a/patches/net/minecraft/world/level/chunk/LevelChunk.java.patch b/patches/net/minecraft/world/level/chunk/LevelChunk.java.patch index a47b0de44e..dfa6a02fdf 100644 --- a/patches/net/minecraft/world/level/chunk/LevelChunk.java.patch +++ b/patches/net/minecraft/world/level/chunk/LevelChunk.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java -@@ -50,7 +_,7 @@ +@@ -51,7 +_,7 @@ import net.minecraft.world.ticks.TickContainerAccess; import org.slf4j.Logger; @@ -9,7 +9,7 @@ static final Logger LOGGER = LogUtils.getLogger(); private static final TickingBlockEntity NULL_TICKER = new TickingBlockEntity() { @Override -@@ -139,6 +_,7 @@ +@@ -142,6 +_,7 @@ this.setAllStarts(p_196851_.getAllStarts()); this.setAllReferences(p_196851_.getAllReferences()); @@ -17,7 +17,16 @@ for (Entry entry : p_196851_.getHeightmaps()) { if (ChunkStatus.FULL.heightmapsAfter().contains(entry.getKey())) { this.setHeightmap(entry.getKey(), entry.getValue().getRawData()); -@@ -278,7 +_,7 @@ +@@ -279,7 +_,7 @@ + this.level.getChunkSource().onSectionEmptinessChanged(this.chunkPos.x, SectionPos.blockToSectionCoord(i), this.chunkPos.z, flag1); + } + +- if (LightEngine.hasDifferentLightProperties(blockstate, p_62866_)) { ++ if (LightEngine.hasDifferentLightProperties(this, p_62865_, blockstate, p_62866_)) { + ProfilerFiller profilerfiller = Profiler.get(); + profilerfiller.push("updateSkyLightSources"); + this.skyLightSources.update(this, j, i, l); +@@ -298,7 +_,7 @@ if (!levelchunksection.getBlockState(j, k, l).is(block)) { return null; } else { @@ -26,7 +35,7 @@ p_62866_.onPlace(this.level, p_62865_, blockstate, p_62867_); } -@@ -327,6 +_,10 @@ +@@ -353,6 +_,10 @@ @Nullable public BlockEntity getBlockEntity(BlockPos p_62868_, LevelChunk.EntityCreationType p_62869_) { BlockEntity blockentity = this.blockEntities.get(p_62868_); @@ -37,7 +46,7 @@ if (blockentity == null) { CompoundTag compoundtag = this.pendingBlockEntities.remove(p_62868_); if (compoundtag != null) { -@@ -344,9 +_,6 @@ +@@ -370,9 +_,6 @@ this.addAndRegisterBlockEntity(blockentity); } } @@ -47,7 +56,7 @@ } return blockentity; -@@ -360,6 +_,7 @@ +@@ -386,6 +_,7 @@ } this.updateBlockEntityTicker(p_156391_); @@ -55,7 +64,7 @@ } } -@@ -403,6 +_,7 @@ +@@ -429,6 +_,7 @@ BlockEntity blockentity = this.blockEntities.put(blockpos.immutable(), p_156374_); if (blockentity != null && blockentity != p_156374_) { blockentity.setRemoved(); @@ -63,7 +72,7 @@ } } } -@@ -412,9 +_,14 @@ +@@ -438,9 +_,14 @@ public CompoundTag getBlockEntityNbtForSaving(BlockPos p_62932_, HolderLookup.Provider p_323699_) { BlockEntity blockentity = this.getBlockEntity(p_62932_); if (blockentity != null && !blockentity.isRemoved()) { @@ -78,7 +87,7 @@ } else { CompoundTag compoundtag = this.pendingBlockEntities.get(p_62932_); if (compoundtag != null) { -@@ -436,6 +_,7 @@ +@@ -462,6 +_,7 @@ } blockentity.setRemoved(); @@ -86,7 +95,7 @@ } } -@@ -496,7 +_,7 @@ +@@ -522,7 +_,7 @@ p_187974_.accept((p_338077_, p_338078_, p_338079_) -> { BlockEntity blockentity = this.getBlockEntity(p_338077_, LevelChunk.EntityCreationType.IMMEDIATE); if (blockentity != null && p_338079_ != null && blockentity.getType() == p_338078_) { @@ -95,7 +104,7 @@ } }); } -@@ -604,6 +_,7 @@ +@@ -632,6 +_,7 @@ } public void clearAllBlockEntities() { @@ -103,7 +112,7 @@ this.blockEntities.values().forEach(BlockEntity::setRemoved); this.blockEntities.clear(); this.tickersInLevel.values().forEach(p_187966_ -> p_187966_.rebind(NULL_TICKER)); -@@ -611,6 +_,7 @@ +@@ -639,6 +_,7 @@ } public void registerAllBlockEntitiesAfterLevelLoad() { @@ -111,7 +120,7 @@ this.blockEntities.values().forEach(p_187988_ -> { if (this.level instanceof ServerLevel serverlevel) { this.addGameEventListener(p_187988_, serverlevel); -@@ -662,6 +_,14 @@ +@@ -690,6 +_,14 @@ return new LevelChunk.BoundTickingBlockEntity<>(p_156376_, p_156377_); } @@ -126,15 +135,15 @@ class BoundTickingBlockEntity implements TickingBlockEntity { private final T blockEntity; private final BlockEntityTicker ticker; -@@ -679,6 +_,7 @@ +@@ -707,6 +_,7 @@ if (LevelChunk.this.isTicking(blockpos)) { try { - ProfilerFiller profilerfiller = LevelChunk.this.level.getProfiler(); + ProfilerFiller profilerfiller = Profiler.get(); + net.neoforged.neoforge.server.timings.TimeTracker.BLOCK_ENTITY_UPDATE.trackStart(blockEntity); profilerfiller.push(this::getType); BlockState blockstate = LevelChunk.this.getBlockState(blockpos); if (this.blockEntity.getType().isValid(blockstate)) { -@@ -700,7 +_,15 @@ +@@ -728,7 +_,15 @@ CrashReport crashreport = CrashReport.forThrowable(throwable, "Ticking block entity"); CrashReportCategory crashreportcategory = crashreport.addCategory("Block entity being ticked"); this.blockEntity.fillCrashReportCategory(crashreportcategory); diff --git a/patches/net/minecraft/world/level/chunk/LevelChunkSection.java.patch b/patches/net/minecraft/world/level/chunk/LevelChunkSection.java.patch index 42b524a34a..ba7c17c926 100644 --- a/patches/net/minecraft/world/level/chunk/LevelChunkSection.java.patch +++ b/patches/net/minecraft/world/level/chunk/LevelChunkSection.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/net/minecraft/world/level/chunk/LevelChunkSection.java -@@ -65,7 +_,7 @@ +@@ -73,7 +_,7 @@ FluidState fluidstate = blockstate.getFluidState(); FluidState fluidstate1 = p_62995_.getFluidState(); @@ -9,7 +9,7 @@ this.nonEmptyBlockCount--; if (blockstate.isRandomlyTicking()) { this.tickingBlockCount--; -@@ -76,7 +_,7 @@ +@@ -84,7 +_,7 @@ this.tickingFluidCount--; } @@ -18,7 +18,7 @@ this.nonEmptyBlockCount++; if (p_62995_.isRandomlyTicking()) { this.tickingBlockCount++; -@@ -114,7 +_,7 @@ +@@ -122,7 +_,7 @@ public void accept(BlockState p_204444_, int p_204445_) { FluidState fluidstate = p_204444_.getFluidState(); diff --git a/patches/net/minecraft/world/level/chunk/ProtoChunk.java.patch b/patches/net/minecraft/world/level/chunk/ProtoChunk.java.patch new file mode 100644 index 0000000000..ecd7f80c42 --- /dev/null +++ b/patches/net/minecraft/world/level/chunk/ProtoChunk.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/chunk/ProtoChunk.java ++++ b/net/minecraft/world/level/chunk/ProtoChunk.java +@@ -134,7 +_,7 @@ + this.lightEngine.updateSectionStatus(p_63217_, flag1); + } + +- if (LightEngine.hasDifferentLightProperties(blockstate, p_63218_)) { ++ if (LightEngine.hasDifferentLightProperties(this, p_63217_, blockstate, p_63218_)) { + this.skyLightSources.update(this, i1, j, k1); + this.lightEngine.checkBlock(p_63217_); + } diff --git a/patches/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch b/patches/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch index 788be92167..a16cba61c5 100644 --- a/patches/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch +++ b/patches/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch @@ -1,24 +1,25 @@ --- a/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java +++ b/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -@@ -201,10 +_,21 @@ - } +@@ -198,11 +_,22 @@ + } - levelchunk.setFullStatus(generationchunkholder::getFullStatus); -+ try { -+ generationchunkholder.currentlyLoading = levelchunk; // Neo: bypass the future chain when getChunk is called, this prevents deadlocks. - levelchunk.runPostLoad(); -+ } finally { -+ generationchunkholder.currentlyLoading = null; // Neo: Stop bypassing the future chain. -+ } - levelchunk.setLoaded(true); -+ try { -+ generationchunkholder.currentlyLoading = levelchunk; // Neo: bypass the future chain when getChunk is called, this prevents deadlocks. - levelchunk.registerAllBlockEntitiesAfterLevelLoad(); - levelchunk.registerTickContainerInLevel(serverlevel); -+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.ChunkEvent.Load(levelchunk, !(protochunk instanceof ImposterProtoChunk))); -+ } finally { -+ generationchunkholder.currentlyLoading = null; // Neo: Stop bypassing the future chain. -+ } - return levelchunk; - }, - p_347404_ -> p_347565_.mainThreadMailBox() + levelchunk.setFullStatus(generationchunkholder::getFullStatus); ++ try { ++ generationchunkholder.currentlyLoading = levelchunk; // Neo: bypass the future chain when getChunk is called, this prevents deadlocks. + levelchunk.runPostLoad(); ++ } finally { ++ generationchunkholder.currentlyLoading = null; // Neo: Stop bypassing the future chain. ++ } + levelchunk.setLoaded(true); ++ try { ++ generationchunkholder.currentlyLoading = levelchunk; // Neo: bypass the future chain when getChunk is called, this prevents deadlocks. + levelchunk.registerAllBlockEntitiesAfterLevelLoad(); + levelchunk.registerTickContainerInLevel(serverlevel); + levelchunk.setUnsavedListener(p_347565_.unsavedListener()); ++ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.ChunkEvent.Load(levelchunk, !(protochunk instanceof ImposterProtoChunk))); ++ } finally { ++ generationchunkholder.currentlyLoading = null; // Neo: Stop bypassing the future chain. ++ } + return levelchunk; + }, p_347565_.mainThreadExecutor()); + } diff --git a/patches/net/minecraft/world/level/chunk/storage/ChunkSerializer.java.patch b/patches/net/minecraft/world/level/chunk/storage/ChunkSerializer.java.patch deleted file mode 100644 index fa78db915f..0000000000 --- a/patches/net/minecraft/world/level/chunk/storage/ChunkSerializer.java.patch +++ /dev/null @@ -1,61 +0,0 @@ ---- a/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -+++ b/net/minecraft/world/level/chunk/storage/ChunkSerializer.java -@@ -183,6 +_,8 @@ - postLoadChunk(p_188231_, p_188234_), - blendingdata - ); -+ if (p_188234_.contains(net.neoforged.neoforge.common.world.LevelChunkAuxiliaryLightManager.LIGHT_NBT_KEY, net.minecraft.nbt.Tag.TAG_LIST)) -+ Objects.requireNonNull(((LevelChunk)chunkaccess).getAuxLightManager(p_188233_)).deserializeNBT(p_188231_.registryAccess(), p_188234_.getList(net.neoforged.neoforge.common.world.LevelChunkAuxiliaryLightManager.LIGHT_NBT_KEY, net.minecraft.nbt.Tag.TAG_COMPOUND)); - } else { - ProtoChunkTicks protochunkticks = ProtoChunkTicks.load( - p_188234_.getList("block_ticks", 10), p_258992_ -> BuiltInRegistries.BLOCK.getOptional(ResourceLocation.tryParse(p_258992_)), p_188233_ -@@ -209,6 +_,8 @@ - } - } - -+ if (p_188234_.contains(net.neoforged.neoforge.attachment.AttachmentHolder.ATTACHMENTS_NBT_KEY, net.minecraft.nbt.Tag.TAG_COMPOUND)) -+ chunkaccess.readAttachmentsFromNBT(p_188231_.registryAccess(), p_188234_.getCompound(net.neoforged.neoforge.attachment.AttachmentHolder.ATTACHMENTS_NBT_KEY)); - chunkaccess.setLightCorrect(flag); - CompoundTag compoundtag2 = p_188234_.getCompound("Heightmaps"); - EnumSet enumset = EnumSet.noneOf(Heightmap.Types.class); -@@ -241,6 +_,7 @@ - } - - if (chunktype == ChunkType.LEVELCHUNK) { -+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.ChunkDataEvent.Load(chunkaccess, p_188234_, chunktype)); - return new ImposterProtoChunk((LevelChunk)chunkaccess, false); - } else { - ProtoChunk protochunk1 = (ProtoChunk)chunkaccess; -@@ -264,6 +_,7 @@ - protochunk1.setCarvingMask(generationstep$carving, new CarvingMask(compoundtag4.getLongArray(s1), chunkaccess.getMinBuildHeight())); - } - -+ net.neoforged.neoforge.common.NeoForge.EVENT_BUS.post(new net.neoforged.neoforge.event.level.ChunkDataEvent.Load(chunkaccess, p_188234_, chunktype)); - return protochunk1; - } - } -@@ -374,6 +_,11 @@ - - compoundtag.put("CarvingMasks", compoundtag4); - } -+ else if (p_63456_ instanceof LevelChunk levelChunk){ -+ -+ Tag lightTag = levelChunk.getAuxLightManager(chunkpos).serializeNBT(p_63455_.registryAccess()); -+ if (lightTag != null) compoundtag.put(net.neoforged.neoforge.common.world.LevelChunkAuxiliaryLightManager.LIGHT_NBT_KEY, lightTag); -+ } - - saveTicks(p_63455_, compoundtag, p_63456_.getTicksForSerialization()); - compoundtag.put("PostProcessing", packOffsets(p_63456_.getPostProcessing())); -@@ -385,6 +_,12 @@ - } - } - -+ try { -+ final CompoundTag capTag = p_63456_.writeAttachmentsToNBT(p_63455_.registryAccess()); -+ if (capTag != null) compoundtag.put(net.neoforged.neoforge.attachment.AttachmentHolder.ATTACHMENTS_NBT_KEY, capTag); -+ } catch (Exception exception) { -+ LOGGER.error("Failed to write chunk attachments. An attachment has likely thrown an exception trying to write state. It will not persist. Report this to the mod author", exception); -+ } - compoundtag.put("Heightmaps", compoundtag2); - compoundtag.put( - "structures", diff --git a/patches/net/minecraft/world/level/chunk/storage/EntityStorage.java.patch b/patches/net/minecraft/world/level/chunk/storage/EntityStorage.java.patch index 07090ecf63..9adff11160 100644 --- a/patches/net/minecraft/world/level/chunk/storage/EntityStorage.java.patch +++ b/patches/net/minecraft/world/level/chunk/storage/EntityStorage.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/storage/EntityStorage.java +++ b/net/minecraft/world/level/chunk/storage/EntityStorage.java -@@ -94,8 +_,12 @@ +@@ -95,8 +_,12 @@ ListTag listtag = new ListTag(); p_156559_.getEntities().forEach(p_156567_ -> { CompoundTag compoundtag1 = new CompoundTag(); diff --git a/patches/net/minecraft/world/level/chunk/storage/SectionStorage.java.patch b/patches/net/minecraft/world/level/chunk/storage/SectionStorage.java.patch index e19c187a3b..5eef3aff03 100644 --- a/patches/net/minecraft/world/level/chunk/storage/SectionStorage.java.patch +++ b/patches/net/minecraft/world/level/chunk/storage/SectionStorage.java.patch @@ -1,15 +1,22 @@ --- a/net/minecraft/world/level/chunk/storage/SectionStorage.java +++ b/net/minecraft/world/level/chunk/storage/SectionStorage.java -@@ -238,4 +_,12 @@ - public void close() throws IOException { +@@ -302,6 +_,19 @@ this.simpleRegionStorage.close(); } -+ + + /** + * Neo: Removes the data for the given chunk position. + * See PR #937 + */ -+ public void remove(long sectionPosAsLong) { -+ this.storage.remove(sectionPosAsLong); ++ public void remove(ChunkPos chunkPos) { ++ synchronized (this.loadLock) { ++ for (int y = this.levelHeightAccessor.getMinSectionY(); y <= this.levelHeightAccessor.getMaxSectionY(); y++) { ++ this.storage.remove(getKey(chunkPos, y)); ++ } ++ this.loadedChunks.remove(chunkPos.toLong()); ++ } + } - } ++ + static record PackedChunk(Int2ObjectMap sectionsByY, boolean versionChanged) { + public static SectionStorage.PackedChunk parse( + Codec p_365233_, DynamicOps p_363840_, Tag p_364375_, SimpleRegionStorage p_362076_, LevelHeightAccessor p_362314_ diff --git a/patches/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch b/patches/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch new file mode 100644 index 0000000000..9cea770ea1 --- /dev/null +++ b/patches/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch @@ -0,0 +1,139 @@ +--- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java ++++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +@@ -91,7 +_,9 @@ + List sectionData, + List entities, + List blockEntities, +- CompoundTag structureData ++ CompoundTag structureData, ++ @Nullable CompoundTag attachmentData, ++ @Nullable ListTag auxLightData + ) { + private static final Codec> BLOCK_STATE_CODEC = PalettedContainer.codecRW( + Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState() +@@ -108,6 +_,33 @@ + public static final String BLOCK_LIGHT_TAG = "BlockLight"; + public static final String SKY_LIGHT_TAG = "SkyLight"; + ++ /** ++ * @deprecated Neo: use constructor with additional data instead ++ */ ++ @Deprecated ++ SerializableChunkData( ++ Registry biomeRegistry, ++ ChunkPos chunkPos, ++ int minSectionY, ++ long lastUpdateTime, ++ long inhabitedTime, ++ ChunkStatus chunkStatus, ++ @Nullable BlendingData.Packed blendingData, ++ @Nullable BelowZeroRetrogen belowZeroRetrogen, ++ UpgradeData upgradeData, ++ @Nullable long[] carvingMask, ++ Map heightmaps, ++ ChunkAccess.PackedTicks packedTicks, ++ ShortList[] postProcessingSections, ++ boolean lightCorrect, ++ List sectionData, ++ List entities, ++ List blockEntities, ++ CompoundTag structureData ++ ) { ++ this(biomeRegistry, chunkPos, minSectionY, lastUpdateTime, inhabitedTime, chunkStatus, blendingData, belowZeroRetrogen, upgradeData, carvingMask, heightmaps, packedTicks, postProcessingSections, lightCorrect, sectionData, entities, blockEntities, structureData, null, null); ++ } ++ + @Nullable + public static SerializableChunkData parse(LevelHeightAccessor p_361938_, RegistryAccess p_365010_, CompoundTag p_362040_) { + if (!p_362040_.contains("Status", 8)) { +@@ -224,6 +_,15 @@ + list.add(new SerializableChunkData.SectionData(j1, levelchunksection, datalayer, datalayer1)); + } + ++ CompoundTag attachmentData = null; ++ if (p_362040_.contains(net.neoforged.neoforge.attachment.AttachmentHolder.ATTACHMENTS_NBT_KEY, Tag.TAG_COMPOUND)) { ++ attachmentData = p_362040_.getCompound(net.neoforged.neoforge.attachment.AttachmentHolder.ATTACHMENTS_NBT_KEY); ++ } ++ ListTag auxLightData = null; ++ if (p_362040_.contains(net.neoforged.neoforge.common.world.LevelChunkAuxiliaryLightManager.LIGHT_NBT_KEY, Tag.TAG_LIST)) { ++ auxLightData = p_362040_.getList(net.neoforged.neoforge.common.world.LevelChunkAuxiliaryLightManager.LIGHT_NBT_KEY, Tag.TAG_COMPOUND); ++ } ++ + return new SerializableChunkData( + registry, + chunkpos, +@@ -242,7 +_,9 @@ + list, + list3, + list4, +- compoundtag2 ++ compoundtag2, ++ attachmentData, ++ auxLightData + ); + } + } +@@ -302,6 +_,9 @@ + postLoadChunk(p_360452_, this.entities, this.blockEntities), + BlendingData.unpack(this.blendingData) + ); ++ if (this.auxLightData != null) { ++ ((LevelChunk) chunkaccess).getAuxLightManager(chunkPos).deserializeNBT(p_360452_.registryAccess(), this.auxLightData); ++ } + } else { + ProtoChunkTicks protochunkticks = ProtoChunkTicks.load(this.packedTicks.blocks()); + ProtoChunkTicks protochunkticks1 = ProtoChunkTicks.load(this.packedTicks.fluids()); +@@ -340,6 +_,10 @@ + chunkaccess.addPackedPostProcess(this.postProcessingSections[j], j); + } + ++ if (this.attachmentData != null) { ++ chunkaccess.readAttachmentsFromNBT(p_360452_.registryAccess(), this.attachmentData); ++ } ++ + if (chunktype == ChunkType.LEVELCHUNK) { + return new ImposterProtoChunk((LevelChunk)chunkaccess, false); + } else { +@@ -429,6 +_,17 @@ + CompoundTag compoundtag1 = packStructureData( + StructurePieceSerializationContext.fromLevel(p_365319_), chunkpos, p_362284_.getAllStarts(), p_362284_.getAllReferences() + ); ++ ++ CompoundTag attachmentData = null; ++ try { ++ attachmentData = p_362284_.writeAttachmentsToNBT(p_365319_.registryAccess()); ++ } catch (Exception exception) { ++ LOGGER.error("Failed to write chunk attachments. An attachment has likely thrown an exception trying to write state. It will not persist. Report this to the mod author", exception); ++ } ++ ListTag auxLightData = null; ++ if (p_362284_ instanceof LevelChunk levelChunk) { ++ auxLightData = levelChunk.getAuxLightManager(chunkpos).serializeNBT(p_365319_.registryAccess()); ++ } + return new SerializableChunkData( + p_365319_.registryAccess().lookupOrThrow(Registries.BIOME), + chunkpos, +@@ -447,7 +_,9 @@ + list, + list2, + list1, +- compoundtag1 ++ compoundtag1, ++ attachmentData, ++ auxLightData + ); + } + } +@@ -526,6 +_,14 @@ + this.heightmaps.forEach((p_362472_, p_363515_) -> compoundtag2.put(p_362472_.getSerializationKey(), new LongArrayTag(p_363515_))); + compoundtag.put("Heightmaps", compoundtag2); + compoundtag.put("structures", this.structureData); ++ ++ if (attachmentData != null) { ++ compoundtag.put(net.neoforged.neoforge.attachment.AttachmentHolder.ATTACHMENTS_NBT_KEY, attachmentData); ++ } ++ if (auxLightData != null) { ++ compoundtag.put(net.neoforged.neoforge.common.world.LevelChunkAuxiliaryLightManager.LIGHT_NBT_KEY, auxLightData); ++ } ++ + return compoundtag; + } + diff --git a/patches/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java.patch b/patches/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java.patch index a62dbf7b2b..181d5880c0 100644 --- a/patches/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java.patch +++ b/patches/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java.patch @@ -20,7 +20,7 @@ static int getGameEventFrequency(ResourceKey p_316800_) { - return VIBRATION_FREQUENCY_FOR_EVENT.applyAsInt(p_316800_); -+ var holder = net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT.getHolder(p_316800_); ++ var holder = net.minecraft.core.registries.BuiltInRegistries.GAME_EVENT.get(p_316800_); + return holder.map(VibrationSystem::getGameEventFrequency).orElse(0); } diff --git a/patches/net/minecraft/world/level/levelgen/PhantomSpawner.java.patch b/patches/net/minecraft/world/level/levelgen/PhantomSpawner.java.patch index 198e5cab39..f715082e4e 100644 --- a/patches/net/minecraft/world/level/levelgen/PhantomSpawner.java.patch +++ b/patches/net/minecraft/world/level/levelgen/PhantomSpawner.java.patch @@ -27,4 +27,4 @@ + int l = event.getPhantomsToSpawn(); for (int i1 = 0; i1 < l; i1++) { - Phantom phantom = EntityType.PHANTOM.create(p_64576_); + Phantom phantom = EntityType.PHANTOM.create(p_64576_, EntitySpawnReason.NATURAL); diff --git a/patches/net/minecraft/world/level/levelgen/WorldDimensions.java.patch b/patches/net/minecraft/world/level/levelgen/WorldDimensions.java.patch index 33276ce214..a65a43a3b7 100644 --- a/patches/net/minecraft/world/level/levelgen/WorldDimensions.java.patch +++ b/patches/net/minecraft/world/level/levelgen/WorldDimensions.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/levelgen/WorldDimensions.java +++ b/net/minecraft/world/level/levelgen/WorldDimensions.java -@@ -36,7 +_,8 @@ +@@ -37,7 +_,8 @@ public record WorldDimensions(Map, LevelStem> dimensions) { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( p_325905_ -> p_325905_.group( diff --git a/patches/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch b/patches/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch index 1b2ac4b713..63803d46c0 100644 --- a/patches/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch +++ b/patches/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/levelgen/structure/StructurePiece.java +++ b/net/minecraft/world/level/levelgen/structure/StructurePiece.java -@@ -91,6 +_,9 @@ +@@ -92,6 +_,9 @@ } public final CompoundTag createTag(StructurePieceSerializationContext p_192645_) { diff --git a/patches/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch b/patches/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch index 71ababbf01..79c1cb74f1 100644 --- a/patches/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch +++ b/patches/net/minecraft/world/level/levelgen/structure/StructureStart.java.patch @@ -4,9 +4,9 @@ public CompoundTag createTag(StructurePieceSerializationContext p_192661_, ChunkPos p_192662_) { CompoundTag compoundtag = new CompoundTag(); if (this.isValid()) { -+ if (p_192661_.registryAccess().registryOrThrow(Registries.STRUCTURE).getKey(this.getStructure()) == null) { // FORGE: This is just a more friendly error instead of the 'Null String' below ++ if (p_192661_.registryAccess().lookupOrThrow(Registries.STRUCTURE).getKey(this.getStructure()) == null) { // FORGE: This is just a more friendly error instead of the 'Null String' below + throw new RuntimeException("StructureStart \"" + this.getClass().getName() + "\": \"" + this.getStructure() + "\" unregistered, serializing impossible."); + } - compoundtag.putString("id", p_192661_.registryAccess().registryOrThrow(Registries.STRUCTURE).getKey(this.structure).toString()); + compoundtag.putString("id", p_192661_.registryAccess().lookupOrThrow(Registries.STRUCTURE).getKey(this.structure).toString()); compoundtag.putInt("ChunkX", p_192662_.x); compoundtag.putInt("ChunkZ", p_192662_.z); diff --git a/patches/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch b/patches/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch index 04e9e46fc6..5f34e65a0c 100644 --- a/patches/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch +++ b/patches/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java +++ b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java -@@ -219,6 +_,10 @@ +@@ -248,6 +_,10 @@ return transform(p_74565_, p_74564_.getMirror(), p_74564_.getRotation(), p_74564_.getRotationPivot()); } @@ -11,7 +11,7 @@ public boolean placeInWorld( ServerLevelAccessor p_230329_, BlockPos p_230330_, BlockPos p_230331_, StructurePlaceSettings p_230332_, RandomSource p_230333_, int p_230334_ ) { -@@ -242,7 +_,7 @@ +@@ -271,7 +_,7 @@ int j1 = Integer.MIN_VALUE; for (StructureTemplate.StructureBlockInfo structuretemplate$structureblockinfo : processBlockInfos( @@ -20,7 +20,7 @@ )) { BlockPos blockpos = structuretemplate$structureblockinfo.pos; if (boundingbox == null || boundingbox.isInside(blockpos)) { -@@ -355,15 +_,7 @@ +@@ -384,15 +_,7 @@ } if (!p_230332_.isIgnoreEntities()) { @@ -37,7 +37,7 @@ } return true; -@@ -402,12 +_,20 @@ +@@ -433,12 +_,20 @@ } public static List processBlockInfos( @@ -58,7 +58,7 @@ List list = new ArrayList<>(); List list1 = new ArrayList<>(); -@@ -422,7 +_,7 @@ +@@ -453,7 +_,7 @@ while (structuretemplate$structureblockinfo1 != null && iterator.hasNext()) { structuretemplate$structureblockinfo1 = iterator.next() @@ -67,7 +67,7 @@ } if (structuretemplate$structureblockinfo1 != null) { -@@ -438,21 +_,29 @@ +@@ -469,21 +_,29 @@ return list1; } @@ -111,26 +111,26 @@ ListTag listtag = new ListTag(); listtag.add(DoubleTag.valueOf(vec31.x)); listtag.add(DoubleTag.valueOf(vec31.y)); -@@ -460,10 +_,10 @@ - compoundtag.put("Pos", listtag); - compoundtag.remove("UUID"); - createEntityIgnoreException(p_74524_, compoundtag).ifPresent(p_275190_ -> { -- float f = p_275190_.rotate(p_74527_); -- f += p_275190_.mirror(p_74526_) - p_275190_.getYRot(); -+ float f = p_275190_.rotate(placementIn.getRotation()); -+ f += p_275190_.mirror(placementIn.getMirror()) - p_275190_.getYRot(); - p_275190_.moveTo(vec31.x, vec31.y, vec31.z, f, p_275190_.getXRot()); -- if (p_74530_ && p_275190_ instanceof Mob) { -+ if (placementIn.shouldFinalizeEntities() && p_275190_ instanceof Mob) { - ((Mob)p_275190_).finalizeSpawn(p_74524_, p_74524_.getCurrentDifficultyAt(BlockPos.containing(vec31)), MobSpawnType.STRUCTURE, null); - } - -@@ -777,7 +_,7 @@ +@@ -493,10 +_,10 @@ + createEntityIgnoreException(p_74524_, compoundtag) + .ifPresent( + p_275190_ -> { +- float f = p_275190_.rotate(p_74527_); +- f += p_275190_.mirror(p_74526_) - p_275190_.getYRot(); ++ float f = p_275190_.rotate(placementIn.getRotation()); ++ f += p_275190_.mirror(placementIn.getMirror()) - p_275190_.getYRot(); + p_275190_.moveTo(vec31.x, vec31.y, vec31.z, f, p_275190_.getXRot()); +- if (p_74530_ && p_275190_ instanceof Mob) { ++ if (placementIn.shouldFinalizeEntities() && p_275190_ instanceof Mob) { + ((Mob)p_275190_) + .finalizeSpawn(p_74524_, p_74524_.getCurrentDifficultyAt(BlockPos.containing(vec31)), EntitySpawnReason.STRUCTURE, null); + } +@@ -867,7 +_,7 @@ public static final class Palette { private final List blocks; - private final Map> cache = Maps.newHashMap(); + private final Map> cache = Maps.newConcurrentMap(); // Neo: Fixes MC-271899 - Make the global StructureTemplate's palette caches now thread safe for worldgen + @Nullable + private List cachedJigsaws; - Palette(List p_74648_) { - this.blocks = p_74648_; diff --git a/patches/net/minecraft/world/level/lighting/BlockLightEngine.java.patch b/patches/net/minecraft/world/level/lighting/BlockLightEngine.java.patch index 1ddb75cafb..7696c79c4e 100644 --- a/patches/net/minecraft/world/level/lighting/BlockLightEngine.java.patch +++ b/patches/net/minecraft/world/level/lighting/BlockLightEngine.java.patch @@ -12,9 +12,9 @@ @@ -119,7 +_,7 @@ LightChunk lightchunk = this.chunkSource.getChunkForLighting(p_285274_.x, p_285274_.z); if (lightchunk != null) { - lightchunk.findBlockLightSources((p_285266_, p_285452_) -> { -- int i = p_285452_.getLightEmission(); -+ int i = p_285452_.getLightEmission(chunkSource.getLevel(), p_285266_); - this.enqueueIncrease(p_285266_.asLong(), LightEngine.QueueEntry.increaseLightFromEmission(i, isEmptyShape(p_285452_))); + lightchunk.findBlockLightSources((p_360252_, p_360253_) -> { +- int i = p_360253_.getLightEmission(); ++ int i = p_360253_.getLightEmission(chunkSource.getLevel(), p_360252_); + this.enqueueIncrease(p_360252_.asLong(), LightEngine.QueueEntry.increaseLightFromEmission(i, isEmptyShape(p_360253_))); }); } diff --git a/patches/net/minecraft/world/level/lighting/LightEngine.java.patch b/patches/net/minecraft/world/level/lighting/LightEngine.java.patch index 63adb6e17d..618090b509 100644 --- a/patches/net/minecraft/world/level/lighting/LightEngine.java.patch +++ b/patches/net/minecraft/world/level/lighting/LightEngine.java.patch @@ -1,11 +1,23 @@ --- a/net/minecraft/world/level/lighting/LightEngine.java +++ b/net/minecraft/world/level/lighting/LightEngine.java -@@ -44,7 +_,7 @@ +@@ -38,11 +_,19 @@ + this.clearChunkCache(); + } + ++ /** ++ * @deprecated Neo: use overload with level context instead ++ */ ++ @Deprecated + public static boolean hasDifferentLightProperties(BlockState p_285110_, BlockState p_285372_) { ++ return hasDifferentLightProperties(net.minecraft.world.level.EmptyBlockGetter.INSTANCE, BlockPos.ZERO, p_285110_, p_285372_); ++ } ++ ++ public static boolean hasDifferentLightProperties(net.minecraft.world.level.BlockGetter level, BlockPos pos, BlockState p_285110_, BlockState p_285372_) { return p_285372_ == p_285110_ ? false - : p_285372_.getLightBlock(p_285159_, p_284985_) != p_285110_.getLightBlock(p_285159_, p_284985_) + : p_285372_.getLightBlock() != p_285110_.getLightBlock() - || p_285372_.getLightEmission() != p_285110_.getLightEmission() -+ || p_285372_.getLightEmission(p_285159_, p_284985_) != p_285110_.getLightEmission(p_285159_, p_284985_) ++ || p_285372_.getLightEmission(level, pos) != p_285110_.getLightEmission(level, pos) || p_285372_.useShapeForLightOcclusion() || p_285110_.useShapeForLightOcclusion(); } diff --git a/patches/net/minecraft/world/level/material/FlowingFluid.java.patch b/patches/net/minecraft/world/level/material/FlowingFluid.java.patch index a0acfa62cb..29f99b880b 100644 --- a/patches/net/minecraft/world/level/material/FlowingFluid.java.patch +++ b/patches/net/minecraft/world/level/material/FlowingFluid.java.patch @@ -1,36 +1,36 @@ --- a/net/minecraft/world/level/material/FlowingFluid.java +++ b/net/minecraft/world/level/material/FlowingFluid.java -@@ -164,7 +_,7 @@ - BlockState blockstate = p_256464_.getBlockState(blockpos); +@@ -171,7 +_,7 @@ + BlockState blockstate = p_376839_.getBlockState(blockpos); FluidState fluidstate = blockstate.getFluidState(); - if (fluidstate.getType().isSame(this) && this.canPassThroughWall(direction, p_256464_, p_76037_, p_76038_, blockpos, blockstate)) { + if (fluidstate.getType().isSame(this) && canPassThroughWall(direction, p_376839_, p_76037_, p_76038_, blockpos, blockstate)) { - if (fluidstate.isSource()) { -+ if (fluidstate.isSource() && net.neoforged.neoforge.event.EventHooks.canCreateFluidSource(p_256464_, blockpos, blockstate)) { ++ if (fluidstate.isSource() && net.neoforged.neoforge.event.EventHooks.canCreateFluidSource(p_376839_, blockpos, blockstate)) { j++; } -@@ -172,7 +_,7 @@ +@@ -179,7 +_,7 @@ } } -- if (this.canConvertToSource(p_256464_) && j >= 2) { +- if (j >= 2 && this.canConvertToSource(p_376839_)) { + if (j >= 2) { - BlockState blockstate1 = p_256464_.getBlockState(p_76037_.below()); + BlockState blockstate1 = p_376839_.getBlockState(blockpos$mutableblockpos.setWithOffset(p_76037_, Direction.DOWN)); FluidState fluidstate1 = blockstate1.getFluidState(); if (blockstate1.isSolid() || this.isSourceBlockOfThisType(fluidstate1)) { -@@ -238,6 +_,15 @@ +@@ -257,6 +_,15 @@ return this.getSource().defaultFluidState().setValue(FALLING, Boolean.valueOf(p_76069_)); } + @Override -+ public boolean canConvertToSource(FluidState state, Level level, BlockPos pos) { ++ public boolean canConvertToSource(FluidState state, ServerLevel level, BlockPos pos) { + return this.canConvertToSource(level); + } + + /** -+ * @deprecated Forge: Use {@link #canConvertToSource(FluidState, Level, BlockPos)} instead. ++ * @deprecated Forge: Use {@link #canConvertToSource(FluidState, ServerLevel, BlockPos)} instead. + */ + @Deprecated - protected abstract boolean canConvertToSource(Level p_256009_); + protected abstract boolean canConvertToSource(ServerLevel p_376940_); protected void spreadTo(LevelAccessor p_76005_, BlockPos p_76006_, BlockState p_76007_, Direction p_76008_, FluidState p_76009_) { diff --git a/patches/net/minecraft/world/level/material/Fluid.java.patch b/patches/net/minecraft/world/level/material/Fluid.java.patch index 9bb749ea45..918a9f72f4 100644 --- a/patches/net/minecraft/world/level/material/Fluid.java.patch +++ b/patches/net/minecraft/world/level/material/Fluid.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/material/Fluid.java +++ b/net/minecraft/world/level/material/Fluid.java -@@ -20,7 +_,7 @@ +@@ -21,7 +_,7 @@ import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.VoxelShape; @@ -9,7 +9,7 @@ public static final IdMapper FLUID_STATE_REGISTRY = new IdMapper<>(); protected final StateDefinition stateDefinition; private FluidState defaultFluidState; -@@ -100,6 +_,13 @@ +@@ -101,6 +_,13 @@ } public abstract VoxelShape getShape(FluidState p_76137_, BlockGetter p_76138_, BlockPos p_76139_); diff --git a/patches/net/minecraft/world/level/material/FluidState.java.patch b/patches/net/minecraft/world/level/material/FluidState.java.patch index 399850a632..acc03677a4 100644 --- a/patches/net/minecraft/world/level/material/FluidState.java.patch +++ b/patches/net/minecraft/world/level/material/FluidState.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/material/FluidState.java +++ b/net/minecraft/world/level/material/FluidState.java -@@ -21,7 +_,7 @@ +@@ -22,7 +_,7 @@ import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.shapes.VoxelShape; @@ -9,7 +9,7 @@ public static final Codec CODEC = codec(BuiltInRegistries.FLUID.byNameCodec(), Fluid::defaultFluidState).stable(); public static final int AMOUNT_MAX = 9; public static final int AMOUNT_FULL = 8; -@@ -113,6 +_,7 @@ +@@ -114,6 +_,7 @@ return this.getType() == p_192918_; } diff --git a/patches/net/minecraft/world/level/material/LavaFluid.java.patch b/patches/net/minecraft/world/level/material/LavaFluid.java.patch index 22bbfb96e8..8569dec5af 100644 --- a/patches/net/minecraft/world/level/material/LavaFluid.java.patch +++ b/patches/net/minecraft/world/level/material/LavaFluid.java.patch @@ -1,26 +1,26 @@ --- a/net/minecraft/world/level/material/LavaFluid.java +++ b/net/minecraft/world/level/material/LavaFluid.java -@@ -87,7 +_,7 @@ - BlockState blockstate = p_230572_.getBlockState(blockpos); +@@ -88,7 +_,7 @@ + BlockState blockstate = p_376493_.getBlockState(blockpos); if (blockstate.isAir()) { - if (this.hasFlammableNeighbours(p_230572_, blockpos)) { -- p_230572_.setBlockAndUpdate(blockpos, BaseFireBlock.getState(p_230572_, blockpos)); -+ p_230572_.setBlockAndUpdate(blockpos, net.neoforged.neoforge.event.EventHooks.fireFluidPlaceBlockEvent(p_230572_, blockpos, p_230573_, BaseFireBlock.getState(p_230572_, blockpos))); + if (this.hasFlammableNeighbours(p_376493_, blockpos)) { +- p_376493_.setBlockAndUpdate(blockpos, BaseFireBlock.getState(p_376493_, blockpos)); ++ p_376493_.setBlockAndUpdate(blockpos, net.neoforged.neoforge.event.EventHooks.fireFluidPlaceBlockEvent(p_376493_, blockpos, p_230573_, BaseFireBlock.getState(p_376493_, blockpos))); return; } } else if (blockstate.blocksMotion()) { -@@ -101,8 +_,8 @@ +@@ -102,8 +_,8 @@ return; } -- if (p_230572_.isEmptyBlock(blockpos1.above()) && this.isFlammable(p_230572_, blockpos1)) { -- p_230572_.setBlockAndUpdate(blockpos1.above(), BaseFireBlock.getState(p_230572_, blockpos1)); -+ if (p_230572_.isEmptyBlock(blockpos1.above()) && this.isFlammable(p_230572_, blockpos1, Direction.UP)) { -+ p_230572_.setBlockAndUpdate(blockpos1.above(), net.neoforged.neoforge.event.EventHooks.fireFluidPlaceBlockEvent(p_230572_, blockpos1.above(), p_230573_, BaseFireBlock.getState(p_230572_, blockpos1))); +- if (p_376493_.isEmptyBlock(blockpos1.above()) && this.isFlammable(p_376493_, blockpos1)) { +- p_376493_.setBlockAndUpdate(blockpos1.above(), BaseFireBlock.getState(p_376493_, blockpos1)); ++ if (p_376493_.isEmptyBlock(blockpos1.above()) && this.isFlammable(p_376493_, blockpos1, Direction.UP)) { ++ p_376493_.setBlockAndUpdate(blockpos1.above(), net.neoforged.neoforge.event.EventHooks.fireFluidPlaceBlockEvent(p_376493_, blockpos1.above(), p_230573_, BaseFireBlock.getState(p_376493_, blockpos1))); } } } -@@ -111,7 +_,7 @@ +@@ -112,7 +_,7 @@ private boolean hasFlammableNeighbours(LevelReader p_76228_, BlockPos p_76229_) { for (Direction direction : Direction.values()) { @@ -29,20 +29,18 @@ return true; } } -@@ -119,12 +_,22 @@ +@@ -120,10 +_,20 @@ return false; } + /** @deprecated Forge: use {@link LavaFluid#isFlammable(LevelReader,BlockPos,Direction)} instead */ + @Deprecated private boolean isFlammable(LevelReader p_76246_, BlockPos p_76247_) { - return p_76247_.getY() >= p_76246_.getMinBuildHeight() && p_76247_.getY() < p_76246_.getMaxBuildHeight() && !p_76246_.hasChunkAt(p_76247_) - ? false - : p_76246_.getBlockState(p_76247_).ignitedByLava(); + return p_76246_.isInsideBuildHeight(p_76247_.getY()) && !p_76246_.hasChunkAt(p_76247_) ? false : p_76246_.getBlockState(p_76247_).ignitedByLava(); } + private boolean isFlammable(LevelReader level, BlockPos pos, Direction face) { -+ if (pos.getY() >= level.getMinBuildHeight() && pos.getY() < level.getMaxBuildHeight() && !level.hasChunkAt(pos)) { ++ if (level.isInsideBuildHeight(pos.getY()) && !level.hasChunkAt(pos)) { + return false; + } + BlockState state = level.getBlockState(pos); @@ -52,7 +50,7 @@ @Nullable @Override public ParticleOptions getDripParticle() { -@@ -196,7 +_,7 @@ +@@ -195,7 +_,7 @@ FluidState fluidstate = p_76220_.getFluidState(p_76221_); if (this.is(FluidTags.LAVA) && fluidstate.is(FluidTags.WATER)) { if (p_76222_.getBlock() instanceof LiquidBlock) { diff --git a/patches/net/minecraft/world/level/portal/PortalShape.java.patch b/patches/net/minecraft/world/level/portal/PortalShape.java.patch index 133b3d8060..6da90f6816 100644 --- a/patches/net/minecraft/world/level/portal/PortalShape.java.patch +++ b/patches/net/minecraft/world/level/portal/PortalShape.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/portal/PortalShape.java +++ b/net/minecraft/world/level/portal/PortalShape.java -@@ -27,7 +_,7 @@ +@@ -28,7 +_,7 @@ public static final int MAX_WIDTH = 21; private static final int MIN_HEIGHT = 3; public static final int MAX_HEIGHT = 21; @@ -8,4 +8,4 @@ + private static final BlockBehaviour.StatePredicate FRAME = net.neoforged.neoforge.common.extensions.IBlockStateExtension::isPortalFrame; private static final float SAFE_TRAVEL_MAX_ENTITY_XY = 4.0F; private static final double SAFE_TRAVEL_MAX_VERTICAL_DELTA = 1.0; - private final LevelAccessor level; + private final Direction.Axis axis; diff --git a/patches/net/minecraft/world/level/saveddata/SavedData.java.patch b/patches/net/minecraft/world/level/saveddata/SavedData.java.patch index ac130d73e8..ed2c2352de 100644 --- a/patches/net/minecraft/world/level/saveddata/SavedData.java.patch +++ b/patches/net/minecraft/world/level/saveddata/SavedData.java.patch @@ -1,15 +1,6 @@ --- a/net/minecraft/world/level/saveddata/SavedData.java +++ b/net/minecraft/world/level/saveddata/SavedData.java -@@ -37,7 +_,7 @@ - NbtUtils.addCurrentDataVersion(compoundtag); - - try { -- NbtIo.writeCompressed(compoundtag, p_77758_.toPath()); -+ net.neoforged.neoforge.common.IOUtilities.writeNbtCompressed(compoundtag, p_77758_.toPath()); - } catch (IOException ioexception) { - LOGGER.error("Could not save data {}", this, ioexception); - } -@@ -47,7 +_,10 @@ +@@ -33,7 +_,10 @@ } public static record Factory( diff --git a/patches/net/minecraft/world/level/storage/DimensionDataStorage.java.patch b/patches/net/minecraft/world/level/storage/DimensionDataStorage.java.patch index ecf3e43153..8dd492afb3 100644 --- a/patches/net/minecraft/world/level/storage/DimensionDataStorage.java.patch +++ b/patches/net/minecraft/world/level/storage/DimensionDataStorage.java.patch @@ -1,24 +1,24 @@ --- a/net/minecraft/world/level/storage/DimensionDataStorage.java +++ b/net/minecraft/world/level/storage/DimensionDataStorage.java -@@ -63,7 +_,7 @@ +@@ -69,7 +_,7 @@ } @Nullable - private T readSavedData(BiFunction p_324609_, DataFixTypes p_295832_, String p_164870_) { + private T readSavedData(BiFunction p_324609_, @Nullable DataFixTypes p_295832_, String p_164870_) { try { - File file1 = this.getDataFile(p_164870_); - if (file1.exists()) { -@@ -81,7 +_,7 @@ - this.cache.put(p_164856_, p_164857_); + Path path = this.getDataFile(p_164870_); + if (Files.exists(path)) { +@@ -88,7 +_,7 @@ + p_164857_.setDirty(); } - public CompoundTag readTagFromDisk(String p_78159_, DataFixTypes p_295038_, int p_78160_) throws IOException { + public CompoundTag readTagFromDisk(String p_78159_, @Nullable DataFixTypes p_295038_, int p_78160_) throws IOException { - File file1 = this.getDataFile(p_78159_); - CompoundTag compoundtag1; -@@ -98,9 +_,16 @@ + try ( + InputStream inputstream = Files.newInputStream(this.getDataFile(p_78159_)); +@@ -103,9 +_,16 @@ } } @@ -33,7 +33,20 @@ } + + // Neo: delete any temporary files so that we don't inflate disk space unnecessarily. -+ net.neoforged.neoforge.common.IOUtilities.cleanupTempFiles(this.dataFolder.toPath(), p_78159_); ++ net.neoforged.neoforge.common.IOUtilities.cleanupTempFiles(this.dataFolder, p_78159_); return compoundtag1; } +@@ -156,7 +_,11 @@ + private static CompletableFuture tryWriteAsync(Path p_364583_, CompoundTag p_363128_) { + return CompletableFuture.runAsync(() -> { + try { +- NbtIo.writeCompressed(p_363128_, p_364583_); ++ // Neo: ensure parent directories exist if the SavedData's path contains slashes ++ if (!Files.exists(p_364583_)) { ++ Files.createDirectories(p_364583_.getParent()); ++ } ++ net.neoforged.neoforge.common.IOUtilities.writeNbtCompressed(p_363128_, p_364583_); + } catch (IOException ioexception) { + LOGGER.error("Could not save data to {}", p_364583_.getFileName(), ioexception); + } diff --git a/patches/net/minecraft/world/level/storage/ServerLevelData.java.patch b/patches/net/minecraft/world/level/storage/ServerLevelData.java.patch index d56c58c499..ff29008c50 100644 --- a/patches/net/minecraft/world/level/storage/ServerLevelData.java.patch +++ b/patches/net/minecraft/world/level/storage/ServerLevelData.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/world/level/storage/ServerLevelData.java +++ b/net/minecraft/world/level/storage/ServerLevelData.java -@@ -87,4 +_,10 @@ - void setGameTime(long p_78617_); - +@@ -90,4 +_,10 @@ void setDayTime(long p_78624_); + + GameRules getGameRules(); + + //Neo + float getDayTimeFraction(); diff --git a/patches/net/minecraft/world/level/storage/loot/LootContext.java.patch b/patches/net/minecraft/world/level/storage/loot/LootContext.java.patch index 533f10a1a5..2c5260f97e 100644 --- a/patches/net/minecraft/world/level/storage/loot/LootContext.java.patch +++ b/patches/net/minecraft/world/level/storage/loot/LootContext.java.patch @@ -64,7 +64,7 @@ @@ -140,6 +_,11 @@ - public LootContextParam getParam() { + public ContextKey getParam() { return this.param; + } + diff --git a/patches/net/minecraft/world/level/storage/loot/LootDataType.java.patch b/patches/net/minecraft/world/level/storage/loot/LootDataType.java.patch index 1fc2c3ab3e..0cbbb86db6 100644 --- a/patches/net/minecraft/world/level/storage/loot/LootDataType.java.patch +++ b/patches/net/minecraft/world/level/storage/loot/LootDataType.java.patch @@ -1,15 +1,14 @@ --- a/net/minecraft/world/level/storage/loot/LootDataType.java +++ b/net/minecraft/world/level/storage/loot/LootDataType.java -@@ -16,7 +_,7 @@ +@@ -9,14 +_,26 @@ + import net.minecraft.world.level.storage.loot.functions.LootItemFunctions; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; - import org.slf4j.Logger; -public record LootDataType(ResourceKey> registryKey, Codec codec, LootDataType.Validator validator) { -+public record LootDataType(ResourceKey> registryKey, Codec codec, LootDataType.Validator validator, @org.jetbrains.annotations.Nullable T defaultValue, Codec> conditionalCodec, java.util.function.BiConsumer idSetter) { - private static final Logger LOGGER = LogUtils.getLogger(); ++public record LootDataType(ResourceKey> registryKey, Codec codec, LootDataType.Validator validator, @org.jetbrains.annotations.Nullable T defaultValue, Codec> conditionalCodec, java.util.function.BiConsumer idSetter) { public static final LootDataType PREDICATE = new LootDataType<>( Registries.PREDICATE, LootItemCondition.DIRECT_CODEC, createSimpleValidator() -@@ -24,17 +_,33 @@ + ); public static final LootDataType MODIFIER = new LootDataType<>( Registries.ITEM_MODIFIER, LootItemFunctions.ROOT_CODEC, createSimpleValidator() ); @@ -24,39 +23,21 @@ + this(registryKey, codec, validator, null, (it, id) -> {}); + } + -+ private LootDataType(ResourceKey> registryKey, Codec codec, LootDataType.Validator validator, @org.jetbrains.annotations.Nullable T defaultValue, java.util.function.BiConsumer idSetter) { ++ private LootDataType(ResourceKey> registryKey, Codec codec, LootDataType.Validator validator, @org.jetbrains.annotations.Nullable T defaultValue, java.util.function.BiConsumer idSetter) { + this(registryKey, codec, validator, defaultValue, net.neoforged.neoforge.common.conditions.ConditionalOps.createConditionalCodec(codec), idSetter); + } public void runValidation(ValidationContext p_279366_, ResourceKey p_336149_, T p_279124_) { this.validator.run(p_279366_, p_336149_, p_279124_); - } - - public Optional deserialize(ResourceLocation p_279253_, DynamicOps p_324006_, V p_324329_) { -- DataResult dataresult = this.codec.parse(p_324006_, p_324329_); -- dataresult.error() -- .ifPresent(p_350259_ -> LOGGER.error("Couldn't parse element {}/{} - {}", this.registryKey.location(), p_279253_, p_350259_.message())); -- return dataresult.result(); -+ var dataresult = this.conditionalCodec.parse(p_324006_, p_324329_); -+ dataresult.error().ifPresent(p_338121_ -> LOGGER.error("Couldn't parse element {}:{} - {}", this.registryKey, p_279253_, p_338121_.message())); -+ return dataresult.result().map(it -> { -+ it.ifPresent(val -> idSetter.accept(val, p_279253_)); -+ T value = it.orElse(defaultValue); -+ if (value instanceof LootTable lootTable) value = (T) net.neoforged.neoforge.event.EventHooks.loadLootTable(p_279253_, lootTable); -+ return value; -+ }); - } - - public static Stream> values() { -@@ -48,9 +_,11 @@ +@@ -33,9 +_,11 @@ } private static LootDataType.Validator createLootTableValidator() { -- return (p_339557_, p_339558_, p_339559_) -> p_339559_.validate( -- p_339557_.setParams(p_339559_.getParamSet()).enterElement("{" + p_339558_.registry() + "/" + p_339558_.location() + "}", p_339558_) +- return (p_380902_, p_380903_, p_380904_) -> p_380904_.validate( +- p_380902_.setContextKeySet(p_380904_.getParamSet()).enterElement("{" + p_380903_.registry() + "/" + p_380903_.location() + "}", p_380903_) + return (p_279333_, p_279227_, p_279406_) -> { + p_279406_.validate( -+ p_279333_.setParams(p_279406_.getParamSet()).enterElement("{" + p_279227_.registry() + ":" + p_279227_.location() + "}", p_279227_) ++ p_279333_.setContextKeySet(p_279406_.getParamSet()).enterElement("{" + p_279227_.registry() + ":" + p_279227_.location() + "}", p_279227_) ); + }; } diff --git a/patches/net/minecraft/world/level/storage/loot/LootParams.java.patch b/patches/net/minecraft/world/level/storage/loot/LootParams.java.patch deleted file mode 100644 index f2d7d0cb00..0000000000 --- a/patches/net/minecraft/world/level/storage/loot/LootParams.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/level/storage/loot/LootParams.java -+++ b/net/minecraft/world/level/storage/loot/LootParams.java -@@ -125,7 +_,7 @@ - - public LootParams create(LootContextParamSet p_287701_) { - Set> set = Sets.difference(this.params.keySet(), p_287701_.getAllowed()); -- if (!set.isEmpty()) { -+ if (false && !set.isEmpty()) { // Forge: Allow mods to pass custom loot parameters (not part of the vanilla loot table) to the loot context. - throw new IllegalArgumentException("Parameters not allowed in this parameter set: " + set); - } else { - Set> set1 = Sets.difference(p_287701_.getRequired(), this.params.keySet()); diff --git a/patches/net/minecraft/world/level/storage/loot/LootTable.java.patch b/patches/net/minecraft/world/level/storage/loot/LootTable.java.patch index 8e1d44d1ab..38d536c345 100644 --- a/patches/net/minecraft/world/level/storage/loot/LootTable.java.patch +++ b/patches/net/minecraft/world/level/storage/loot/LootTable.java.patch @@ -1,19 +1,19 @@ --- a/net/minecraft/world/level/storage/loot/LootTable.java +++ b/net/minecraft/world/level/storage/loot/LootTable.java @@ -38,8 +_,8 @@ - p_338123_ -> p_338123_.group( - LootContextParamSets.CODEC.lenientOptionalFieldOf("type", DEFAULT_PARAM_SET).forGetter(p_298001_ -> p_298001_.paramSet), + p_380905_ -> p_380905_.group( + LootContextParamSets.CODEC.lenientOptionalFieldOf("type", DEFAULT_PARAM_SET).forGetter(p_380906_ -> p_380906_.paramSet), ResourceLocation.CODEC.optionalFieldOf("random_sequence").forGetter(p_297998_ -> p_297998_.randomSequence), - LootPool.CODEC.listOf().optionalFieldOf("pools", List.of()).forGetter(p_298002_ -> p_298002_.pools), - LootItemFunctions.ROOT_CODEC.listOf().optionalFieldOf("functions", List.of()).forGetter(p_298000_ -> p_298000_.functions) + net.neoforged.neoforge.common.CommonHooks.lootPoolsCodec(LootPool::setName).optionalFieldOf("pools", List.of()).forGetter(p_298002_ -> p_298002_.pools), + net.neoforged.neoforge.common.conditions.ConditionalOps.decodeListWithElementConditions(LootItemFunctions.ROOT_CODEC).optionalFieldOf("functions", List.of()).forGetter(p_298000_ -> p_298000_.functions) ) - .apply(p_338123_, LootTable::new) + .apply(p_380905_, LootTable::new) ); @@ -53,7 +_,7 @@ - LootTable(LootContextParamSet p_287716_, Optional p_299055_, List p_298390_, List p_298775_) { - this.paramSet = p_287716_; + LootTable(ContextKeySet p_380952_, Optional p_299055_, List p_298390_, List p_298775_) { + this.paramSet = p_380952_; this.randomSequence = p_299055_; - this.pools = p_298390_; + this.pools = Lists.newArrayList(p_298390_); diff --git a/patches/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java.patch b/patches/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java.patch index 57bef15771..d56bd6e4d1 100644 --- a/patches/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java.patch +++ b/patches/net/minecraft/world/level/storage/loot/functions/EnchantRandomlyFunction.java.patch @@ -3,7 +3,7 @@ @@ -59,7 +_,7 @@ Stream> stream = this.options .map(HolderSet::stream) - .orElseGet(() -> p_80430_.getLevel().registryAccess().registryOrThrow(Registries.ENCHANTMENT).holders().map(Function.identity())) + .orElseGet(() -> p_80430_.getLevel().registryAccess().lookupOrThrow(Registries.ENCHANTMENT).listElements().map(Function.identity())) - .filter(p_344686_ -> !flag1 || p_344686_.value().canEnchant(p_80429_)); + .filter(p_344686_ -> !flag1 || p_80429_.supportsEnchantment(p_344686_)); // Neo: Respect IItemExtension#supportsEnchantment List> list = stream.toList(); diff --git a/patches/net/minecraft/world/level/storage/loot/functions/SmeltItemFunction.java.patch b/patches/net/minecraft/world/level/storage/loot/functions/SmeltItemFunction.java.patch index 22bb631d44..0851d8d1ab 100644 --- a/patches/net/minecraft/world/level/storage/loot/functions/SmeltItemFunction.java.patch +++ b/patches/net/minecraft/world/level/storage/loot/functions/SmeltItemFunction.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/world/level/storage/loot/functions/SmeltItemFunction.java +++ b/net/minecraft/world/level/storage/loot/functions/SmeltItemFunction.java -@@ -41,7 +_,7 @@ +@@ -42,7 +_,7 @@ if (optional.isPresent()) { - ItemStack itemstack = optional.get().value().getResultItem(p_81269_.getLevel().registryAccess()); + ItemStack itemstack = optional.get().value().assemble(singlerecipeinput, p_81269_.getLevel().registryAccess()); if (!itemstack.isEmpty()) { - return itemstack.copyWithCount(p_81268_.getCount()); + return itemstack.copyWithCount(p_81268_.getCount() * itemstack.getCount()); // Forge: Support smelting returning multiple diff --git a/patches/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java.patch b/patches/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java.patch index 17ecf039d9..ad4a552cc4 100644 --- a/patches/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java.patch +++ b/patches/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java.patch @@ -1,20 +1,20 @@ --- a/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java +++ b/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java -@@ -20,7 +_,7 @@ - public static final LootContextParamSet EMPTY = register("empty", p_81454_ -> { +@@ -21,7 +_,7 @@ + public static final ContextKeySet EMPTY = register("empty", p_381149_ -> { }); - public static final LootContextParamSet CHEST = register( -- "chest", p_323464_ -> p_323464_.required(LootContextParams.ORIGIN).optional(LootContextParams.THIS_ENTITY) + public static final ContextKeySet CHEST = register( +- "chest", p_380909_ -> p_380909_.required(LootContextParams.ORIGIN).optional(LootContextParams.THIS_ENTITY) + "chest", p_81452_ -> p_81452_.required(LootContextParams.ORIGIN).optional(LootContextParams.THIS_ENTITY).optional(LootContextParams.ATTACKING_ENTITY) //Forge: Chest minecarts can have killer entities ); - public static final LootContextParamSet COMMAND = register( - "command", p_330195_ -> p_330195_.required(LootContextParams.ORIGIN).optional(LootContextParams.THIS_ENTITY) -@@ -29,7 +_,7 @@ - "selector", p_81442_ -> p_81442_.required(LootContextParams.ORIGIN).required(LootContextParams.THIS_ENTITY) + public static final ContextKeySet COMMAND = register( + "command", p_380924_ -> p_380924_.required(LootContextParams.ORIGIN).optional(LootContextParams.THIS_ENTITY) +@@ -30,7 +_,7 @@ + "selector", p_380913_ -> p_380913_.required(LootContextParams.ORIGIN).required(LootContextParams.THIS_ENTITY) ); - public static final LootContextParamSet FISHING = register( -- "fishing", p_81446_ -> p_81446_.required(LootContextParams.ORIGIN).required(LootContextParams.TOOL).optional(LootContextParams.THIS_ENTITY) + public static final ContextKeySet FISHING = register( +- "fishing", p_380928_ -> p_380928_.required(LootContextParams.ORIGIN).required(LootContextParams.TOOL).optional(LootContextParams.THIS_ENTITY) + "fishing", p_81446_ -> p_81446_.required(LootContextParams.ORIGIN).required(LootContextParams.TOOL).optional(LootContextParams.THIS_ENTITY).optional(LootContextParams.ATTACKING_ENTITY) //Forge: Add the fisher as a killer. ); - public static final LootContextParamSet ENTITY = register( + public static final ContextKeySet ENTITY = register( "entity", diff --git a/patches/net/minecraft/world/level/storage/loot/providers/nbt/ContextNbtProvider.java.patch b/patches/net/minecraft/world/level/storage/loot/providers/nbt/ContextNbtProvider.java.patch index c00e726253..69771175ba 100644 --- a/patches/net/minecraft/world/level/storage/loot/providers/nbt/ContextNbtProvider.java.patch +++ b/patches/net/minecraft/world/level/storage/loot/providers/nbt/ContextNbtProvider.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/storage/loot/providers/nbt/ContextNbtProvider.java +++ b/net/minecraft/world/level/storage/loot/providers/nbt/ContextNbtProvider.java -@@ -60,7 +_,7 @@ +@@ -59,7 +_,7 @@ @Override public String getId() { diff --git a/patches/net/minecraft/world/phys/AABB.java.patch b/patches/net/minecraft/world/phys/AABB.java.patch index 334c4f33b7..1f108aea04 100644 --- a/patches/net/minecraft/world/phys/AABB.java.patch +++ b/patches/net/minecraft/world/phys/AABB.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/phys/AABB.java +++ b/net/minecraft/world/phys/AABB.java -@@ -10,6 +_,7 @@ +@@ -11,6 +_,7 @@ public class AABB { private static final double EPSILON = 1.0E-7; @@ -8,7 +8,7 @@ public final double minX; public final double minY; public final double minZ; -@@ -528,5 +_,13 @@ +@@ -584,5 +_,13 @@ p_165883_.y + p_165885_ / 2.0, p_165883_.z + p_165886_ / 2.0 ); diff --git a/patches/net/minecraft/world/phys/shapes/MinecartCollisionContext.java.patch b/patches/net/minecraft/world/phys/shapes/MinecartCollisionContext.java.patch new file mode 100644 index 0000000000..fec8905831 --- /dev/null +++ b/patches/net/minecraft/world/phys/shapes/MinecartCollisionContext.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/phys/shapes/MinecartCollisionContext.java ++++ b/net/minecraft/world/phys/shapes/MinecartCollisionContext.java +@@ -25,7 +_,7 @@ + boolean flag = BaseRailBlock.isRail(blockstate); + if (flag) { + this.ingoreBelow = blockpos.below(); +- RailShape railshape = blockstate.getValue(((BaseRailBlock)blockstate.getBlock()).getShapeProperty()); ++ RailShape railshape = ((BaseRailBlock)blockstate.getBlock()).getRailDirection(blockstate, p_366450_.level(), blockpos, p_366450_); + if (railshape.isSlope()) { + this.slopeIgnore = switch (railshape) { + case ASCENDING_EAST -> blockpos.east(); diff --git a/projects/neoforge/build.gradle b/projects/neoforge/build.gradle index 669b21be2a..bc642bd0c9 100644 --- a/projects/neoforge/build.gradle +++ b/projects/neoforge/build.gradle @@ -81,11 +81,15 @@ dependencies { runtimeOnly "cpw.mods:bootstraplauncher:${project.bootstraplauncher_version}" moduleOnly "cpw.mods:securejarhandler:${project.securejarhandler_version}" - moduleOnly "org.ow2.asm:asm:${project.asm_version}" - moduleOnly "org.ow2.asm:asm-commons:${project.asm_version}" - moduleOnly "org.ow2.asm:asm-tree:${project.asm_version}" - moduleOnly "org.ow2.asm:asm-util:${project.asm_version}" - moduleOnly "org.ow2.asm:asm-analysis:${project.asm_version}" + for (var asmModule : ["org.ow2.asm:asm", "org.ow2.asm:asm-commons", "org.ow2.asm:asm-tree", "org.ow2.asm:asm-util", "org.ow2.asm:asm-analysis"]) { + moduleOnly(asmModule) { + // Vanilla ships with ASM 9.3 transitively (via their OpenID connect library dependency), we require + // ASM in a more recent version and have to strictly require this to override the strict Minecraft version. + version { + strictly project.asm_version + } + } + } moduleOnly "cpw.mods:bootstraplauncher:${project.bootstraplauncher_version}" moduleOnly "net.neoforged:JarJarFileSystems:${project.jarjar_version}" @@ -215,6 +219,10 @@ runs.configureEach { it -> it.arguments.addAll '--gameDir', gameDir.absolutePath } +tasks.register("genPatches") { + dependsOn tasks.unpackSourcePatches +} + launcherProfile { arguments { game '--fml.neoForgeVersion' diff --git a/src/generated/resources/data/c/tags/entity_type/boats.json b/src/generated/resources/data/c/tags/entity_type/boats.json index 58e89216d1..134759720c 100644 --- a/src/generated/resources/data/c/tags/entity_type/boats.json +++ b/src/generated/resources/data/c/tags/entity_type/boats.json @@ -1,7 +1,15 @@ { "values": [ - "minecraft:boat", - "minecraft:chest_boat", + "#minecraft:boat", + "minecraft:oak_chest_boat", + "minecraft:spruce_chest_boat", + "minecraft:birch_chest_boat", + "minecraft:jungle_chest_boat", + "minecraft:acacia_chest_boat", + "minecraft:cherry_chest_boat", + "minecraft:dark_oak_chest_boat", + "minecraft:mangrove_chest_boat", + "minecraft:bamboo_chest_raft", { "id": "#forge:boats", "required": false diff --git a/src/generated/resources/data/minecraft/recipe/acacia_chest_boat.json b/src/generated/resources/data/minecraft/recipe/acacia_chest_boat.json index 96b6a5a3b9..745f8237ba 100644 --- a/src/generated/resources/data/minecraft/recipe/acacia_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/acacia_chest_boat.json @@ -4,17 +4,11 @@ "group": "chest_boat", "ingredients": [ { - "type": "neoforge:difference", - "base": { - "tag": "c:chests/wooden" - }, - "subtracted": { - "tag": "c:chests/trapped" - } + "neoforge:ingredient_type": "neoforge:difference", + "base": "#c:chests/wooden", + "subtracted": "#c:chests/trapped" }, - { - "item": "minecraft:acacia_boat" - } + "minecraft:acacia_boat" ], "result": { "count": 1, diff --git a/src/generated/resources/data/minecraft/recipe/acacia_fence.json b/src/generated/resources/data/minecraft/recipe/acacia_fence.json index 1df661b7b1..abc4d37cba 100644 --- a/src/generated/resources/data/minecraft/recipe/acacia_fence.json +++ b/src/generated/resources/data/minecraft/recipe/acacia_fence.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_fence", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:acacia_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:acacia_planks" }, "pattern": [ "W#W", diff --git a/src/generated/resources/data/minecraft/recipe/acacia_fence_gate.json b/src/generated/resources/data/minecraft/recipe/acacia_fence_gate.json index 01c8f1d461..af366bf332 100644 --- a/src/generated/resources/data/minecraft/recipe/acacia_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/acacia_fence_gate.json @@ -3,12 +3,8 @@ "category": "redstone", "group": "wooden_fence_gate", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:acacia_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:acacia_planks" }, "pattern": [ "#W#", diff --git a/src/generated/resources/data/minecraft/recipe/acacia_sign.json b/src/generated/resources/data/minecraft/recipe/acacia_sign.json index 8591a10c68..3232b1b89a 100644 --- a/src/generated/resources/data/minecraft/recipe/acacia_sign.json +++ b/src/generated/resources/data/minecraft/recipe/acacia_sign.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_sign", "key": { - "#": { - "item": "minecraft:acacia_planks" - }, - "X": { - "tag": "c:rods/wooden" - } + "#": "minecraft:acacia_planks", + "X": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/activator_rail.json b/src/generated/resources/data/minecraft/recipe/activator_rail.json index f3e8a6d92a..555bb300db 100644 --- a/src/generated/resources/data/minecraft/recipe/activator_rail.json +++ b/src/generated/resources/data/minecraft/recipe/activator_rail.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "item": "minecraft:redstone_torch" - }, - "S": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:ingots/iron" - } + "#": "minecraft:redstone_torch", + "S": "#c:rods/wooden", + "X": "#c:ingots/iron" }, "pattern": [ "XSX", diff --git a/src/generated/resources/data/minecraft/recipe/andesite.json b/src/generated/resources/data/minecraft/recipe/andesite.json index 909e6271f9..5dfdf07cd9 100644 --- a/src/generated/resources/data/minecraft/recipe/andesite.json +++ b/src/generated/resources/data/minecraft/recipe/andesite.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shapeless", "category": "building", "ingredients": [ - { - "item": "minecraft:diorite" - }, - { - "tag": "c:cobblestones/normal" - } + "minecraft:diorite", + "#c:cobblestones/normal" ], "result": { "count": 2, diff --git a/src/generated/resources/data/minecraft/recipe/anvil.json b/src/generated/resources/data/minecraft/recipe/anvil.json index 405668a7af..e50cd1febe 100644 --- a/src/generated/resources/data/minecraft/recipe/anvil.json +++ b/src/generated/resources/data/minecraft/recipe/anvil.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "I": { - "item": "minecraft:iron_block" - }, - "i": { - "tag": "c:ingots/iron" - } + "I": "minecraft:iron_block", + "i": "#c:ingots/iron" }, "pattern": [ "III", diff --git a/src/generated/resources/data/minecraft/recipe/armor_stand.json b/src/generated/resources/data/minecraft/recipe/armor_stand.json index 55e7dbeaff..a3ad60d12c 100644 --- a/src/generated/resources/data/minecraft/recipe/armor_stand.json +++ b/src/generated/resources/data/minecraft/recipe/armor_stand.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "/": { - "tag": "c:rods/wooden" - }, - "_": { - "item": "minecraft:smooth_stone_slab" - } + "/": "#c:rods/wooden", + "_": "minecraft:smooth_stone_slab" }, "pattern": [ "///", diff --git a/src/generated/resources/data/minecraft/recipe/arrow.json b/src/generated/resources/data/minecraft/recipe/arrow.json index 5b160e1c5a..8948fda6f2 100644 --- a/src/generated/resources/data/minecraft/recipe/arrow.json +++ b/src/generated/resources/data/minecraft/recipe/arrow.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "item": "minecraft:flint" - }, - "Y": { - "item": "minecraft:feather" - } + "#": "#c:rods/wooden", + "X": "minecraft:flint", + "Y": "minecraft:feather" }, "pattern": [ "X", diff --git a/src/generated/resources/data/minecraft/recipe/bamboo_chest_raft.json b/src/generated/resources/data/minecraft/recipe/bamboo_chest_raft.json index a26be3e5ca..0b97b7f4cf 100644 --- a/src/generated/resources/data/minecraft/recipe/bamboo_chest_raft.json +++ b/src/generated/resources/data/minecraft/recipe/bamboo_chest_raft.json @@ -4,17 +4,11 @@ "group": "chest_boat", "ingredients": [ { - "type": "neoforge:difference", - "base": { - "tag": "c:chests/wooden" - }, - "subtracted": { - "tag": "c:chests/trapped" - } + "neoforge:ingredient_type": "neoforge:difference", + "base": "#c:chests/wooden", + "subtracted": "#c:chests/trapped" }, - { - "item": "minecraft:bamboo_raft" - } + "minecraft:bamboo_raft" ], "result": { "count": 1, diff --git a/src/generated/resources/data/minecraft/recipe/bamboo_fence.json b/src/generated/resources/data/minecraft/recipe/bamboo_fence.json index 190c83b690..d36413016a 100644 --- a/src/generated/resources/data/minecraft/recipe/bamboo_fence.json +++ b/src/generated/resources/data/minecraft/recipe/bamboo_fence.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_fence", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:bamboo_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:bamboo_planks" }, "pattern": [ "W#W", diff --git a/src/generated/resources/data/minecraft/recipe/bamboo_fence_gate.json b/src/generated/resources/data/minecraft/recipe/bamboo_fence_gate.json index 1d2e0f107b..444acda7be 100644 --- a/src/generated/resources/data/minecraft/recipe/bamboo_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/bamboo_fence_gate.json @@ -3,12 +3,8 @@ "category": "redstone", "group": "wooden_fence_gate", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:bamboo_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:bamboo_planks" }, "pattern": [ "#W#", diff --git a/src/generated/resources/data/minecraft/recipe/bamboo_sign.json b/src/generated/resources/data/minecraft/recipe/bamboo_sign.json index 2ea528857f..79d256d984 100644 --- a/src/generated/resources/data/minecraft/recipe/bamboo_sign.json +++ b/src/generated/resources/data/minecraft/recipe/bamboo_sign.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_sign", "key": { - "#": { - "item": "minecraft:bamboo_planks" - }, - "X": { - "tag": "c:rods/wooden" - } + "#": "minecraft:bamboo_planks", + "X": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/birch_chest_boat.json b/src/generated/resources/data/minecraft/recipe/birch_chest_boat.json index 92de5a6d41..3043b2193a 100644 --- a/src/generated/resources/data/minecraft/recipe/birch_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/birch_chest_boat.json @@ -4,17 +4,11 @@ "group": "chest_boat", "ingredients": [ { - "type": "neoforge:difference", - "base": { - "tag": "c:chests/wooden" - }, - "subtracted": { - "tag": "c:chests/trapped" - } + "neoforge:ingredient_type": "neoforge:difference", + "base": "#c:chests/wooden", + "subtracted": "#c:chests/trapped" }, - { - "item": "minecraft:birch_boat" - } + "minecraft:birch_boat" ], "result": { "count": 1, diff --git a/src/generated/resources/data/minecraft/recipe/birch_fence.json b/src/generated/resources/data/minecraft/recipe/birch_fence.json index fef03a747d..f340e905c3 100644 --- a/src/generated/resources/data/minecraft/recipe/birch_fence.json +++ b/src/generated/resources/data/minecraft/recipe/birch_fence.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_fence", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:birch_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:birch_planks" }, "pattern": [ "W#W", diff --git a/src/generated/resources/data/minecraft/recipe/birch_fence_gate.json b/src/generated/resources/data/minecraft/recipe/birch_fence_gate.json index c0f380a750..55e6c5133a 100644 --- a/src/generated/resources/data/minecraft/recipe/birch_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/birch_fence_gate.json @@ -3,12 +3,8 @@ "category": "redstone", "group": "wooden_fence_gate", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:birch_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:birch_planks" }, "pattern": [ "#W#", diff --git a/src/generated/resources/data/minecraft/recipe/birch_sign.json b/src/generated/resources/data/minecraft/recipe/birch_sign.json index c7a1c36a77..94b286ed75 100644 --- a/src/generated/resources/data/minecraft/recipe/birch_sign.json +++ b/src/generated/resources/data/minecraft/recipe/birch_sign.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_sign", "key": { - "#": { - "item": "minecraft:birch_planks" - }, - "X": { - "tag": "c:rods/wooden" - } + "#": "minecraft:birch_planks", + "X": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/black_banner.json b/src/generated/resources/data/minecraft/recipe/black_banner.json index 26cb29a877..7f67600216 100644 --- a/src/generated/resources/data/minecraft/recipe/black_banner.json +++ b/src/generated/resources/data/minecraft/recipe/black_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:black_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:black_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/black_candle.json b/src/generated/resources/data/minecraft/recipe/black_candle.json new file mode 100644 index 0000000000..5d54b78d10 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/black_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/black" + ], + "result": { + "count": 1, + "id": "minecraft:black_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/black_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/black_concrete_powder.json new file mode 100644 index 0000000000..1028880277 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/black_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/black", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:black_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/black_stained_glass.json b/src/generated/resources/data/minecraft/recipe/black_stained_glass.json new file mode 100644 index 0000000000..4373c79565 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/black_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/black" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:black_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/black_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/black_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..68ad84bb87 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/black_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/black" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:black_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/black_terracotta.json b/src/generated/resources/data/minecraft/recipe/black_terracotta.json new file mode 100644 index 0000000000..8dcb00446e --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/black_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/black" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:black_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/blast_furnace.json b/src/generated/resources/data/minecraft/recipe/blast_furnace.json index 6b73dce306..eb2c292aac 100644 --- a/src/generated/resources/data/minecraft/recipe/blast_furnace.json +++ b/src/generated/resources/data/minecraft/recipe/blast_furnace.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "item": "minecraft:smooth_stone" - }, - "I": { - "tag": "c:ingots/iron" - }, - "X": { - "item": "minecraft:furnace" - } + "#": "minecraft:smooth_stone", + "I": "#c:ingots/iron", + "X": "minecraft:furnace" }, "pattern": [ "III", diff --git a/src/generated/resources/data/minecraft/recipe/blue_banner.json b/src/generated/resources/data/minecraft/recipe/blue_banner.json index afb3cddb99..a98940c6b1 100644 --- a/src/generated/resources/data/minecraft/recipe/blue_banner.json +++ b/src/generated/resources/data/minecraft/recipe/blue_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:blue_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:blue_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/blue_candle.json b/src/generated/resources/data/minecraft/recipe/blue_candle.json new file mode 100644 index 0000000000..34f5806015 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/blue_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/blue" + ], + "result": { + "count": 1, + "id": "minecraft:blue_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/blue_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/blue_concrete_powder.json new file mode 100644 index 0000000000..0c04ee5a59 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/blue_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/blue", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:blue_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/blue_stained_glass.json b/src/generated/resources/data/minecraft/recipe/blue_stained_glass.json new file mode 100644 index 0000000000..d58eff4d56 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/blue_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/blue" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:blue_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/blue_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/blue_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..02431bf00f --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/blue_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/blue" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:blue_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/blue_terracotta.json b/src/generated/resources/data/minecraft/recipe/blue_terracotta.json new file mode 100644 index 0000000000..58d3ee058c --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/blue_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/blue" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:blue_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/bolt_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/bolt_armor_trim_smithing_template.json index c7dcf7ebff..e5db16797d 100644 --- a/src/generated/resources/data/minecraft/recipe/bolt_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/bolt_armor_trim_smithing_template.json @@ -2,20 +2,12 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, + "#": "#c:gems/diamond", "C": [ - { - "item": "minecraft:copper_block" - }, - { - "item": "minecraft:waxed_copper_block" - } + "minecraft:copper_block", + "minecraft:waxed_copper_block" ], - "S": { - "item": "minecraft:bolt_armor_trim_smithing_template" - } + "S": "minecraft:bolt_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/bow.json b/src/generated/resources/data/minecraft/recipe/bow.json index b531f496f4..5831fc36f1 100644 --- a/src/generated/resources/data/minecraft/recipe/bow.json +++ b/src/generated/resources/data/minecraft/recipe/bow.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:strings" - } + "#": "#c:rods/wooden", + "X": "#c:strings" }, "pattern": [ " #X", diff --git a/src/generated/resources/data/minecraft/recipe/brown_banner.json b/src/generated/resources/data/minecraft/recipe/brown_banner.json index b3b8c24a19..5394a3d33c 100644 --- a/src/generated/resources/data/minecraft/recipe/brown_banner.json +++ b/src/generated/resources/data/minecraft/recipe/brown_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:brown_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:brown_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/brown_candle.json b/src/generated/resources/data/minecraft/recipe/brown_candle.json new file mode 100644 index 0000000000..730b80253d --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/brown_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/brown" + ], + "result": { + "count": 1, + "id": "minecraft:brown_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/brown_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/brown_concrete_powder.json new file mode 100644 index 0000000000..32a7ffd0b3 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/brown_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/brown", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:brown_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/brown_stained_glass.json b/src/generated/resources/data/minecraft/recipe/brown_stained_glass.json new file mode 100644 index 0000000000..a74be3067e --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/brown_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/brown" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:brown_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/brown_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/brown_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..0ab288f7b7 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/brown_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/brown" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:brown_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/brown_terracotta.json b/src/generated/resources/data/minecraft/recipe/brown_terracotta.json new file mode 100644 index 0000000000..1447b2e5fa --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/brown_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/brown" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:brown_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/brush.json b/src/generated/resources/data/minecraft/recipe/brush.json index ff366537c6..4fc5863cee 100644 --- a/src/generated/resources/data/minecraft/recipe/brush.json +++ b/src/generated/resources/data/minecraft/recipe/brush.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:ingots/copper" - }, - "I": { - "tag": "c:rods/wooden" - }, - "X": { - "item": "minecraft:feather" - } + "#": "#c:ingots/copper", + "I": "#c:rods/wooden", + "X": "minecraft:feather" }, "pattern": [ "X", diff --git a/src/generated/resources/data/minecraft/recipe/bucket.json b/src/generated/resources/data/minecraft/recipe/bucket.json index 6da8ba3ded..692ea8b728 100644 --- a/src/generated/resources/data/minecraft/recipe/bucket.json +++ b/src/generated/resources/data/minecraft/recipe/bucket.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:ingots/iron" - } + "#": "#c:ingots/iron" }, "pattern": [ "# #", diff --git a/src/generated/resources/data/minecraft/recipe/bundle.json b/src/generated/resources/data/minecraft/recipe/bundle.json new file mode 100644 index 0000000000..fb9cad8657 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/bundle.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "equipment", + "key": { + "#": "minecraft:leather", + "-": "#c:strings" + }, + "pattern": [ + "-", + "#" + ], + "result": { + "count": 1, + "id": "minecraft:bundle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/calibrated_sculk_sensor.json b/src/generated/resources/data/minecraft/recipe/calibrated_sculk_sensor.json index 5cb919ad6c..7b748c17a2 100644 --- a/src/generated/resources/data/minecraft/recipe/calibrated_sculk_sensor.json +++ b/src/generated/resources/data/minecraft/recipe/calibrated_sculk_sensor.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "c:gems/amethyst" - }, - "X": { - "item": "minecraft:sculk_sensor" - } + "#": "#c:gems/amethyst", + "X": "minecraft:sculk_sensor" }, "pattern": [ " # ", diff --git a/src/generated/resources/data/minecraft/recipe/campfire.json b/src/generated/resources/data/minecraft/recipe/campfire.json index de8dffe49a..fd2f337523 100644 --- a/src/generated/resources/data/minecraft/recipe/campfire.json +++ b/src/generated/resources/data/minecraft/recipe/campfire.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "C": { - "tag": "minecraft:coals" - }, - "L": { - "tag": "minecraft:logs" - }, - "S": { - "tag": "c:rods/wooden" - } + "C": "#minecraft:coals", + "L": "#minecraft:logs", + "S": "#c:rods/wooden" }, "pattern": [ " S ", diff --git a/src/generated/resources/data/minecraft/recipe/candle.json b/src/generated/resources/data/minecraft/recipe/candle.json index c19d2b0e7b..6cb6864e6b 100644 --- a/src/generated/resources/data/minecraft/recipe/candle.json +++ b/src/generated/resources/data/minecraft/recipe/candle.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "H": { - "item": "minecraft:honeycomb" - }, - "S": { - "tag": "c:strings" - } + "H": "minecraft:honeycomb", + "S": "#c:strings" }, "pattern": [ "S", diff --git a/src/generated/resources/data/minecraft/recipe/cauldron.json b/src/generated/resources/data/minecraft/recipe/cauldron.json index 9fbb8b5af2..101a0b54d6 100644 --- a/src/generated/resources/data/minecraft/recipe/cauldron.json +++ b/src/generated/resources/data/minecraft/recipe/cauldron.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:ingots/iron" - } + "#": "#c:ingots/iron" }, "pattern": [ "# #", diff --git a/src/generated/resources/data/minecraft/recipe/chain.json b/src/generated/resources/data/minecraft/recipe/chain.json index 057c9304ce..5e16cbe16e 100644 --- a/src/generated/resources/data/minecraft/recipe/chain.json +++ b/src/generated/resources/data/minecraft/recipe/chain.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "I": { - "tag": "c:ingots/iron" - }, - "N": { - "tag": "c:nuggets/iron" - } + "I": "#c:ingots/iron", + "N": "#c:nuggets/iron" }, "pattern": [ "N", diff --git a/src/generated/resources/data/minecraft/recipe/cherry_chest_boat.json b/src/generated/resources/data/minecraft/recipe/cherry_chest_boat.json index c5806df844..1a6fb591c0 100644 --- a/src/generated/resources/data/minecraft/recipe/cherry_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/cherry_chest_boat.json @@ -4,17 +4,11 @@ "group": "chest_boat", "ingredients": [ { - "type": "neoforge:difference", - "base": { - "tag": "c:chests/wooden" - }, - "subtracted": { - "tag": "c:chests/trapped" - } + "neoforge:ingredient_type": "neoforge:difference", + "base": "#c:chests/wooden", + "subtracted": "#c:chests/trapped" }, - { - "item": "minecraft:cherry_boat" - } + "minecraft:cherry_boat" ], "result": { "count": 1, diff --git a/src/generated/resources/data/minecraft/recipe/cherry_fence.json b/src/generated/resources/data/minecraft/recipe/cherry_fence.json index c199386881..9866480fe0 100644 --- a/src/generated/resources/data/minecraft/recipe/cherry_fence.json +++ b/src/generated/resources/data/minecraft/recipe/cherry_fence.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_fence", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:cherry_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:cherry_planks" }, "pattern": [ "W#W", diff --git a/src/generated/resources/data/minecraft/recipe/cherry_fence_gate.json b/src/generated/resources/data/minecraft/recipe/cherry_fence_gate.json index d3f7509557..7ad275d012 100644 --- a/src/generated/resources/data/minecraft/recipe/cherry_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/cherry_fence_gate.json @@ -3,12 +3,8 @@ "category": "redstone", "group": "wooden_fence_gate", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:cherry_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:cherry_planks" }, "pattern": [ "#W#", diff --git a/src/generated/resources/data/minecraft/recipe/cherry_sign.json b/src/generated/resources/data/minecraft/recipe/cherry_sign.json index fbd15b6ef9..000659bd4a 100644 --- a/src/generated/resources/data/minecraft/recipe/cherry_sign.json +++ b/src/generated/resources/data/minecraft/recipe/cherry_sign.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_sign", "key": { - "#": { - "item": "minecraft:cherry_planks" - }, - "X": { - "tag": "c:rods/wooden" - } + "#": "minecraft:cherry_planks", + "X": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/chest_minecart.json b/src/generated/resources/data/minecraft/recipe/chest_minecart.json index 160f781384..961f895291 100644 --- a/src/generated/resources/data/minecraft/recipe/chest_minecart.json +++ b/src/generated/resources/data/minecraft/recipe/chest_minecart.json @@ -3,17 +3,11 @@ "category": "misc", "ingredients": [ { - "type": "neoforge:difference", - "base": { - "tag": "c:chests/wooden" - }, - "subtracted": { - "tag": "c:chests/trapped" - } + "neoforge:ingredient_type": "neoforge:difference", + "base": "#c:chests/wooden", + "subtracted": "#c:chests/trapped" }, - { - "item": "minecraft:minecart" - } + "minecraft:minecart" ], "result": { "count": 1, diff --git a/src/generated/resources/data/minecraft/recipe/clock.json b/src/generated/resources/data/minecraft/recipe/clock.json index 276fe557ef..0ffa5dfe00 100644 --- a/src/generated/resources/data/minecraft/recipe/clock.json +++ b/src/generated/resources/data/minecraft/recipe/clock.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:ingots/gold" - }, - "X": { - "item": "minecraft:redstone" - } + "#": "#c:ingots/gold", + "X": "minecraft:redstone" }, "pattern": [ " # ", diff --git a/src/generated/resources/data/minecraft/recipe/coast_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/coast_armor_trim_smithing_template.json index b507e536a1..91af5fbabf 100644 --- a/src/generated/resources/data/minecraft/recipe/coast_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/coast_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "tag": "c:cobblestones/normal" - }, - "S": { - "item": "minecraft:coast_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "#c:cobblestones/normal", + "S": "minecraft:coast_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/compass.json b/src/generated/resources/data/minecraft/recipe/compass.json index 3c7cbcb015..89310bdf95 100644 --- a/src/generated/resources/data/minecraft/recipe/compass.json +++ b/src/generated/resources/data/minecraft/recipe/compass.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:ingots/iron" - }, - "X": { - "item": "minecraft:redstone" - } + "#": "#c:ingots/iron", + "X": "minecraft:redstone" }, "pattern": [ " # ", diff --git a/src/generated/resources/data/minecraft/recipe/copper_door.json b/src/generated/resources/data/minecraft/recipe/copper_door.json index b4010399b8..544440c5c7 100644 --- a/src/generated/resources/data/minecraft/recipe/copper_door.json +++ b/src/generated/resources/data/minecraft/recipe/copper_door.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "c:ingots/copper" - } + "#": "#c:ingots/copper" }, "pattern": [ "##", diff --git a/src/generated/resources/data/minecraft/recipe/copper_trapdoor.json b/src/generated/resources/data/minecraft/recipe/copper_trapdoor.json index 2e8d8efe09..2a117e7c5b 100644 --- a/src/generated/resources/data/minecraft/recipe/copper_trapdoor.json +++ b/src/generated/resources/data/minecraft/recipe/copper_trapdoor.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "c:ingots/copper" - } + "#": "#c:ingots/copper" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/crafter.json b/src/generated/resources/data/minecraft/recipe/crafter.json index b01e9c2509..8db88e0466 100644 --- a/src/generated/resources/data/minecraft/recipe/crafter.json +++ b/src/generated/resources/data/minecraft/recipe/crafter.json @@ -2,18 +2,10 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "c:ingots/iron" - }, - "C": { - "item": "minecraft:crafting_table" - }, - "D": { - "item": "minecraft:dropper" - }, - "R": { - "item": "minecraft:redstone" - } + "#": "#c:ingots/iron", + "C": "minecraft:crafting_table", + "D": "minecraft:dropper", + "R": "minecraft:redstone" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/crimson_fence.json b/src/generated/resources/data/minecraft/recipe/crimson_fence.json index 7b9e174282..20e9d8a6e3 100644 --- a/src/generated/resources/data/minecraft/recipe/crimson_fence.json +++ b/src/generated/resources/data/minecraft/recipe/crimson_fence.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_fence", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:crimson_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:crimson_planks" }, "pattern": [ "W#W", diff --git a/src/generated/resources/data/minecraft/recipe/crimson_fence_gate.json b/src/generated/resources/data/minecraft/recipe/crimson_fence_gate.json index 6953799156..fdbdfa0f4b 100644 --- a/src/generated/resources/data/minecraft/recipe/crimson_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/crimson_fence_gate.json @@ -3,12 +3,8 @@ "category": "redstone", "group": "wooden_fence_gate", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:crimson_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:crimson_planks" }, "pattern": [ "#W#", diff --git a/src/generated/resources/data/minecraft/recipe/crimson_sign.json b/src/generated/resources/data/minecraft/recipe/crimson_sign.json index 3bb6d2cd40..b175242019 100644 --- a/src/generated/resources/data/minecraft/recipe/crimson_sign.json +++ b/src/generated/resources/data/minecraft/recipe/crimson_sign.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_sign", "key": { - "#": { - "item": "minecraft:crimson_planks" - }, - "X": { - "tag": "c:rods/wooden" - } + "#": "minecraft:crimson_planks", + "X": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/crossbow.json b/src/generated/resources/data/minecraft/recipe/crossbow.json index 87d3fb5baf..96364225e1 100644 --- a/src/generated/resources/data/minecraft/recipe/crossbow.json +++ b/src/generated/resources/data/minecraft/recipe/crossbow.json @@ -2,18 +2,10 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "$": { - "item": "minecraft:tripwire_hook" - }, - "&": { - "tag": "c:ingots/iron" - }, - "~": { - "tag": "c:strings" - } + "#": "#c:rods/wooden", + "$": "minecraft:tripwire_hook", + "&": "#c:ingots/iron", + "~": "#c:strings" }, "pattern": [ "#&#", diff --git a/src/generated/resources/data/minecraft/recipe/cyan_banner.json b/src/generated/resources/data/minecraft/recipe/cyan_banner.json index 7c029672c6..2efc2367e5 100644 --- a/src/generated/resources/data/minecraft/recipe/cyan_banner.json +++ b/src/generated/resources/data/minecraft/recipe/cyan_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:cyan_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:cyan_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/cyan_candle.json b/src/generated/resources/data/minecraft/recipe/cyan_candle.json new file mode 100644 index 0000000000..50c38c52c7 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/cyan_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/cyan" + ], + "result": { + "count": 1, + "id": "minecraft:cyan_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/cyan_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/cyan_concrete_powder.json new file mode 100644 index 0000000000..376392655e --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/cyan_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/cyan", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:cyan_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/cyan_dye.json b/src/generated/resources/data/minecraft/recipe/cyan_dye.json new file mode 100644 index 0000000000..da65344e0d --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/cyan_dye.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "cyan_dye", + "ingredients": [ + "#c:dyes/blue", + "#c:dyes/green" + ], + "result": { + "count": 2, + "id": "minecraft:cyan_dye" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/cyan_stained_glass.json b/src/generated/resources/data/minecraft/recipe/cyan_stained_glass.json new file mode 100644 index 0000000000..a7981f9ac7 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/cyan_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/cyan" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:cyan_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/cyan_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/cyan_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..007546af61 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/cyan_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/cyan" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:cyan_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/cyan_terracotta.json b/src/generated/resources/data/minecraft/recipe/cyan_terracotta.json new file mode 100644 index 0000000000..ed9858a7f6 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/cyan_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/cyan" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:cyan_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dark_oak_chest_boat.json b/src/generated/resources/data/minecraft/recipe/dark_oak_chest_boat.json index 8396336c72..e7dd8b53d2 100644 --- a/src/generated/resources/data/minecraft/recipe/dark_oak_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/dark_oak_chest_boat.json @@ -4,17 +4,11 @@ "group": "chest_boat", "ingredients": [ { - "type": "neoforge:difference", - "base": { - "tag": "c:chests/wooden" - }, - "subtracted": { - "tag": "c:chests/trapped" - } + "neoforge:ingredient_type": "neoforge:difference", + "base": "#c:chests/wooden", + "subtracted": "#c:chests/trapped" }, - { - "item": "minecraft:dark_oak_boat" - } + "minecraft:dark_oak_boat" ], "result": { "count": 1, diff --git a/src/generated/resources/data/minecraft/recipe/dark_oak_fence.json b/src/generated/resources/data/minecraft/recipe/dark_oak_fence.json index ba37e3f888..d5c3933be8 100644 --- a/src/generated/resources/data/minecraft/recipe/dark_oak_fence.json +++ b/src/generated/resources/data/minecraft/recipe/dark_oak_fence.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_fence", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:dark_oak_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:dark_oak_planks" }, "pattern": [ "W#W", diff --git a/src/generated/resources/data/minecraft/recipe/dark_oak_fence_gate.json b/src/generated/resources/data/minecraft/recipe/dark_oak_fence_gate.json index b8365d4a28..d7db1861f2 100644 --- a/src/generated/resources/data/minecraft/recipe/dark_oak_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/dark_oak_fence_gate.json @@ -3,12 +3,8 @@ "category": "redstone", "group": "wooden_fence_gate", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:dark_oak_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:dark_oak_planks" }, "pattern": [ "#W#", diff --git a/src/generated/resources/data/minecraft/recipe/dark_oak_sign.json b/src/generated/resources/data/minecraft/recipe/dark_oak_sign.json index 4d53a6d24f..aeb6ace8bf 100644 --- a/src/generated/resources/data/minecraft/recipe/dark_oak_sign.json +++ b/src/generated/resources/data/minecraft/recipe/dark_oak_sign.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_sign", "key": { - "#": { - "item": "minecraft:dark_oak_planks" - }, - "X": { - "tag": "c:rods/wooden" - } + "#": "minecraft:dark_oak_planks", + "X": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/dark_prismarine.json b/src/generated/resources/data/minecraft/recipe/dark_prismarine.json new file mode 100644 index 0000000000..c81c46bf21 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dark_prismarine.json @@ -0,0 +1,17 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "key": { + "I": "#c:dyes/black", + "S": "minecraft:prismarine_shard" + }, + "pattern": [ + "SSS", + "SIS", + "SSS" + ], + "result": { + "count": 1, + "id": "minecraft:dark_prismarine" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/detector_rail.json b/src/generated/resources/data/minecraft/recipe/detector_rail.json index 97238ca6e4..aa0d8b1f83 100644 --- a/src/generated/resources/data/minecraft/recipe/detector_rail.json +++ b/src/generated/resources/data/minecraft/recipe/detector_rail.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "item": "minecraft:stone_pressure_plate" - }, - "R": { - "item": "minecraft:redstone" - }, - "X": { - "tag": "c:ingots/iron" - } + "#": "minecraft:stone_pressure_plate", + "R": "minecraft:redstone", + "X": "#c:ingots/iron" }, "pattern": [ "X X", diff --git a/src/generated/resources/data/minecraft/recipe/diamond_axe.json b/src/generated/resources/data/minecraft/recipe/diamond_axe.json index 118f99e563..81cfd04879 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_axe.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_axe.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:gems/diamond" - } + "#": "#c:rods/wooden", + "X": "#minecraft:diamond_tool_materials" }, "pattern": [ "XX", diff --git a/src/generated/resources/data/minecraft/recipe/diamond_boots.json b/src/generated/resources/data/minecraft/recipe/diamond_boots.json index 7d6ace85e7..38ea7f8e5d 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_boots.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_boots.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "X": { - "tag": "c:gems/diamond" - } + "X": "#c:gems/diamond" }, "pattern": [ "X X", diff --git a/src/generated/resources/data/minecraft/recipe/diamond_chestplate.json b/src/generated/resources/data/minecraft/recipe/diamond_chestplate.json index 46ad865dff..bace9a7d21 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_chestplate.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_chestplate.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "X": { - "tag": "c:gems/diamond" - } + "X": "#c:gems/diamond" }, "pattern": [ "X X", diff --git a/src/generated/resources/data/minecraft/recipe/diamond_helmet.json b/src/generated/resources/data/minecraft/recipe/diamond_helmet.json index 50a88a0967..59067194a0 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_helmet.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_helmet.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "X": { - "tag": "c:gems/diamond" - } + "X": "#c:gems/diamond" }, "pattern": [ "XXX", diff --git a/src/generated/resources/data/minecraft/recipe/diamond_hoe.json b/src/generated/resources/data/minecraft/recipe/diamond_hoe.json index b2bf02dd07..6a770c0452 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_hoe.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_hoe.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:gems/diamond" - } + "#": "#c:rods/wooden", + "X": "#minecraft:diamond_tool_materials" }, "pattern": [ "XX", diff --git a/src/generated/resources/data/minecraft/recipe/diamond_leggings.json b/src/generated/resources/data/minecraft/recipe/diamond_leggings.json index 5df5635836..7992a0d478 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_leggings.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_leggings.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "X": { - "tag": "c:gems/diamond" - } + "X": "#c:gems/diamond" }, "pattern": [ "XXX", diff --git a/src/generated/resources/data/minecraft/recipe/diamond_pickaxe.json b/src/generated/resources/data/minecraft/recipe/diamond_pickaxe.json index 3397993a01..bc06ce4af1 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_pickaxe.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_pickaxe.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:gems/diamond" - } + "#": "#c:rods/wooden", + "X": "#minecraft:diamond_tool_materials" }, "pattern": [ "XXX", diff --git a/src/generated/resources/data/minecraft/recipe/diamond_shovel.json b/src/generated/resources/data/minecraft/recipe/diamond_shovel.json index ae4f9eb985..ff947a6fd7 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_shovel.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_shovel.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:gems/diamond" - } + "#": "#c:rods/wooden", + "X": "#minecraft:diamond_tool_materials" }, "pattern": [ "X", diff --git a/src/generated/resources/data/minecraft/recipe/diamond_sword.json b/src/generated/resources/data/minecraft/recipe/diamond_sword.json index 338ca63240..cb872879e7 100644 --- a/src/generated/resources/data/minecraft/recipe/diamond_sword.json +++ b/src/generated/resources/data/minecraft/recipe/diamond_sword.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:gems/diamond" - } + "#": "#c:rods/wooden", + "X": "#minecraft:diamond_tool_materials" }, "pattern": [ "X", diff --git a/src/generated/resources/data/minecraft/recipe/diorite.json b/src/generated/resources/data/minecraft/recipe/diorite.json index 54714b8f40..35427a7339 100644 --- a/src/generated/resources/data/minecraft/recipe/diorite.json +++ b/src/generated/resources/data/minecraft/recipe/diorite.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "building", "key": { - "C": { - "tag": "c:cobblestones/normal" - }, - "Q": { - "item": "minecraft:quartz" - } + "C": "#c:cobblestones/normal", + "Q": "minecraft:quartz" }, "pattern": [ "CQ", diff --git a/src/generated/resources/data/minecraft/recipe/dispenser.json b/src/generated/resources/data/minecraft/recipe/dispenser.json index 6ab105c14c..08d2b51f71 100644 --- a/src/generated/resources/data/minecraft/recipe/dispenser.json +++ b/src/generated/resources/data/minecraft/recipe/dispenser.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "c:cobblestones/normal" - }, - "R": { - "item": "minecraft:redstone" - }, - "X": { - "item": "minecraft:bow" - } + "#": "#c:cobblestones/normal", + "R": "minecraft:redstone", + "X": "minecraft:bow" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/dropper.json b/src/generated/resources/data/minecraft/recipe/dropper.json index e358894ca7..a079f7c193 100644 --- a/src/generated/resources/data/minecraft/recipe/dropper.json +++ b/src/generated/resources/data/minecraft/recipe/dropper.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "c:cobblestones/normal" - }, - "R": { - "item": "minecraft:redstone" - } + "#": "#c:cobblestones/normal", + "R": "minecraft:redstone" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/dune_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/dune_armor_trim_smithing_template.json index 905e1f3f0d..a732119fe5 100644 --- a/src/generated/resources/data/minecraft/recipe/dune_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/dune_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "item": "minecraft:sandstone" - }, - "S": { - "item": "minecraft:dune_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "minecraft:sandstone", + "S": "minecraft:dune_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/dye_black_bed.json b/src/generated/resources/data/minecraft/recipe/dye_black_bed.json new file mode 100644 index 0000000000..46ce620b7f --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_black_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/black", + [ + "minecraft:blue_bed", + "minecraft:brown_bed", + "minecraft:cyan_bed", + "minecraft:gray_bed", + "minecraft:green_bed", + "minecraft:light_blue_bed", + "minecraft:light_gray_bed", + "minecraft:lime_bed", + "minecraft:magenta_bed", + "minecraft:orange_bed", + "minecraft:pink_bed", + "minecraft:purple_bed", + "minecraft:red_bed", + "minecraft:yellow_bed", + "minecraft:white_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:black_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_black_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_black_carpet.json new file mode 100644 index 0000000000..24345b7688 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_black_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/black", + [ + "minecraft:blue_carpet", + "minecraft:brown_carpet", + "minecraft:cyan_carpet", + "minecraft:gray_carpet", + "minecraft:green_carpet", + "minecraft:light_blue_carpet", + "minecraft:light_gray_carpet", + "minecraft:lime_carpet", + "minecraft:magenta_carpet", + "minecraft:orange_carpet", + "minecraft:pink_carpet", + "minecraft:purple_carpet", + "minecraft:red_carpet", + "minecraft:yellow_carpet", + "minecraft:white_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:black_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_black_wool.json b/src/generated/resources/data/minecraft/recipe/dye_black_wool.json new file mode 100644 index 0000000000..4b00f9de04 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_black_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/black", + [ + "minecraft:blue_wool", + "minecraft:brown_wool", + "minecraft:cyan_wool", + "minecraft:gray_wool", + "minecraft:green_wool", + "minecraft:light_blue_wool", + "minecraft:light_gray_wool", + "minecraft:lime_wool", + "minecraft:magenta_wool", + "minecraft:orange_wool", + "minecraft:pink_wool", + "minecraft:purple_wool", + "minecraft:red_wool", + "minecraft:yellow_wool", + "minecraft:white_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:black_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_blue_bed.json b/src/generated/resources/data/minecraft/recipe/dye_blue_bed.json new file mode 100644 index 0000000000..1addcaaf89 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_blue_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/blue", + [ + "minecraft:black_bed", + "minecraft:brown_bed", + "minecraft:cyan_bed", + "minecraft:gray_bed", + "minecraft:green_bed", + "minecraft:light_blue_bed", + "minecraft:light_gray_bed", + "minecraft:lime_bed", + "minecraft:magenta_bed", + "minecraft:orange_bed", + "minecraft:pink_bed", + "minecraft:purple_bed", + "minecraft:red_bed", + "minecraft:yellow_bed", + "minecraft:white_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:blue_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_blue_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_blue_carpet.json new file mode 100644 index 0000000000..f936b365bb --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_blue_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/blue", + [ + "minecraft:black_carpet", + "minecraft:brown_carpet", + "minecraft:cyan_carpet", + "minecraft:gray_carpet", + "minecraft:green_carpet", + "minecraft:light_blue_carpet", + "minecraft:light_gray_carpet", + "minecraft:lime_carpet", + "minecraft:magenta_carpet", + "minecraft:orange_carpet", + "minecraft:pink_carpet", + "minecraft:purple_carpet", + "minecraft:red_carpet", + "minecraft:yellow_carpet", + "minecraft:white_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:blue_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_blue_wool.json b/src/generated/resources/data/minecraft/recipe/dye_blue_wool.json new file mode 100644 index 0000000000..1e41106f6c --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_blue_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/blue", + [ + "minecraft:black_wool", + "minecraft:brown_wool", + "minecraft:cyan_wool", + "minecraft:gray_wool", + "minecraft:green_wool", + "minecraft:light_blue_wool", + "minecraft:light_gray_wool", + "minecraft:lime_wool", + "minecraft:magenta_wool", + "minecraft:orange_wool", + "minecraft:pink_wool", + "minecraft:purple_wool", + "minecraft:red_wool", + "minecraft:yellow_wool", + "minecraft:white_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:blue_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_brown_bed.json b/src/generated/resources/data/minecraft/recipe/dye_brown_bed.json new file mode 100644 index 0000000000..acd45c9cd7 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_brown_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/brown", + [ + "minecraft:black_bed", + "minecraft:blue_bed", + "minecraft:cyan_bed", + "minecraft:gray_bed", + "minecraft:green_bed", + "minecraft:light_blue_bed", + "minecraft:light_gray_bed", + "minecraft:lime_bed", + "minecraft:magenta_bed", + "minecraft:orange_bed", + "minecraft:pink_bed", + "minecraft:purple_bed", + "minecraft:red_bed", + "minecraft:yellow_bed", + "minecraft:white_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:brown_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_brown_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_brown_carpet.json new file mode 100644 index 0000000000..40fd195def --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_brown_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/brown", + [ + "minecraft:black_carpet", + "minecraft:blue_carpet", + "minecraft:cyan_carpet", + "minecraft:gray_carpet", + "minecraft:green_carpet", + "minecraft:light_blue_carpet", + "minecraft:light_gray_carpet", + "minecraft:lime_carpet", + "minecraft:magenta_carpet", + "minecraft:orange_carpet", + "minecraft:pink_carpet", + "minecraft:purple_carpet", + "minecraft:red_carpet", + "minecraft:yellow_carpet", + "minecraft:white_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:brown_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_brown_wool.json b/src/generated/resources/data/minecraft/recipe/dye_brown_wool.json new file mode 100644 index 0000000000..ce7255818f --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_brown_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/brown", + [ + "minecraft:black_wool", + "minecraft:blue_wool", + "minecraft:cyan_wool", + "minecraft:gray_wool", + "minecraft:green_wool", + "minecraft:light_blue_wool", + "minecraft:light_gray_wool", + "minecraft:lime_wool", + "minecraft:magenta_wool", + "minecraft:orange_wool", + "minecraft:pink_wool", + "minecraft:purple_wool", + "minecraft:red_wool", + "minecraft:yellow_wool", + "minecraft:white_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:brown_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_cyan_bed.json b/src/generated/resources/data/minecraft/recipe/dye_cyan_bed.json new file mode 100644 index 0000000000..58c42b416a --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_cyan_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/cyan", + [ + "minecraft:black_bed", + "minecraft:blue_bed", + "minecraft:brown_bed", + "minecraft:gray_bed", + "minecraft:green_bed", + "minecraft:light_blue_bed", + "minecraft:light_gray_bed", + "minecraft:lime_bed", + "minecraft:magenta_bed", + "minecraft:orange_bed", + "minecraft:pink_bed", + "minecraft:purple_bed", + "minecraft:red_bed", + "minecraft:yellow_bed", + "minecraft:white_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:cyan_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_cyan_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_cyan_carpet.json new file mode 100644 index 0000000000..d35689356c --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_cyan_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/cyan", + [ + "minecraft:black_carpet", + "minecraft:blue_carpet", + "minecraft:brown_carpet", + "minecraft:gray_carpet", + "minecraft:green_carpet", + "minecraft:light_blue_carpet", + "minecraft:light_gray_carpet", + "minecraft:lime_carpet", + "minecraft:magenta_carpet", + "minecraft:orange_carpet", + "minecraft:pink_carpet", + "minecraft:purple_carpet", + "minecraft:red_carpet", + "minecraft:yellow_carpet", + "minecraft:white_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:cyan_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_cyan_wool.json b/src/generated/resources/data/minecraft/recipe/dye_cyan_wool.json new file mode 100644 index 0000000000..3c6551327f --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_cyan_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/cyan", + [ + "minecraft:black_wool", + "minecraft:blue_wool", + "minecraft:brown_wool", + "minecraft:gray_wool", + "minecraft:green_wool", + "minecraft:light_blue_wool", + "minecraft:light_gray_wool", + "minecraft:lime_wool", + "minecraft:magenta_wool", + "minecraft:orange_wool", + "minecraft:pink_wool", + "minecraft:purple_wool", + "minecraft:red_wool", + "minecraft:yellow_wool", + "minecraft:white_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:cyan_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_gray_bed.json b/src/generated/resources/data/minecraft/recipe/dye_gray_bed.json new file mode 100644 index 0000000000..e65ec79aa5 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_gray_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/gray", + [ + "minecraft:black_bed", + "minecraft:blue_bed", + "minecraft:brown_bed", + "minecraft:cyan_bed", + "minecraft:green_bed", + "minecraft:light_blue_bed", + "minecraft:light_gray_bed", + "minecraft:lime_bed", + "minecraft:magenta_bed", + "minecraft:orange_bed", + "minecraft:pink_bed", + "minecraft:purple_bed", + "minecraft:red_bed", + "minecraft:yellow_bed", + "minecraft:white_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:gray_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_gray_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_gray_carpet.json new file mode 100644 index 0000000000..0c93c78cb5 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_gray_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/gray", + [ + "minecraft:black_carpet", + "minecraft:blue_carpet", + "minecraft:brown_carpet", + "minecraft:cyan_carpet", + "minecraft:green_carpet", + "minecraft:light_blue_carpet", + "minecraft:light_gray_carpet", + "minecraft:lime_carpet", + "minecraft:magenta_carpet", + "minecraft:orange_carpet", + "minecraft:pink_carpet", + "minecraft:purple_carpet", + "minecraft:red_carpet", + "minecraft:yellow_carpet", + "minecraft:white_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:gray_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_gray_wool.json b/src/generated/resources/data/minecraft/recipe/dye_gray_wool.json new file mode 100644 index 0000000000..54b7a841c2 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_gray_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/gray", + [ + "minecraft:black_wool", + "minecraft:blue_wool", + "minecraft:brown_wool", + "minecraft:cyan_wool", + "minecraft:green_wool", + "minecraft:light_blue_wool", + "minecraft:light_gray_wool", + "minecraft:lime_wool", + "minecraft:magenta_wool", + "minecraft:orange_wool", + "minecraft:pink_wool", + "minecraft:purple_wool", + "minecraft:red_wool", + "minecraft:yellow_wool", + "minecraft:white_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:gray_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_green_bed.json b/src/generated/resources/data/minecraft/recipe/dye_green_bed.json new file mode 100644 index 0000000000..d743ad317a --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_green_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/green", + [ + "minecraft:black_bed", + "minecraft:blue_bed", + "minecraft:brown_bed", + "minecraft:cyan_bed", + "minecraft:gray_bed", + "minecraft:light_blue_bed", + "minecraft:light_gray_bed", + "minecraft:lime_bed", + "minecraft:magenta_bed", + "minecraft:orange_bed", + "minecraft:pink_bed", + "minecraft:purple_bed", + "minecraft:red_bed", + "minecraft:yellow_bed", + "minecraft:white_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:green_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_green_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_green_carpet.json new file mode 100644 index 0000000000..575f6b4ef6 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_green_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/green", + [ + "minecraft:black_carpet", + "minecraft:blue_carpet", + "minecraft:brown_carpet", + "minecraft:cyan_carpet", + "minecraft:gray_carpet", + "minecraft:light_blue_carpet", + "minecraft:light_gray_carpet", + "minecraft:lime_carpet", + "minecraft:magenta_carpet", + "minecraft:orange_carpet", + "minecraft:pink_carpet", + "minecraft:purple_carpet", + "minecraft:red_carpet", + "minecraft:yellow_carpet", + "minecraft:white_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:green_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_green_wool.json b/src/generated/resources/data/minecraft/recipe/dye_green_wool.json new file mode 100644 index 0000000000..63e86df341 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_green_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/green", + [ + "minecraft:black_wool", + "minecraft:blue_wool", + "minecraft:brown_wool", + "minecraft:cyan_wool", + "minecraft:gray_wool", + "minecraft:light_blue_wool", + "minecraft:light_gray_wool", + "minecraft:lime_wool", + "minecraft:magenta_wool", + "minecraft:orange_wool", + "minecraft:pink_wool", + "minecraft:purple_wool", + "minecraft:red_wool", + "minecraft:yellow_wool", + "minecraft:white_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:green_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_light_blue_bed.json b/src/generated/resources/data/minecraft/recipe/dye_light_blue_bed.json new file mode 100644 index 0000000000..fd5df881e0 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_light_blue_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/light_blue", + [ + "minecraft:black_bed", + "minecraft:blue_bed", + "minecraft:brown_bed", + "minecraft:cyan_bed", + "minecraft:gray_bed", + "minecraft:green_bed", + "minecraft:light_gray_bed", + "minecraft:lime_bed", + "minecraft:magenta_bed", + "minecraft:orange_bed", + "minecraft:pink_bed", + "minecraft:purple_bed", + "minecraft:red_bed", + "minecraft:yellow_bed", + "minecraft:white_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:light_blue_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_light_blue_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_light_blue_carpet.json new file mode 100644 index 0000000000..b9f92de4d2 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_light_blue_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/light_blue", + [ + "minecraft:black_carpet", + "minecraft:blue_carpet", + "minecraft:brown_carpet", + "minecraft:cyan_carpet", + "minecraft:gray_carpet", + "minecraft:green_carpet", + "minecraft:light_gray_carpet", + "minecraft:lime_carpet", + "minecraft:magenta_carpet", + "minecraft:orange_carpet", + "minecraft:pink_carpet", + "minecraft:purple_carpet", + "minecraft:red_carpet", + "minecraft:yellow_carpet", + "minecraft:white_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:light_blue_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_light_blue_wool.json b/src/generated/resources/data/minecraft/recipe/dye_light_blue_wool.json new file mode 100644 index 0000000000..9c97901ec9 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_light_blue_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/light_blue", + [ + "minecraft:black_wool", + "minecraft:blue_wool", + "minecraft:brown_wool", + "minecraft:cyan_wool", + "minecraft:gray_wool", + "minecraft:green_wool", + "minecraft:light_gray_wool", + "minecraft:lime_wool", + "minecraft:magenta_wool", + "minecraft:orange_wool", + "minecraft:pink_wool", + "minecraft:purple_wool", + "minecraft:red_wool", + "minecraft:yellow_wool", + "minecraft:white_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:light_blue_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_light_gray_bed.json b/src/generated/resources/data/minecraft/recipe/dye_light_gray_bed.json new file mode 100644 index 0000000000..9a859ed12f --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_light_gray_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/light_gray", + [ + "minecraft:black_bed", + "minecraft:blue_bed", + "minecraft:brown_bed", + "minecraft:cyan_bed", + "minecraft:gray_bed", + "minecraft:green_bed", + "minecraft:light_blue_bed", + "minecraft:lime_bed", + "minecraft:magenta_bed", + "minecraft:orange_bed", + "minecraft:pink_bed", + "minecraft:purple_bed", + "minecraft:red_bed", + "minecraft:yellow_bed", + "minecraft:white_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:light_gray_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_light_gray_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_light_gray_carpet.json new file mode 100644 index 0000000000..f0d0c19aab --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_light_gray_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/light_gray", + [ + "minecraft:black_carpet", + "minecraft:blue_carpet", + "minecraft:brown_carpet", + "minecraft:cyan_carpet", + "minecraft:gray_carpet", + "minecraft:green_carpet", + "minecraft:light_blue_carpet", + "minecraft:lime_carpet", + "minecraft:magenta_carpet", + "minecraft:orange_carpet", + "minecraft:pink_carpet", + "minecraft:purple_carpet", + "minecraft:red_carpet", + "minecraft:yellow_carpet", + "minecraft:white_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:light_gray_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_light_gray_wool.json b/src/generated/resources/data/minecraft/recipe/dye_light_gray_wool.json new file mode 100644 index 0000000000..701df4f96e --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_light_gray_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/light_gray", + [ + "minecraft:black_wool", + "minecraft:blue_wool", + "minecraft:brown_wool", + "minecraft:cyan_wool", + "minecraft:gray_wool", + "minecraft:green_wool", + "minecraft:light_blue_wool", + "minecraft:lime_wool", + "minecraft:magenta_wool", + "minecraft:orange_wool", + "minecraft:pink_wool", + "minecraft:purple_wool", + "minecraft:red_wool", + "minecraft:yellow_wool", + "minecraft:white_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:light_gray_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_lime_bed.json b/src/generated/resources/data/minecraft/recipe/dye_lime_bed.json new file mode 100644 index 0000000000..af4ec42f52 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_lime_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/lime", + [ + "minecraft:black_bed", + "minecraft:blue_bed", + "minecraft:brown_bed", + "minecraft:cyan_bed", + "minecraft:gray_bed", + "minecraft:green_bed", + "minecraft:light_blue_bed", + "minecraft:light_gray_bed", + "minecraft:magenta_bed", + "minecraft:orange_bed", + "minecraft:pink_bed", + "minecraft:purple_bed", + "minecraft:red_bed", + "minecraft:yellow_bed", + "minecraft:white_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:lime_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_lime_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_lime_carpet.json new file mode 100644 index 0000000000..4a0a8df0ce --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_lime_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/lime", + [ + "minecraft:black_carpet", + "minecraft:blue_carpet", + "minecraft:brown_carpet", + "minecraft:cyan_carpet", + "minecraft:gray_carpet", + "minecraft:green_carpet", + "minecraft:light_blue_carpet", + "minecraft:light_gray_carpet", + "minecraft:magenta_carpet", + "minecraft:orange_carpet", + "minecraft:pink_carpet", + "minecraft:purple_carpet", + "minecraft:red_carpet", + "minecraft:yellow_carpet", + "minecraft:white_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:lime_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_lime_wool.json b/src/generated/resources/data/minecraft/recipe/dye_lime_wool.json new file mode 100644 index 0000000000..9cfaecd17a --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_lime_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/lime", + [ + "minecraft:black_wool", + "minecraft:blue_wool", + "minecraft:brown_wool", + "minecraft:cyan_wool", + "minecraft:gray_wool", + "minecraft:green_wool", + "minecraft:light_blue_wool", + "minecraft:light_gray_wool", + "minecraft:magenta_wool", + "minecraft:orange_wool", + "minecraft:pink_wool", + "minecraft:purple_wool", + "minecraft:red_wool", + "minecraft:yellow_wool", + "minecraft:white_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:lime_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_magenta_bed.json b/src/generated/resources/data/minecraft/recipe/dye_magenta_bed.json new file mode 100644 index 0000000000..f6683771f7 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_magenta_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/magenta", + [ + "minecraft:black_bed", + "minecraft:blue_bed", + "minecraft:brown_bed", + "minecraft:cyan_bed", + "minecraft:gray_bed", + "minecraft:green_bed", + "minecraft:light_blue_bed", + "minecraft:light_gray_bed", + "minecraft:lime_bed", + "minecraft:orange_bed", + "minecraft:pink_bed", + "minecraft:purple_bed", + "minecraft:red_bed", + "minecraft:yellow_bed", + "minecraft:white_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:magenta_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_magenta_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_magenta_carpet.json new file mode 100644 index 0000000000..7e97162ed4 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_magenta_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/magenta", + [ + "minecraft:black_carpet", + "minecraft:blue_carpet", + "minecraft:brown_carpet", + "minecraft:cyan_carpet", + "minecraft:gray_carpet", + "minecraft:green_carpet", + "minecraft:light_blue_carpet", + "minecraft:light_gray_carpet", + "minecraft:lime_carpet", + "minecraft:orange_carpet", + "minecraft:pink_carpet", + "minecraft:purple_carpet", + "minecraft:red_carpet", + "minecraft:yellow_carpet", + "minecraft:white_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:magenta_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_magenta_wool.json b/src/generated/resources/data/minecraft/recipe/dye_magenta_wool.json new file mode 100644 index 0000000000..b5cb50c8c0 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_magenta_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/magenta", + [ + "minecraft:black_wool", + "minecraft:blue_wool", + "minecraft:brown_wool", + "minecraft:cyan_wool", + "minecraft:gray_wool", + "minecraft:green_wool", + "minecraft:light_blue_wool", + "minecraft:light_gray_wool", + "minecraft:lime_wool", + "minecraft:orange_wool", + "minecraft:pink_wool", + "minecraft:purple_wool", + "minecraft:red_wool", + "minecraft:yellow_wool", + "minecraft:white_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:magenta_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_orange_bed.json b/src/generated/resources/data/minecraft/recipe/dye_orange_bed.json new file mode 100644 index 0000000000..4f051cff93 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_orange_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/orange", + [ + "minecraft:black_bed", + "minecraft:blue_bed", + "minecraft:brown_bed", + "minecraft:cyan_bed", + "minecraft:gray_bed", + "minecraft:green_bed", + "minecraft:light_blue_bed", + "minecraft:light_gray_bed", + "minecraft:lime_bed", + "minecraft:magenta_bed", + "minecraft:pink_bed", + "minecraft:purple_bed", + "minecraft:red_bed", + "minecraft:yellow_bed", + "minecraft:white_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:orange_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_orange_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_orange_carpet.json new file mode 100644 index 0000000000..a4271e5768 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_orange_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/orange", + [ + "minecraft:black_carpet", + "minecraft:blue_carpet", + "minecraft:brown_carpet", + "minecraft:cyan_carpet", + "minecraft:gray_carpet", + "minecraft:green_carpet", + "minecraft:light_blue_carpet", + "minecraft:light_gray_carpet", + "minecraft:lime_carpet", + "minecraft:magenta_carpet", + "minecraft:pink_carpet", + "minecraft:purple_carpet", + "minecraft:red_carpet", + "minecraft:yellow_carpet", + "minecraft:white_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:orange_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_orange_wool.json b/src/generated/resources/data/minecraft/recipe/dye_orange_wool.json new file mode 100644 index 0000000000..0b89a2fe23 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_orange_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/orange", + [ + "minecraft:black_wool", + "minecraft:blue_wool", + "minecraft:brown_wool", + "minecraft:cyan_wool", + "minecraft:gray_wool", + "minecraft:green_wool", + "minecraft:light_blue_wool", + "minecraft:light_gray_wool", + "minecraft:lime_wool", + "minecraft:magenta_wool", + "minecraft:pink_wool", + "minecraft:purple_wool", + "minecraft:red_wool", + "minecraft:yellow_wool", + "minecraft:white_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:orange_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_pink_bed.json b/src/generated/resources/data/minecraft/recipe/dye_pink_bed.json new file mode 100644 index 0000000000..6c59760629 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_pink_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/pink", + [ + "minecraft:black_bed", + "minecraft:blue_bed", + "minecraft:brown_bed", + "minecraft:cyan_bed", + "minecraft:gray_bed", + "minecraft:green_bed", + "minecraft:light_blue_bed", + "minecraft:light_gray_bed", + "minecraft:lime_bed", + "minecraft:magenta_bed", + "minecraft:orange_bed", + "minecraft:purple_bed", + "minecraft:red_bed", + "minecraft:yellow_bed", + "minecraft:white_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:pink_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_pink_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_pink_carpet.json new file mode 100644 index 0000000000..bda90f993c --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_pink_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/pink", + [ + "minecraft:black_carpet", + "minecraft:blue_carpet", + "minecraft:brown_carpet", + "minecraft:cyan_carpet", + "minecraft:gray_carpet", + "minecraft:green_carpet", + "minecraft:light_blue_carpet", + "minecraft:light_gray_carpet", + "minecraft:lime_carpet", + "minecraft:magenta_carpet", + "minecraft:orange_carpet", + "minecraft:purple_carpet", + "minecraft:red_carpet", + "minecraft:yellow_carpet", + "minecraft:white_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:pink_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_pink_wool.json b/src/generated/resources/data/minecraft/recipe/dye_pink_wool.json new file mode 100644 index 0000000000..bb15342a01 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_pink_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/pink", + [ + "minecraft:black_wool", + "minecraft:blue_wool", + "minecraft:brown_wool", + "minecraft:cyan_wool", + "minecraft:gray_wool", + "minecraft:green_wool", + "minecraft:light_blue_wool", + "minecraft:light_gray_wool", + "minecraft:lime_wool", + "minecraft:magenta_wool", + "minecraft:orange_wool", + "minecraft:purple_wool", + "minecraft:red_wool", + "minecraft:yellow_wool", + "minecraft:white_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:pink_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_purple_bed.json b/src/generated/resources/data/minecraft/recipe/dye_purple_bed.json new file mode 100644 index 0000000000..ab9de93037 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_purple_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/purple", + [ + "minecraft:black_bed", + "minecraft:blue_bed", + "minecraft:brown_bed", + "minecraft:cyan_bed", + "minecraft:gray_bed", + "minecraft:green_bed", + "minecraft:light_blue_bed", + "minecraft:light_gray_bed", + "minecraft:lime_bed", + "minecraft:magenta_bed", + "minecraft:orange_bed", + "minecraft:pink_bed", + "minecraft:red_bed", + "minecraft:yellow_bed", + "minecraft:white_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:purple_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_purple_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_purple_carpet.json new file mode 100644 index 0000000000..1c23eee26b --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_purple_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/purple", + [ + "minecraft:black_carpet", + "minecraft:blue_carpet", + "minecraft:brown_carpet", + "minecraft:cyan_carpet", + "minecraft:gray_carpet", + "minecraft:green_carpet", + "minecraft:light_blue_carpet", + "minecraft:light_gray_carpet", + "minecraft:lime_carpet", + "minecraft:magenta_carpet", + "minecraft:orange_carpet", + "minecraft:pink_carpet", + "minecraft:red_carpet", + "minecraft:yellow_carpet", + "minecraft:white_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:purple_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_purple_wool.json b/src/generated/resources/data/minecraft/recipe/dye_purple_wool.json new file mode 100644 index 0000000000..8d26252d27 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_purple_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/purple", + [ + "minecraft:black_wool", + "minecraft:blue_wool", + "minecraft:brown_wool", + "minecraft:cyan_wool", + "minecraft:gray_wool", + "minecraft:green_wool", + "minecraft:light_blue_wool", + "minecraft:light_gray_wool", + "minecraft:lime_wool", + "minecraft:magenta_wool", + "minecraft:orange_wool", + "minecraft:pink_wool", + "minecraft:red_wool", + "minecraft:yellow_wool", + "minecraft:white_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:purple_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_red_bed.json b/src/generated/resources/data/minecraft/recipe/dye_red_bed.json new file mode 100644 index 0000000000..1fe4e977a4 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_red_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/red", + [ + "minecraft:black_bed", + "minecraft:blue_bed", + "minecraft:brown_bed", + "minecraft:cyan_bed", + "minecraft:gray_bed", + "minecraft:green_bed", + "minecraft:light_blue_bed", + "minecraft:light_gray_bed", + "minecraft:lime_bed", + "minecraft:magenta_bed", + "minecraft:orange_bed", + "minecraft:pink_bed", + "minecraft:purple_bed", + "minecraft:yellow_bed", + "minecraft:white_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:red_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_red_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_red_carpet.json new file mode 100644 index 0000000000..5d778fac1c --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_red_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/red", + [ + "minecraft:black_carpet", + "minecraft:blue_carpet", + "minecraft:brown_carpet", + "minecraft:cyan_carpet", + "minecraft:gray_carpet", + "minecraft:green_carpet", + "minecraft:light_blue_carpet", + "minecraft:light_gray_carpet", + "minecraft:lime_carpet", + "minecraft:magenta_carpet", + "minecraft:orange_carpet", + "minecraft:pink_carpet", + "minecraft:purple_carpet", + "minecraft:yellow_carpet", + "minecraft:white_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:red_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_red_wool.json b/src/generated/resources/data/minecraft/recipe/dye_red_wool.json new file mode 100644 index 0000000000..cfd0569b72 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_red_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/red", + [ + "minecraft:black_wool", + "minecraft:blue_wool", + "minecraft:brown_wool", + "minecraft:cyan_wool", + "minecraft:gray_wool", + "minecraft:green_wool", + "minecraft:light_blue_wool", + "minecraft:light_gray_wool", + "minecraft:lime_wool", + "minecraft:magenta_wool", + "minecraft:orange_wool", + "minecraft:pink_wool", + "minecraft:purple_wool", + "minecraft:yellow_wool", + "minecraft:white_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:red_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_white_bed.json b/src/generated/resources/data/minecraft/recipe/dye_white_bed.json new file mode 100644 index 0000000000..759f3294d7 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_white_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/white", + [ + "minecraft:black_bed", + "minecraft:blue_bed", + "minecraft:brown_bed", + "minecraft:cyan_bed", + "minecraft:gray_bed", + "minecraft:green_bed", + "minecraft:light_blue_bed", + "minecraft:light_gray_bed", + "minecraft:lime_bed", + "minecraft:magenta_bed", + "minecraft:orange_bed", + "minecraft:pink_bed", + "minecraft:purple_bed", + "minecraft:red_bed", + "minecraft:yellow_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:white_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_white_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_white_carpet.json new file mode 100644 index 0000000000..9065897b86 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_white_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/white", + [ + "minecraft:black_carpet", + "minecraft:blue_carpet", + "minecraft:brown_carpet", + "minecraft:cyan_carpet", + "minecraft:gray_carpet", + "minecraft:green_carpet", + "minecraft:light_blue_carpet", + "minecraft:light_gray_carpet", + "minecraft:lime_carpet", + "minecraft:magenta_carpet", + "minecraft:orange_carpet", + "minecraft:pink_carpet", + "minecraft:purple_carpet", + "minecraft:red_carpet", + "minecraft:yellow_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:white_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_white_wool.json b/src/generated/resources/data/minecraft/recipe/dye_white_wool.json new file mode 100644 index 0000000000..f88f447f88 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_white_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/white", + [ + "minecraft:black_wool", + "minecraft:blue_wool", + "minecraft:brown_wool", + "minecraft:cyan_wool", + "minecraft:gray_wool", + "minecraft:green_wool", + "minecraft:light_blue_wool", + "minecraft:light_gray_wool", + "minecraft:lime_wool", + "minecraft:magenta_wool", + "minecraft:orange_wool", + "minecraft:pink_wool", + "minecraft:purple_wool", + "minecraft:red_wool", + "minecraft:yellow_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:white_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_yellow_bed.json b/src/generated/resources/data/minecraft/recipe/dye_yellow_bed.json new file mode 100644 index 0000000000..f336bb857f --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_yellow_bed.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "bed", + "ingredients": [ + "#c:dyes/yellow", + [ + "minecraft:black_bed", + "minecraft:blue_bed", + "minecraft:brown_bed", + "minecraft:cyan_bed", + "minecraft:gray_bed", + "minecraft:green_bed", + "minecraft:light_blue_bed", + "minecraft:light_gray_bed", + "minecraft:lime_bed", + "minecraft:magenta_bed", + "minecraft:orange_bed", + "minecraft:pink_bed", + "minecraft:purple_bed", + "minecraft:red_bed", + "minecraft:white_bed" + ] + ], + "result": { + "count": 1, + "id": "minecraft:yellow_bed" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_yellow_carpet.json b/src/generated/resources/data/minecraft/recipe/dye_yellow_carpet.json new file mode 100644 index 0000000000..81f9c193b8 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_yellow_carpet.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "carpet", + "ingredients": [ + "#c:dyes/yellow", + [ + "minecraft:black_carpet", + "minecraft:blue_carpet", + "minecraft:brown_carpet", + "minecraft:cyan_carpet", + "minecraft:gray_carpet", + "minecraft:green_carpet", + "minecraft:light_blue_carpet", + "minecraft:light_gray_carpet", + "minecraft:lime_carpet", + "minecraft:magenta_carpet", + "minecraft:orange_carpet", + "minecraft:pink_carpet", + "minecraft:purple_carpet", + "minecraft:red_carpet", + "minecraft:white_carpet" + ] + ], + "result": { + "count": 1, + "id": "minecraft:yellow_carpet" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/dye_yellow_wool.json b/src/generated/resources/data/minecraft/recipe/dye_yellow_wool.json new file mode 100644 index 0000000000..7cb4a1f1ca --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/dye_yellow_wool.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "wool", + "ingredients": [ + "#c:dyes/yellow", + [ + "minecraft:black_wool", + "minecraft:blue_wool", + "minecraft:brown_wool", + "minecraft:cyan_wool", + "minecraft:gray_wool", + "minecraft:green_wool", + "minecraft:light_blue_wool", + "minecraft:light_gray_wool", + "minecraft:lime_wool", + "minecraft:magenta_wool", + "minecraft:orange_wool", + "minecraft:pink_wool", + "minecraft:purple_wool", + "minecraft:red_wool", + "minecraft:white_wool" + ] + ], + "result": { + "count": 1, + "id": "minecraft:yellow_wool" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/enchanting_table.json b/src/generated/resources/data/minecraft/recipe/enchanting_table.json index 0b202c954e..a18e62aa60 100644 --- a/src/generated/resources/data/minecraft/recipe/enchanting_table.json +++ b/src/generated/resources/data/minecraft/recipe/enchanting_table.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "item": "minecraft:obsidian" - }, - "B": { - "item": "minecraft:book" - }, - "D": { - "tag": "c:gems/diamond" - } + "#": "minecraft:obsidian", + "B": "minecraft:book", + "D": "#c:gems/diamond" }, "pattern": [ " B ", diff --git a/src/generated/resources/data/minecraft/recipe/eye_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/eye_armor_trim_smithing_template.json index f4183152ba..24c0e2e4ad 100644 --- a/src/generated/resources/data/minecraft/recipe/eye_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/eye_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "item": "minecraft:end_stone" - }, - "S": { - "item": "minecraft:eye_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "minecraft:end_stone", + "S": "minecraft:eye_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/fishing_rod.json b/src/generated/resources/data/minecraft/recipe/fishing_rod.json index 72690672d3..8308c1ef46 100644 --- a/src/generated/resources/data/minecraft/recipe/fishing_rod.json +++ b/src/generated/resources/data/minecraft/recipe/fishing_rod.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:strings" - } + "#": "#c:rods/wooden", + "X": "#c:strings" }, "pattern": [ " #", diff --git a/src/generated/resources/data/minecraft/recipe/flint_and_steel.json b/src/generated/resources/data/minecraft/recipe/flint_and_steel.json index c1ecbca55f..291b18605e 100644 --- a/src/generated/resources/data/minecraft/recipe/flint_and_steel.json +++ b/src/generated/resources/data/minecraft/recipe/flint_and_steel.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shapeless", "category": "equipment", "ingredients": [ - { - "tag": "c:ingots/iron" - }, - { - "item": "minecraft:flint" - } + "#c:ingots/iron", + "minecraft:flint" ], "result": { "count": 1, diff --git a/src/generated/resources/data/minecraft/recipe/flow_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/flow_armor_trim_smithing_template.json index 3b8d02a56d..958fdf6b4c 100644 --- a/src/generated/resources/data/minecraft/recipe/flow_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/flow_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "item": "minecraft:breeze_rod" - }, - "S": { - "item": "minecraft:flow_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "minecraft:breeze_rod", + "S": "minecraft:flow_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/glistering_melon_slice.json b/src/generated/resources/data/minecraft/recipe/glistering_melon_slice.json index 52c02f8057..d9f7cb56c0 100644 --- a/src/generated/resources/data/minecraft/recipe/glistering_melon_slice.json +++ b/src/generated/resources/data/minecraft/recipe/glistering_melon_slice.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:nuggets/gold" - }, - "X": { - "item": "minecraft:melon_slice" - } + "#": "#c:nuggets/gold", + "X": "minecraft:melon_slice" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/gold_ingot_from_nuggets.json b/src/generated/resources/data/minecraft/recipe/gold_ingot_from_nuggets.json index ca6e7b8674..e1e752fdac 100644 --- a/src/generated/resources/data/minecraft/recipe/gold_ingot_from_nuggets.json +++ b/src/generated/resources/data/minecraft/recipe/gold_ingot_from_nuggets.json @@ -3,9 +3,7 @@ "category": "misc", "group": "gold_ingot", "key": { - "#": { - "tag": "c:nuggets/gold" - } + "#": "#c:nuggets/gold" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/golden_apple.json b/src/generated/resources/data/minecraft/recipe/golden_apple.json index 6839d31d1e..0a029564aa 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_apple.json +++ b/src/generated/resources/data/minecraft/recipe/golden_apple.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:ingots/gold" - }, - "X": { - "item": "minecraft:apple" - } + "#": "#c:ingots/gold", + "X": "minecraft:apple" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/golden_axe.json b/src/generated/resources/data/minecraft/recipe/golden_axe.json index ed95ebdd0a..aad3355e76 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_axe.json +++ b/src/generated/resources/data/minecraft/recipe/golden_axe.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:ingots/gold" - } + "#": "#c:rods/wooden", + "X": "#minecraft:gold_tool_materials" }, "pattern": [ "XX", diff --git a/src/generated/resources/data/minecraft/recipe/golden_boots.json b/src/generated/resources/data/minecraft/recipe/golden_boots.json index 0b9010aa3c..baede9b2b0 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_boots.json +++ b/src/generated/resources/data/minecraft/recipe/golden_boots.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "X": { - "tag": "c:ingots/gold" - } + "X": "#c:ingots/gold" }, "pattern": [ "X X", diff --git a/src/generated/resources/data/minecraft/recipe/golden_carrot.json b/src/generated/resources/data/minecraft/recipe/golden_carrot.json index 444588c03d..de1984305c 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_carrot.json +++ b/src/generated/resources/data/minecraft/recipe/golden_carrot.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:nuggets/gold" - }, - "X": { - "item": "minecraft:carrot" - } + "#": "#c:nuggets/gold", + "X": "minecraft:carrot" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/golden_chestplate.json b/src/generated/resources/data/minecraft/recipe/golden_chestplate.json index edd79c9908..44610c5b75 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_chestplate.json +++ b/src/generated/resources/data/minecraft/recipe/golden_chestplate.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "X": { - "tag": "c:ingots/gold" - } + "X": "#c:ingots/gold" }, "pattern": [ "X X", diff --git a/src/generated/resources/data/minecraft/recipe/golden_helmet.json b/src/generated/resources/data/minecraft/recipe/golden_helmet.json index f275fa7514..77e0c12be8 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_helmet.json +++ b/src/generated/resources/data/minecraft/recipe/golden_helmet.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "X": { - "tag": "c:ingots/gold" - } + "X": "#c:ingots/gold" }, "pattern": [ "XXX", diff --git a/src/generated/resources/data/minecraft/recipe/golden_hoe.json b/src/generated/resources/data/minecraft/recipe/golden_hoe.json index 6a305f1b18..6a31db7ec1 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_hoe.json +++ b/src/generated/resources/data/minecraft/recipe/golden_hoe.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:ingots/gold" - } + "#": "#c:rods/wooden", + "X": "#minecraft:gold_tool_materials" }, "pattern": [ "XX", diff --git a/src/generated/resources/data/minecraft/recipe/golden_leggings.json b/src/generated/resources/data/minecraft/recipe/golden_leggings.json index 54c8ae061e..6ffc3edd1c 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_leggings.json +++ b/src/generated/resources/data/minecraft/recipe/golden_leggings.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "X": { - "tag": "c:ingots/gold" - } + "X": "#c:ingots/gold" }, "pattern": [ "XXX", diff --git a/src/generated/resources/data/minecraft/recipe/golden_pickaxe.json b/src/generated/resources/data/minecraft/recipe/golden_pickaxe.json index be94e94d06..7e88522f3e 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_pickaxe.json +++ b/src/generated/resources/data/minecraft/recipe/golden_pickaxe.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:ingots/gold" - } + "#": "#c:rods/wooden", + "X": "#minecraft:gold_tool_materials" }, "pattern": [ "XXX", diff --git a/src/generated/resources/data/minecraft/recipe/golden_shovel.json b/src/generated/resources/data/minecraft/recipe/golden_shovel.json index b71a44cb47..ed7b535236 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_shovel.json +++ b/src/generated/resources/data/minecraft/recipe/golden_shovel.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:ingots/gold" - } + "#": "#c:rods/wooden", + "X": "#minecraft:gold_tool_materials" }, "pattern": [ "X", diff --git a/src/generated/resources/data/minecraft/recipe/golden_sword.json b/src/generated/resources/data/minecraft/recipe/golden_sword.json index fdfc713b40..a400bb8117 100644 --- a/src/generated/resources/data/minecraft/recipe/golden_sword.json +++ b/src/generated/resources/data/minecraft/recipe/golden_sword.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:ingots/gold" - } + "#": "#c:rods/wooden", + "X": "#minecraft:gold_tool_materials" }, "pattern": [ "X", diff --git a/src/generated/resources/data/minecraft/recipe/gray_banner.json b/src/generated/resources/data/minecraft/recipe/gray_banner.json index 9a36e40aed..75e5ac3ebe 100644 --- a/src/generated/resources/data/minecraft/recipe/gray_banner.json +++ b/src/generated/resources/data/minecraft/recipe/gray_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:gray_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:gray_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/gray_candle.json b/src/generated/resources/data/minecraft/recipe/gray_candle.json new file mode 100644 index 0000000000..ef9a61dea2 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/gray_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/gray" + ], + "result": { + "count": 1, + "id": "minecraft:gray_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/gray_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/gray_concrete_powder.json new file mode 100644 index 0000000000..11e77a047c --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/gray_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/gray", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:gray_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/gray_dye.json b/src/generated/resources/data/minecraft/recipe/gray_dye.json new file mode 100644 index 0000000000..eaf25e280f --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/gray_dye.json @@ -0,0 +1,12 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "#c:dyes/black", + "#c:dyes/white" + ], + "result": { + "count": 2, + "id": "minecraft:gray_dye" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/gray_stained_glass.json b/src/generated/resources/data/minecraft/recipe/gray_stained_glass.json new file mode 100644 index 0000000000..6944a3a0e3 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/gray_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/gray" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:gray_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/gray_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/gray_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..d73c5334d2 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/gray_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/gray" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:gray_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/gray_terracotta.json b/src/generated/resources/data/minecraft/recipe/gray_terracotta.json new file mode 100644 index 0000000000..4aa191b3f9 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/gray_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/gray" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:gray_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/green_banner.json b/src/generated/resources/data/minecraft/recipe/green_banner.json index 3960ffd83b..e18d67a1f3 100644 --- a/src/generated/resources/data/minecraft/recipe/green_banner.json +++ b/src/generated/resources/data/minecraft/recipe/green_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:green_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:green_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/green_candle.json b/src/generated/resources/data/minecraft/recipe/green_candle.json new file mode 100644 index 0000000000..a95ce3d9d7 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/green_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/green" + ], + "result": { + "count": 1, + "id": "minecraft:green_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/green_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/green_concrete_powder.json new file mode 100644 index 0000000000..9f5cfeab6d --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/green_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/green", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:green_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/green_stained_glass.json b/src/generated/resources/data/minecraft/recipe/green_stained_glass.json new file mode 100644 index 0000000000..d2deaf8899 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/green_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/green" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:green_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/green_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/green_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..683c58b104 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/green_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/green" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:green_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/green_terracotta.json b/src/generated/resources/data/minecraft/recipe/green_terracotta.json new file mode 100644 index 0000000000..7247824388 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/green_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/green" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:green_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/grindstone.json b/src/generated/resources/data/minecraft/recipe/grindstone.json index 234b5a8e4f..5edf22f750 100644 --- a/src/generated/resources/data/minecraft/recipe/grindstone.json +++ b/src/generated/resources/data/minecraft/recipe/grindstone.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "minecraft:planks" - }, - "-": { - "item": "minecraft:stone_slab" - }, - "I": { - "tag": "c:rods/wooden" - } + "#": "#minecraft:planks", + "-": "minecraft:stone_slab", + "I": "#c:rods/wooden" }, "pattern": [ "I-I", diff --git a/src/generated/resources/data/minecraft/recipe/heavy_weighted_pressure_plate.json b/src/generated/resources/data/minecraft/recipe/heavy_weighted_pressure_plate.json index ac9cd700dc..e4c401e38e 100644 --- a/src/generated/resources/data/minecraft/recipe/heavy_weighted_pressure_plate.json +++ b/src/generated/resources/data/minecraft/recipe/heavy_weighted_pressure_plate.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "c:ingots/iron" - } + "#": "#c:ingots/iron" }, "pattern": [ "##" diff --git a/src/generated/resources/data/minecraft/recipe/hopper.json b/src/generated/resources/data/minecraft/recipe/hopper.json index 91bdccdd82..37560a9e85 100644 --- a/src/generated/resources/data/minecraft/recipe/hopper.json +++ b/src/generated/resources/data/minecraft/recipe/hopper.json @@ -3,17 +3,11 @@ "category": "redstone", "key": { "C": { - "type": "neoforge:difference", - "base": { - "tag": "c:chests/wooden" - }, - "subtracted": { - "tag": "c:chests/trapped" - } + "neoforge:ingredient_type": "neoforge:difference", + "base": "#c:chests/wooden", + "subtracted": "#c:chests/trapped" }, - "I": { - "tag": "c:ingots/iron" - } + "I": "#c:ingots/iron" }, "pattern": [ "I I", diff --git a/src/generated/resources/data/minecraft/recipe/host_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/host_armor_trim_smithing_template.json index f84de52ad6..ae84d48cc6 100644 --- a/src/generated/resources/data/minecraft/recipe/host_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/host_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "item": "minecraft:terracotta" - }, - "S": { - "item": "minecraft:host_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "minecraft:terracotta", + "S": "minecraft:host_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/iron_axe.json b/src/generated/resources/data/minecraft/recipe/iron_axe.json index 950fa6ac7a..535479a2ba 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_axe.json +++ b/src/generated/resources/data/minecraft/recipe/iron_axe.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:ingots/iron" - } + "#": "#c:rods/wooden", + "X": "#minecraft:iron_tool_materials" }, "pattern": [ "XX", diff --git a/src/generated/resources/data/minecraft/recipe/iron_bars.json b/src/generated/resources/data/minecraft/recipe/iron_bars.json index 28be431fc6..e33ecdcc4f 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_bars.json +++ b/src/generated/resources/data/minecraft/recipe/iron_bars.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:ingots/iron" - } + "#": "#c:ingots/iron" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/iron_boots.json b/src/generated/resources/data/minecraft/recipe/iron_boots.json index f489f382e6..459f753384 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_boots.json +++ b/src/generated/resources/data/minecraft/recipe/iron_boots.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "X": { - "tag": "c:ingots/iron" - } + "X": "#c:ingots/iron" }, "pattern": [ "X X", diff --git a/src/generated/resources/data/minecraft/recipe/iron_chestplate.json b/src/generated/resources/data/minecraft/recipe/iron_chestplate.json index 67f70bc19c..42ac070a95 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_chestplate.json +++ b/src/generated/resources/data/minecraft/recipe/iron_chestplate.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "X": { - "tag": "c:ingots/iron" - } + "X": "#c:ingots/iron" }, "pattern": [ "X X", diff --git a/src/generated/resources/data/minecraft/recipe/iron_door.json b/src/generated/resources/data/minecraft/recipe/iron_door.json index be3bbbf4da..2155da533f 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_door.json +++ b/src/generated/resources/data/minecraft/recipe/iron_door.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "c:ingots/iron" - } + "#": "#c:ingots/iron" }, "pattern": [ "##", diff --git a/src/generated/resources/data/minecraft/recipe/iron_helmet.json b/src/generated/resources/data/minecraft/recipe/iron_helmet.json index 4b7326c79f..67b4fa7229 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_helmet.json +++ b/src/generated/resources/data/minecraft/recipe/iron_helmet.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "X": { - "tag": "c:ingots/iron" - } + "X": "#c:ingots/iron" }, "pattern": [ "XXX", diff --git a/src/generated/resources/data/minecraft/recipe/iron_hoe.json b/src/generated/resources/data/minecraft/recipe/iron_hoe.json index e175c35d0c..65fb6202de 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_hoe.json +++ b/src/generated/resources/data/minecraft/recipe/iron_hoe.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:ingots/iron" - } + "#": "#c:rods/wooden", + "X": "#minecraft:iron_tool_materials" }, "pattern": [ "XX", diff --git a/src/generated/resources/data/minecraft/recipe/iron_ingot_from_nuggets.json b/src/generated/resources/data/minecraft/recipe/iron_ingot_from_nuggets.json index 2cf9cdfd88..3880618510 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_ingot_from_nuggets.json +++ b/src/generated/resources/data/minecraft/recipe/iron_ingot_from_nuggets.json @@ -3,9 +3,7 @@ "category": "misc", "group": "iron_ingot", "key": { - "#": { - "tag": "c:nuggets/iron" - } + "#": "#c:nuggets/iron" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/iron_leggings.json b/src/generated/resources/data/minecraft/recipe/iron_leggings.json index db1ad0850c..ca4c45bc62 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_leggings.json +++ b/src/generated/resources/data/minecraft/recipe/iron_leggings.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "X": { - "tag": "c:ingots/iron" - } + "X": "#c:ingots/iron" }, "pattern": [ "XXX", diff --git a/src/generated/resources/data/minecraft/recipe/iron_pickaxe.json b/src/generated/resources/data/minecraft/recipe/iron_pickaxe.json index f829c9df56..169d8f7094 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_pickaxe.json +++ b/src/generated/resources/data/minecraft/recipe/iron_pickaxe.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:ingots/iron" - } + "#": "#c:rods/wooden", + "X": "#minecraft:iron_tool_materials" }, "pattern": [ "XXX", diff --git a/src/generated/resources/data/minecraft/recipe/iron_shovel.json b/src/generated/resources/data/minecraft/recipe/iron_shovel.json index 5a11203af5..b436766778 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_shovel.json +++ b/src/generated/resources/data/minecraft/recipe/iron_shovel.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:ingots/iron" - } + "#": "#c:rods/wooden", + "X": "#minecraft:iron_tool_materials" }, "pattern": [ "X", diff --git a/src/generated/resources/data/minecraft/recipe/iron_sword.json b/src/generated/resources/data/minecraft/recipe/iron_sword.json index 6f4c0a46cd..8c909bfa56 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_sword.json +++ b/src/generated/resources/data/minecraft/recipe/iron_sword.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:ingots/iron" - } + "#": "#c:rods/wooden", + "X": "#minecraft:iron_tool_materials" }, "pattern": [ "X", diff --git a/src/generated/resources/data/minecraft/recipe/iron_trapdoor.json b/src/generated/resources/data/minecraft/recipe/iron_trapdoor.json index 45d3357442..a64774b455 100644 --- a/src/generated/resources/data/minecraft/recipe/iron_trapdoor.json +++ b/src/generated/resources/data/minecraft/recipe/iron_trapdoor.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "c:ingots/iron" - } + "#": "#c:ingots/iron" }, "pattern": [ "##", diff --git a/src/generated/resources/data/minecraft/recipe/item_frame.json b/src/generated/resources/data/minecraft/recipe/item_frame.json index f73e86feb5..9daf39f512 100644 --- a/src/generated/resources/data/minecraft/recipe/item_frame.json +++ b/src/generated/resources/data/minecraft/recipe/item_frame.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "item": "minecraft:leather" - } + "#": "#c:rods/wooden", + "X": "minecraft:leather" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/jukebox.json b/src/generated/resources/data/minecraft/recipe/jukebox.json index 08f3d3b4d3..c7c109d95f 100644 --- a/src/generated/resources/data/minecraft/recipe/jukebox.json +++ b/src/generated/resources/data/minecraft/recipe/jukebox.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "minecraft:planks" - }, - "X": { - "tag": "c:gems/diamond" - } + "#": "#minecraft:planks", + "X": "#c:gems/diamond" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/jungle_chest_boat.json b/src/generated/resources/data/minecraft/recipe/jungle_chest_boat.json index 8a86eca6db..4ce71a21b8 100644 --- a/src/generated/resources/data/minecraft/recipe/jungle_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/jungle_chest_boat.json @@ -4,17 +4,11 @@ "group": "chest_boat", "ingredients": [ { - "type": "neoforge:difference", - "base": { - "tag": "c:chests/wooden" - }, - "subtracted": { - "tag": "c:chests/trapped" - } + "neoforge:ingredient_type": "neoforge:difference", + "base": "#c:chests/wooden", + "subtracted": "#c:chests/trapped" }, - { - "item": "minecraft:jungle_boat" - } + "minecraft:jungle_boat" ], "result": { "count": 1, diff --git a/src/generated/resources/data/minecraft/recipe/jungle_fence.json b/src/generated/resources/data/minecraft/recipe/jungle_fence.json index b49a38c19a..dc919dea44 100644 --- a/src/generated/resources/data/minecraft/recipe/jungle_fence.json +++ b/src/generated/resources/data/minecraft/recipe/jungle_fence.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_fence", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:jungle_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:jungle_planks" }, "pattern": [ "W#W", diff --git a/src/generated/resources/data/minecraft/recipe/jungle_fence_gate.json b/src/generated/resources/data/minecraft/recipe/jungle_fence_gate.json index a1dcfbde01..3f3ee533ed 100644 --- a/src/generated/resources/data/minecraft/recipe/jungle_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/jungle_fence_gate.json @@ -3,12 +3,8 @@ "category": "redstone", "group": "wooden_fence_gate", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:jungle_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:jungle_planks" }, "pattern": [ "#W#", diff --git a/src/generated/resources/data/minecraft/recipe/jungle_sign.json b/src/generated/resources/data/minecraft/recipe/jungle_sign.json index 713c47d1fa..9c22e2bcd1 100644 --- a/src/generated/resources/data/minecraft/recipe/jungle_sign.json +++ b/src/generated/resources/data/minecraft/recipe/jungle_sign.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_sign", "key": { - "#": { - "item": "minecraft:jungle_planks" - }, - "X": { - "tag": "c:rods/wooden" - } + "#": "minecraft:jungle_planks", + "X": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/ladder.json b/src/generated/resources/data/minecraft/recipe/ladder.json index 8d64f336a8..0aefdd0268 100644 --- a/src/generated/resources/data/minecraft/recipe/ladder.json +++ b/src/generated/resources/data/minecraft/recipe/ladder.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:rods/wooden" - } + "#": "#c:rods/wooden" }, "pattern": [ "# #", diff --git a/src/generated/resources/data/minecraft/recipe/lantern.json b/src/generated/resources/data/minecraft/recipe/lantern.json index d7435e4ee2..547cee5246 100644 --- a/src/generated/resources/data/minecraft/recipe/lantern.json +++ b/src/generated/resources/data/minecraft/recipe/lantern.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "item": "minecraft:torch" - }, - "X": { - "tag": "c:nuggets/iron" - } + "#": "minecraft:torch", + "X": "#c:nuggets/iron" }, "pattern": [ "XXX", diff --git a/src/generated/resources/data/minecraft/recipe/lead.json b/src/generated/resources/data/minecraft/recipe/lead.json index 57ca6d0bbc..a48100d61a 100644 --- a/src/generated/resources/data/minecraft/recipe/lead.json +++ b/src/generated/resources/data/minecraft/recipe/lead.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "O": { - "item": "minecraft:slime_ball" - }, - "~": { - "tag": "c:strings" - } + "O": "minecraft:slime_ball", + "~": "#c:strings" }, "pattern": [ "~~ ", diff --git a/src/generated/resources/data/minecraft/recipe/lever.json b/src/generated/resources/data/minecraft/recipe/lever.json index a92056e26a..25196040a9 100644 --- a/src/generated/resources/data/minecraft/recipe/lever.json +++ b/src/generated/resources/data/minecraft/recipe/lever.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "c:cobblestones/normal" - }, - "X": { - "tag": "c:rods/wooden" - } + "#": "#c:cobblestones/normal", + "X": "#c:rods/wooden" }, "pattern": [ "X", diff --git a/src/generated/resources/data/minecraft/recipe/light_blue_banner.json b/src/generated/resources/data/minecraft/recipe/light_blue_banner.json index 1fb0a66d80..b0fa080366 100644 --- a/src/generated/resources/data/minecraft/recipe/light_blue_banner.json +++ b/src/generated/resources/data/minecraft/recipe/light_blue_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:light_blue_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:light_blue_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/light_blue_candle.json b/src/generated/resources/data/minecraft/recipe/light_blue_candle.json new file mode 100644 index 0000000000..43cbfe0211 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/light_blue_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/light_blue" + ], + "result": { + "count": 1, + "id": "minecraft:light_blue_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_blue_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/light_blue_concrete_powder.json new file mode 100644 index 0000000000..ffb30f0661 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/light_blue_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/light_blue", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:light_blue_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_blue_dye_from_blue_white_dye.json b/src/generated/resources/data/minecraft/recipe/light_blue_dye_from_blue_white_dye.json new file mode 100644 index 0000000000..1d33b2a8f9 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/light_blue_dye_from_blue_white_dye.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "light_blue_dye", + "ingredients": [ + "#c:dyes/blue", + "#c:dyes/white" + ], + "result": { + "count": 2, + "id": "minecraft:light_blue_dye" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_blue_stained_glass.json b/src/generated/resources/data/minecraft/recipe/light_blue_stained_glass.json new file mode 100644 index 0000000000..9768131cfd --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/light_blue_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/light_blue" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:light_blue_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_blue_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/light_blue_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..0b1d1516e8 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/light_blue_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/light_blue" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:light_blue_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_blue_terracotta.json b/src/generated/resources/data/minecraft/recipe/light_blue_terracotta.json new file mode 100644 index 0000000000..219536884b --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/light_blue_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/light_blue" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:light_blue_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_gray_banner.json b/src/generated/resources/data/minecraft/recipe/light_gray_banner.json index 35d93c6693..7a16563cc0 100644 --- a/src/generated/resources/data/minecraft/recipe/light_gray_banner.json +++ b/src/generated/resources/data/minecraft/recipe/light_gray_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:light_gray_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:light_gray_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/light_gray_candle.json b/src/generated/resources/data/minecraft/recipe/light_gray_candle.json new file mode 100644 index 0000000000..5fbd4a55c6 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/light_gray_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/light_gray" + ], + "result": { + "count": 1, + "id": "minecraft:light_gray_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_gray_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/light_gray_concrete_powder.json new file mode 100644 index 0000000000..e967595cfe --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/light_gray_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/light_gray", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:light_gray_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_gray_dye_from_black_white_dye.json b/src/generated/resources/data/minecraft/recipe/light_gray_dye_from_black_white_dye.json new file mode 100644 index 0000000000..23c04e8044 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/light_gray_dye_from_black_white_dye.json @@ -0,0 +1,14 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "light_gray_dye", + "ingredients": [ + "#c:dyes/black", + "#c:dyes/white", + "#c:dyes/white" + ], + "result": { + "count": 3, + "id": "minecraft:light_gray_dye" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_gray_dye_from_gray_white_dye.json b/src/generated/resources/data/minecraft/recipe/light_gray_dye_from_gray_white_dye.json new file mode 100644 index 0000000000..24ffa80ddf --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/light_gray_dye_from_gray_white_dye.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "light_gray_dye", + "ingredients": [ + "#c:dyes/gray", + "#c:dyes/white" + ], + "result": { + "count": 2, + "id": "minecraft:light_gray_dye" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_gray_stained_glass.json b/src/generated/resources/data/minecraft/recipe/light_gray_stained_glass.json new file mode 100644 index 0000000000..9956a97647 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/light_gray_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/light_gray" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:light_gray_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_gray_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/light_gray_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..3cf7396ff0 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/light_gray_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/light_gray" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:light_gray_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_gray_terracotta.json b/src/generated/resources/data/minecraft/recipe/light_gray_terracotta.json new file mode 100644 index 0000000000..7bd8663ba9 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/light_gray_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/light_gray" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:light_gray_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/light_weighted_pressure_plate.json b/src/generated/resources/data/minecraft/recipe/light_weighted_pressure_plate.json index 0d6eec2360..ef08a13e3f 100644 --- a/src/generated/resources/data/minecraft/recipe/light_weighted_pressure_plate.json +++ b/src/generated/resources/data/minecraft/recipe/light_weighted_pressure_plate.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "c:ingots/gold" - } + "#": "#c:ingots/gold" }, "pattern": [ "##" diff --git a/src/generated/resources/data/minecraft/recipe/lightning_rod.json b/src/generated/resources/data/minecraft/recipe/lightning_rod.json index 5a2186f659..614ed2737e 100644 --- a/src/generated/resources/data/minecraft/recipe/lightning_rod.json +++ b/src/generated/resources/data/minecraft/recipe/lightning_rod.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "c:ingots/copper" - } + "#": "#c:ingots/copper" }, "pattern": [ "#", diff --git a/src/generated/resources/data/minecraft/recipe/lime_banner.json b/src/generated/resources/data/minecraft/recipe/lime_banner.json index c076add05b..49b26aba09 100644 --- a/src/generated/resources/data/minecraft/recipe/lime_banner.json +++ b/src/generated/resources/data/minecraft/recipe/lime_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:lime_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:lime_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/lime_candle.json b/src/generated/resources/data/minecraft/recipe/lime_candle.json new file mode 100644 index 0000000000..f38b4cd3c5 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/lime_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/lime" + ], + "result": { + "count": 1, + "id": "minecraft:lime_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/lime_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/lime_concrete_powder.json new file mode 100644 index 0000000000..d3e0f4a0cc --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/lime_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/lime", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:lime_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/lime_dye.json b/src/generated/resources/data/minecraft/recipe/lime_dye.json new file mode 100644 index 0000000000..03f7de71e1 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/lime_dye.json @@ -0,0 +1,12 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "#c:dyes/green", + "#c:dyes/white" + ], + "result": { + "count": 2, + "id": "minecraft:lime_dye" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/lime_stained_glass.json b/src/generated/resources/data/minecraft/recipe/lime_stained_glass.json new file mode 100644 index 0000000000..ced0fd369e --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/lime_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/lime" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:lime_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/lime_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/lime_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..a6fd9c362a --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/lime_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/lime" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:lime_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/lime_terracotta.json b/src/generated/resources/data/minecraft/recipe/lime_terracotta.json new file mode 100644 index 0000000000..199a1fab04 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/lime_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/lime" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:lime_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/lodestone.json b/src/generated/resources/data/minecraft/recipe/lodestone.json index 5d1bc8a33a..aabb2183d5 100644 --- a/src/generated/resources/data/minecraft/recipe/lodestone.json +++ b/src/generated/resources/data/minecraft/recipe/lodestone.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:ingots/netherite" - }, - "S": { - "item": "minecraft:chiseled_stone_bricks" - } + "#": "#c:ingots/netherite", + "S": "minecraft:chiseled_stone_bricks" }, "pattern": [ "SSS", diff --git a/src/generated/resources/data/minecraft/recipe/loom.json b/src/generated/resources/data/minecraft/recipe/loom.json index 7fbb48dfe9..9b25eeb36f 100644 --- a/src/generated/resources/data/minecraft/recipe/loom.json +++ b/src/generated/resources/data/minecraft/recipe/loom.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "minecraft:planks" - }, - "@": { - "tag": "c:strings" - } + "#": "#minecraft:planks", + "@": "#c:strings" }, "pattern": [ "@@", diff --git a/src/generated/resources/data/minecraft/recipe/magenta_banner.json b/src/generated/resources/data/minecraft/recipe/magenta_banner.json index 5996580e8d..f09624c2ac 100644 --- a/src/generated/resources/data/minecraft/recipe/magenta_banner.json +++ b/src/generated/resources/data/minecraft/recipe/magenta_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:magenta_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:magenta_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/magenta_candle.json b/src/generated/resources/data/minecraft/recipe/magenta_candle.json new file mode 100644 index 0000000000..a424f2970c --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/magenta_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/magenta" + ], + "result": { + "count": 1, + "id": "minecraft:magenta_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/magenta_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/magenta_concrete_powder.json new file mode 100644 index 0000000000..16e3792d0f --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/magenta_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/magenta", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:magenta_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/magenta_dye_from_blue_red_pink.json b/src/generated/resources/data/minecraft/recipe/magenta_dye_from_blue_red_pink.json new file mode 100644 index 0000000000..a2fa3f6d96 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/magenta_dye_from_blue_red_pink.json @@ -0,0 +1,14 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "magenta_dye", + "ingredients": [ + "#c:dyes/blue", + "#c:dyes/red", + "#c:dyes/pink" + ], + "result": { + "count": 3, + "id": "minecraft:magenta_dye" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/magenta_dye_from_blue_red_white_dye.json b/src/generated/resources/data/minecraft/recipe/magenta_dye_from_blue_red_white_dye.json new file mode 100644 index 0000000000..4eae10075b --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/magenta_dye_from_blue_red_white_dye.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "magenta_dye", + "ingredients": [ + "#c:dyes/blue", + "#c:dyes/red", + "#c:dyes/red", + "#c:dyes/white" + ], + "result": { + "count": 4, + "id": "minecraft:magenta_dye" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/magenta_dye_from_purple_and_pink.json b/src/generated/resources/data/minecraft/recipe/magenta_dye_from_purple_and_pink.json new file mode 100644 index 0000000000..ef29fdbd87 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/magenta_dye_from_purple_and_pink.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "magenta_dye", + "ingredients": [ + "#c:dyes/purple", + "#c:dyes/pink" + ], + "result": { + "count": 2, + "id": "minecraft:magenta_dye" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/magenta_stained_glass.json b/src/generated/resources/data/minecraft/recipe/magenta_stained_glass.json new file mode 100644 index 0000000000..35c7057b7e --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/magenta_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/magenta" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:magenta_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/magenta_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/magenta_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..79dbe6233b --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/magenta_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/magenta" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:magenta_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/magenta_terracotta.json b/src/generated/resources/data/minecraft/recipe/magenta_terracotta.json new file mode 100644 index 0000000000..3205ae4824 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/magenta_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/magenta" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:magenta_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/mangrove_chest_boat.json b/src/generated/resources/data/minecraft/recipe/mangrove_chest_boat.json index 23e510eb5a..66a4dacf45 100644 --- a/src/generated/resources/data/minecraft/recipe/mangrove_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/mangrove_chest_boat.json @@ -4,17 +4,11 @@ "group": "chest_boat", "ingredients": [ { - "type": "neoforge:difference", - "base": { - "tag": "c:chests/wooden" - }, - "subtracted": { - "tag": "c:chests/trapped" - } + "neoforge:ingredient_type": "neoforge:difference", + "base": "#c:chests/wooden", + "subtracted": "#c:chests/trapped" }, - { - "item": "minecraft:mangrove_boat" - } + "minecraft:mangrove_boat" ], "result": { "count": 1, diff --git a/src/generated/resources/data/minecraft/recipe/mangrove_fence.json b/src/generated/resources/data/minecraft/recipe/mangrove_fence.json index 01d6d24181..f939810940 100644 --- a/src/generated/resources/data/minecraft/recipe/mangrove_fence.json +++ b/src/generated/resources/data/minecraft/recipe/mangrove_fence.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_fence", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:mangrove_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:mangrove_planks" }, "pattern": [ "W#W", diff --git a/src/generated/resources/data/minecraft/recipe/mangrove_fence_gate.json b/src/generated/resources/data/minecraft/recipe/mangrove_fence_gate.json index 3a0927be5e..8510a15d3f 100644 --- a/src/generated/resources/data/minecraft/recipe/mangrove_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/mangrove_fence_gate.json @@ -3,12 +3,8 @@ "category": "redstone", "group": "wooden_fence_gate", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:mangrove_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:mangrove_planks" }, "pattern": [ "#W#", diff --git a/src/generated/resources/data/minecraft/recipe/mangrove_sign.json b/src/generated/resources/data/minecraft/recipe/mangrove_sign.json index a55530fcd8..2c1eeab8a2 100644 --- a/src/generated/resources/data/minecraft/recipe/mangrove_sign.json +++ b/src/generated/resources/data/minecraft/recipe/mangrove_sign.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_sign", "key": { - "#": { - "item": "minecraft:mangrove_planks" - }, - "X": { - "tag": "c:rods/wooden" - } + "#": "minecraft:mangrove_planks", + "X": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/minecart.json b/src/generated/resources/data/minecraft/recipe/minecart.json index 15fdd90d0e..3a407b046e 100644 --- a/src/generated/resources/data/minecraft/recipe/minecart.json +++ b/src/generated/resources/data/minecraft/recipe/minecart.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:ingots/iron" - } + "#": "#c:ingots/iron" }, "pattern": [ "# #", diff --git a/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_moss_block.json b/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_moss_block.json index 80acf71a6d..0600f03431 100644 --- a/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_moss_block.json +++ b/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_moss_block.json @@ -3,12 +3,8 @@ "category": "building", "group": "mossy_cobblestone", "ingredients": [ - { - "tag": "c:cobblestones/normal" - }, - { - "item": "minecraft:moss_block" - } + "#c:cobblestones/normal", + "minecraft:moss_block" ], "result": { "count": 1, diff --git a/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_vine.json b/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_vine.json index 6980c8b3a2..fb39076601 100644 --- a/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_vine.json +++ b/src/generated/resources/data/minecraft/recipe/mossy_cobblestone_from_vine.json @@ -3,12 +3,8 @@ "category": "building", "group": "mossy_cobblestone", "ingredients": [ - { - "tag": "c:cobblestones/normal" - }, - { - "item": "minecraft:vine" - } + "#c:cobblestones/normal", + "minecraft:vine" ], "result": { "count": 1, diff --git a/src/generated/resources/data/minecraft/recipe/netherite_ingot.json b/src/generated/resources/data/minecraft/recipe/netherite_ingot.json index ffa224998e..839b4ad4f5 100644 --- a/src/generated/resources/data/minecraft/recipe/netherite_ingot.json +++ b/src/generated/resources/data/minecraft/recipe/netherite_ingot.json @@ -3,30 +3,14 @@ "category": "misc", "group": "netherite_ingot", "ingredients": [ - { - "item": "minecraft:netherite_scrap" - }, - { - "item": "minecraft:netherite_scrap" - }, - { - "item": "minecraft:netherite_scrap" - }, - { - "item": "minecraft:netherite_scrap" - }, - { - "tag": "c:ingots/gold" - }, - { - "tag": "c:ingots/gold" - }, - { - "tag": "c:ingots/gold" - }, - { - "tag": "c:ingots/gold" - } + "minecraft:netherite_scrap", + "minecraft:netherite_scrap", + "minecraft:netherite_scrap", + "minecraft:netherite_scrap", + "#c:ingots/gold", + "#c:ingots/gold", + "#c:ingots/gold", + "#c:ingots/gold" ], "result": { "count": 1, diff --git a/src/generated/resources/data/minecraft/recipe/netherite_upgrade_smithing_template.json b/src/generated/resources/data/minecraft/recipe/netherite_upgrade_smithing_template.json index 44fc480189..aa03072c28 100644 --- a/src/generated/resources/data/minecraft/recipe/netherite_upgrade_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/netherite_upgrade_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "item": "minecraft:netherrack" - }, - "S": { - "item": "minecraft:netherite_upgrade_smithing_template" - } + "#": "#c:gems/diamond", + "C": "minecraft:netherrack", + "S": "minecraft:netherite_upgrade_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/oak_chest_boat.json b/src/generated/resources/data/minecraft/recipe/oak_chest_boat.json index 4477f4980a..76a88f4aa3 100644 --- a/src/generated/resources/data/minecraft/recipe/oak_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/oak_chest_boat.json @@ -4,17 +4,11 @@ "group": "chest_boat", "ingredients": [ { - "type": "neoforge:difference", - "base": { - "tag": "c:chests/wooden" - }, - "subtracted": { - "tag": "c:chests/trapped" - } + "neoforge:ingredient_type": "neoforge:difference", + "base": "#c:chests/wooden", + "subtracted": "#c:chests/trapped" }, - { - "item": "minecraft:oak_boat" - } + "minecraft:oak_boat" ], "result": { "count": 1, diff --git a/src/generated/resources/data/minecraft/recipe/oak_fence.json b/src/generated/resources/data/minecraft/recipe/oak_fence.json index 3227fa2bc7..b3684fd871 100644 --- a/src/generated/resources/data/minecraft/recipe/oak_fence.json +++ b/src/generated/resources/data/minecraft/recipe/oak_fence.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_fence", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:oak_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:oak_planks" }, "pattern": [ "W#W", diff --git a/src/generated/resources/data/minecraft/recipe/oak_fence_gate.json b/src/generated/resources/data/minecraft/recipe/oak_fence_gate.json index 45923171d8..36941138d7 100644 --- a/src/generated/resources/data/minecraft/recipe/oak_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/oak_fence_gate.json @@ -3,12 +3,8 @@ "category": "redstone", "group": "wooden_fence_gate", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:oak_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:oak_planks" }, "pattern": [ "#W#", diff --git a/src/generated/resources/data/minecraft/recipe/oak_sign.json b/src/generated/resources/data/minecraft/recipe/oak_sign.json index 618d6d414a..1692e49e39 100644 --- a/src/generated/resources/data/minecraft/recipe/oak_sign.json +++ b/src/generated/resources/data/minecraft/recipe/oak_sign.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_sign", "key": { - "#": { - "item": "minecraft:oak_planks" - }, - "X": { - "tag": "c:rods/wooden" - } + "#": "minecraft:oak_planks", + "X": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/observer.json b/src/generated/resources/data/minecraft/recipe/observer.json index d48ca4adf2..f29722af98 100644 --- a/src/generated/resources/data/minecraft/recipe/observer.json +++ b/src/generated/resources/data/minecraft/recipe/observer.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "c:cobblestones/normal" - }, - "Q": { - "item": "minecraft:quartz" - }, - "R": { - "item": "minecraft:redstone" - } + "#": "#c:cobblestones/normal", + "Q": "minecraft:quartz", + "R": "minecraft:redstone" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/orange_banner.json b/src/generated/resources/data/minecraft/recipe/orange_banner.json index f2f3b03d6c..8bbc0dbf42 100644 --- a/src/generated/resources/data/minecraft/recipe/orange_banner.json +++ b/src/generated/resources/data/minecraft/recipe/orange_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:orange_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:orange_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/orange_candle.json b/src/generated/resources/data/minecraft/recipe/orange_candle.json new file mode 100644 index 0000000000..9708bbc215 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/orange_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/orange" + ], + "result": { + "count": 1, + "id": "minecraft:orange_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/orange_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/orange_concrete_powder.json new file mode 100644 index 0000000000..39d2b83e2e --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/orange_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/orange", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:orange_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/orange_dye_from_red_yellow.json b/src/generated/resources/data/minecraft/recipe/orange_dye_from_red_yellow.json new file mode 100644 index 0000000000..72f057275b --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/orange_dye_from_red_yellow.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "orange_dye", + "ingredients": [ + "#c:dyes/red", + "#c:dyes/yellow" + ], + "result": { + "count": 2, + "id": "minecraft:orange_dye" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/orange_stained_glass.json b/src/generated/resources/data/minecraft/recipe/orange_stained_glass.json new file mode 100644 index 0000000000..2af7f1c934 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/orange_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/orange" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:orange_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/orange_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/orange_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..34da9c5f66 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/orange_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/orange" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:orange_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/orange_terracotta.json b/src/generated/resources/data/minecraft/recipe/orange_terracotta.json new file mode 100644 index 0000000000..aad543f050 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/orange_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/orange" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:orange_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/painting.json b/src/generated/resources/data/minecraft/recipe/painting.json index df1b6d324d..64b32014dc 100644 --- a/src/generated/resources/data/minecraft/recipe/painting.json +++ b/src/generated/resources/data/minecraft/recipe/painting.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "minecraft:wool" - } + "#": "#c:rods/wooden", + "X": "#minecraft:wool" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/pink_banner.json b/src/generated/resources/data/minecraft/recipe/pink_banner.json index 951e77cedd..4fd7901e5d 100644 --- a/src/generated/resources/data/minecraft/recipe/pink_banner.json +++ b/src/generated/resources/data/minecraft/recipe/pink_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:pink_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:pink_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/pink_candle.json b/src/generated/resources/data/minecraft/recipe/pink_candle.json new file mode 100644 index 0000000000..d62dd11724 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/pink_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/pink" + ], + "result": { + "count": 1, + "id": "minecraft:pink_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/pink_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/pink_concrete_powder.json new file mode 100644 index 0000000000..90df434f33 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/pink_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/pink", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:pink_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/pink_dye_from_red_white_dye.json b/src/generated/resources/data/minecraft/recipe/pink_dye_from_red_white_dye.json new file mode 100644 index 0000000000..7118cf0343 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/pink_dye_from_red_white_dye.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "pink_dye", + "ingredients": [ + "#c:dyes/red", + "#c:dyes/white" + ], + "result": { + "count": 2, + "id": "minecraft:pink_dye" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/pink_stained_glass.json b/src/generated/resources/data/minecraft/recipe/pink_stained_glass.json new file mode 100644 index 0000000000..ea7cf3ecae --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/pink_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/pink" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:pink_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/pink_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/pink_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..d2e13b56e0 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/pink_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/pink" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:pink_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/pink_terracotta.json b/src/generated/resources/data/minecraft/recipe/pink_terracotta.json new file mode 100644 index 0000000000..6d21dd2a75 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/pink_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/pink" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:pink_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/piston.json b/src/generated/resources/data/minecraft/recipe/piston.json index b57e13cfbc..84593e660c 100644 --- a/src/generated/resources/data/minecraft/recipe/piston.json +++ b/src/generated/resources/data/minecraft/recipe/piston.json @@ -2,18 +2,10 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "c:cobblestones/normal" - }, - "R": { - "item": "minecraft:redstone" - }, - "T": { - "tag": "minecraft:planks" - }, - "X": { - "tag": "c:ingots/iron" - } + "#": "#c:cobblestones/normal", + "R": "minecraft:redstone", + "T": "#minecraft:planks", + "X": "#c:ingots/iron" }, "pattern": [ "TTT", diff --git a/src/generated/resources/data/minecraft/recipe/polished_deepslate.json b/src/generated/resources/data/minecraft/recipe/polished_deepslate.json index 97f277e6b1..10b6ccbff7 100644 --- a/src/generated/resources/data/minecraft/recipe/polished_deepslate.json +++ b/src/generated/resources/data/minecraft/recipe/polished_deepslate.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "building", "key": { - "S": { - "tag": "c:cobblestones/deepslate" - } + "S": "#c:cobblestones/deepslate" }, "pattern": [ "SS", diff --git a/src/generated/resources/data/minecraft/recipe/powered_rail.json b/src/generated/resources/data/minecraft/recipe/powered_rail.json index 97f3e17964..40d834f692 100644 --- a/src/generated/resources/data/minecraft/recipe/powered_rail.json +++ b/src/generated/resources/data/minecraft/recipe/powered_rail.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "R": { - "item": "minecraft:redstone" - }, - "X": { - "tag": "c:ingots/gold" - } + "#": "#c:rods/wooden", + "R": "minecraft:redstone", + "X": "#c:ingots/gold" }, "pattern": [ "X X", diff --git a/src/generated/resources/data/minecraft/recipe/purple_banner.json b/src/generated/resources/data/minecraft/recipe/purple_banner.json index 5475bffc70..ed4b36c136 100644 --- a/src/generated/resources/data/minecraft/recipe/purple_banner.json +++ b/src/generated/resources/data/minecraft/recipe/purple_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:purple_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:purple_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/purple_candle.json b/src/generated/resources/data/minecraft/recipe/purple_candle.json new file mode 100644 index 0000000000..7f5ddcf289 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/purple_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/purple" + ], + "result": { + "count": 1, + "id": "minecraft:purple_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/purple_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/purple_concrete_powder.json new file mode 100644 index 0000000000..4f0c587f5a --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/purple_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/purple", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:purple_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/purple_dye.json b/src/generated/resources/data/minecraft/recipe/purple_dye.json new file mode 100644 index 0000000000..c3c75ae3d2 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/purple_dye.json @@ -0,0 +1,12 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + "#c:dyes/blue", + "#c:dyes/red" + ], + "result": { + "count": 2, + "id": "minecraft:purple_dye" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/purple_stained_glass.json b/src/generated/resources/data/minecraft/recipe/purple_stained_glass.json new file mode 100644 index 0000000000..a76149bc89 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/purple_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/purple" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:purple_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/purple_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/purple_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..bf11a7d689 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/purple_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/purple" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:purple_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/purple_terracotta.json b/src/generated/resources/data/minecraft/recipe/purple_terracotta.json new file mode 100644 index 0000000000..a7ee6cc737 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/purple_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/purple" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:purple_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/rail.json b/src/generated/resources/data/minecraft/recipe/rail.json index 481af10ee3..b9ed74f2f2 100644 --- a/src/generated/resources/data/minecraft/recipe/rail.json +++ b/src/generated/resources/data/minecraft/recipe/rail.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "c:ingots/iron" - } + "#": "#c:rods/wooden", + "X": "#c:ingots/iron" }, "pattern": [ "X X", diff --git a/src/generated/resources/data/minecraft/recipe/raiser_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/raiser_armor_trim_smithing_template.json index 97a148d159..f49dd8b54a 100644 --- a/src/generated/resources/data/minecraft/recipe/raiser_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/raiser_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "item": "minecraft:terracotta" - }, - "S": { - "item": "minecraft:raiser_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "minecraft:terracotta", + "S": "minecraft:raiser_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/red_banner.json b/src/generated/resources/data/minecraft/recipe/red_banner.json index 89b92a5470..9b0643110e 100644 --- a/src/generated/resources/data/minecraft/recipe/red_banner.json +++ b/src/generated/resources/data/minecraft/recipe/red_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:red_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:red_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/red_candle.json b/src/generated/resources/data/minecraft/recipe/red_candle.json new file mode 100644 index 0000000000..f658efa5d3 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/red_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/red" + ], + "result": { + "count": 1, + "id": "minecraft:red_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/red_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/red_concrete_powder.json new file mode 100644 index 0000000000..06ede8a2b6 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/red_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/red", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:red_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/red_stained_glass.json b/src/generated/resources/data/minecraft/recipe/red_stained_glass.json new file mode 100644 index 0000000000..0323b84f07 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/red_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/red" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:red_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/red_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/red_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..32f751142b --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/red_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/red" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:red_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/red_terracotta.json b/src/generated/resources/data/minecraft/recipe/red_terracotta.json new file mode 100644 index 0000000000..3a006cab3d --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/red_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/red" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:red_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/redstone_torch.json b/src/generated/resources/data/minecraft/recipe/redstone_torch.json index 378c0d7b88..ea402cb6e4 100644 --- a/src/generated/resources/data/minecraft/recipe/redstone_torch.json +++ b/src/generated/resources/data/minecraft/recipe/redstone_torch.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "item": "minecraft:redstone" - } + "#": "#c:rods/wooden", + "X": "minecraft:redstone" }, "pattern": [ "X", diff --git a/src/generated/resources/data/minecraft/recipe/rib_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/rib_armor_trim_smithing_template.json index 6ec72db0dd..f99a49c84f 100644 --- a/src/generated/resources/data/minecraft/recipe/rib_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/rib_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "item": "minecraft:netherrack" - }, - "S": { - "item": "minecraft:rib_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "minecraft:netherrack", + "S": "minecraft:rib_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/scaffolding.json b/src/generated/resources/data/minecraft/recipe/scaffolding.json index c0290aba8c..1393f3b416 100644 --- a/src/generated/resources/data/minecraft/recipe/scaffolding.json +++ b/src/generated/resources/data/minecraft/recipe/scaffolding.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "I": { - "item": "minecraft:bamboo" - }, - "~": { - "tag": "c:strings" - } + "I": "minecraft:bamboo", + "~": "#c:strings" }, "pattern": [ "I~I", diff --git a/src/generated/resources/data/minecraft/recipe/sentry_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/sentry_armor_trim_smithing_template.json index 8bfac2e3f9..e0a1a2a451 100644 --- a/src/generated/resources/data/minecraft/recipe/sentry_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/sentry_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "tag": "c:cobblestones/normal" - }, - "S": { - "item": "minecraft:sentry_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "#c:cobblestones/normal", + "S": "minecraft:sentry_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/shaper_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/shaper_armor_trim_smithing_template.json index 980b1d2108..e1f08a5ca1 100644 --- a/src/generated/resources/data/minecraft/recipe/shaper_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/shaper_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "item": "minecraft:terracotta" - }, - "S": { - "item": "minecraft:shaper_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "minecraft:terracotta", + "S": "minecraft:shaper_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/shears.json b/src/generated/resources/data/minecraft/recipe/shears.json index cc526718eb..ca02dfb8aa 100644 --- a/src/generated/resources/data/minecraft/recipe/shears.json +++ b/src/generated/resources/data/minecraft/recipe/shears.json @@ -2,9 +2,7 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:ingots/iron" - } + "#": "#c:ingots/iron" }, "pattern": [ " #", diff --git a/src/generated/resources/data/minecraft/recipe/shield.json b/src/generated/resources/data/minecraft/recipe/shield.json index 46aa8fbe7d..e0cc4be9a4 100644 --- a/src/generated/resources/data/minecraft/recipe/shield.json +++ b/src/generated/resources/data/minecraft/recipe/shield.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "W": { - "tag": "minecraft:planks" - }, - "o": { - "tag": "c:ingots/iron" - } + "W": "#minecraft:wooden_tool_materials", + "o": "#c:ingots/iron" }, "pattern": [ "WoW", diff --git a/src/generated/resources/data/minecraft/recipe/shulker_box.json b/src/generated/resources/data/minecraft/recipe/shulker_box.json index dd1c970102..6b74b70a57 100644 --- a/src/generated/resources/data/minecraft/recipe/shulker_box.json +++ b/src/generated/resources/data/minecraft/recipe/shulker_box.json @@ -3,17 +3,11 @@ "category": "misc", "key": { "#": { - "type": "neoforge:difference", - "base": { - "tag": "c:chests/wooden" - }, - "subtracted": { - "tag": "c:chests/trapped" - } + "neoforge:ingredient_type": "neoforge:difference", + "base": "#c:chests/wooden", + "subtracted": "#c:chests/trapped" }, - "-": { - "item": "minecraft:shulker_shell" - } + "-": "minecraft:shulker_shell" }, "pattern": [ "-", diff --git a/src/generated/resources/data/minecraft/recipe/silence_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/silence_armor_trim_smithing_template.json index 4ade3deadd..364cdd75a6 100644 --- a/src/generated/resources/data/minecraft/recipe/silence_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/silence_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "tag": "c:cobblestones/deepslate" - }, - "S": { - "item": "minecraft:silence_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "#c:cobblestones/deepslate", + "S": "minecraft:silence_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/smithing_table.json b/src/generated/resources/data/minecraft/recipe/smithing_table.json index e7dadd831c..cdf474dfc5 100644 --- a/src/generated/resources/data/minecraft/recipe/smithing_table.json +++ b/src/generated/resources/data/minecraft/recipe/smithing_table.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "minecraft:planks" - }, - "@": { - "tag": "c:ingots/iron" - } + "#": "#minecraft:planks", + "@": "#c:ingots/iron" }, "pattern": [ "@@", diff --git a/src/generated/resources/data/minecraft/recipe/snout_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/snout_armor_trim_smithing_template.json index 8aa0dd55c1..8f24674fdd 100644 --- a/src/generated/resources/data/minecraft/recipe/snout_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/snout_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "item": "minecraft:blackstone" - }, - "S": { - "item": "minecraft:snout_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "minecraft:blackstone", + "S": "minecraft:snout_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/soul_campfire.json b/src/generated/resources/data/minecraft/recipe/soul_campfire.json index e7459aa07d..8daec84a10 100644 --- a/src/generated/resources/data/minecraft/recipe/soul_campfire.json +++ b/src/generated/resources/data/minecraft/recipe/soul_campfire.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "minecraft:soul_fire_base_blocks" - }, - "L": { - "tag": "minecraft:logs" - }, - "S": { - "tag": "c:rods/wooden" - } + "#": "#minecraft:soul_fire_base_blocks", + "L": "#minecraft:logs", + "S": "#c:rods/wooden" }, "pattern": [ " S ", diff --git a/src/generated/resources/data/minecraft/recipe/soul_lantern.json b/src/generated/resources/data/minecraft/recipe/soul_lantern.json index e5f39ad8ec..3d06fd51d1 100644 --- a/src/generated/resources/data/minecraft/recipe/soul_lantern.json +++ b/src/generated/resources/data/minecraft/recipe/soul_lantern.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "item": "minecraft:soul_torch" - }, - "X": { - "tag": "c:nuggets/iron" - } + "#": "minecraft:soul_torch", + "X": "#c:nuggets/iron" }, "pattern": [ "XXX", diff --git a/src/generated/resources/data/minecraft/recipe/soul_torch.json b/src/generated/resources/data/minecraft/recipe/soul_torch.json index fc57b7b0d3..89fba8cfe0 100644 --- a/src/generated/resources/data/minecraft/recipe/soul_torch.json +++ b/src/generated/resources/data/minecraft/recipe/soul_torch.json @@ -2,19 +2,11 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "S": { - "tag": "minecraft:soul_fire_base_blocks" - }, + "#": "#c:rods/wooden", + "S": "#minecraft:soul_fire_base_blocks", "X": [ - { - "item": "minecraft:coal" - }, - { - "item": "minecraft:charcoal" - } + "minecraft:coal", + "minecraft:charcoal" ] }, "pattern": [ diff --git a/src/generated/resources/data/minecraft/recipe/spire_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/spire_armor_trim_smithing_template.json index 4cd59d3d03..a4f55cc155 100644 --- a/src/generated/resources/data/minecraft/recipe/spire_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/spire_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "item": "minecraft:purpur_block" - }, - "S": { - "item": "minecraft:spire_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "minecraft:purpur_block", + "S": "minecraft:spire_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/spruce_chest_boat.json b/src/generated/resources/data/minecraft/recipe/spruce_chest_boat.json index a98470ee61..b1c0547180 100644 --- a/src/generated/resources/data/minecraft/recipe/spruce_chest_boat.json +++ b/src/generated/resources/data/minecraft/recipe/spruce_chest_boat.json @@ -4,17 +4,11 @@ "group": "chest_boat", "ingredients": [ { - "type": "neoforge:difference", - "base": { - "tag": "c:chests/wooden" - }, - "subtracted": { - "tag": "c:chests/trapped" - } + "neoforge:ingredient_type": "neoforge:difference", + "base": "#c:chests/wooden", + "subtracted": "#c:chests/trapped" }, - { - "item": "minecraft:spruce_boat" - } + "minecraft:spruce_boat" ], "result": { "count": 1, diff --git a/src/generated/resources/data/minecraft/recipe/spruce_fence.json b/src/generated/resources/data/minecraft/recipe/spruce_fence.json index d8790bce04..f84b63a72b 100644 --- a/src/generated/resources/data/minecraft/recipe/spruce_fence.json +++ b/src/generated/resources/data/minecraft/recipe/spruce_fence.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_fence", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:spruce_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:spruce_planks" }, "pattern": [ "W#W", diff --git a/src/generated/resources/data/minecraft/recipe/spruce_fence_gate.json b/src/generated/resources/data/minecraft/recipe/spruce_fence_gate.json index 61815e9606..ea1f612c1f 100644 --- a/src/generated/resources/data/minecraft/recipe/spruce_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/spruce_fence_gate.json @@ -3,12 +3,8 @@ "category": "redstone", "group": "wooden_fence_gate", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:spruce_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:spruce_planks" }, "pattern": [ "#W#", diff --git a/src/generated/resources/data/minecraft/recipe/spruce_sign.json b/src/generated/resources/data/minecraft/recipe/spruce_sign.json index 03fb28133e..58046b4828 100644 --- a/src/generated/resources/data/minecraft/recipe/spruce_sign.json +++ b/src/generated/resources/data/minecraft/recipe/spruce_sign.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_sign", "key": { - "#": { - "item": "minecraft:spruce_planks" - }, - "X": { - "tag": "c:rods/wooden" - } + "#": "minecraft:spruce_planks", + "X": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/spyglass.json b/src/generated/resources/data/minecraft/recipe/spyglass.json index ea680e3fb9..d2caaad362 100644 --- a/src/generated/resources/data/minecraft/recipe/spyglass.json +++ b/src/generated/resources/data/minecraft/recipe/spyglass.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:gems/amethyst" - }, - "X": { - "tag": "c:ingots/copper" - } + "#": "#c:gems/amethyst", + "X": "#c:ingots/copper" }, "pattern": [ " # ", diff --git a/src/generated/resources/data/minecraft/recipe/stone_axe.json b/src/generated/resources/data/minecraft/recipe/stone_axe.json index 0bac2f1180..8d557557d6 100644 --- a/src/generated/resources/data/minecraft/recipe/stone_axe.json +++ b/src/generated/resources/data/minecraft/recipe/stone_axe.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "minecraft:stone_tool_materials" - } + "#": "#c:rods/wooden", + "X": "#minecraft:stone_tool_materials" }, "pattern": [ "XX", diff --git a/src/generated/resources/data/minecraft/recipe/stone_hoe.json b/src/generated/resources/data/minecraft/recipe/stone_hoe.json index 8c5b5eceee..8ed74421de 100644 --- a/src/generated/resources/data/minecraft/recipe/stone_hoe.json +++ b/src/generated/resources/data/minecraft/recipe/stone_hoe.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "minecraft:stone_tool_materials" - } + "#": "#c:rods/wooden", + "X": "#minecraft:stone_tool_materials" }, "pattern": [ "XX", diff --git a/src/generated/resources/data/minecraft/recipe/stone_pickaxe.json b/src/generated/resources/data/minecraft/recipe/stone_pickaxe.json index b366ac2065..cd245c22c4 100644 --- a/src/generated/resources/data/minecraft/recipe/stone_pickaxe.json +++ b/src/generated/resources/data/minecraft/recipe/stone_pickaxe.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "minecraft:stone_tool_materials" - } + "#": "#c:rods/wooden", + "X": "#minecraft:stone_tool_materials" }, "pattern": [ "XXX", diff --git a/src/generated/resources/data/minecraft/recipe/stone_shovel.json b/src/generated/resources/data/minecraft/recipe/stone_shovel.json index d1fbdebd22..bde9b0a8be 100644 --- a/src/generated/resources/data/minecraft/recipe/stone_shovel.json +++ b/src/generated/resources/data/minecraft/recipe/stone_shovel.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "minecraft:stone_tool_materials" - } + "#": "#c:rods/wooden", + "X": "#minecraft:stone_tool_materials" }, "pattern": [ "X", diff --git a/src/generated/resources/data/minecraft/recipe/stone_sword.json b/src/generated/resources/data/minecraft/recipe/stone_sword.json index 559caac73d..cdff3bf44e 100644 --- a/src/generated/resources/data/minecraft/recipe/stone_sword.json +++ b/src/generated/resources/data/minecraft/recipe/stone_sword.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "minecraft:stone_tool_materials" - } + "#": "#c:rods/wooden", + "X": "#minecraft:stone_tool_materials" }, "pattern": [ "X", diff --git a/src/generated/resources/data/minecraft/recipe/stonecutter.json b/src/generated/resources/data/minecraft/recipe/stonecutter.json index e0820aeedb..e2f95eecf4 100644 --- a/src/generated/resources/data/minecraft/recipe/stonecutter.json +++ b/src/generated/resources/data/minecraft/recipe/stonecutter.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "item": "minecraft:stone" - }, - "I": { - "tag": "c:ingots/iron" - } + "#": "minecraft:stone", + "I": "#c:ingots/iron" }, "pattern": [ " I ", diff --git a/src/generated/resources/data/minecraft/recipe/tide_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/tide_armor_trim_smithing_template.json index 8292dd0993..4f4f0feec4 100644 --- a/src/generated/resources/data/minecraft/recipe/tide_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/tide_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "item": "minecraft:prismarine" - }, - "S": { - "item": "minecraft:tide_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "minecraft:prismarine", + "S": "minecraft:tide_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/tinted_glass.json b/src/generated/resources/data/minecraft/recipe/tinted_glass.json index 99d27ab3d3..899d357f7e 100644 --- a/src/generated/resources/data/minecraft/recipe/tinted_glass.json +++ b/src/generated/resources/data/minecraft/recipe/tinted_glass.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "building", "key": { - "G": { - "item": "minecraft:glass" - }, - "S": { - "tag": "c:gems/amethyst" - } + "G": "minecraft:glass", + "S": "#c:gems/amethyst" }, "pattern": [ " S ", diff --git a/src/generated/resources/data/minecraft/recipe/torch.json b/src/generated/resources/data/minecraft/recipe/torch.json index 031078faf0..442a61780e 100644 --- a/src/generated/resources/data/minecraft/recipe/torch.json +++ b/src/generated/resources/data/minecraft/recipe/torch.json @@ -2,16 +2,10 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:rods/wooden" - }, + "#": "#c:rods/wooden", "X": [ - { - "item": "minecraft:coal" - }, - { - "item": "minecraft:charcoal" - } + "minecraft:coal", + "minecraft:charcoal" ] }, "pattern": [ diff --git a/src/generated/resources/data/minecraft/recipe/trapped_chest.json b/src/generated/resources/data/minecraft/recipe/trapped_chest.json index 1d48d691df..bd85e9bcad 100644 --- a/src/generated/resources/data/minecraft/recipe/trapped_chest.json +++ b/src/generated/resources/data/minecraft/recipe/trapped_chest.json @@ -3,17 +3,11 @@ "category": "redstone", "ingredients": [ { - "type": "neoforge:difference", - "base": { - "tag": "c:chests/wooden" - }, - "subtracted": { - "tag": "c:chests/trapped" - } + "neoforge:ingredient_type": "neoforge:difference", + "base": "#c:chests/wooden", + "subtracted": "#c:chests/trapped" }, - { - "item": "minecraft:tripwire_hook" - } + "minecraft:tripwire_hook" ], "result": { "count": 1, diff --git a/src/generated/resources/data/minecraft/recipe/tripwire_hook.json b/src/generated/resources/data/minecraft/recipe/tripwire_hook.json index b966ce7a63..9248d9973e 100644 --- a/src/generated/resources/data/minecraft/recipe/tripwire_hook.json +++ b/src/generated/resources/data/minecraft/recipe/tripwire_hook.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "redstone", "key": { - "#": { - "tag": "minecraft:planks" - }, - "I": { - "tag": "c:ingots/iron" - }, - "S": { - "tag": "c:rods/wooden" - } + "#": "#minecraft:planks", + "I": "#c:ingots/iron", + "S": "#c:rods/wooden" }, "pattern": [ "I", diff --git a/src/generated/resources/data/minecraft/recipe/vex_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/vex_armor_trim_smithing_template.json index c4346ef9e4..33b599c546 100644 --- a/src/generated/resources/data/minecraft/recipe/vex_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/vex_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "tag": "c:cobblestones/normal" - }, - "S": { - "item": "minecraft:vex_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "#c:cobblestones/normal", + "S": "minecraft:vex_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/ward_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/ward_armor_trim_smithing_template.json index 1e6185aa9d..9a4b94b40f 100644 --- a/src/generated/resources/data/minecraft/recipe/ward_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/ward_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "tag": "c:cobblestones/deepslate" - }, - "S": { - "item": "minecraft:ward_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "#c:cobblestones/deepslate", + "S": "minecraft:ward_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/warped_fence.json b/src/generated/resources/data/minecraft/recipe/warped_fence.json index 715d558dd6..54684ffb50 100644 --- a/src/generated/resources/data/minecraft/recipe/warped_fence.json +++ b/src/generated/resources/data/minecraft/recipe/warped_fence.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_fence", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:warped_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:warped_planks" }, "pattern": [ "W#W", diff --git a/src/generated/resources/data/minecraft/recipe/warped_fence_gate.json b/src/generated/resources/data/minecraft/recipe/warped_fence_gate.json index 15dcad57d5..bd500ac089 100644 --- a/src/generated/resources/data/minecraft/recipe/warped_fence_gate.json +++ b/src/generated/resources/data/minecraft/recipe/warped_fence_gate.json @@ -3,12 +3,8 @@ "category": "redstone", "group": "wooden_fence_gate", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "W": { - "item": "minecraft:warped_planks" - } + "#": "#c:rods/wooden", + "W": "minecraft:warped_planks" }, "pattern": [ "#W#", diff --git a/src/generated/resources/data/minecraft/recipe/warped_sign.json b/src/generated/resources/data/minecraft/recipe/warped_sign.json index b0f4112a6d..fd63852c3b 100644 --- a/src/generated/resources/data/minecraft/recipe/warped_sign.json +++ b/src/generated/resources/data/minecraft/recipe/warped_sign.json @@ -3,12 +3,8 @@ "category": "misc", "group": "wooden_sign", "key": { - "#": { - "item": "minecraft:warped_planks" - }, - "X": { - "tag": "c:rods/wooden" - } + "#": "minecraft:warped_planks", + "X": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/wayfinder_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/wayfinder_armor_trim_smithing_template.json index 563776c2c5..3c93a650a0 100644 --- a/src/generated/resources/data/minecraft/recipe/wayfinder_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/wayfinder_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "item": "minecraft:terracotta" - }, - "S": { - "item": "minecraft:wayfinder_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "minecraft:terracotta", + "S": "minecraft:wayfinder_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/white_banner.json b/src/generated/resources/data/minecraft/recipe/white_banner.json index 418906d5b9..0f87a1e878 100644 --- a/src/generated/resources/data/minecraft/recipe/white_banner.json +++ b/src/generated/resources/data/minecraft/recipe/white_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:white_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:white_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/white_candle.json b/src/generated/resources/data/minecraft/recipe/white_candle.json new file mode 100644 index 0000000000..45b193d999 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/white_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/white" + ], + "result": { + "count": 1, + "id": "minecraft:white_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/white_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/white_concrete_powder.json new file mode 100644 index 0000000000..e5778a9ff2 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/white_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/white", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:white_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/white_stained_glass.json b/src/generated/resources/data/minecraft/recipe/white_stained_glass.json new file mode 100644 index 0000000000..f609fa37f4 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/white_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/white" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:white_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/white_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/white_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..ce5471a140 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/white_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/white" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:white_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/white_terracotta.json b/src/generated/resources/data/minecraft/recipe/white_terracotta.json new file mode 100644 index 0000000000..7fd1569e33 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/white_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/white" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:white_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/wild_armor_trim_smithing_template.json b/src/generated/resources/data/minecraft/recipe/wild_armor_trim_smithing_template.json index 8eec0dc5e9..0048eb4531 100644 --- a/src/generated/resources/data/minecraft/recipe/wild_armor_trim_smithing_template.json +++ b/src/generated/resources/data/minecraft/recipe/wild_armor_trim_smithing_template.json @@ -2,15 +2,9 @@ "type": "minecraft:crafting_shaped", "category": "misc", "key": { - "#": { - "tag": "c:gems/diamond" - }, - "C": { - "item": "minecraft:mossy_cobblestone" - }, - "S": { - "item": "minecraft:wild_armor_trim_smithing_template" - } + "#": "#c:gems/diamond", + "C": "minecraft:mossy_cobblestone", + "S": "minecraft:wild_armor_trim_smithing_template" }, "pattern": [ "#S#", diff --git a/src/generated/resources/data/minecraft/recipe/wooden_axe.json b/src/generated/resources/data/minecraft/recipe/wooden_axe.json index 25cc73c46f..05fdaaad7e 100644 --- a/src/generated/resources/data/minecraft/recipe/wooden_axe.json +++ b/src/generated/resources/data/minecraft/recipe/wooden_axe.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "minecraft:planks" - } + "#": "#c:rods/wooden", + "X": "#minecraft:wooden_tool_materials" }, "pattern": [ "XX", diff --git a/src/generated/resources/data/minecraft/recipe/wooden_hoe.json b/src/generated/resources/data/minecraft/recipe/wooden_hoe.json index a068c7fdc5..6fd2085dda 100644 --- a/src/generated/resources/data/minecraft/recipe/wooden_hoe.json +++ b/src/generated/resources/data/minecraft/recipe/wooden_hoe.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "minecraft:planks" - } + "#": "#c:rods/wooden", + "X": "#minecraft:wooden_tool_materials" }, "pattern": [ "XX", diff --git a/src/generated/resources/data/minecraft/recipe/wooden_pickaxe.json b/src/generated/resources/data/minecraft/recipe/wooden_pickaxe.json index b09f9389ab..ff84e265b6 100644 --- a/src/generated/resources/data/minecraft/recipe/wooden_pickaxe.json +++ b/src/generated/resources/data/minecraft/recipe/wooden_pickaxe.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "minecraft:planks" - } + "#": "#c:rods/wooden", + "X": "#minecraft:wooden_tool_materials" }, "pattern": [ "XXX", diff --git a/src/generated/resources/data/minecraft/recipe/wooden_shovel.json b/src/generated/resources/data/minecraft/recipe/wooden_shovel.json index dd2aa5e363..3aac8226a5 100644 --- a/src/generated/resources/data/minecraft/recipe/wooden_shovel.json +++ b/src/generated/resources/data/minecraft/recipe/wooden_shovel.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "minecraft:planks" - } + "#": "#c:rods/wooden", + "X": "#minecraft:wooden_tool_materials" }, "pattern": [ "X", diff --git a/src/generated/resources/data/minecraft/recipe/wooden_sword.json b/src/generated/resources/data/minecraft/recipe/wooden_sword.json index 8906ea876f..35a7a42140 100644 --- a/src/generated/resources/data/minecraft/recipe/wooden_sword.json +++ b/src/generated/resources/data/minecraft/recipe/wooden_sword.json @@ -2,12 +2,8 @@ "type": "minecraft:crafting_shaped", "category": "equipment", "key": { - "#": { - "tag": "c:rods/wooden" - }, - "X": { - "tag": "minecraft:planks" - } + "#": "#c:rods/wooden", + "X": "#minecraft:wooden_tool_materials" }, "pattern": [ "X", diff --git a/src/generated/resources/data/minecraft/recipe/yellow_banner.json b/src/generated/resources/data/minecraft/recipe/yellow_banner.json index 5c1c07e88b..6228650872 100644 --- a/src/generated/resources/data/minecraft/recipe/yellow_banner.json +++ b/src/generated/resources/data/minecraft/recipe/yellow_banner.json @@ -3,12 +3,8 @@ "category": "misc", "group": "banner", "key": { - "#": { - "item": "minecraft:yellow_wool" - }, - "|": { - "tag": "c:rods/wooden" - } + "#": "minecraft:yellow_wool", + "|": "#c:rods/wooden" }, "pattern": [ "###", diff --git a/src/generated/resources/data/minecraft/recipe/yellow_candle.json b/src/generated/resources/data/minecraft/recipe/yellow_candle.json new file mode 100644 index 0000000000..a3decc14ae --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/yellow_candle.json @@ -0,0 +1,13 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "group": "dyed_candle", + "ingredients": [ + "minecraft:candle", + "#c:dyes/yellow" + ], + "result": { + "count": 1, + "id": "minecraft:yellow_candle" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/yellow_concrete_powder.json b/src/generated/resources/data/minecraft/recipe/yellow_concrete_powder.json new file mode 100644 index 0000000000..924d919978 --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/yellow_concrete_powder.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "building", + "group": "concrete_powder", + "ingredients": [ + "#c:dyes/yellow", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:sand", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel", + "minecraft:gravel" + ], + "result": { + "count": 8, + "id": "minecraft:yellow_concrete_powder" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/yellow_stained_glass.json b/src/generated/resources/data/minecraft/recipe/yellow_stained_glass.json new file mode 100644 index 0000000000..40f451fd6d --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/yellow_stained_glass.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_glass", + "key": { + "#": "minecraft:glass", + "X": "#c:dyes/yellow" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:yellow_stained_glass" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/yellow_stained_glass_pane_from_glass_pane.json b/src/generated/resources/data/minecraft/recipe/yellow_stained_glass_pane_from_glass_pane.json new file mode 100644 index 0000000000..ddfae8467d --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/yellow_stained_glass_pane_from_glass_pane.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "group": "stained_glass_pane", + "key": { + "#": "minecraft:glass_pane", + "$": "#c:dyes/yellow" + }, + "pattern": [ + "###", + "#$#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:yellow_stained_glass_pane" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/recipe/yellow_terracotta.json b/src/generated/resources/data/minecraft/recipe/yellow_terracotta.json new file mode 100644 index 0000000000..250951eefc --- /dev/null +++ b/src/generated/resources/data/minecraft/recipe/yellow_terracotta.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "building", + "group": "stained_terracotta", + "key": { + "#": "minecraft:terracotta", + "X": "#c:dyes/yellow" + }, + "pattern": [ + "###", + "#X#", + "###" + ], + "result": { + "count": 8, + "id": "minecraft:yellow_terracotta" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/neoforge/data_maps/entity_type/parrot_imitations.json b/src/generated/resources/data/neoforge/data_maps/entity_type/parrot_imitations.json index 15a3911080..513f03410d 100644 --- a/src/generated/resources/data/neoforge/data_maps/entity_type/parrot_imitations.json +++ b/src/generated/resources/data/neoforge/data_maps/entity_type/parrot_imitations.json @@ -12,6 +12,12 @@ "minecraft:cave_spider": { "sound": "minecraft:entity.parrot.imitate.spider" }, + "minecraft:creaking": { + "sound": "minecraft:entity.parrot.imitate.creaking" + }, + "minecraft:creaking_transient": { + "sound": "minecraft:entity.parrot.imitate.creaking" + }, "minecraft:creeper": { "sound": "minecraft:entity.parrot.imitate.creeper" }, diff --git a/src/generated/resources/data/neoforge/data_maps/item/compostables.json b/src/generated/resources/data/neoforge/data_maps/item/compostables.json index 7ed50fabc5..2b3bdff6a6 100644 --- a/src/generated/resources/data/neoforge/data_maps/item/compostables.json +++ b/src/generated/resources/data/neoforge/data_maps/item/compostables.json @@ -190,6 +190,21 @@ "minecraft:oxeye_daisy": { "chance": 0.65 }, + "minecraft:pale_hanging_moss": { + "chance": 0.3 + }, + "minecraft:pale_moss_block": { + "chance": 0.65 + }, + "minecraft:pale_moss_carpet": { + "chance": 0.3 + }, + "minecraft:pale_oak_leaves": { + "chance": 0.3 + }, + "minecraft:pale_oak_sapling": { + "chance": 0.3 + }, "minecraft:peony": { "chance": 0.65 }, diff --git a/src/generated/resources/pack.mcmeta b/src/generated/resources/pack.mcmeta index 6ab3546301..f49d678e8d 100644 --- a/src/generated/resources/pack.mcmeta +++ b/src/generated/resources/pack.mcmeta @@ -3,7 +3,7 @@ "description": { "translate": "pack.neoforge.description" }, - "pack_format": 48, + "pack_format": 57, "supported_formats": [ 0, 2147483647 diff --git a/src/generated/resources/reports/registry_order.json b/src/generated/resources/reports/registry_order.json index 17ea12b63d..0a52e90bf1 100644 --- a/src/generated/resources/reports/registry_order.json +++ b/src/generated/resources/reports/registry_order.json @@ -2,7 +2,6 @@ "order": [ "minecraft:attribute", "minecraft:data_component_type", - "minecraft:armor_material", "minecraft:game_event", "minecraft:sound_event", "minecraft:fluid", @@ -64,7 +63,6 @@ "minecraft:worldgen/pool_alias_binding", "minecraft:cat_variant", "minecraft:frog_variant", - "minecraft:instrument", "minecraft:decorated_pot_pattern", "minecraft:creative_mode_tab", "minecraft:trigger_type", @@ -78,6 +76,10 @@ "minecraft:enchantment_location_based_effect_type", "minecraft:enchantment_value_effect_type", "minecraft:enchantment_provider_type", + "minecraft:consume_effect_type", + "minecraft:recipe_display", + "minecraft:slot_display", + "minecraft:recipe_book_category", "neoforge:attachment_types", "neoforge:biome_modifier_serializers", "neoforge:condition_codecs", diff --git a/src/main/java/net/neoforged/neoforge/attachment/AttachmentHolder.java b/src/main/java/net/neoforged/neoforge/attachment/AttachmentHolder.java index 53b2c8bc49..e822d369cf 100644 --- a/src/main/java/net/neoforged/neoforge/attachment/AttachmentHolder.java +++ b/src/main/java/net/neoforged/neoforge/attachment/AttachmentHolder.java @@ -145,7 +145,7 @@ protected final void deserializeAttachments(HolderLookup.Provider provider, Comp continue; } - var type = NeoForgeRegistries.ATTACHMENT_TYPES.get(keyLocation); + var type = NeoForgeRegistries.ATTACHMENT_TYPES.getValue(keyLocation); if (type == null || type.serializer == null) { LOGGER.error("Encountered unknown or non-serializable data attachment {}. Skipping.", key); continue; diff --git a/src/main/java/net/neoforged/neoforge/capabilities/CapabilityHooks.java b/src/main/java/net/neoforged/neoforge/capabilities/CapabilityHooks.java index 73fe62a7f4..478e79e2ec 100644 --- a/src/main/java/net/neoforged/neoforge/capabilities/CapabilityHooks.java +++ b/src/main/java/net/neoforged/neoforge/capabilities/CapabilityHooks.java @@ -104,7 +104,15 @@ public static void registerVanillaProviders(RegisterCapabilitiesEvent event) { // Entities var containerEntities = List.of( - EntityType.CHEST_BOAT, + EntityType.ACACIA_CHEST_BOAT, + EntityType.BIRCH_CHEST_BOAT, + EntityType.CHERRY_CHEST_BOAT, + EntityType.DARK_OAK_CHEST_BOAT, + EntityType.JUNGLE_CHEST_BOAT, + EntityType.MANGROVE_CHEST_BOAT, + EntityType.OAK_CHEST_BOAT, + EntityType.SPRUCE_CHEST_BOAT, + EntityType.BAMBOO_CHEST_RAFT, EntityType.CHEST_MINECART, EntityType.HOPPER_MINECART); for (var entityType : containerEntities) { diff --git a/src/main/java/net/neoforged/neoforge/client/BlockEntityRenderBoundsDebugRenderer.java b/src/main/java/net/neoforged/neoforge/client/BlockEntityRenderBoundsDebugRenderer.java index a7cef0f09a..4df6e384c6 100644 --- a/src/main/java/net/neoforged/neoforge/client/BlockEntityRenderBoundsDebugRenderer.java +++ b/src/main/java/net/neoforged/neoforge/client/BlockEntityRenderBoundsDebugRenderer.java @@ -12,6 +12,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.ShapeRenderer; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.commands.Commands; import net.minecraft.core.BlockPos; @@ -52,7 +53,7 @@ private static void drawRenderBoundingBox(PoseStack poseStack, VertexConsumer co poseStack.pushPose(); poseStack.translate(offset.x, offset.y, offset.z); - LevelRenderer.renderLineBox(poseStack, consumer, aabb, 1F, 0F, 0F, 1F); + ShapeRenderer.renderLineBox(poseStack, consumer, aabb, 1F, 0F, 0F, 1F); poseStack.popPose(); } } diff --git a/src/main/java/net/neoforged/neoforge/client/ClientCommandHandler.java b/src/main/java/net/neoforged/neoforge/client/ClientCommandHandler.java index 742a76da5e..f4d4f28d01 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientCommandHandler.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientCommandHandler.java @@ -20,6 +20,7 @@ import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.client.player.LocalPlayer; import net.minecraft.commands.CommandBuildContext; +import net.minecraft.commands.CommandSource; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.SharedSuggestionProvider; import net.minecraft.commands.synchronization.SuggestionProviders; @@ -105,7 +106,28 @@ public static CommandDispatcher getDispatcher() { */ public static ClientCommandSourceStack getSource() { LocalPlayer player = Minecraft.getInstance().player; - return new ClientCommandSourceStack(player, player.position(), player.getRotationVector(), player.getPermissionLevel(), + CommandSource commandSource = new CommandSource() { + @Override + public boolean acceptsSuccess() { + return true; + } + + @Override + public boolean acceptsFailure() { + return true; + } + + @Override + public boolean shouldInformAdmins() { + return true; + } + + @Override + public void sendSystemMessage(Component message) { + Minecraft.getInstance().gui.getChat().addMessage(message); + } + }; + return new ClientCommandSourceStack(commandSource, player.position(), player.getRotationVector(), player.getPermissionLevel(), player.getName().getString(), player.getDisplayName(), player); } @@ -157,7 +179,7 @@ public static boolean runCommand(String command) { // in case of unknown command, let the server try and handle it return false; } - Minecraft.getInstance().player.sendSystemMessage( + Minecraft.getInstance().gui.getChat().addMessage( Component.literal("").append(ComponentUtils.fromMessage(syntax.getRawMessage())).withStyle(ChatFormatting.RED)); if (syntax.getInput() != null && syntax.getCursor() >= 0) { int position = Math.min(syntax.getInput().length(), syntax.getCursor()); @@ -173,12 +195,12 @@ public static boolean runCommand(String command) { details.append(Component.literal(syntax.getInput().substring(position)).withStyle(ChatFormatting.RED, ChatFormatting.UNDERLINE)); } details.append(Component.translatable("command.context.here").withStyle(ChatFormatting.RED, ChatFormatting.ITALIC)); - Minecraft.getInstance().player.sendSystemMessage(Component.literal("").append(details).withStyle(ChatFormatting.RED)); + Minecraft.getInstance().gui.getChat().addMessage(Component.literal("").append(details).withStyle(ChatFormatting.RED)); } } catch (Exception generic)// Probably thrown by the command { MutableComponent message = Component.literal(generic.getMessage() == null ? generic.getClass().getName() : generic.getMessage()); - Minecraft.getInstance().player.sendSystemMessage(Component.translatable("command.failed") + Minecraft.getInstance().gui.getChat().addMessage(Component.translatable("command.failed") .withStyle(ChatFormatting.RED) .withStyle((style) -> style .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, message)))); diff --git a/src/main/java/net/neoforged/neoforge/client/ClientCommandSourceStack.java b/src/main/java/net/neoforged/neoforge/client/ClientCommandSourceStack.java index 0d5a537de1..471b085f82 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientCommandSourceStack.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientCommandSourceStack.java @@ -5,27 +5,33 @@ package net.neoforged.neoforge.client; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; import java.util.Collection; import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; import java.util.stream.Collectors; -import java.util.stream.Stream; import net.minecraft.advancements.AdvancementHolder; import net.minecraft.client.Minecraft; import net.minecraft.commands.CommandSource; import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.SharedSuggestionProvider; +import net.minecraft.core.Registry; import net.minecraft.core.RegistryAccess; +import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; -import net.minecraft.world.item.crafting.RecipeManager; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; import net.minecraft.world.scores.Scoreboard; +import org.jetbrains.annotations.Nullable; /** * overrides for {@link CommandSourceStack} so that the methods will run successfully client side @@ -41,7 +47,7 @@ public ClientCommandSourceStack(CommandSource source, Vec3 position, Vec2 rotati */ @Override public void sendSuccess(Supplier message, boolean sendToAdmins) { - Minecraft.getInstance().player.sendSystemMessage(message.get()); + Minecraft.getInstance().gui.getChat().addMessage(message.get()); } /** @@ -60,12 +66,17 @@ public Collection getOnlinePlayerNames() { return Minecraft.getInstance().getConnection().getOnlinePlayers().stream().map((player) -> player.getProfile().getName()).collect(Collectors.toList()); } - /** - * {@return a {@link Stream} of recipe ids that are available on the client} - */ @Override - public Stream getRecipeNames() { - return Minecraft.getInstance().getConnection().getRecipeManager().getRecipeIds(); + public CompletableFuture suggestRegistryElements( + ResourceKey> p_212330_, + SharedSuggestionProvider.ElementSuggestionType p_212331_, + SuggestionsBuilder p_212332_, + CommandContext p_212333_) { + // TODO 1.21.2: Not sure what to do here. Letting super get called will cause an NPE on this.server. + if (p_212330_ == Registries.RECIPE || p_212330_ == Registries.ADVANCEMENT) { + return Suggestions.empty(); + } + return super.suggestRegistryElements(p_212330_, p_212331_, p_212332_, p_212333_); } /** @@ -96,18 +107,11 @@ public Scoreboard getScoreboard() { * {@return the advancement from the id from the client side where the advancement needs to be visible to the player} */ @Override + @Nullable public AdvancementHolder getAdvancement(ResourceLocation id) { return Minecraft.getInstance().getConnection().getAdvancements().get(id); } - /** - * {@return the {@link RecipeManager} from the client side} - */ - @Override - public RecipeManager getRecipeManager() { - return Minecraft.getInstance().getConnection().getRecipeManager(); - } - /** * {@return the level from the client side} */ diff --git a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java index 8bc74f258c..66c1e266d4 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientHooks.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientHooks.java @@ -10,14 +10,11 @@ import com.google.common.collect.ImmutableMap; import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.platform.Window; -import com.mojang.blaze3d.shaders.FogShape; -import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.datafixers.util.Either; import java.io.File; -import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -34,7 +31,6 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; -import net.minecraft.FileUtil; import net.minecraft.client.Camera; import net.minecraft.client.DeltaTracker; import net.minecraft.client.KeyMapping; @@ -50,7 +46,8 @@ import net.minecraft.client.gui.screens.MenuScreens; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.TitleScreen; -import net.minecraft.client.gui.screens.inventory.EffectRenderingInventoryScreen; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.gui.screens.inventory.EffectsInInventory; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipPositioner; import net.minecraft.client.model.HumanoidModel; @@ -64,14 +61,16 @@ import net.minecraft.client.particle.ParticleEngine; import net.minecraft.client.particle.ParticleRenderType; import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.client.player.Input; +import net.minecraft.client.player.ClientInput; import net.minecraft.client.player.LocalPlayer; +import net.minecraft.client.renderer.FogParameters; import net.minecraft.client.renderer.FogRenderer; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.ShaderInstance; +import net.minecraft.client.renderer.ShaderDefines; +import net.minecraft.client.renderer.ShaderProgram; import net.minecraft.client.renderer.block.BlockRenderDispatcher; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.BlockElement; @@ -79,6 +78,7 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.client.renderer.chunk.RenderChunkRegion; import net.minecraft.client.renderer.culling.Frustum; +import net.minecraft.client.renderer.entity.state.HumanoidRenderState; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.atlas.SpriteSourceType; @@ -107,19 +107,18 @@ import net.minecraft.sounds.Music; import net.minecraft.util.Mth; import net.minecraft.util.RandomSource; +import net.minecraft.util.profiling.Profiler; import net.minecraft.world.InteractionHand; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.HumanoidArm; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.RecipeBookType; import net.minecraft.world.inventory.tooltip.TooltipComponent; -import net.minecraft.world.item.ArmorMaterial; import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.RecipeManager; +import net.minecraft.world.item.equipment.EquipmentModel; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.GameType; import net.minecraft.world.level.Level; @@ -129,8 +128,6 @@ import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.FogType; import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.EntityHitResult; -import net.minecraft.world.phys.HitResult; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.Event; import net.neoforged.bus.api.SubscribeEvent; @@ -154,7 +151,6 @@ import net.neoforged.neoforge.client.event.InputEvent; import net.neoforged.neoforge.client.event.ModelEvent; import net.neoforged.neoforge.client.event.MovementInputUpdateEvent; -import net.neoforged.neoforge.client.event.RecipesUpdatedEvent; import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent; import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent; import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; @@ -196,6 +192,7 @@ import org.jetbrains.annotations.Nullable; import org.joml.Matrix4f; import org.joml.Vector3f; +import org.joml.Vector4f; /** * Class for various client-side-only hooks. @@ -256,9 +253,9 @@ public static float getGuiFarPlane() { return 11_000F + depth; } - public static ResourceLocation getArmorTexture(Entity entity, ItemStack armor, ArmorMaterial.Layer layer, boolean innerModel, EquipmentSlot slot) { - ResourceLocation result = armor.getItem().getArmorTexture(armor, entity, slot, layer, innerModel); - return result != null ? result : layer.texture(innerModel); + public static ResourceLocation getArmorTexture(ItemStack armor, EquipmentModel.LayerType type, EquipmentModel.Layer layer, ResourceLocation _default) { + ResourceLocation result = armor.getItem().getArmorTexture(armor, type, layer, _default); + return result != null ? result : _default; } public static boolean onClientPauseChangePre(boolean pause) { @@ -270,25 +267,15 @@ public static void onClientPauseChangePost(boolean pause) { NeoForge.EVENT_BUS.post(new ClientPauseChangeEvent.Post(pause)); } - public static boolean onDrawHighlight(LevelRenderer context, Camera camera, HitResult target, DeltaTracker deltaTracker, PoseStack poseStack, MultiBufferSource bufferSource) { - switch (target.getType()) { - case BLOCK: - if (!(target instanceof BlockHitResult blockTarget)) return false; - return NeoForge.EVENT_BUS.post(new RenderHighlightEvent.Block(context, camera, blockTarget, deltaTracker, poseStack, bufferSource)).isCanceled(); - case ENTITY: - if (!(target instanceof EntityHitResult entityTarget)) return false; - NeoForge.EVENT_BUS.post(new RenderHighlightEvent.Entity(context, camera, entityTarget, deltaTracker, poseStack, bufferSource)); - return false; - default: - return false; // NO-OP - This doesn't even get called for anything other than blocks and entities - } + public static boolean onDrawHighlight(LevelRenderer context, Camera camera, BlockHitResult target, DeltaTracker deltaTracker, PoseStack poseStack, MultiBufferSource bufferSource, boolean forTranslucentBlocks) { + return NeoForge.EVENT_BUS.post(new RenderHighlightEvent.Block(context, camera, target, deltaTracker, poseStack, bufferSource, forTranslucentBlocks)).isCanceled(); } public static void dispatchRenderStage(RenderLevelStageEvent.Stage stage, LevelRenderer levelRenderer, @Nullable PoseStack poseStack, Matrix4f modelViewMatrix, Matrix4f projectionMatrix, int renderTick, Camera camera, Frustum frustum) { var mc = Minecraft.getInstance(); - var profiler = mc.getProfiler(); + var profiler = Profiler.get(); profiler.push(stage.toString()); - NeoForge.EVENT_BUS.post(new RenderLevelStageEvent(stage, levelRenderer, poseStack, modelViewMatrix, projectionMatrix, renderTick, mc.getTimer(), camera, frustum)); + NeoForge.EVENT_BUS.post(new RenderLevelStageEvent(stage, levelRenderer, poseStack, modelViewMatrix, projectionMatrix, renderTick, mc.getDeltaTracker(), camera, frustum)); profiler.pop(); } @@ -318,13 +305,13 @@ public static void onItemColorsInit(ItemColors itemColors, BlockColors blockColo ModLoader.postEvent(new RegisterColorHandlersEvent.Item(itemColors, blockColors)); } - public static Model getArmorModel(LivingEntity entityLiving, ItemStack itemStack, EquipmentSlot slot, HumanoidModel _default) { - return IClientItemExtensions.of(itemStack).getGenericArmorModel(entityLiving, itemStack, slot, _default); + public static Model getArmorModel(ItemStack itemStack, EquipmentModel.LayerType layerType, Model _default) { + return IClientItemExtensions.of(itemStack).getGenericArmorModel(itemStack, layerType, _default); } /** Copies humanoid model properties from the original model to another, used for armor models */ @SuppressWarnings("unchecked") - public static void copyModelProperties(HumanoidModel original, HumanoidModel replacement) { + public static void copyModelProperties(HumanoidModel original, HumanoidModel replacement) { // this function does not make use of the generic, so the unchecked cast should be safe original.copyPropertiesTo((HumanoidModel) replacement); replacement.head.visible = original.head.visible; @@ -352,13 +339,13 @@ public static String fixDomain(String base, String complex) { } } - public static float getFieldOfViewModifier(Player entity, float fovModifier) { - ComputeFovModifierEvent fovModifierEvent = new ComputeFovModifierEvent(entity, fovModifier); + public static float getFieldOfViewModifier(Player entity, float fovModifier, float fovScale) { + ComputeFovModifierEvent fovModifierEvent = new ComputeFovModifierEvent(entity, fovModifier, fovScale); NeoForge.EVENT_BUS.post(fovModifierEvent); return fovModifierEvent.getNewFovModifier(); } - public static double getFieldOfView(GameRenderer renderer, Camera camera, double partialTick, double fov, boolean usedConfiguredFov) { + public static float getFieldOfView(GameRenderer renderer, Camera camera, float partialTick, float fov, boolean usedConfiguredFov) { ViewportEvent.ComputeFov event = new ViewportEvent.ComputeFov(renderer, camera, partialTick, fov, usedConfiguredFov); NeoForge.EVENT_BUS.post(event); return event.getFOV(); @@ -429,10 +416,10 @@ private static void drawScreenInternal(Screen screen, GuiGraphics guiGraphics, i NeoForge.EVENT_BUS.post(new ScreenEvent.Render.Post(screen, guiGraphics, mouseX, mouseY, partialTick)); } - public static Vector3f getFogColor(Camera camera, float partialTick, ClientLevel level, int renderDistance, float darkenWorldAmount, float fogRed, float fogGreen, float fogBlue) { + public static Vector4f getFogColor(Camera camera, float partialTick, ClientLevel level, int renderDistance, float darkenWorldAmount, float fogRed, float fogGreen, float fogBlue) { // Modify fog color depending on the fluid FluidState state = level.getFluidState(camera.getBlockPosition()); - Vector3f fluidFogColor = new Vector3f(fogRed, fogGreen, fogBlue); + Vector4f fluidFogColor = new Vector4f(fogRed, fogGreen, fogBlue, 1F); if (camera.getPosition().y < (double) ((float) camera.getBlockPosition().getY() + state.getHeight(level, camera.getBlockPosition()))) fluidFogColor = IClientFluidTypeExtensions.of(state).modifyFogColor(camera, partialTick, level, renderDistance, darkenWorldAmount, fluidFogColor); @@ -443,18 +430,24 @@ public static Vector3f getFogColor(Camera camera, float partialTick, ClientLevel return fluidFogColor; } - public static void onFogRender(FogRenderer.FogMode mode, FogType type, Camera camera, float partialTick, float renderDistance, float nearDistance, float farDistance, FogShape shape) { + public static FogParameters onFogRender(FogRenderer.FogMode mode, FogType type, Camera camera, float partialTick, float renderDistance, FogParameters fogParameters) { // Modify fog rendering depending on the fluid FluidState state = camera.getEntity().level().getFluidState(camera.getBlockPosition()); if (camera.getPosition().y < (double) ((float) camera.getBlockPosition().getY() + state.getHeight(camera.getEntity().level(), camera.getBlockPosition()))) - IClientFluidTypeExtensions.of(state).modifyFogRender(camera, mode, renderDistance, partialTick, nearDistance, farDistance, shape); + fogParameters = IClientFluidTypeExtensions.of(state).modifyFogRender(camera, mode, renderDistance, partialTick, fogParameters); - ViewportEvent.RenderFog event = new ViewportEvent.RenderFog(mode, type, camera, partialTick, nearDistance, farDistance, shape); + ViewportEvent.RenderFog event = new ViewportEvent.RenderFog(mode, type, camera, partialTick, fogParameters); if (NeoForge.EVENT_BUS.post(event).isCanceled()) { - RenderSystem.setShaderFogStart(event.getNearPlaneDistance()); - RenderSystem.setShaderFogEnd(event.getFarPlaneDistance()); - RenderSystem.setShaderFogShape(event.getFogShape()); + return new FogParameters( + event.getNearPlaneDistance(), + event.getFarPlaneDistance(), + event.getFogShape(), + fogParameters.red(), + fogParameters.green(), + fogParameters.blue(), + fogParameters.alpha()); } + return fogParameters; } public static void onModifyBakingResult(Map models, Map stitchResults, ModelBakery modelBakery) { @@ -530,11 +523,11 @@ public static boolean calculateFaceWithoutAO(BlockAndTintGetter getter, BlockSta return true; } - public static void loadEntityShader(Entity entity, GameRenderer entityRenderer) { + public static void loadEntityShader(@Nullable Entity entity, GameRenderer gameRenderer) { if (entity != null) { ResourceLocation shader = EntitySpectatorShaderManager.get(entity.getType()); if (shader != null) { - entityRenderer.loadEffect(shader); + gameRenderer.setPostEffect(shader); } } } @@ -558,7 +551,7 @@ public static boolean shouldCauseReequipAnimation(ItemStack from, ItemStack to, public static CustomizeGuiOverlayEvent.BossEventProgress onCustomizeBossEventProgress(GuiGraphics guiGraphics, Window window, LerpingBossEvent bossInfo, int x, int y, int increment) { CustomizeGuiOverlayEvent.BossEventProgress evt = new CustomizeGuiOverlayEvent.BossEventProgress(window, guiGraphics, - Minecraft.getInstance().getTimer(), bossInfo, x, y, increment); + Minecraft.getInstance().getDeltaTracker(), bossInfo, x, y, increment); NeoForge.EVENT_BUS.post(evt); return evt; } @@ -576,7 +569,7 @@ public static void onClientChangeGameType(PlayerInfo info, GameType currentGameM } } - public static void onMovementInputUpdate(Player player, Input movementInput) { + public static void onMovementInputUpdate(Player player, ClientInput movementInput) { NeoForge.EVENT_BUS.post(new MovementInputUpdateEvent(player, movementInput)); } @@ -658,11 +651,6 @@ public static void onScreenCharTypedPost(Screen guiScreen, char codePoint, int m NeoForge.EVENT_BUS.post(event); } - public static void onRecipesUpdated(RecipeManager mgr) { - Event event = new RecipesUpdatedEvent(mgr); - NeoForge.EVENT_BUS.post(event); - } - public static boolean onMouseButtonPre(int button, int action, int mods) { return NeoForge.EVENT_BUS.post(new InputEvent.MouseButton.Pre(button, action, mods)).isCanceled(); } @@ -686,12 +674,9 @@ public static InputEvent.InteractionKeyMappingTriggered onClickInput(int button, return event; } - public static boolean isNameplateInRenderDistance(Entity entity, double squareDistance) { - if (entity instanceof LivingEntity) { - double value = ((LivingEntity) entity).getAttributeValue(NeoForgeMod.NAMETAG_DISTANCE); - return !(squareDistance > value * value); - } - return !(squareDistance > 4096.0f); + public static boolean isNameplateInRenderDistance(LivingEntity entity, double squareDistance) { + double value = entity.getAttributeValue(NeoForgeMod.NAMETAG_DISTANCE); + return !(squareDistance > value * value); } public static void renderPistonMovedBlocks(BlockPos pos, BlockState state, PoseStack stack, MultiBufferSource bufferSource, Level level, boolean checkSides, int packedOverlay, BlockRenderDispatcher blockRenderer) { @@ -765,28 +750,16 @@ public static String onClientSendMessage(String message) { return NeoForge.EVENT_BUS.post(event).isCanceled() ? "" : event.getMessage(); } - /** - * Mimics the behavior of {@link net.minecraft.client.renderer.ItemBlockRenderTypes#getRenderType(BlockState, boolean)} - * for the input {@link RenderType}. - */ - public static RenderType getEntityRenderType(RenderType chunkRenderType, boolean cull) { - return RenderTypeHelper.getEntityRenderType(chunkRenderType, cull); - } - @EventBusSubscriber(value = Dist.CLIENT, modid = "neoforge", bus = EventBusSubscriber.Bus.MOD) public static class ClientEvents { - @Nullable - private static ShaderInstance rendertypeEntityTranslucentUnlitShader; - - public static ShaderInstance getEntityTranslucentUnlitShader() { - return Objects.requireNonNull(rendertypeEntityTranslucentUnlitShader, "Attempted to call getEntityTranslucentUnlitShader before shaders have finished loading."); - } + public static final ShaderProgram RENDERTYPE_ENTITY_TRANSLUCENT_UNLIT_SHADER = new ShaderProgram( + ResourceLocation.fromNamespaceAndPath(NeoForgeVersion.MOD_ID, "core/rendertype_entity_unlit_translucent"), + DefaultVertexFormat.NEW_ENTITY, + ShaderDefines.EMPTY); @SubscribeEvent - public static void registerShaders(RegisterShadersEvent event) throws IOException { - event.registerShader(new ShaderInstance(event.getResourceProvider(), ResourceLocation.fromNamespaceAndPath("neoforge", "rendertype_entity_unlit_translucent"), DefaultVertexFormat.NEW_ENTITY), (p_172645_) -> { - rendertypeEntityTranslucentUnlitShader = p_172645_; - }); + public static void registerShaders(RegisterShadersEvent event) { + event.registerShader(RENDERTYPE_ENTITY_TRANSLUCENT_UNLIT_SHADER); } } @@ -801,6 +774,7 @@ public static RenderTooltipEvent.Pre onRenderTooltipPre(ItemStack stack, GuiGrap return preEvent; } + // TODO porting: potentially replace with a background texture event public static RenderTooltipEvent.Color onRenderTooltipColor(ItemStack stack, GuiGraphics graphics, int x, int y, Font font, List components) { var colorEvent = new RenderTooltipEvent.Color(stack, graphics, x, y, font, 0xf0100010, 0x505000FF, 0x5028007f, components); NeoForge.EVENT_BUS.post(colorEvent); @@ -923,13 +897,6 @@ public static int getMaxMipmapLevel(int width, int height) { Mth.log2(Math.max(1, height))); } - public static ResourceLocation getShaderImportLocation(String basePath, boolean isRelative, String importPath) { - final var loc = ResourceLocation.parse(importPath); - final var normalised = FileUtil.normalizeResourcePath( - (isRelative ? basePath : "shaders/include/") + loc.getPath()); - return ResourceLocation.fromNamespaceAndPath(loc.getNamespace(), normalised); - } - private static final BiMap SPRITE_SOURCE_TYPES_MAP = HashBiMap.create(); public static BiMap makeSpriteSourceTypesMap() { @@ -1038,10 +1005,11 @@ public static void initClientHooks(Minecraft mc, ReloadableResourceManager resou MapDecorationRendererManager.init(); DimensionTransitionScreenManager.init(); AnimationTypeManager.init(); + CoreShaderManager.init(); } /** - * Fires {@link RenderFrameEvent.Pre}. Called just before {@link GameRenderer#render(float, long, boolean)} in {@link Minecraft#runTick(boolean)}. + * Fires {@link RenderFrameEvent.Pre}. Called just before {@link GameRenderer#render(DeltaTracker, boolean)} in {@link Minecraft#runTick(boolean)}. *

* Fired before the profiler section for "gameRenderer" is started. * @@ -1052,14 +1020,14 @@ public static void fireRenderFramePre(DeltaTracker partialTick) { } /** - * Fires {@link RenderFrameEvent.Post}. Called just after {@link GameRenderer#render(float, long, boolean)} in {@link Minecraft#runTick(boolean)}. + * Fires {@link RenderFrameEvent.Post}. Called just after {@link GameRenderer#render(DeltaTracker, boolean)} in {@link Minecraft#runTick(boolean)}. *

* Fired after the profiler section for "gameRenderer" is ended. * * @param partialTick The current partial tick */ - public static void fireRenderFramePost(DeltaTracker partialRick) { - NeoForge.EVENT_BUS.post(new RenderFrameEvent.Post(partialRick)); + public static void fireRenderFramePost(DeltaTracker partialTick) { + NeoForge.EVENT_BUS.post(new RenderFrameEvent.Post(partialTick)); } /** @@ -1089,14 +1057,14 @@ public static RegistryLookup resolveLookup(ResourceKey - * Called from {@link EffectRenderingInventoryScreen#renderEffects} just before {@link GuiGraphics#renderTooltip(Font, List, Optional, int, int)} is called. + * Called from {@link EffectsInInventory#renderEffects} just before {@link GuiGraphics#renderTooltip(Font, List, Optional, int, int)} is called. * * @param screen The screen rendering the tooltip. * @param effectInst The effect instance whose tooltip is being rendered. * @param tooltip An immutable list containing the existing tooltip lines, which consist of the name and the duration. * @return The new tooltip lines, modified by the event. */ - public static List getEffectTooltip(EffectRenderingInventoryScreen screen, MobEffectInstance effectInst, List tooltip) { + public static List getEffectTooltip(AbstractContainerScreen screen, MobEffectInstance effectInst, List tooltip) { var event = new GatherEffectScreenTooltipsEvent(screen, effectInst, tooltip); NeoForge.EVENT_BUS.post(event); return event.getTooltip(); diff --git a/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java b/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java index 071977233d..c378194405 100644 --- a/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/client/ClientNeoForgeMod.java @@ -30,7 +30,6 @@ import net.neoforged.neoforge.client.gui.IConfigScreenFactory; import net.neoforged.neoforge.client.model.CompositeModel; import net.neoforged.neoforge.client.model.DynamicFluidContainerModel; -import net.neoforged.neoforge.client.model.ElementsModel; import net.neoforged.neoforge.client.model.EmptyModel; import net.neoforged.neoforge.client.model.ItemLayerModel; import net.neoforged.neoforge.client.model.SeparateTransformsModel; @@ -66,7 +65,6 @@ public ClientNeoForgeMod(IEventBus modEventBus, ModContainer container) { @SubscribeEvent static void onRegisterGeometryLoaders(ModelEvent.RegisterGeometryLoaders event) { event.register(ResourceLocation.fromNamespaceAndPath("neoforge", "empty"), EmptyModel.LOADER); - event.register(ResourceLocation.fromNamespaceAndPath("neoforge", "elements"), ElementsModel.Loader.INSTANCE); event.register(ResourceLocation.fromNamespaceAndPath("neoforge", "obj"), ObjLoader.INSTANCE); event.register(ResourceLocation.fromNamespaceAndPath("neoforge", "fluid_container"), DynamicFluidContainerModel.Loader.INSTANCE); event.register(ResourceLocation.fromNamespaceAndPath("neoforge", "composite"), CompositeModel.Loader.INSTANCE); diff --git a/src/main/java/net/neoforged/neoforge/client/CoreShaderManager.java b/src/main/java/net/neoforged/neoforge/client/CoreShaderManager.java new file mode 100644 index 0000000000..a07d12e86a --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/CoreShaderManager.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import net.minecraft.client.renderer.CoreShaders; +import net.minecraft.client.renderer.ShaderProgram; +import net.neoforged.fml.ModLoader; +import net.neoforged.neoforge.client.event.RegisterShadersEvent; +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +public final class CoreShaderManager { + private static List shaderPrograms = Collections.emptyList(); + + private CoreShaderManager() {} + + public static void init() { + List programs = new ArrayList<>(CoreShaders.getProgramsToPreload()); + ModLoader.postEvent(new RegisterShadersEvent(programs)); + shaderPrograms = List.copyOf(programs); + } + + public static List getProgramsToPreload() { + return shaderPrograms; + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/IArmPoseTransformer.java b/src/main/java/net/neoforged/neoforge/client/IArmPoseTransformer.java index cd41d9e1b0..9cac689cf5 100644 --- a/src/main/java/net/neoforged/neoforge/client/IArmPoseTransformer.java +++ b/src/main/java/net/neoforged/neoforge/client/IArmPoseTransformer.java @@ -6,6 +6,7 @@ package net.neoforged.neoforge.client; import net.minecraft.client.model.HumanoidModel; +import net.minecraft.client.renderer.entity.state.HumanoidRenderState; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.HumanoidArm; import net.minecraft.world.entity.LivingEntity; @@ -27,5 +28,5 @@ public interface IArmPoseTransformer { * @param entity The humanoid entity * @param arm Arm to pose */ - void applyTransform(HumanoidModel model, LivingEntity entity, HumanoidArm arm); + void applyTransform(HumanoidModel model, HumanoidRenderState entity, HumanoidArm arm); } diff --git a/src/main/java/net/neoforged/neoforge/client/NeoForgeRenderTypes.java b/src/main/java/net/neoforged/neoforge/client/NeoForgeRenderTypes.java index 2fc2461c10..98988e55c7 100644 --- a/src/main/java/net/neoforged/neoforge/client/NeoForgeRenderTypes.java +++ b/src/main/java/net/neoforged/neoforge/client/NeoForgeRenderTypes.java @@ -17,6 +17,7 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.TriState; import net.neoforged.neoforge.client.event.RenderLevelStageEvent; import net.neoforged.neoforge.common.util.Lazy; @@ -157,7 +158,7 @@ public RenderType get() { } private static class Internal { - private static final RenderStateShard.ShaderStateShard RENDERTYPE_ENTITY_TRANSLUCENT_UNLIT_SHADER = new RenderStateShard.ShaderStateShard(ClientHooks.ClientEvents::getEntityTranslucentUnlitShader); + private static final RenderStateShard.ShaderStateShard RENDERTYPE_ENTITY_TRANSLUCENT_UNLIT_SHADER = new RenderStateShard.ShaderStateShard(ClientHooks.ClientEvents.RENDERTYPE_ENTITY_TRANSLUCENT_UNLIT_SHADER); public static Function UNSORTED_TRANSLUCENT = Util.memoize(Internal::unsortedTranslucent); @@ -165,7 +166,7 @@ private static RenderType unsortedTranslucent(ResourceLocation textureLocation) final boolean sortingEnabled = false; var renderState = RenderType.CompositeState.builder() .setShaderState(RenderType.RENDERTYPE_ENTITY_TRANSLUCENT_SHADER) - .setTextureState(new TextureStateShard(textureLocation, false, false)) + .setTextureState(new TextureStateShard(textureLocation, TriState.DEFAULT, false)) .setTransparencyState(RenderType.TRANSLUCENT_TRANSPARENCY) .setCullState(RenderType.NO_CULL) .setLightmapState(RenderType.LIGHTMAP) @@ -180,7 +181,7 @@ private static RenderType unsortedTranslucent(ResourceLocation textureLocation) private static RenderType unlitTranslucent(ResourceLocation textureLocation, boolean sortingEnabled) { var renderState = RenderType.CompositeState.builder() .setShaderState(RENDERTYPE_ENTITY_TRANSLUCENT_UNLIT_SHADER) - .setTextureState(new TextureStateShard(textureLocation, false, false)) + .setTextureState(new TextureStateShard(textureLocation, TriState.DEFAULT, false)) .setTransparencyState(RenderType.TRANSLUCENT_TRANSPARENCY) .setCullState(RenderType.NO_CULL) .setLightmapState(RenderType.LIGHTMAP) @@ -194,7 +195,7 @@ private static RenderType unlitTranslucent(ResourceLocation textureLocation, boo private static RenderType layeredItemSolid(ResourceLocation locationIn) { var rendertype$state = RenderType.CompositeState.builder() .setShaderState(RenderType.RENDERTYPE_ENTITY_SOLID_SHADER) - .setTextureState(new RenderStateShard.TextureStateShard(locationIn, false, false)) + .setTextureState(new RenderStateShard.TextureStateShard(locationIn, TriState.DEFAULT, false)) .setTransparencyState(RenderType.NO_TRANSPARENCY) .setLightmapState(RenderType.LIGHTMAP) .setOverlayState(RenderType.OVERLAY) @@ -207,7 +208,7 @@ private static RenderType layeredItemSolid(ResourceLocation locationIn) { private static RenderType layeredItemCutout(ResourceLocation locationIn) { var rendertype$state = RenderType.CompositeState.builder() .setShaderState(RenderType.RENDERTYPE_ENTITY_CUTOUT_SHADER) - .setTextureState(new RenderStateShard.TextureStateShard(locationIn, false, false)) + .setTextureState(new RenderStateShard.TextureStateShard(locationIn, TriState.DEFAULT, false)) .setTransparencyState(RenderType.NO_TRANSPARENCY) .setLightmapState(RenderType.LIGHTMAP) .setOverlayState(RenderType.OVERLAY) @@ -220,7 +221,7 @@ private static RenderType layeredItemCutout(ResourceLocation locationIn) { private static RenderType layeredItemCutoutMipped(ResourceLocation locationIn) { var rendertype$state = RenderType.CompositeState.builder() .setShaderState(RenderType.RENDERTYPE_ENTITY_SMOOTH_CUTOUT_SHADER) - .setTextureState(new RenderStateShard.TextureStateShard(locationIn, false, true)) + .setTextureState(new RenderStateShard.TextureStateShard(locationIn, TriState.DEFAULT, true)) .setTransparencyState(RenderType.NO_TRANSPARENCY) .setLightmapState(RenderType.LIGHTMAP) .setOverlayState(RenderType.OVERLAY) @@ -233,7 +234,7 @@ private static RenderType layeredItemCutoutMipped(ResourceLocation locationIn) { private static RenderType layeredItemTranslucent(ResourceLocation locationIn) { var rendertype$state = RenderType.CompositeState.builder() .setShaderState(RenderType.RENDERTYPE_ENTITY_TRANSLUCENT_SHADER) - .setTextureState(new RenderStateShard.TextureStateShard(locationIn, false, false)) + .setTextureState(new RenderStateShard.TextureStateShard(locationIn, TriState.DEFAULT, false)) .setTransparencyState(RenderType.TRANSLUCENT_TRANSPARENCY) .setLightmapState(RenderType.LIGHTMAP) .setOverlayState(RenderType.OVERLAY) @@ -324,7 +325,7 @@ private static RenderType getTextIntensitySeeThrough(ResourceLocation locationIn private static RenderType getTranslucentParticlesTarget(ResourceLocation locationIn) { var rendertype$state = RenderType.CompositeState.builder() .setShaderState(RenderType.RENDERTYPE_TRANSLUCENT_SHADER) - .setTextureState(new RenderStateShard.TextureStateShard(locationIn, false, true)) + .setTextureState(new RenderStateShard.TextureStateShard(locationIn, TriState.DEFAULT, true)) .setTransparencyState(RenderType.TRANSLUCENT_TRANSPARENCY) .setLightmapState(RenderType.LIGHTMAP) .setOutputState(RenderType.PARTICLES_TARGET) @@ -338,7 +339,7 @@ private static class CustomizableTextureState extends TextureStateShard { private final BooleanSupplier mipmapSupplier; private CustomizableTextureState(ResourceLocation resLoc, BooleanSupplier blur, BooleanSupplier mipmap) { - super(resLoc, blur.getAsBoolean(), mipmap.getAsBoolean()); + super(resLoc, blur.getAsBoolean() ? TriState.TRUE : TriState.DEFAULT, mipmap.getAsBoolean()); blurSupplier = blur; mipmapSupplier = mipmap; } @@ -346,7 +347,7 @@ private CustomizableTextureState(ResourceLocation resLoc, BooleanSupplier blur, @Override public void setupRenderState() { // must be done before super call as super uses the `blur` and `mipmap` fields within the `setupState` runnable | See super constructor - blur = blurSupplier.getAsBoolean(); + blur = blurSupplier.getAsBoolean() ? TriState.TRUE : TriState.DEFAULT; mipmap = mipmapSupplier.getAsBoolean(); super.setupRenderState(); } diff --git a/src/main/java/net/neoforged/neoforge/client/ParticleBoundsDebugRenderer.java b/src/main/java/net/neoforged/neoforge/client/ParticleBoundsDebugRenderer.java index 9b57ae8f05..eef4be7949 100644 --- a/src/main/java/net/neoforged/neoforge/client/ParticleBoundsDebugRenderer.java +++ b/src/main/java/net/neoforged/neoforge/client/ParticleBoundsDebugRenderer.java @@ -10,8 +10,8 @@ import com.mojang.brigadier.Command; import com.mojang.brigadier.arguments.BoolArgumentType; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.ShapeRenderer; import net.minecraft.commands.Commands; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; @@ -44,7 +44,7 @@ public static void onRenderLevelStage(RenderLevelStageEvent event) { var offset = particle.getPos().subtract(camPos); poseStack.translate(offset.x, offset.y, offset.z); bb = bb.move(-particle.getPos().x, -particle.getPos().y, -particle.getPos().z); - LevelRenderer.renderLineBox(poseStack, consumer, bb, 1F, 0F, 0F, 1F); + ShapeRenderer.renderLineBox(poseStack, consumer, bb, 1F, 0F, 0F, 1F); poseStack.popPose(); } }); diff --git a/src/main/java/net/neoforged/neoforge/client/RecipeBookManager.java b/src/main/java/net/neoforged/neoforge/client/RecipeBookManager.java index 829d5f27fa..c8eb916505 100644 --- a/src/main/java/net/neoforged/neoforge/client/RecipeBookManager.java +++ b/src/main/java/net/neoforged/neoforge/client/RecipeBookManager.java @@ -5,69 +5,31 @@ package net.neoforged.neoforge.client; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import java.util.Collections; -import java.util.HashMap; +import java.util.IdentityHashMap; import java.util.List; import java.util.Map; -import java.util.function.Function; -import net.minecraft.client.RecipeBookCategories; -import net.minecraft.world.inventory.RecipeBookType; -import net.minecraft.world.item.crafting.Recipe; -import net.minecraft.world.item.crafting.RecipeHolder; -import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.item.crafting.ExtendedRecipeBookCategory; +import net.minecraft.world.item.crafting.RecipeBookCategory; import net.neoforged.fml.ModLoader; -import net.neoforged.neoforge.client.event.RegisterRecipeBookCategoriesEvent; +import net.neoforged.neoforge.client.event.RegisterRecipeBookSearchCategoriesEvent; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Nullable; /** - * Manager for {@link RecipeBookType recipe book types} and {@link RecipeBookCategories categories}. - *

- * Provides a recipe category lookup. + * Manager for mod-provided search {@link ExtendedRecipeBookCategory} implementations. */ public final class RecipeBookManager { - // Not using ConcurrentHashMap here because it's slower for lookups, so we only use it during init - private static final Map> AGGREGATE_CATEGORIES = new HashMap<>(); - private static final Map> TYPE_CATEGORIES = new HashMap<>(); - private static final Map, Function, RecipeBookCategories>> RECIPE_CATEGORY_LOOKUPS = new HashMap<>(); - private static final Map> AGGREGATE_CATEGORIES_VIEW = Collections.unmodifiableMap(AGGREGATE_CATEGORIES); + private static Map> searchCategories = Map.of(); - /** - * Finds the category the specified recipe should display in, or null if none. - */ - @Nullable - public static > RecipeBookCategories findCategories(RecipeType type, RecipeHolder recipe) { - var lookup = RECIPE_CATEGORY_LOOKUPS.get(type); - return lookup != null ? lookup.apply(recipe) : null; - } - - @ApiStatus.Internal - public static Map> getAggregateCategories() { - return AGGREGATE_CATEGORIES_VIEW; - } - - @ApiStatus.Internal - public static List getCustomCategoriesOrEmpty(RecipeBookType recipeBookType) { - return TYPE_CATEGORIES.getOrDefault(recipeBookType, List.of()); + public static Map> getSearchCategories() { + return searchCategories; } @ApiStatus.Internal public static void init() { - // The ImmutableMap is the patched out value of AGGREGATE_CATEGORIES - var aggregateCategories = new HashMap<>(ImmutableMap.of( - RecipeBookCategories.CRAFTING_SEARCH, ImmutableList.of(RecipeBookCategories.CRAFTING_EQUIPMENT, RecipeBookCategories.CRAFTING_BUILDING_BLOCKS, RecipeBookCategories.CRAFTING_MISC, RecipeBookCategories.CRAFTING_REDSTONE), - RecipeBookCategories.FURNACE_SEARCH, ImmutableList.of(RecipeBookCategories.FURNACE_FOOD, RecipeBookCategories.FURNACE_BLOCKS, RecipeBookCategories.FURNACE_MISC), - RecipeBookCategories.BLAST_FURNACE_SEARCH, ImmutableList.of(RecipeBookCategories.BLAST_FURNACE_BLOCKS, RecipeBookCategories.BLAST_FURNACE_MISC), - RecipeBookCategories.SMOKER_SEARCH, ImmutableList.of(RecipeBookCategories.SMOKER_FOOD))); - - var typeCategories = new HashMap>(); - var recipeCategoryLookups = new HashMap, Function, RecipeBookCategories>>(); - var event = new RegisterRecipeBookCategoriesEvent(aggregateCategories, typeCategories, recipeCategoryLookups); - ModLoader.postEventWrapContainerInModOrder(event); - AGGREGATE_CATEGORIES.putAll(aggregateCategories); - TYPE_CATEGORIES.putAll(typeCategories); - RECIPE_CATEGORY_LOOKUPS.putAll(recipeCategoryLookups); + var searchCategories = new IdentityHashMap>(); + var event = new RegisterRecipeBookSearchCategoriesEvent(searchCategories); + ModLoader.postEvent(event); + RecipeBookManager.searchCategories = Collections.unmodifiableMap(searchCategories); } } diff --git a/src/main/java/net/neoforged/neoforge/client/RenderTypeGroup.java b/src/main/java/net/neoforged/neoforge/client/RenderTypeGroup.java index 91d9eccfc1..18c34366d5 100644 --- a/src/main/java/net/neoforged/neoforge/client/RenderTypeGroup.java +++ b/src/main/java/net/neoforged/neoforge/client/RenderTypeGroup.java @@ -9,21 +9,15 @@ /** * A set of functionally equivalent shaders. One using {@link com.mojang.blaze3d.vertex.DefaultVertexFormat#BLOCK}, - * and the other two using {@link com.mojang.blaze3d.vertex.DefaultVertexFormat#NEW_ENTITY}. - * {@code entityFabulous} may support custom render targets and other aspects of the fabulous pipeline, or can otherwise - * be the same as {@code entity}. + * and the other one using {@link com.mojang.blaze3d.vertex.DefaultVertexFormat#NEW_ENTITY}. */ -public record RenderTypeGroup(RenderType block, RenderType entity, RenderType entityFabulous) { +public record RenderTypeGroup(RenderType block, RenderType entity) { public RenderTypeGroup { - if ((block == null) != (entity == null) || (block == null) != (entityFabulous == null)) + if ((block == null) != (entity == null)) throw new IllegalArgumentException("The render types in a group must either be all null, or all non-null."); } - public RenderTypeGroup(RenderType block, RenderType entity) { - this(block, entity, entity); - } - - public static RenderTypeGroup EMPTY = new RenderTypeGroup(null, null, null); + public static RenderTypeGroup EMPTY = new RenderTypeGroup(null, null); /** * {@return true if this group has render types or not. It either has all, or none} diff --git a/src/main/java/net/neoforged/neoforge/client/RenderTypeHelper.java b/src/main/java/net/neoforged/neoforge/client/RenderTypeHelper.java index ef5a486921..ad22d070ca 100644 --- a/src/main/java/net/neoforged/neoforge/client/RenderTypeHelper.java +++ b/src/main/java/net/neoforged/neoforge/client/RenderTypeHelper.java @@ -6,7 +6,6 @@ package net.neoforged.neoforge.client; import com.mojang.blaze3d.vertex.DefaultVertexFormat; -import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ItemBlockRenderTypes; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.Sheets; @@ -25,12 +24,12 @@ public final class RenderTypeHelper { * Provides a {@link RenderType} using {@link DefaultVertexFormat#NEW_ENTITY} for the given {@link DefaultVertexFormat#BLOCK} format. * This should be called for each {@link RenderType} returned by {@link BakedModel#getRenderTypes(BlockState, RandomSource, ModelData)}. *

- * Mimics the behavior of vanilla's {@link ItemBlockRenderTypes#getRenderType(BlockState, boolean)}. + * Mimics the behavior of vanilla's {@link ItemBlockRenderTypes#getRenderType(BlockState)}. */ - public static RenderType getEntityRenderType(RenderType chunkRenderType, boolean cull) { + public static RenderType getEntityRenderType(RenderType chunkRenderType) { if (chunkRenderType != RenderType.translucent()) return Sheets.cutoutBlockSheet(); - return cull || !Minecraft.useShaderTransparency() ? Sheets.translucentCullBlockSheet() : Sheets.translucentItemSheet(); + return Sheets.translucentItemSheet(); } /** @@ -48,17 +47,17 @@ public static RenderType getMovingBlockRenderType(RenderType renderType) { /** * Provides a fallback {@link RenderType} for the given {@link ItemStack} in the case that none is explicitly specified. *

- * Mimics the behavior of vanilla's {@link ItemBlockRenderTypes#getRenderType(ItemStack, boolean)} + * Mimics the behavior of vanilla's {@link ItemBlockRenderTypes#getRenderType(ItemStack)} * but removes the need to query the model again if the item is a {@link BlockItem}. */ - public static RenderType getFallbackItemRenderType(ItemStack stack, BakedModel model, boolean cull) { + public static RenderType getFallbackItemRenderType(ItemStack stack, BakedModel model) { if (stack.getItem() instanceof BlockItem blockItem) { var renderTypes = model.getRenderTypes(blockItem.getBlock().defaultBlockState(), RandomSource.create(42), ModelData.EMPTY); if (renderTypes.contains(RenderType.translucent())) - return getEntityRenderType(RenderType.translucent(), cull); + return getEntityRenderType(RenderType.translucent()); return Sheets.cutoutBlockSheet(); } - return cull ? Sheets.translucentCullBlockSheet() : Sheets.translucentItemSheet(); + return Sheets.translucentItemSheet(); } private RenderTypeHelper() {} diff --git a/src/main/java/net/neoforged/neoforge/client/TagConventionLogWarningClient.java b/src/main/java/net/neoforged/neoforge/client/TagConventionLogWarningClient.java index 4e68adbed5..72c8d0b881 100644 --- a/src/main/java/net/neoforged/neoforge/client/TagConventionLogWarningClient.java +++ b/src/main/java/net/neoforged/neoforge/client/TagConventionLogWarningClient.java @@ -8,6 +8,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; import java.util.List; import net.minecraft.client.resources.language.I18n; +import net.minecraft.core.HolderSet; import net.minecraft.core.Registry; import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; @@ -49,7 +50,7 @@ static void setupUntranslatedItemTagWarning(IEventBus forgeBus) { if (!FMLLoader.isProduction() == isConfigSetToDev) { List> untranslatedTags = new ObjectArrayList<>(); RegistryAccess.Frozen registryAccess = serverStartingEvent.getServer().registryAccess(); - extractUnregisteredModdedTags(registryAccess.registryOrThrow(Registries.ITEM), untranslatedTags); + extractUnregisteredModdedTags(registryAccess.lookupOrThrow(Registries.ITEM), untranslatedTags); if (!untranslatedTags.isEmpty()) { StringBuilder stringBuilder = new StringBuilder(); @@ -80,7 +81,7 @@ static void setupUntranslatedItemTagWarning(IEventBus forgeBus) { } private static void extractUnregisteredModdedTags(Registry registry, List> untranslatedTags) { - registry.getTagNames().forEach(itemTagKey -> { + registry.getTags().map(HolderSet.Named::key).forEach(itemTagKey -> { // We do not translate vanilla's tags at this moment. if (itemTagKey.location().getNamespace().equals("minecraft")) { return; diff --git a/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java index 8fd278c8fc..7d788419d2 100644 --- a/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java +++ b/src/main/java/net/neoforged/neoforge/client/entity/animation/json/AnimationLoader.java @@ -6,11 +6,7 @@ package net.neoforged.neoforge.client.entity.animation.json; import com.google.common.collect.MapMaker; -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; import com.mojang.logging.LogUtils; -import com.mojang.serialization.JsonOps; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -25,7 +21,7 @@ /** * A loader for entity animations written in JSON. You can also get parsed animations from this class. */ -public final class AnimationLoader extends SimpleJsonResourceReloadListener { +public final class AnimationLoader extends SimpleJsonResourceReloadListener { private static final Logger LOGGER = LogUtils.getLogger(); public static final AnimationLoader INSTANCE = new AnimationLoader(); @@ -35,7 +31,7 @@ public final class AnimationLoader extends SimpleJsonResourceReloadListener { private final List strongHolderReferences = new ArrayList<>(); private AnimationLoader() { - super(new Gson(), "neoforge/animations/entity"); + super(AnimationParser.CODEC, "neoforge/animations/entity"); } /** @@ -56,21 +52,15 @@ public AnimationHolder getAnimationHolder(ResourceLocation key) { } @Override - protected void apply(Map animationJsons, ResourceManager resourceManager, ProfilerFiller profiler) { + protected void apply(Map animationJsons, ResourceManager resourceManager, ProfilerFiller profiler) { animations.values().forEach(AnimationHolder::unbind); strongHolderReferences.clear(); int loaded = 0; for (final var entry : animationJsons.entrySet()) { - try { - final var animation = AnimationParser.CODEC.parse(JsonOps.INSTANCE, entry.getValue()) - .getOrThrow(JsonParseException::new); - final var holder = getAnimationHolder(entry.getKey()); - holder.bind(animation); - strongHolderReferences.add(holder); - loaded++; - } catch (Exception e) { - LOGGER.error("Failed to load animation {}", entry.getKey(), e); - } + final var holder = getAnimationHolder(entry.getKey()); + holder.bind(entry.getValue()); + strongHolderReferences.add(holder); + loaded++; } LOGGER.info("Loaded {} entity animations", loaded); } diff --git a/src/main/java/net/neoforged/neoforge/client/event/ComputeFovModifierEvent.java b/src/main/java/net/neoforged/neoforge/client/event/ComputeFovModifierEvent.java index 7e85540c4b..a2afcc39dd 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/ComputeFovModifierEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/ComputeFovModifierEvent.java @@ -5,7 +5,6 @@ package net.neoforged.neoforge.client.event; -import net.minecraft.client.Minecraft; import net.minecraft.util.Mth; import net.minecraft.world.entity.player.Player; import net.neoforged.bus.api.Event; @@ -26,13 +25,15 @@ public class ComputeFovModifierEvent extends Event { private final Player player; private final float fovModifier; + private final float fovScale; private float newFovModifier; @ApiStatus.Internal - public ComputeFovModifierEvent(Player player, float fovModifier) { + public ComputeFovModifierEvent(Player player, float fovModifier, float fovScale) { this.player = player; this.fovModifier = fovModifier; - this.setNewFovModifier((float) Mth.lerp(Minecraft.getInstance().options.fovEffectScale().get(), 1.0F, fovModifier)); + this.fovScale = fovScale; + this.setNewFovModifier(Mth.lerp(fovScale, 1.0F, fovModifier)); } /** @@ -49,6 +50,13 @@ public float getFovModifier() { return fovModifier; } + /** + * {@return the FOV scale to use for interpolating the final FOV modifier} + */ + public float getFovScale() { + return fovScale; + } + /** * {@return the current field of vision (FOV) of the player} */ diff --git a/src/main/java/net/neoforged/neoforge/client/event/EntityRenderersEvent.java b/src/main/java/net/neoforged/neoforge/client/event/EntityRenderersEvent.java index 9498a500e9..fc2d26c7ac 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/EntityRenderersEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/EntityRenderersEvent.java @@ -121,12 +121,12 @@ public void registerBlockEntityRenderer(BlockEntityType< * only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ public static class AddLayers extends EntityRenderersEvent { - private final Map, EntityRenderer> renderers; - private final Map> skinMap; + private final Map, EntityRenderer> renderers; + private final Map> skinMap; private final EntityRendererProvider.Context context; @ApiStatus.Internal - public AddLayers(Map, EntityRenderer> renderers, Map> playerRenderers, EntityRendererProvider.Context context) { + public AddLayers(Map, EntityRenderer> renderers, Map> playerRenderers, EntityRendererProvider.Context context) { this.renderers = renderers; this.skinMap = playerRenderers; this.context = context; @@ -153,7 +153,7 @@ public Set getSkins() { */ @Nullable @SuppressWarnings("unchecked") - public > R getSkin(PlayerSkin.Model skinModel) { + public > R getSkin(PlayerSkin.Model skinModel) { return (R) skinMap.get(skinModel); } @@ -175,7 +175,7 @@ public Set> getEntityTypes() { */ @Nullable @SuppressWarnings("unchecked") - public > R getRenderer(EntityType entityType) { + public > R getRenderer(EntityType entityType) { return (R) renderers.get(entityType); } diff --git a/src/main/java/net/neoforged/neoforge/client/event/GatherEffectScreenTooltipsEvent.java b/src/main/java/net/neoforged/neoforge/client/event/GatherEffectScreenTooltipsEvent.java index 6eb49da866..9cb08ceae6 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/GatherEffectScreenTooltipsEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/GatherEffectScreenTooltipsEvent.java @@ -7,24 +7,25 @@ import java.util.ArrayList; import java.util.List; -import net.minecraft.client.gui.screens.inventory.EffectRenderingInventoryScreen; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.gui.screens.inventory.EffectsInInventory; import net.minecraft.network.chat.Component; import net.minecraft.world.effect.MobEffectInstance; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.Event; /** - * This event is called when an {@link EffectRenderingInventoryScreen} draws the tooltip lines for a hovered {@link MobEffectInstance}. + * This event is called when {@link EffectsInInventory} draws the tooltip lines for a hovered {@link MobEffectInstance} in an {@link AbstractContainerScreen}. * It can be used to modify the tooltip. *

* This event is only fired on the {@linkplain Dist#CLIENT physical client}. */ public class GatherEffectScreenTooltipsEvent extends Event { - protected final EffectRenderingInventoryScreen screen; + protected final AbstractContainerScreen screen; protected final MobEffectInstance effectInst; protected final List tooltip; - public GatherEffectScreenTooltipsEvent(EffectRenderingInventoryScreen screen, MobEffectInstance effectInst, List tooltip) { + public GatherEffectScreenTooltipsEvent(AbstractContainerScreen screen, MobEffectInstance effectInst, List tooltip) { this.screen = screen; this.effectInst = effectInst; this.tooltip = new ArrayList<>(tooltip); @@ -33,7 +34,7 @@ public GatherEffectScreenTooltipsEvent(EffectRenderingInventoryScreen screen, /** * @return The screen which will be rendering the tooltip lines. */ - public EffectRenderingInventoryScreen getScreen() { + public AbstractContainerScreen getScreen() { return this.screen; } diff --git a/src/main/java/net/neoforged/neoforge/client/event/MovementInputUpdateEvent.java b/src/main/java/net/neoforged/neoforge/client/event/MovementInputUpdateEvent.java index 1478760beb..4fa6142d2d 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/MovementInputUpdateEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/MovementInputUpdateEvent.java @@ -5,7 +5,7 @@ package net.neoforged.neoforge.client.event; -import net.minecraft.client.player.Input; +import net.minecraft.client.player.ClientInput; import net.minecraft.world.entity.player.Player; import net.neoforged.bus.api.Event; import net.neoforged.fml.LogicalSide; @@ -22,10 +22,10 @@ * only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ public class MovementInputUpdateEvent extends PlayerEvent { - private final Input input; + private final ClientInput input; @ApiStatus.Internal - public MovementInputUpdateEvent(Player player, Input input) { + public MovementInputUpdateEvent(Player player, ClientInput input) { super(player); this.input = input; } @@ -33,7 +33,7 @@ public MovementInputUpdateEvent(Player player, Input input) { /** * {@return the player's movement inputs} */ - public Input getInput() { + public ClientInput getInput() { return input; } } diff --git a/src/main/java/net/neoforged/neoforge/client/event/RecipesUpdatedEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RecipesUpdatedEvent.java deleted file mode 100644 index 1e4343698b..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/event/RecipesUpdatedEvent.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.event; - -import net.minecraft.world.item.crafting.RecipeManager; -import net.neoforged.bus.api.Event; -import net.neoforged.fml.LogicalSide; -import net.neoforged.neoforge.common.NeoForge; -import org.jetbrains.annotations.ApiStatus; - -/** - * Fired when the {@link RecipeManager} has received and synced the recipes from the server to the client. - * - *

This event is not {@linkplain ICancellableEvent cancellable}, and does not {@linkplain HasResult have a result}.

- * - *

This event is fired on the {@linkplain NeoForge#EVENT_BUS main Forge event bus}, - * only on the {@linkplain LogicalSide#CLIENT logical client}.

- */ -public class RecipesUpdatedEvent extends Event { - private final RecipeManager recipeManager; - - @ApiStatus.Internal - public RecipesUpdatedEvent(RecipeManager recipeManager) { - this.recipeManager = recipeManager; - } - - /** - * {@return the recipe manager} - */ - public RecipeManager getRecipeManager() { - return recipeManager; - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/event/RegisterNamedRenderTypesEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RegisterNamedRenderTypesEvent.java index df6a02fa91..7464dbac9b 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/RegisterNamedRenderTypesEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/RegisterNamedRenderTypesEvent.java @@ -40,24 +40,10 @@ public RegisterNamedRenderTypesEvent(Map rend * @param entityRenderType A {@link RenderType} using {@link DefaultVertexFormat#NEW_ENTITY} */ public void register(ResourceLocation key, RenderType blockRenderType, RenderType entityRenderType) { - register(key, blockRenderType, entityRenderType, entityRenderType); - } - - /** - * Registers a named {@link RenderTypeGroup}. - * - * @param key The ID of the group - * @param blockRenderType One of the values returned by {@link RenderType#chunkBufferLayers()} - * @param entityRenderType A {@link RenderType} using {@link DefaultVertexFormat#NEW_ENTITY} - * @param fabulousEntityRenderType A {@link RenderType} using {@link DefaultVertexFormat#NEW_ENTITY} for use when - * "fabulous" rendering is enabled - */ - public void register(ResourceLocation key, RenderType blockRenderType, RenderType entityRenderType, RenderType fabulousEntityRenderType) { Preconditions.checkArgument(!renderTypes.containsKey(key), "Render type already registered: " + key); Preconditions.checkArgument(blockRenderType.format() == DefaultVertexFormat.BLOCK, "The block render type must use the BLOCK vertex format."); Preconditions.checkArgument(blockRenderType.getChunkLayerId() >= 0, "Only chunk render types can be used for block rendering. Query RenderType#chunkBufferLayers() for a list."); Preconditions.checkArgument(entityRenderType.format() == DefaultVertexFormat.NEW_ENTITY, "The entity render type must use the NEW_ENTITY vertex format."); - Preconditions.checkArgument(fabulousEntityRenderType.format() == DefaultVertexFormat.NEW_ENTITY, "The fabulous entity render type must use the NEW_ENTITY vertex format."); - renderTypes.put(key, new RenderTypeGroup(blockRenderType, entityRenderType, fabulousEntityRenderType)); + renderTypes.put(key, new RenderTypeGroup(blockRenderType, entityRenderType)); } } diff --git a/src/main/java/net/neoforged/neoforge/client/event/RegisterRecipeBookCategoriesEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RegisterRecipeBookCategoriesEvent.java deleted file mode 100644 index 4a2c2ef651..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/event/RegisterRecipeBookCategoriesEvent.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.event; - -import com.google.common.collect.ImmutableList; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import net.minecraft.client.RecipeBookCategories; -import net.minecraft.world.inventory.RecipeBookType; -import net.minecraft.world.item.crafting.RecipeHolder; -import net.minecraft.world.item.crafting.RecipeType; -import net.neoforged.bus.api.Event; -import net.neoforged.bus.api.ICancellableEvent; -import net.neoforged.fml.LogicalSide; -import net.neoforged.fml.event.IModBusEvent; -import org.jetbrains.annotations.ApiStatus; - -/** - * Allows users to register custom categories for the vanilla recipe book, making it usable in modded GUIs. - * - *

This event is not {@linkplain ICancellableEvent cancellable}, and does not {@linkplain HasResult have a result}. - * - *

This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}.

- */ -public class RegisterRecipeBookCategoriesEvent extends Event implements IModBusEvent { - private final Map> aggregateCategories; - private final Map> typeCategories; - private final Map, Function, RecipeBookCategories>> recipeCategoryLookups; - - @ApiStatus.Internal - public RegisterRecipeBookCategoriesEvent( - Map> aggregateCategories, - Map> typeCategories, - Map, Function, RecipeBookCategories>> recipeCategoryLookups) { - this.aggregateCategories = aggregateCategories; - this.typeCategories = typeCategories; - this.recipeCategoryLookups = recipeCategoryLookups; - } - - /** - * Registers the list of categories that compose an aggregate category. - */ - public void registerAggregateCategory(RecipeBookCategories category, List others) { - aggregateCategories.put(category, ImmutableList.copyOf(others)); - } - - /** - * Registers the list of categories that compose a recipe book. - */ - public void registerBookCategories(RecipeBookType type, List categories) { - typeCategories.put(type, ImmutableList.copyOf(categories)); - } - - /** - * Registers a category lookup for a certain recipe type. - */ - public void registerRecipeCategoryFinder(RecipeType type, Function, RecipeBookCategories> lookup) { - recipeCategoryLookups.put(type, lookup); - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/event/RegisterRecipeBookSearchCategoriesEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RegisterRecipeBookSearchCategoriesEvent.java new file mode 100644 index 0000000000..af1827c98d --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/client/event/RegisterRecipeBookSearchCategoriesEvent.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.client.event; + +import java.util.List; +import java.util.Map; +import net.minecraft.client.gui.screens.recipebook.SearchRecipeBookCategory; +import net.minecraft.world.item.crafting.ExtendedRecipeBookCategory; +import net.minecraft.world.item.crafting.RecipeBookCategory; +import net.neoforged.bus.api.Event; +import net.neoforged.fml.LogicalSide; +import net.neoforged.fml.event.IModBusEvent; +import org.jetbrains.annotations.ApiStatus; + +/** + * Event to register {@link ExtendedRecipeBookCategory} instances for search. + * Modded equivalent of vanilla's {@link SearchRecipeBookCategory}. + * + *

This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}. + */ +public class RegisterRecipeBookSearchCategoriesEvent extends Event implements IModBusEvent { + private final Map> categories; + + @ApiStatus.Internal + public RegisterRecipeBookSearchCategoriesEvent(Map> categories) { + this.categories = categories; + } + + public void register(ExtendedRecipeBookCategory searchCategory, RecipeBookCategory... includedCategories) { + if (includedCategories.length == 0) { + throw new IllegalArgumentException("Forgot to register included categories."); + } + if (categories.containsKey(searchCategory)) { + throw new IllegalArgumentException("Duplicate registration of search category " + searchCategory); + } + categories.put(searchCategory, List.of(includedCategories)); + } +} diff --git a/src/main/java/net/neoforged/neoforge/client/event/RegisterShadersEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RegisterShadersEvent.java index 28f1788c04..a0a89fe747 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/RegisterShadersEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/RegisterShadersEvent.java @@ -5,11 +5,8 @@ package net.neoforged.neoforge.client.event; -import com.mojang.datafixers.util.Pair; import java.util.List; -import java.util.function.Consumer; -import net.minecraft.client.renderer.ShaderInstance; -import net.minecraft.server.packs.resources.ResourceProvider; +import net.minecraft.client.renderer.ShaderProgram; import net.neoforged.bus.api.Event; import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.fml.LogicalSide; @@ -17,43 +14,27 @@ import org.jetbrains.annotations.ApiStatus; /** - * Fired to allow mods to register custom {@linkplain ShaderInstance shaders}. + * Fired to allow mods to register custom {@linkplain ShaderProgram shaders}. * This event is fired after the default Minecraft shaders have been registered. * - *

This event is not {@linkplain ICancellableEvent cancellable}, and does not {@linkplain HasResult have a result}.

+ *

This event is not {@linkplain ICancellableEvent cancellable}.

* *

This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ public class RegisterShadersEvent extends Event implements IModBusEvent { - private final ResourceProvider resourceProvider; - private final List>> shaderList; + private final List shaderList; @ApiStatus.Internal - public RegisterShadersEvent(ResourceProvider resourceProvider, List>> shaderList) { - this.resourceProvider = resourceProvider; + public RegisterShadersEvent(List shaderList) { this.shaderList = shaderList; } /** - * {@return the client-side resource provider} - */ - public ResourceProvider getResourceProvider() { - return resourceProvider; - } - - /** - * Registers a shader, and a callback for when the shader is loaded. - * - *

When creating a {@link ShaderInstance}, pass in the {@linkplain #getResourceProvider() - * client-side resource provider} as the resource provider.

- * - *

Mods should not store the shader instance passed into this method. Instead, mods should store the shader - * passed into the registered load callback.

+ * Registers a {@link ShaderProgram} * - * @param shaderInstance a shader - * @param onLoaded a callback for when the shader is loaded + * @param program a shader */ - public void registerShader(ShaderInstance shaderInstance, Consumer onLoaded) { - shaderList.add(Pair.of(shaderInstance, onLoaded)); + public void registerShader(ShaderProgram program) { + shaderList.add(program); } } diff --git a/src/main/java/net/neoforged/neoforge/client/event/RenderHighlightEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RenderHighlightEvent.java index 089081b67a..69b486d44f 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/RenderHighlightEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/RenderHighlightEvent.java @@ -96,9 +96,12 @@ public MultiBufferSource getMultiBufferSource() { * only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ public static class Block extends RenderHighlightEvent implements ICancellableEvent { + private final boolean forTranslucentBlocks; + @ApiStatus.Internal - public Block(LevelRenderer levelRenderer, Camera camera, BlockHitResult target, DeltaTracker deltaTracker, PoseStack poseStack, MultiBufferSource bufferSource) { + public Block(LevelRenderer levelRenderer, Camera camera, BlockHitResult target, DeltaTracker deltaTracker, PoseStack poseStack, MultiBufferSource bufferSource, boolean forTranslucentBlocks) { super(levelRenderer, camera, target, deltaTracker, poseStack, bufferSource); + this.forTranslucentBlocks = forTranslucentBlocks; } /** @@ -108,6 +111,13 @@ public Block(LevelRenderer levelRenderer, Camera camera, BlockHitResult target, public BlockHitResult getTarget() { return (BlockHitResult) super.target; } + + /** + * {@return whether the event is fired for outlines on translucent or non-translucent blocks} + */ + public boolean isForTranslucentBlocks() { + return forTranslucentBlocks; + } } /** @@ -118,6 +128,7 @@ public BlockHitResult getTarget() { *

This event is fired on the {@linkplain NeoForge#EVENT_BUS main Forge event bus}, * only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ + // TODO porting: reevaluate public static class Entity extends RenderHighlightEvent { @ApiStatus.Internal public Entity(LevelRenderer levelRenderer, Camera camera, EntityHitResult target, DeltaTracker deltaTracker, PoseStack poseStack, MultiBufferSource bufferSource) { diff --git a/src/main/java/net/neoforged/neoforge/client/event/RenderItemInFrameEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RenderItemInFrameEvent.java index 09753d88c5..479758d4c0 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/RenderItemInFrameEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/RenderItemInFrameEvent.java @@ -9,7 +9,7 @@ import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.entity.ItemFrameRenderer; -import net.minecraft.world.entity.decoration.ItemFrame; +import net.minecraft.client.renderer.entity.state.ItemFrameRenderState; import net.minecraft.world.item.ItemStack; import net.neoforged.bus.api.Event; import net.neoforged.bus.api.ICancellableEvent; @@ -31,18 +31,18 @@ */ public class RenderItemInFrameEvent extends Event implements ICancellableEvent { private final ItemStack itemStack; - private final ItemFrame itemFrameEntity; + private final ItemFrameRenderState frameRenderState; private final ItemFrameRenderer renderer; private final PoseStack poseStack; private final MultiBufferSource multiBufferSource; private final int packedLight; @ApiStatus.Internal - public RenderItemInFrameEvent(ItemFrame itemFrame, ItemFrameRenderer renderItemFrame, PoseStack poseStack, + public RenderItemInFrameEvent(ItemFrameRenderState frameRenderState, ItemFrameRenderer renderItemFrame, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight) { - itemStack = itemFrame.getItem(); - itemFrameEntity = itemFrame; - renderer = renderItemFrame; + this.itemStack = frameRenderState.itemStack; + this.frameRenderState = frameRenderState; + this.renderer = renderItemFrame; this.poseStack = poseStack; this.multiBufferSource = multiBufferSource; this.packedLight = packedLight; @@ -58,8 +58,8 @@ public ItemStack getItemStack() { /** * {@return the item frame entity} */ - public ItemFrame getItemFrameEntity() { - return itemFrameEntity; + public ItemFrameRenderState getItemFrameRenderState() { + return frameRenderState; } /** diff --git a/src/main/java/net/neoforged/neoforge/client/event/RenderLivingEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RenderLivingEvent.java index 6c8f42986c..5ecbefe370 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/RenderLivingEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/RenderLivingEvent.java @@ -10,6 +10,7 @@ import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.client.renderer.entity.state.LivingEntityRenderState; import net.minecraft.world.entity.LivingEntity; import net.neoforged.bus.api.Event; import net.neoforged.bus.api.ICancellableEvent; @@ -31,18 +32,18 @@ * @see RenderPlayerEvent * @see LivingEntityRenderer */ -public abstract class RenderLivingEvent> extends Event { - private final LivingEntity entity; - private final LivingEntityRenderer renderer; +public abstract class RenderLivingEvent> extends Event { + private final S renderState; + private final LivingEntityRenderer renderer; private final float partialTick; private final PoseStack poseStack; private final MultiBufferSource multiBufferSource; private final int packedLight; @ApiStatus.Internal - protected RenderLivingEvent(LivingEntity entity, LivingEntityRenderer renderer, float partialTick, PoseStack poseStack, + protected RenderLivingEvent(S renderState, LivingEntityRenderer renderer, float partialTick, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight) { - this.entity = entity; + this.renderState = renderState; this.renderer = renderer; this.partialTick = partialTick; this.poseStack = poseStack; @@ -51,16 +52,16 @@ protected RenderLivingEvent(LivingEntity entity, LivingEntityRenderer rend } /** - * @return the living entity being rendered + * @return the render state of the living entity being rendered */ - public LivingEntity getEntity() { - return entity; + public S getRenderState() { + return renderState; } /** * @return the renderer for the living entity */ - public LivingEntityRenderer getRenderer() { + public LivingEntityRenderer getRenderer() { return renderer; } @@ -108,10 +109,10 @@ public int getPackedLight() { * @param the living entity that is being rendered * @param the model for the living entity */ - public static class Pre> extends RenderLivingEvent implements ICancellableEvent { + public static class Pre> extends RenderLivingEvent implements ICancellableEvent { @ApiStatus.Internal - public Pre(LivingEntity entity, LivingEntityRenderer renderer, float partialTick, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight) { - super(entity, renderer, partialTick, poseStack, multiBufferSource, packedLight); + public Pre(S renderState, LivingEntityRenderer renderer, float partialTick, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight) { + super(renderState, renderer, partialTick, poseStack, multiBufferSource, packedLight); } } @@ -126,10 +127,10 @@ public Pre(LivingEntity entity, LivingEntityRenderer renderer, float parti * @param the living entity that was rendered * @param the model for the living entity */ - public static class Post> extends RenderLivingEvent { + public static class Post> extends RenderLivingEvent { @ApiStatus.Internal - public Post(LivingEntity entity, LivingEntityRenderer renderer, float partialTick, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight) { - super(entity, renderer, partialTick, poseStack, multiBufferSource, packedLight); + public Post(S renderState, LivingEntityRenderer renderer, float partialTick, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight) { + super(renderState, renderer, partialTick, poseStack, multiBufferSource, packedLight); } } } diff --git a/src/main/java/net/neoforged/neoforge/client/event/RenderNameTagEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RenderNameTagEvent.java index fcc27f82a1..6e6c501f2f 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/RenderNameTagEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/RenderNameTagEvent.java @@ -8,117 +8,174 @@ import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.client.renderer.entity.state.EntityRenderState; import net.minecraft.network.chat.Component; import net.minecraft.world.entity.Entity; +import net.neoforged.bus.api.Event; +import net.neoforged.bus.api.ICancellableEvent; +import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.common.util.TriState; -import net.neoforged.neoforge.event.entity.EntityEvent; import org.jetbrains.annotations.ApiStatus; /** * This event is fired before an entity renderer renders the nameplate of an entity. - * It allows reacting to the render and controlling if the name plate will be rendered, as well as changing the rendered name. *

* This event is only fired on the logical client. * * @see EntityRenderer */ -public class RenderNameTagEvent extends EntityEvent { - private final Component originalContent; - private final EntityRenderer entityRenderer; - private final PoseStack poseStack; - private final MultiBufferSource multiBufferSource; - private final int packedLight; +public abstract class RenderNameTagEvent extends Event { + private final EntityRenderState renderState; + protected final Component originalContent; + private final EntityRenderer entityRenderer; private final float partialTick; - private Component content; - private TriState canRender = TriState.DEFAULT; - @ApiStatus.Internal - public RenderNameTagEvent(Entity entity, Component content, EntityRenderer entityRenderer, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight, float partialTick) { - super(entity); + public RenderNameTagEvent(EntityRenderState renderState, Component content, EntityRenderer entityRenderer, float partialTick) { + this.renderState = renderState; this.originalContent = content; - this.setContent(this.originalContent); this.entityRenderer = entityRenderer; - this.poseStack = poseStack; - this.multiBufferSource = multiBufferSource; - this.packedLight = packedLight; this.partialTick = partialTick; } /** - * Changes if the {@link #getContent() content} of the nameplate will be rendered. - * {@link TriState#TRUE} and {@link TriState#FALSE} will allow/deny the render respectively. - *

- * Using {@link TriState#DEFAULT} will cause the name to render if {@link EntityRenderer#shouldShowName} returns true. + * {@return the render state of the entity whose nameplate is being rendered} */ - public void setCanRender(TriState canRender) { - this.canRender = canRender; + public EntityRenderState getEntityRenderState() { + return renderState; } /** - * {@return if the nameplate will render or not} + * {@return the entity renderer rendering the nameplate} */ - public TriState canRender() { - return canRender; + public EntityRenderer getEntityRenderer() { + return this.entityRenderer; } /** - * Sets the new text on the nameplate. - * - * @param contents the new text + * {@return the partial tick} */ - public void setContent(Component contents) { - this.content = contents; + public float getPartialTick() { + return this.partialTick; } /** - * {@return the text on the nameplate that will be rendered} + * This event is fired when an entity renderer extracts the render state of an entity relevant to rendering the nametag. + * It allows controlling whether the name plate will be rendered, as well as changing the rendered name. + *

+ * This event is only fired on the logical client on the {@link NeoForge#EVENT_BUS}. + * + * @see EntityRenderer */ - public Component getContent() { - return this.content; - } + public static class CanRender extends RenderNameTagEvent { + private final Entity entity; + private Component content; + private TriState canRender = TriState.DEFAULT; - /** - * {@return the original text on the nameplate} - */ - public Component getOriginalContent() { - return this.originalContent; - } + public CanRender(Entity entity, EntityRenderState renderState, Component content, EntityRenderer entityRenderer, float partialTick) { + super(renderState, content, entityRenderer, partialTick); + this.entity = entity; + this.content = content; + } - /** - * {@return the entity renderer rendering the nameplate} - */ - public EntityRenderer getEntityRenderer() { - return this.entityRenderer; - } + /** + * {@return the entity whose nameplate is being rendered} + */ + public Entity getEntity() { + return entity; + } - /** - * {@return the pose stack used for rendering} - */ - public PoseStack getPoseStack() { - return this.poseStack; - } + /** + * {@return the original text on the nameplate} + */ + public Component getOriginalContent() { + return this.originalContent; + } - /** - * {@return the source of rendering buffers} - */ - public MultiBufferSource getMultiBufferSource() { - return this.multiBufferSource; + /** + * Changes if the {@link #getContent() content} of the nameplate will be rendered. + * {@link TriState#TRUE} and {@link TriState#FALSE} will allow/deny the render respectively. + *

+ * Using {@link TriState#DEFAULT} will cause the name to render if {@link EntityRenderer#shouldShowName} returns true. + */ + public void setCanRender(TriState canRender) { + this.canRender = canRender; + } + + /** + * {@return if the nameplate will render or not} + */ + public TriState canRender() { + return canRender; + } + + /** + * Sets the new text on the nameplate. + * + * @param contents the new text + */ + public void setContent(Component contents) { + this.content = contents; + } + + /** + * {@return the text on the nameplate that will be rendered} + */ + public Component getContent() { + return this.content; + } } /** - * {@return the amount of packed (sky and block) light for rendering} + * This event is fired before an entity renderer renders the nameplate of an entity. + *

+ * It allows reacting to the rendering as well as performing custom rendering and preventing + * the vanilla rendering. + *

+ * This event is only fired on the logical client on the {@link NeoForge#EVENT_BUS}. * - * @see net.minecraft.client.renderer.LightTexture + * @see EntityRenderer */ - public int getPackedLight() { - return this.packedLight; - } + public static class DoRender extends RenderNameTagEvent implements ICancellableEvent { + private final PoseStack poseStack; + private final MultiBufferSource multiBufferSource; + private final int packedLight; - /** - * {@return the partial tick} - */ - public float getPartialTick() { - return this.partialTick; + public DoRender(EntityRenderState renderState, Component content, EntityRenderer entityRenderer, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight, float partialTick) { + super(renderState, content, entityRenderer, partialTick); + this.poseStack = poseStack; + this.multiBufferSource = multiBufferSource; + this.packedLight = packedLight; + } + + /** + * {@return the text on the nameplate} + */ + public Component getContent() { + return this.originalContent; + } + + /** + * {@return the pose stack used for rendering} + */ + public PoseStack getPoseStack() { + return this.poseStack; + } + + /** + * {@return the source of rendering buffers} + */ + public MultiBufferSource getMultiBufferSource() { + return this.multiBufferSource; + } + + /** + * {@return the amount of packed (sky and block) light for rendering} + * + * @see net.minecraft.client.renderer.LightTexture + */ + public int getPackedLight() { + return this.packedLight; + } } } diff --git a/src/main/java/net/neoforged/neoforge/client/event/RenderPlayerEvent.java b/src/main/java/net/neoforged/neoforge/client/event/RenderPlayerEvent.java index b9b3fc6818..b2fd3652e7 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/RenderPlayerEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/RenderPlayerEvent.java @@ -6,15 +6,15 @@ package net.neoforged.neoforge.client.event; import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.model.PlayerModel; +import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.entity.player.PlayerRenderer; -import net.minecraft.world.entity.player.Player; +import net.minecraft.client.renderer.entity.state.PlayerRenderState; import net.neoforged.bus.api.Event; import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.fml.LogicalSide; import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.event.entity.player.PlayerEvent; import org.jetbrains.annotations.ApiStatus; /** @@ -25,58 +25,10 @@ * @see RenderPlayerEvent.Post * @see PlayerRenderer */ -public abstract class RenderPlayerEvent extends PlayerEvent { - private final PlayerRenderer renderer; - private final float partialTick; - private final PoseStack poseStack; - private final MultiBufferSource multiBufferSource; - private final int packedLight; - +public abstract class RenderPlayerEvent extends RenderLivingEvent { @ApiStatus.Internal - protected RenderPlayerEvent(Player player, PlayerRenderer renderer, float partialTick, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight) { - super(player); - this.renderer = renderer; - this.partialTick = partialTick; - this.poseStack = poseStack; - this.multiBufferSource = multiBufferSource; - this.packedLight = packedLight; - } - - /** - * {@return the player entity renderer} - */ - public PlayerRenderer getRenderer() { - return renderer; - } - - /** - * {@return the partial tick} - */ - public float getPartialTick() { - return partialTick; - } - - /** - * {@return the pose stack used for rendering} - */ - public PoseStack getPoseStack() { - return poseStack; - } - - /** - * {@return the source of rendering buffers} - */ - public MultiBufferSource getMultiBufferSource() { - return multiBufferSource; - } - - /** - * {@return the amount of packed (sky and block) light for rendering} - * - * @see LightTexture - */ - public int getPackedLight() { - return packedLight; + protected RenderPlayerEvent(PlayerRenderState renderState, PlayerRenderer renderer, float partialTick, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight) { + super(renderState, renderer, partialTick, poseStack, multiBufferSource, packedLight); } /** @@ -92,8 +44,8 @@ public int getPackedLight() { */ public static class Pre extends RenderPlayerEvent implements ICancellableEvent { @ApiStatus.Internal - public Pre(Player player, PlayerRenderer renderer, float partialTick, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight) { - super(player, renderer, partialTick, poseStack, multiBufferSource, packedLight); + public Pre(PlayerRenderState renderState, PlayerRenderer renderer, float partialTick, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight) { + super(renderState, renderer, partialTick, poseStack, multiBufferSource, packedLight); } } @@ -107,8 +59,8 @@ public Pre(Player player, PlayerRenderer renderer, float partialTick, PoseStack */ public static class Post extends RenderPlayerEvent { @ApiStatus.Internal - public Post(Player player, PlayerRenderer renderer, float partialTick, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight) { - super(player, renderer, partialTick, poseStack, multiBufferSource, packedLight); + public Post(PlayerRenderState renderState, PlayerRenderer renderer, float partialTick, PoseStack poseStack, MultiBufferSource multiBufferSource, int packedLight) { + super(renderState, renderer, partialTick, poseStack, multiBufferSource, packedLight); } } } diff --git a/src/main/java/net/neoforged/neoforge/client/event/ScreenEvent.java b/src/main/java/net/neoforged/neoforge/client/event/ScreenEvent.java index bb40c082b8..d3d22931a9 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/ScreenEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/ScreenEvent.java @@ -13,7 +13,8 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.gui.screens.inventory.EffectRenderingInventoryScreen; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.gui.screens.inventory.EffectsInInventory; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; import net.neoforged.bus.api.Event; @@ -256,7 +257,7 @@ public GuiGraphics getGuiGraphics() { } /** - * Fired ahead of rendering any active mob effects in the {@link EffectRenderingInventoryScreen inventory screen}. + * Fired ahead of rendering any active mob effects in the {@link EffectsInInventory} held by a {@link AbstractContainerScreen}. * Can be used to select the size of the effects display (full or compact) or even hide or replace vanilla's rendering entirely. * This event can also be used to modify the horizontal position of the stack of effects being rendered. * diff --git a/src/main/java/net/neoforged/neoforge/client/event/ViewportEvent.java b/src/main/java/net/neoforged/neoforge/client/event/ViewportEvent.java index 77c664415a..cf0e2541c3 100644 --- a/src/main/java/net/neoforged/neoforge/client/event/ViewportEvent.java +++ b/src/main/java/net/neoforged/neoforge/client/event/ViewportEvent.java @@ -8,6 +8,7 @@ import com.mojang.blaze3d.shaders.FogShape; import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.FogParameters; import net.minecraft.client.renderer.FogRenderer.FogMode; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.world.level.material.FogType; @@ -80,13 +81,13 @@ public static class RenderFog extends ViewportEvent implements ICancellableEvent private FogShape fogShape; @ApiStatus.Internal - public RenderFog(FogMode mode, FogType type, Camera camera, float partialTicks, float nearPlaneDistance, float farPlaneDistance, FogShape fogShape) { + public RenderFog(FogMode mode, FogType type, Camera camera, float partialTicks, FogParameters fogParameters) { super(Minecraft.getInstance().gameRenderer, camera, partialTicks); this.mode = mode; this.type = type; - setFarPlaneDistance(farPlaneDistance); - setNearPlaneDistance(nearPlaneDistance); - setFogShape(fogShape); + setFarPlaneDistance(fogParameters.end()); + setNearPlaneDistance(fogParameters.start()); + setFogShape(fogParameters.shape()); } /** @@ -326,10 +327,10 @@ public void setRoll(float roll) { */ public static class ComputeFov extends ViewportEvent { private final boolean usedConfiguredFov; - private double fov; + private float fov; @ApiStatus.Internal - public ComputeFov(GameRenderer renderer, Camera camera, double renderPartialTicks, double fov, boolean usedConfiguredFov) { + public ComputeFov(GameRenderer renderer, Camera camera, float renderPartialTicks, float fov, boolean usedConfiguredFov) { super(renderer, camera, renderPartialTicks); this.usedConfiguredFov = usedConfiguredFov; this.setFOV(fov); @@ -338,7 +339,7 @@ public ComputeFov(GameRenderer renderer, Camera camera, double renderPartialTick /** * {@return the raw field of view value} */ - public double getFOV() { + public float getFOV() { return fov; } @@ -347,7 +348,7 @@ public double getFOV() { * * @param fov the new FOV value */ - public void setFOV(double fov) { + public void setFOV(float fov) { this.fov = fov; } diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/IBakedModelExtension.java b/src/main/java/net/neoforged/neoforge/client/extensions/IBakedModelExtension.java index 52ffd3c84b..eee572c5e7 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/IBakedModelExtension.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/IBakedModelExtension.java @@ -89,25 +89,25 @@ default ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, M * Gets an ordered list of {@link RenderType render types} to use when drawing this item. * All render types using the {@link com.mojang.blaze3d.vertex.DefaultVertexFormat#NEW_ENTITY} format are supported. *

- * This method will only be called on the models returned by {@link #getRenderPasses(ItemStack, boolean)}. + * This method will only be called on the models returned by {@link #getRenderPasses(ItemStack)}. *

* By default, defers query to {@link ItemBlockRenderTypes}. * - * @see #getRenderPasses(ItemStack, boolean) + * @see #getRenderPasses(ItemStack) */ - default List getRenderTypes(ItemStack itemStack, boolean fabulous) { - return List.of(RenderTypeHelper.getFallbackItemRenderType(itemStack, self(), fabulous)); + default List getRenderTypes(ItemStack itemStack) { + return List.of(RenderTypeHelper.getFallbackItemRenderType(itemStack, self())); } /** * Gets an ordered list of baked models used to render this model as an item. - * Each of those models' render types will be queried via {@link #getRenderTypes(ItemStack, boolean)}. + * Each of those models' render types will be queried via {@link #getRenderTypes(ItemStack)}. *

* By default, returns the model itself. * - * @see #getRenderTypes(ItemStack, boolean) + * @see #getRenderTypes(ItemStack) */ - default List getRenderPasses(ItemStack itemStack, boolean fabulous) { + default List getRenderPasses(ItemStack itemStack) { return List.of(self()); } } diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/IDimensionSpecialEffectsExtension.java b/src/main/java/net/neoforged/neoforge/client/extensions/IDimensionSpecialEffectsExtension.java index b8253c7ba7..9268c20007 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/IDimensionSpecialEffectsExtension.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/IDimensionSpecialEffectsExtension.java @@ -5,13 +5,11 @@ package net.neoforged.neoforge.client.extensions; -import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Camera; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.DimensionSpecialEffects; import net.minecraft.client.renderer.LightTexture; import org.joml.Matrix4f; -import org.joml.Vector3f; /** * Extension interface for {@link DimensionSpecialEffects}. @@ -26,7 +24,7 @@ private DimensionSpecialEffects self() { * * @return true to prevent vanilla cloud rendering */ - default boolean renderClouds(ClientLevel level, int ticks, float partialTick, PoseStack poseStack, double camX, double camY, double camZ, Matrix4f modelViewMatrix, Matrix4f projectionMatrix) { + default boolean renderClouds(ClientLevel level, int ticks, float partialTick, double camX, double camY, double camZ, Matrix4f modelViewMatrix, Matrix4f projectionMatrix) { return false; } @@ -35,7 +33,7 @@ default boolean renderClouds(ClientLevel level, int ticks, float partialTick, Po * * @return true to prevent vanilla sky rendering */ - default boolean renderSky(ClientLevel level, int ticks, float partialTick, Matrix4f modelViewMatrix, Camera camera, Matrix4f projectionMatrix, boolean isFoggy, Runnable setupFog) { + default boolean renderSky(ClientLevel level, int ticks, float partialTick, Matrix4f modelViewMatrix, Camera camera, Matrix4f projectionMatrix, Runnable setupFog) { return false; } @@ -56,20 +54,4 @@ default boolean renderSnowAndRain(ClientLevel level, int ticks, float partialTic default boolean tickRain(ClientLevel level, int ticks, Camera camera) { return false; } - - /** - * Allows for manipulating the coloring of the lightmap texture. - * Will be called for each 16*16 combination of sky/block light values. - * - * @param level The current level (client-side). - * @param partialTicks Progress between ticks. - * @param skyDarken Current darkness of the sky (can be used to calculate sky light). - * @param blockLightRedFlicker Block light flicker factor (red color) (can be used to calculate block light). - * @param skyLight Sky light brightness (accounting for sky darkness). - * @param pixelX X-coordinate of the lightmap texture (block). - * @param pixelY Y-coordinate of the lightmap texture (sky). - * @param colors The color values that will be used: [r, g, b]. - * @see LightTexture#updateLightTexture(float) - */ - default void adjustLightmapColors(ClientLevel level, float partialTicks, float skyDarken, float blockLightRedFlicker, float skyLight, int pixelX, int pixelY, Vector3f colors) {} } diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/IGuiGraphicsExtension.java b/src/main/java/net/neoforged/neoforge/client/extensions/IGuiGraphicsExtension.java index ff0d2c3cc3..d6b1da00e0 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/IGuiGraphicsExtension.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/IGuiGraphicsExtension.java @@ -8,6 +8,7 @@ import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.renderer.RenderType; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -49,6 +50,7 @@ default int drawScrollingString(Font font, Component text, int minX, int maxX, i } } + // TODO: 1.21.2: do we need to fix these or can we just remove them? /** * Draws a textured box of any size (smallest size is borderSize * 2 square) * based on a fixed size textured box with continuous borders and filler. @@ -64,9 +66,9 @@ default int drawScrollingString(Font font, Component text, int minX, int maxX, i * @param textureHeight the height of the box texture in the resource location image * @param borderSize the size of the box's borders */ - default void blitWithBorder(ResourceLocation texture, int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight, int borderSize) { + /*default void blitWithBorder(ResourceLocation texture, int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight, int borderSize) { this.blitWithBorder(texture, x, y, u, v, width, height, textureWidth, textureHeight, borderSize, borderSize, borderSize, borderSize); - } + }*/ /** * Draws a textured box of any size (smallest size is borderSize * 2 square) @@ -86,7 +88,7 @@ default void blitWithBorder(ResourceLocation texture, int x, int y, int u, int v * @param leftBorder the size of the box's left border * @param rightBorder the size of the box's right border */ - default void blitWithBorder(ResourceLocation texture, int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight, int topBorder, int bottomBorder, int leftBorder, int rightBorder) { + /*default void blitWithBorder(ResourceLocation texture, int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight, int topBorder, int bottomBorder, int leftBorder, int rightBorder) { int fillerWidth = textureWidth - leftBorder - rightBorder; int fillerHeight = textureHeight - topBorder - bottomBorder; int canvasWidth = width - leftBorder - rightBorder; @@ -95,7 +97,7 @@ default void blitWithBorder(ResourceLocation texture, int x, int y, int u, int v int remainderWidth = canvasWidth % fillerWidth; int yPasses = canvasHeight / fillerHeight; int remainderHeight = canvasHeight % fillerHeight; - + // Draw Border // Top Left self().blit(texture, x, y, u, v, leftBorder, topBorder); @@ -105,18 +107,18 @@ default void blitWithBorder(ResourceLocation texture, int x, int y, int u, int v self().blit(texture, x, y + topBorder + canvasHeight, u, v + topBorder + fillerHeight, leftBorder, bottomBorder); // Bottom Right self().blit(texture, x + leftBorder + canvasWidth, y + topBorder + canvasHeight, u + leftBorder + fillerWidth, v + topBorder + fillerHeight, rightBorder, bottomBorder); - + for (int i = 0; i < xPasses + (remainderWidth > 0 ? 1 : 0); i++) { // Top Border self().blit(texture, x + leftBorder + (i * fillerWidth), y, u + leftBorder, v, (i == xPasses ? remainderWidth : fillerWidth), topBorder); // Bottom Border self().blit(texture, x + leftBorder + (i * fillerWidth), y + topBorder + canvasHeight, u + leftBorder, v + topBorder + fillerHeight, (i == xPasses ? remainderWidth : fillerWidth), bottomBorder); - + // Throw in some filler for good measure for (int j = 0; j < yPasses + (remainderHeight > 0 ? 1 : 0); j++) self().blit(texture, x + leftBorder + (i * fillerWidth), y + topBorder + (j * fillerHeight), u + leftBorder, v + topBorder, (i == xPasses ? remainderWidth : fillerWidth), (j == yPasses ? remainderHeight : fillerHeight)); } - + // Side Borders for (int j = 0; j < yPasses + (remainderHeight > 0 ? 1 : 0); j++) { // Left Border @@ -124,7 +126,7 @@ default void blitWithBorder(ResourceLocation texture, int x, int y, int u, int v // Right Border self().blit(texture, x + leftBorder + canvasWidth, y + topBorder + (j * fillerHeight), u + leftBorder + fillerWidth, v + topBorder, rightBorder, (j == yPasses ? remainderHeight : fillerHeight)); } - } + }*/ default void blitInscribed(ResourceLocation texture, int x, int y, int boundsWidth, int boundsHeight, int rectWidth, int rectHeight) { this.blitInscribed(texture, x, y, boundsWidth, boundsHeight, rectWidth, rectHeight, true, true); @@ -141,7 +143,7 @@ default void blitInscribed(ResourceLocation texture, int x, int y, int boundsWid if (centerX) x += (w - boundsWidth) / 2; } - self().blit(texture, x, y, boundsWidth, boundsHeight, 0.0f, 0.0f, rectWidth, rectHeight, rectWidth, rectHeight); + self().blit(RenderType::guiTextured, texture, x, y, boundsWidth, boundsHeight, 0, 0, rectWidth, rectHeight, rectWidth, rectHeight); } // TODO: 1.20.2: do we need to fix these or can we just remove them? diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/IModelBakerExtension.java b/src/main/java/net/neoforged/neoforge/client/extensions/IModelBakerExtension.java index c509d32b3f..90d84c3928 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/IModelBakerExtension.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/IModelBakerExtension.java @@ -19,10 +19,8 @@ public interface IModelBakerExtension { @Nullable UnbakedModel getTopLevelModel(ModelResourceLocation location); - @Nullable BakedModel bake(ResourceLocation location, ModelState state, Function sprites); - @Nullable BakedModel bakeUncached(UnbakedModel model, ModelState state, Function sprites); Function getModelTextureGetter(); diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/common/ClientExtensionsManager.java b/src/main/java/net/neoforged/neoforge/client/extensions/common/ClientExtensionsManager.java index 731f432259..7d7a22d6fc 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/common/ClientExtensionsManager.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/common/ClientExtensionsManager.java @@ -9,14 +9,12 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; import net.neoforged.fml.ModLoader; import net.neoforged.neoforge.data.loading.DatagenModLoader; import net.neoforged.neoforge.fluids.FluidType; -import net.neoforged.neoforge.registries.NeoForgeRegistries; import org.jetbrains.annotations.ApiStatus; @ApiStatus.Internal @@ -25,7 +23,6 @@ public final class ClientExtensionsManager { static final Map ITEM_EXTENSIONS = new Reference2ObjectOpenHashMap<>(); static final Map MOB_EFFECT_EXTENSIONS = new Reference2ObjectOpenHashMap<>(); static final Map FLUID_TYPE_EXTENSIONS = new Reference2ObjectOpenHashMap<>(); - private static boolean earlyInitialized = false; private static boolean initialized = false; private ClientExtensionsManager() {} @@ -51,22 +48,6 @@ static void register(E extensions, Map target, T... objects) { } } - @Deprecated(forRemoval = true, since = "1.21") - public static void earlyInit() { - // Minecraft instance isn't available in datagen, so don't initialize client extensions in datagen - if (DatagenModLoader.isRunningDataGen()) return; - - if (earlyInitialized) { - throw new IllegalStateException("Duplicate early initialization of ClientExtensionsManager"); - } - - earlyInitialized = true; - BuiltInRegistries.BLOCK.forEach(block -> block.initializeClient(ext -> register(ext, BLOCK_EXTENSIONS, block))); - BuiltInRegistries.ITEM.forEach(item -> item.initializeClient(ext -> register(ext, ITEM_EXTENSIONS, item))); - BuiltInRegistries.MOB_EFFECT.forEach(mobEffect -> mobEffect.initializeClient(ext -> register(ext, MOB_EFFECT_EXTENSIONS, mobEffect))); - NeoForgeRegistries.FLUID_TYPES.forEach(fluidType -> fluidType.initializeClient(ext -> register(ext, FLUID_TYPE_EXTENSIONS, fluidType))); - } - public static void init() { // Minecraft instance isn't available in datagen, so don't initialize client extensions in datagen if (DatagenModLoader.isRunningDataGen()) return; diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientFluidTypeExtensions.java b/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientFluidTypeExtensions.java index 11e44b56c5..d9df521cab 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientFluidTypeExtensions.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientFluidTypeExtensions.java @@ -5,13 +5,13 @@ package net.neoforged.neoforge.client.extensions.common; -import com.mojang.blaze3d.shaders.FogShape; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import java.util.function.Consumer; import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.renderer.FogParameters; import net.minecraft.client.renderer.FogRenderer; import net.minecraft.client.renderer.ScreenEffectRenderer; import net.minecraft.core.BlockPos; @@ -25,7 +25,7 @@ import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.FluidType; import org.jetbrains.annotations.Nullable; -import org.joml.Vector3f; +import org.joml.Vector4f; /** * {@linkplain LogicalSide#CLIENT Client-only} extensions to {@link FluidType}. @@ -167,10 +167,10 @@ default void renderOverlay(Minecraft mc, PoseStack poseStack) { * @param level the level the camera is located in * @param renderDistance the render distance of the client * @param darkenWorldAmount the amount to darken the world by - * @param fluidFogColor the current color of the fog + * @param fluidFogColor the current RGBA color of the fog * @return the color of the fog */ - default Vector3f modifyFogColor(Camera camera, float partialTick, ClientLevel level, int renderDistance, float darkenWorldAmount, Vector3f fluidFogColor) { + default Vector4f modifyFogColor(Camera camera, float partialTick, ClientLevel level, int renderDistance, float darkenWorldAmount, Vector4f fluidFogColor) { return fluidFogColor; } @@ -182,11 +182,12 @@ default Vector3f modifyFogColor(Camera camera, float partialTick, ClientLevel le * @param mode the type of fog being rendered * @param renderDistance the render distance of the client * @param partialTick the delta time of where the current frame is within a tick - * @param nearDistance the near plane of where the fog starts to render - * @param farDistance the far plane of where the fog ends rendering - * @param shape the shape of the fog being rendered + * @param fogParameters the parameters to use for rendering the fog + * @return the modified fog parameters */ - default void modifyFogRender(Camera camera, FogRenderer.FogMode mode, float renderDistance, float partialTick, float nearDistance, float farDistance, FogShape shape) {} + default FogParameters modifyFogRender(Camera camera, FogRenderer.FogMode mode, float renderDistance, float partialTick, FogParameters fogParameters) { + return fogParameters; + } /* Level-Based Accessors */ diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java b/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java index 16ac6d3853..34018888a6 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientItemExtensions.java @@ -6,35 +6,34 @@ package net.neoforged.neoforge.client.extensions.common; import com.mojang.blaze3d.vertex.PoseStack; -import java.util.function.Consumer; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.Model; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.BlockEntityWithoutLevelRenderer; +import net.minecraft.client.renderer.entity.layers.EquipmentLayerRenderer; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.tags.ItemTags; -import net.minecraft.util.FastColor; +import net.minecraft.util.ARGB; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.HumanoidArm; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ArmorMaterial; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.DyedItemColor; +import net.minecraft.world.item.equipment.EquipmentModel; import net.minecraft.world.level.block.state.BlockState; import net.neoforged.fml.LogicalSide; -import net.neoforged.neoforge.client.ClientHooks; import net.neoforged.neoforge.client.IArmPoseTransformer; import org.jetbrains.annotations.Nullable; /** * {@linkplain LogicalSide#CLIENT Client-only} extensions to {@link Item}. * - * @see Item#initializeClient(Consumer) + * @see RegisterClientExtensionsEvent */ public interface IClientItemExtensions { IClientItemExtensions DEFAULT = new IClientItemExtensions() {}; @@ -93,35 +92,34 @@ default boolean applyForgeHandTransform(PoseStack poseStack, LocalPlayer player, /** * Queries the humanoid armor model for this item when it's equipped. * - * @param livingEntity The entity wearing the armor - * @param itemStack The item stack - * @param equipmentSlot The slot the item is in - * @param original The original armor model. Will have attributes set. + * @param itemStack The item stack + * @param layerType The slot the item is in + * @param original The original armor model. Will have attributes set. * @return A HumanoidModel to be rendered. Relevant properties are to be copied over by the caller. - * @see #getGenericArmorModel(LivingEntity, ItemStack, EquipmentSlot, HumanoidModel) + * @see #getGenericArmorModel(ItemStack, EquipmentModel.LayerType, Model) */ - default HumanoidModel getHumanoidArmorModel(LivingEntity livingEntity, ItemStack itemStack, EquipmentSlot equipmentSlot, HumanoidModel original) { + default Model getHumanoidArmorModel(ItemStack itemStack, EquipmentModel.LayerType layerType, Model original) { return original; } /** * Queries the armor model for this item when it's equipped. Useful in place of - * {@link #getHumanoidArmorModel(LivingEntity, ItemStack, EquipmentSlot, HumanoidModel)} for wrapping the original + * {@link #getHumanoidArmorModel(ItemStack, EquipmentModel.LayerType, Model)} for wrapping the original * model or returning anything non-standard. *

* If you override this method you are responsible for copying any properties you care about from the original model. * - * @param livingEntity The entity wearing the armor - * @param itemStack The item stack - * @param equipmentSlot The slot the item is in - * @param original The original armor model. Will have attributes set. + * @param itemStack The item stack + * @param layerType The slot the item is in + * @param original The original armor model. Will have attributes set. * @return A Model to be rendered. Relevant properties must be copied over manually. - * @see #getHumanoidArmorModel(LivingEntity, ItemStack, EquipmentSlot, HumanoidModel) + * @see #getHumanoidArmorModel(ItemStack, EquipmentModel.LayerType, Model) */ - default Model getGenericArmorModel(LivingEntity livingEntity, ItemStack itemStack, EquipmentSlot equipmentSlot, HumanoidModel original) { - HumanoidModel replacement = getHumanoidArmorModel(livingEntity, itemStack, equipmentSlot, original); + default Model getGenericArmorModel(ItemStack itemStack, EquipmentModel.LayerType layerType, Model original) { + Model replacement = getHumanoidArmorModel(itemStack, layerType, original); if (replacement != original) { - ClientHooks.copyModelProperties(original, replacement); + // FIXME: equipment rendering deals with a plain Model now + //ClientHooks.copyModelProperties(original, replacement); return replacement; } return original; @@ -141,6 +139,7 @@ default Model getGenericArmorModel(LivingEntity livingEntity, ItemStack itemStac * @param netHeadYaw The yaw (Y rotation) of the entity's head * @param headPitch The pitch (X rotation) of the entity's head */ + // TODO 1.21.2: add back patch that calls this method from HumanoidArmorLayer default void setupModelAnimations(LivingEntity livingEntity, ItemStack itemStack, EquipmentSlot equipmentSlot, Model model, float limbSwing, float limbSwingAmount, float partialTick, float ageInTicks, float netHeadYaw, float headPitch) {} /** @@ -187,7 +186,7 @@ default boolean shouldSpreadAsEntity(ItemStack stack) { } /** - * Called when armor layers are rendered by {@link net.minecraft.client.renderer.entity.layers.HumanoidArmorLayer}. + * Called when armor layers are rendered by {@link net.minecraft.client.renderer.entity.layers.EquipmentLayerRenderer}. *

* Allows custom dye colors to be specified per-layer; default vanilla behavior allows for only a single dye color * (specified by the {@link net.minecraft.core.component.DataComponents#DYED_COLOR} data component) for all layers. @@ -196,20 +195,19 @@ default boolean shouldSpreadAsEntity(ItemStack stack) { * doesn't need to be rendered for a particular armor slot. * * @param stack the armor item stack being rendered - * @param entity the entity wearing the armor * @param layer the armor layer being rendered * @param layerIdx an index into the list of layers for the {@code ArmorMaterial} used by this item * @param fallbackColor the return value of {@link #getDefaultDyeColor(ItemStack)}, passed as a parameter for * performance * @return a custom color for the layer, in ARGB format, or 0 to skip rendering */ - default int getArmorLayerTintColor(ItemStack stack, LivingEntity entity, ArmorMaterial.Layer layer, int layerIdx, int fallbackColor) { - return layer.dyeable() ? fallbackColor : 0xFFFFFFFF; + default int getArmorLayerTintColor(ItemStack stack, EquipmentModel.Layer layer, int layerIdx, int fallbackColor) { + return EquipmentLayerRenderer.getColorForLayer(layer, fallbackColor); } /** * Called once per render pass of equipped armor items, regardless of the number of layers; the return value of this - * method is passed to {@link #getArmorLayerTintColor(ItemStack, LivingEntity, ArmorMaterial.Layer, int, int)} as + * method is passed to {@link #getArmorLayerTintColor(ItemStack, EquipmentModel.Layer, int, int)} as * the {@code fallbackColor} parameter. *

* You can override this method for your custom armor item to provide an alternative default color for the item when @@ -219,7 +217,7 @@ default int getArmorLayerTintColor(ItemStack stack, LivingEntity entity, ArmorMa * @return a default color for the layer, in ARGB format */ default int getDefaultDyeColor(ItemStack stack) { - return stack.is(ItemTags.DYEABLE) ? FastColor.ARGB32.opaque(DyedItemColor.getOrDefault(stack, DyedItemColor.LEATHER_COLOR)) : 0xFFFFFFFF; + return stack.is(ItemTags.DYEABLE) ? ARGB.opaque(DyedItemColor.getOrDefault(stack, 0)) : 0; } enum FontContext { diff --git a/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientMobEffectExtensions.java b/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientMobEffectExtensions.java index dbcde12749..d8cc391382 100644 --- a/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientMobEffectExtensions.java +++ b/src/main/java/net/neoforged/neoforge/client/extensions/common/IClientMobEffectExtensions.java @@ -5,10 +5,9 @@ package net.neoforged.neoforge.client.extensions.common; -import java.util.function.Consumer; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.screens.inventory.EffectRenderingInventoryScreen; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectInstance; import net.neoforged.fml.LogicalSide; @@ -16,7 +15,7 @@ /** * {@linkplain LogicalSide#CLIENT Client-only} extensions to {@link MobEffect}. * - * @see MobEffect#initializeClient(Consumer) + * @see RegisterClientExtensionsEvent */ public interface IClientMobEffectExtensions { IClientMobEffectExtensions DEFAULT = new IClientMobEffectExtensions() {}; @@ -59,7 +58,7 @@ default boolean isVisibleInGui(MobEffectInstance instance) { * @param blitOffset The blit offset * @return true to prevent default rendering, false otherwise */ - default boolean renderInventoryIcon(MobEffectInstance instance, EffectRenderingInventoryScreen screen, GuiGraphics guiGraphics, int x, int y, int blitOffset) { + default boolean renderInventoryIcon(MobEffectInstance instance, AbstractContainerScreen screen, GuiGraphics guiGraphics, int x, int y, int blitOffset) { return false; } @@ -74,7 +73,7 @@ default boolean renderInventoryIcon(MobEffectInstance instance, EffectRenderingI * @param blitOffset The blit offset * @return true to prevent default rendering, false otherwise */ - default boolean renderInventoryText(MobEffectInstance instance, EffectRenderingInventoryScreen screen, GuiGraphics guiGraphics, int x, int y, int blitOffset) { + default boolean renderInventoryText(MobEffectInstance instance, AbstractContainerScreen screen, GuiGraphics guiGraphics, int x, int y, int blitOffset) { return false; } diff --git a/src/main/java/net/neoforged/neoforge/client/gui/ScreenUtils.java b/src/main/java/net/neoforged/neoforge/client/gui/ScreenUtils.java index 9ec8fc38f9..456a0dd0bc 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/ScreenUtils.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/ScreenUtils.java @@ -12,7 +12,7 @@ import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexFormat; import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.CoreShaders; import net.minecraft.resources.ResourceLocation; import net.neoforged.neoforge.client.extensions.IGuiGraphicsExtension; import org.joml.Matrix4f; @@ -108,7 +108,7 @@ public static void blitWithBorder(GuiGraphics guiGraphics, ResourceLocation res, */ public static void blitWithBorder(GuiGraphics guiGraphics, ResourceLocation res, int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight, int topBorder, int bottomBorder, int leftBorder, int rightBorder, float zLevel) { - RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShader(CoreShaders.POSITION_TEX); RenderSystem.setShaderTexture(0, res); blitWithBorder(guiGraphics, x, y, u, v, width, height, textureWidth, textureHeight, topBorder, bottomBorder, leftBorder, rightBorder, zLevel); } @@ -213,7 +213,7 @@ public static void drawGradientRect(Matrix4f mat, int zLevel, int left, int top, RenderSystem.enableDepthTest(); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); - RenderSystem.setShader(GameRenderer::getPositionColorShader); + RenderSystem.setShader(CoreShaders.POSITION_COLOR); Tesselator tessellator = Tesselator.getInstance(); BufferBuilder buffer = tessellator.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); @@ -224,22 +224,4 @@ public static void drawGradientRect(Matrix4f mat, int zLevel, int left, int top, BufferUploader.drawWithShader(buffer.buildOrThrow()); RenderSystem.disableBlend(); } - - public static void blitInscribed(GuiGraphics guiGraphics, ResourceLocation texture, int x, int y, int boundsWidth, int boundsHeight, int rectWidth, int rectHeight) { - blitInscribed(guiGraphics, texture, x, y, boundsWidth, boundsHeight, rectWidth, rectHeight, true, true); - } - - public static void blitInscribed(GuiGraphics guiGraphics, ResourceLocation texture, int x, int y, int boundsWidth, int boundsHeight, int rectWidth, int rectHeight, boolean centerX, boolean centerY) { - if (rectWidth * boundsHeight > rectHeight * boundsWidth) { - int h = boundsHeight; - boundsHeight = (int) (boundsWidth * ((double) rectHeight / rectWidth)); - if (centerY) y += (h - boundsHeight) / 2; - } else { - int w = boundsWidth; - boundsWidth = (int) (boundsHeight * ((double) rectWidth / rectHeight)); - if (centerX) x += (w - boundsWidth) / 2; - } - - guiGraphics.blit(texture, x, y, boundsWidth, boundsHeight, 0.0f, 0.0f, rectWidth, rectHeight, rectWidth, rectHeight); - } } diff --git a/src/main/java/net/neoforged/neoforge/client/gui/map/IMapDecorationRenderer.java b/src/main/java/net/neoforged/neoforge/client/gui/map/IMapDecorationRenderer.java index 09154babfb..3e86c41049 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/map/IMapDecorationRenderer.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/map/IMapDecorationRenderer.java @@ -7,9 +7,9 @@ import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.state.MapRenderState; import net.minecraft.client.resources.MapDecorationTextureManager; import net.minecraft.world.level.saveddata.maps.MapDecoration; -import net.minecraft.world.level.saveddata.maps.MapItemSavedData; /** * Interface for custom {@link MapDecoration} renderers @@ -19,21 +19,21 @@ public interface IMapDecorationRenderer { * Render the given {@link MapDecoration} on the map. If this method returns true, the vanilla rendering will be * canceled. Otherwise, it will render above whatever is rendered in this method, if anything * - * @param decoration The decoration to be rendered - * @param poseStack The {@link PoseStack} to render the decoration with - * @param bufferSource The {@link MultiBufferSource} to render the decoration with - * @param mapData The data of the map being rendered - * @param decorationTextures The manager holding map decoration sprites - * @param inItemFrame Whether the map is being rendered in an item frame - * @param packedLight The packed light value - * @param index The z index of the decoration being rendered + * @param decorationRenderState The state decoration to be rendered + * @param poseStack The {@link PoseStack} to render the decoration with + * @param bufferSource The {@link MultiBufferSource} to render the decoration with + * @param mapRenderState The state of the map being rendered + * @param decorationTextures The manager holding map decoration sprites + * @param inItemFrame Whether the map is being rendered in an item frame + * @param packedLight The packed light value + * @param index The z index of the decoration being rendered * @return true to cancel vanilla rendering */ boolean render( - MapDecoration decoration, + MapRenderState.MapDecorationRenderState decorationRenderState, PoseStack poseStack, MultiBufferSource bufferSource, - MapItemSavedData mapData, + MapRenderState mapRenderState, MapDecorationTextureManager decorationTextures, boolean inItemFrame, int packedLight, diff --git a/src/main/java/net/neoforged/neoforge/client/gui/map/MapDecorationRendererManager.java b/src/main/java/net/neoforged/neoforge/client/gui/map/MapDecorationRendererManager.java index df4dafc331..6cfda70ccd 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/map/MapDecorationRendererManager.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/map/MapDecorationRendererManager.java @@ -9,10 +9,9 @@ import java.util.IdentityHashMap; import java.util.Map; import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.state.MapRenderState; import net.minecraft.client.resources.MapDecorationTextureManager; -import net.minecraft.world.level.saveddata.maps.MapDecoration; import net.minecraft.world.level.saveddata.maps.MapDecorationType; -import net.minecraft.world.level.saveddata.maps.MapItemSavedData; import net.neoforged.fml.ModLoader; import org.jetbrains.annotations.ApiStatus; @@ -24,17 +23,17 @@ public final class MapDecorationRendererManager { private MapDecorationRendererManager() {} public static boolean render( - MapDecoration decoration, + MapRenderState.MapDecorationRenderState decorationRenderState, PoseStack poseStack, MultiBufferSource bufferSource, - MapItemSavedData mapData, + MapRenderState mapRenderState, MapDecorationTextureManager decorationTextures, boolean inItemFrame, int packedLight, int index) { - IMapDecorationRenderer decorationRenderer = RENDERERS.get(decoration.type().value()); + IMapDecorationRenderer decorationRenderer = RENDERERS.get(decorationRenderState.type.value()); if (decorationRenderer != null) { - return decorationRenderer.render(decoration, poseStack, bufferSource, mapData, decorationTextures, inItemFrame, packedLight, index); + return decorationRenderer.render(decorationRenderState, poseStack, bufferSource, mapRenderState, decorationTextures, inItemFrame, packedLight, index); } return false; } diff --git a/src/main/java/net/neoforged/neoforge/client/gui/widget/ExtendedButton.java b/src/main/java/net/neoforged/neoforge/client/gui/widget/ExtendedButton.java index cf1b0ecb9c..7636faf04e 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/widget/ExtendedButton.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/widget/ExtendedButton.java @@ -8,6 +8,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; +import net.minecraft.client.renderer.RenderType; import net.minecraft.locale.Language; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.FormattedText; @@ -41,7 +42,7 @@ public ExtendedButton(Button.Builder builder) { @Override public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { Minecraft mc = Minecraft.getInstance(); - guiGraphics.blitSprite(SPRITES.get(this.active, this.isHoveredOrFocused()), this.getX(), this.getY(), this.getWidth(), this.getHeight()); + guiGraphics.blitSprite(RenderType::guiTextured, SPRITES.get(this.active, this.isHoveredOrFocused()), this.getX(), this.getY(), this.getWidth(), this.getHeight()); final FormattedText buttonText = mc.font.ellipsize(this.getMessage(), this.width - 6); // Remove 6 pixels so that the text is always contained within the button's borders guiGraphics.drawCenteredString(mc.font, Language.getInstance().getVisualOrder(buttonText), this.getX() + this.width / 2, this.getY() + (this.height - 8) / 2, getFGColor()); diff --git a/src/main/java/net/neoforged/neoforge/client/gui/widget/ExtendedSlider.java b/src/main/java/net/neoforged/neoforge/client/gui/widget/ExtendedSlider.java index ec4f2e9d18..787e97066a 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/widget/ExtendedSlider.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/widget/ExtendedSlider.java @@ -5,12 +5,13 @@ package net.neoforged.neoforge.client.gui.widget; -import com.mojang.blaze3d.systems.RenderSystem; import java.text.DecimalFormat; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.AbstractSliderButton; +import net.minecraft.client.renderer.RenderType; import net.minecraft.network.chat.Component; +import net.minecraft.util.ARGB; import net.minecraft.util.Mth; import org.lwjgl.glfw.GLFW; @@ -195,13 +196,8 @@ protected void applyValue() {} @Override public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { Minecraft minecraft = Minecraft.getInstance(); - guiGraphics.setColor(1.0F, 1.0F, 1.0F, this.alpha); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.enableDepthTest(); - guiGraphics.blitSprite(this.getSprite(), this.getX(), this.getY(), this.getWidth(), this.getHeight()); - guiGraphics.blitSprite(this.getHandleSprite(), this.getX() + (int) (this.value * (double) (this.width - 8)), this.getY(), 8, this.getHeight()); - guiGraphics.setColor(1.0F, 1.0F, 1.0F, 1.0F); + guiGraphics.blitSprite(RenderType::guiTextured, this.getSprite(), this.getX(), this.getY(), this.getWidth(), this.getHeight(), ARGB.white(this.alpha)); + guiGraphics.blitSprite(RenderType::guiTextured, this.getHandleSprite(), this.getX() + (int) (this.value * (double) (this.width - 8)), this.getY(), 8, this.getHeight(), ARGB.white(this.alpha)); int i = this.active ? 16777215 : 10526880; this.renderScrollingString(guiGraphics, minecraft.font, 2, i | Mth.ceil(this.alpha * 255.0F) << 24); } diff --git a/src/main/java/net/neoforged/neoforge/client/gui/widget/ModListWidget.java b/src/main/java/net/neoforged/neoforge/client/gui/widget/ModListWidget.java index 2411aec988..cd6626c322 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/widget/ModListWidget.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/widget/ModListWidget.java @@ -9,6 +9,7 @@ import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.ObjectSelectionList; +import net.minecraft.client.renderer.RenderType; import net.minecraft.locale.Language; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.FormattedText; @@ -79,7 +80,7 @@ public void render(GuiGraphics guiGraphics, int entryIdx, int top, int left, int //TODO: Consider adding more icons for visualization RenderSystem.setShaderColor(1, 1, 1, 1); guiGraphics.pose().pushPose(); - guiGraphics.blit(VERSION_CHECK_ICONS, getX() + width - 12, top + entryHeight / 4, vercheck.status().getSheetOffset() * 8, (vercheck.status().isAnimated() && ((System.currentTimeMillis() / 800 & 1)) == 1) ? 8 : 0, 8, 8, 64, 16); + guiGraphics.blit(RenderType::guiTextured, VERSION_CHECK_ICONS, getX() + width - 12, top + entryHeight / 4, vercheck.status().getSheetOffset() * 8, (vercheck.status().isAnimated() && ((System.currentTimeMillis() / 800 & 1)) == 1) ? 8 : 0, 8, 8, 64, 16); guiGraphics.pose().popPose(); } } diff --git a/src/main/java/net/neoforged/neoforge/client/gui/widget/ModsButton.java b/src/main/java/net/neoforged/neoforge/client/gui/widget/ModsButton.java index c06a66359b..518fe707a5 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/widget/ModsButton.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/widget/ModsButton.java @@ -7,6 +7,7 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; +import net.minecraft.client.renderer.RenderType; import net.minecraft.resources.ResourceLocation; import net.neoforged.fml.VersionChecker; import net.neoforged.fml.loading.FMLConfig; @@ -49,6 +50,7 @@ protected void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, flo int h = getHeight(); guiGraphics.blit( + RenderType::guiTextured, VERSION_CHECK_ICONS, x + w - (h / 2 + 4), y + (h / 2 - 4), diff --git a/src/main/java/net/neoforged/neoforge/client/gui/widget/ScrollPanel.java b/src/main/java/net/neoforged/neoforge/client/gui/widget/ScrollPanel.java index 9e12367e2d..e836d58b6f 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/widget/ScrollPanel.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/widget/ScrollPanel.java @@ -20,7 +20,7 @@ import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.narration.NarratableEntry; import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.CoreShaders; /** * Abstract scroll panel class. @@ -250,7 +250,7 @@ public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partia int barBgGreen = this.barBgColor >> 8 & 0xff; int barBgBlue = this.barBgColor & 0xff; - RenderSystem.setShader(GameRenderer::getPositionColorShader); + RenderSystem.setShader(CoreShaders.POSITION_COLOR); BufferBuilder worldr = tess.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); worldr.addVertex(barLeft, this.bottom, 0.0F).setColor(barBgRed, barBgGreen, barBgBlue, barBgAlpha); worldr.addVertex(barLeft + barWidth, this.bottom, 0.0F).setColor(barBgRed, barBgGreen, barBgBlue, barBgAlpha); diff --git a/src/main/java/net/neoforged/neoforge/client/gui/widget/UnicodeGlyphButton.java b/src/main/java/net/neoforged/neoforge/client/gui/widget/UnicodeGlyphButton.java index ec903080d4..d733fd5593 100644 --- a/src/main/java/net/neoforged/neoforge/client/gui/widget/UnicodeGlyphButton.java +++ b/src/main/java/net/neoforged/neoforge/client/gui/widget/UnicodeGlyphButton.java @@ -7,6 +7,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.RenderType; import net.minecraft.network.chat.Component; /** @@ -27,7 +28,7 @@ public UnicodeGlyphButton(int xPos, int yPos, int width, int height, Component d @Override public void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { Minecraft mc = Minecraft.getInstance(); - guiGraphics.blitSprite(SPRITES.get(this.active, this.isHoveredOrFocused()), this.getX(), this.getY(), this.getWidth(), this.getHeight()); + guiGraphics.blitSprite(RenderType::guiTextured, SPRITES.get(this.active, this.isHoveredOrFocused()), this.getX(), this.getY(), this.getWidth(), this.getHeight()); Component buttonText = this.createNarrationMessage(); int glyphWidth = (int) (mc.font.width(glyph) * glyphScale); diff --git a/src/main/java/net/neoforged/neoforge/client/loading/ClientModLoader.java b/src/main/java/net/neoforged/neoforge/client/loading/ClientModLoader.java index 2b1f3ca889..d8c4a35e61 100644 --- a/src/main/java/net/neoforged/neoforge/client/loading/ClientModLoader.java +++ b/src/main/java/net/neoforged/neoforge/client/loading/ClientModLoader.java @@ -15,7 +15,6 @@ import net.minecraft.server.packs.resources.PreparableReloadListener; import net.minecraft.server.packs.resources.ReloadableResourceManager; import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.level.DataPackConfig; import net.neoforged.fml.Logging; import net.neoforged.fml.ModList; @@ -69,7 +68,7 @@ public static void begin(final Minecraft minecraft, final PackRepository default } } - private static CompletableFuture onResourceReload(final PreparableReloadListener.PreparationBarrier stage, final ResourceManager resourceManager, final ProfilerFiller prepareProfiler, final ProfilerFiller executeProfiler, final Executor asyncExecutor, final Executor syncExecutor) { + private static CompletableFuture onResourceReload(final PreparableReloadListener.PreparationBarrier stage, final ResourceManager resourceManager, final Executor asyncExecutor, final Executor syncExecutor) { return CompletableFuture.runAsync(() -> startModLoading(syncExecutor, asyncExecutor), ModWorkManager.parallelExecutor()) .thenCompose(stage::wait) .thenRunAsync(() -> finishModLoading(syncExecutor, asyncExecutor), ModWorkManager.parallelExecutor()); diff --git a/src/main/java/net/neoforged/neoforge/client/loading/NeoForgeLoadingOverlay.java b/src/main/java/net/neoforged/neoforge/client/loading/NeoForgeLoadingOverlay.java index 4b51f797c1..9f14b44d2a 100644 --- a/src/main/java/net/neoforged/neoforge/client/loading/NeoForgeLoadingOverlay.java +++ b/src/main/java/net/neoforged/neoforge/client/loading/NeoForgeLoadingOverlay.java @@ -5,6 +5,7 @@ package net.neoforged.neoforge.client.loading; +import com.mojang.blaze3d.ProjectionType; import com.mojang.blaze3d.platform.GlConst; import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; @@ -14,7 +15,6 @@ import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexFormat; -import com.mojang.blaze3d.vertex.VertexSorting; import java.util.Optional; import java.util.function.Consumer; import java.util.function.Supplier; @@ -22,7 +22,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.LoadingOverlay; -import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.CoreShaders; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.ReloadInstance; import net.minecraft.util.Mth; @@ -80,9 +80,11 @@ public void render(final GuiGraphics graphics, final int mouseX, final int mouse displayWindow.render(0xff); } else { GlStateManager._clearColor(colour.redf(), colour.greenf(), colour.bluef(), 1f); - GlStateManager._clear(GlConst.GL_COLOR_BUFFER_BIT, Minecraft.ON_OSX); + GlStateManager._clear(GlConst.GL_COLOR_BUFFER_BIT); displayWindow.render(0xFF); } + // EarlyWindow will call glBindTexture with 0. Make sure the GlStateManager's cache is aware of it. + RenderSystem.bindTexture(0); RenderSystem.enableBlend(); RenderSystem.blendFunc(GlConst.GL_SRC_ALPHA, GlConst.GL_ONE_MINUS_SRC_ALPHA); var fbWidth = this.minecraft.getWindow().getWidth(); @@ -102,8 +104,8 @@ public void render(final GuiGraphics graphics, final int mouseX, final int mouse BufferBuilder bufferbuilder = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, fade); RenderSystem.getModelViewMatrix().identity(); - RenderSystem.setProjectionMatrix(new Matrix4f().setOrtho(0.0F, fbWidth, 0.0F, fbHeight, 0.1f, -0.1f), VertexSorting.ORTHOGRAPHIC_Z); - RenderSystem.setShader(GameRenderer::getPositionColorShader); + RenderSystem.setProjectionMatrix(new Matrix4f().setOrtho(0.0F, fbWidth, 0.0F, fbHeight, 0.1f, -0.1f), ProjectionType.ORTHOGRAPHIC); + RenderSystem.setShader(CoreShaders.RENDERTYPE_GUI_OVERLAY); // This is fill in around the edges - it's empty solid colour // top box from hpos addQuad(bufferbuilder, 0, fbWidth, wtop, fbHeight, colour, fade); @@ -118,7 +120,7 @@ public void render(final GuiGraphics graphics, final int mouseX, final int mouse // This is the actual screen data from the loading screen RenderSystem.enableBlend(); RenderSystem.blendFunc(GlConst.GL_SRC_ALPHA, GlConst.GL_ONE_MINUS_SRC_ALPHA); - RenderSystem.setShader(GameRenderer::getPositionTexColorShader); + RenderSystem.setShader(CoreShaders.POSITION_TEX_COLOR); RenderSystem.setShaderTexture(0, displayWindow.getFramebufferTextureId()); bufferbuilder = Tesselator.getInstance().begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR); bufferbuilder.addVertex(wleft, wbottom, 0f).setUv(0, 0).setColor(1f, 1f, 1f, fade); diff --git a/src/main/java/net/neoforged/neoforge/client/model/BakedModelWrapper.java b/src/main/java/net/neoforged/neoforge/client/model/BakedModelWrapper.java index 0b9491dc0c..01417638b2 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/BakedModelWrapper.java +++ b/src/main/java/net/neoforged/neoforge/client/model/BakedModelWrapper.java @@ -8,8 +8,8 @@ import com.mojang.blaze3d.vertex.PoseStack; import java.util.List; import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.block.model.BakedOverrides; import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.ItemOverrides; import net.minecraft.client.renderer.block.model.ItemTransforms; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.BakedModel; @@ -78,8 +78,8 @@ public ItemTransforms getTransforms() { } @Override - public ItemOverrides getOverrides() { - return originalModel.getOverrides(); + public BakedOverrides overrides() { + return originalModel.overrides(); } @Override @@ -108,12 +108,12 @@ public ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, Mo } @Override - public List getRenderTypes(ItemStack itemStack, boolean fabulous) { - return originalModel.getRenderTypes(itemStack, fabulous); + public List getRenderTypes(ItemStack itemStack) { + return originalModel.getRenderTypes(itemStack); } @Override - public List getRenderPasses(ItemStack itemStack, boolean fabulous) { - return originalModel.getRenderPasses(itemStack, fabulous); + public List getRenderPasses(ItemStack itemStack) { + return originalModel.getRenderPasses(itemStack); } } diff --git a/src/main/java/net/neoforged/neoforge/client/model/CompositeModel.java b/src/main/java/net/neoforged/neoforge/client/model/CompositeModel.java index 8ee0e0fd8e..93fde9b743 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/CompositeModel.java +++ b/src/main/java/net/neoforged/neoforge/client/model/CompositeModel.java @@ -21,19 +21,20 @@ import java.util.Set; import java.util.function.Function; import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.block.model.BakedOverrides; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.renderer.block.model.ItemOverrides; +import net.minecraft.client.renderer.block.model.ItemOverride; import net.minecraft.client.renderer.block.model.ItemTransforms; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ItemModel; import net.minecraft.client.resources.model.Material; import net.minecraft.client.resources.model.ModelBaker; import net.minecraft.client.resources.model.ModelState; import net.minecraft.client.resources.model.UnbakedModel; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.resources.ResourceLocation; import net.minecraft.util.RandomSource; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.BlockAndTintGetter; @@ -65,7 +66,7 @@ public CompositeModel(ImmutableMap children, ImmutableList spriteGetter, ModelState modelState, ItemOverrides overrides) { + public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, List overrides) { Material particleLocation = context.getMaterial("particle"); TextureAtlasSprite particle = spriteGetter.apply(particleLocation); @@ -79,7 +80,7 @@ public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Functio if (!context.isComponentVisible(name, true)) continue; var model = entry.getValue(); - bakedPartsBuilder.put(name, model.bake(baker, model, spriteGetter, modelState, true)); + bakedPartsBuilder.put(name, model.bake(baker, spriteGetter, modelState)); } var bakedParts = bakedPartsBuilder.build(); @@ -91,12 +92,16 @@ public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Functio itemPassesBuilder.add(model); } - return new Baked(context.isGui3d(), context.useBlockLight(), context.useAmbientOcclusion(), particle, context.getTransforms(), overrides, bakedParts, itemPassesBuilder.build()); + BakedModel baked = new Baked(context.isGui3d(), context.useBlockLight(), context.useAmbientOcclusion(), particle, context.getTransforms(), bakedParts, itemPassesBuilder.build()); + if (!overrides.isEmpty()) { + baked = new ItemModel.BakedModelWithOverrides(baked, new BakedOverrides(baker, overrides, spriteGetter)); + } + return baked; } @Override - public void resolveParents(Function modelGetter, IGeometryBakingContext context) { - children.values().forEach(child -> child.resolveParents(modelGetter)); + public void resolveDependencies(UnbakedModel.Resolver modelGetter, IGeometryBakingContext context) { + children.values().forEach(child -> child.resolveDependencies(modelGetter)); } @Override @@ -109,18 +114,16 @@ public static class Baked implements IDynamicBakedModel { private final boolean isGui3d; private final boolean isSideLit; private final TextureAtlasSprite particle; - private final ItemOverrides overrides; private final ItemTransforms transforms; private final ImmutableMap children; private final ImmutableList itemPasses; - public Baked(boolean isGui3d, boolean isSideLit, boolean isAmbientOcclusion, TextureAtlasSprite particle, ItemTransforms transforms, ItemOverrides overrides, ImmutableMap children, ImmutableList itemPasses) { + public Baked(boolean isGui3d, boolean isSideLit, boolean isAmbientOcclusion, TextureAtlasSprite particle, ItemTransforms transforms, ImmutableMap children, ImmutableList itemPasses) { this.children = children; this.isAmbientOcclusion = isAmbientOcclusion; this.isGui3d = isGui3d; this.isSideLit = isSideLit; this.particle = particle; - this.overrides = overrides; this.transforms = transforms; this.itemPasses = itemPasses; } @@ -169,11 +172,6 @@ public TextureAtlasSprite getParticleIcon() { return particle; } - @Override - public ItemOverrides getOverrides() { - return overrides; - } - @Override public ItemTransforms getTransforms() { return transforms; @@ -188,7 +186,7 @@ public ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, Mo } @Override - public List getRenderPasses(ItemStack itemStack, boolean fabulous) { + public List getRenderPasses(ItemStack itemStack) { return itemPasses; } @@ -197,12 +195,12 @@ public BakedModel getPart(String name) { return children.get(name); } - public static Builder builder(IGeometryBakingContext owner, TextureAtlasSprite particle, ItemOverrides overrides, ItemTransforms cameraTransforms) { - return builder(owner.useAmbientOcclusion(), owner.isGui3d(), owner.useBlockLight(), particle, overrides, cameraTransforms); + public static Builder builder(IGeometryBakingContext owner, TextureAtlasSprite particle, ItemTransforms cameraTransforms) { + return builder(owner.useAmbientOcclusion(), owner.isGui3d(), owner.useBlockLight(), particle, cameraTransforms); } - public static Builder builder(boolean isAmbientOcclusion, boolean isGui3d, boolean isSideLit, TextureAtlasSprite particle, ItemOverrides overrides, ItemTransforms cameraTransforms) { - return new Builder(isAmbientOcclusion, isGui3d, isSideLit, particle, overrides, cameraTransforms); + public static Builder builder(boolean isAmbientOcclusion, boolean isGui3d, boolean isSideLit, TextureAtlasSprite particle, ItemTransforms cameraTransforms) { + return new Builder(isAmbientOcclusion, isGui3d, isSideLit, particle, cameraTransforms); } public static class Builder { @@ -211,17 +209,15 @@ public static class Builder { private final boolean isSideLit; private final List children = new ArrayList<>(); private final List quads = new ArrayList<>(); - private final ItemOverrides overrides; private final ItemTransforms transforms; private TextureAtlasSprite particle; private RenderTypeGroup lastRenderTypes = RenderTypeGroup.EMPTY; - private Builder(boolean isAmbientOcclusion, boolean isGui3d, boolean isSideLit, TextureAtlasSprite particle, ItemOverrides overrides, ItemTransforms transforms) { + private Builder(boolean isAmbientOcclusion, boolean isGui3d, boolean isSideLit, TextureAtlasSprite particle, ItemTransforms transforms) { this.isAmbientOcclusion = isAmbientOcclusion; this.isGui3d = isGui3d; this.isSideLit = isSideLit; this.particle = particle; - this.overrides = overrides; this.transforms = transforms; } @@ -231,14 +227,14 @@ public void addLayer(BakedModel model) { } private void addLayer(RenderTypeGroup renderTypes, List quads) { - var modelBuilder = IModelBuilder.of(isAmbientOcclusion, isSideLit, isGui3d, transforms, overrides, particle, renderTypes); + var modelBuilder = IModelBuilder.of(isAmbientOcclusion, isSideLit, isGui3d, transforms, particle, renderTypes); quads.forEach(modelBuilder::addUnculledFace); children.add(modelBuilder.build()); } - private void flushQuads(RenderTypeGroup renderTypes) { + private void flushQuads(@Nullable RenderTypeGroup renderTypes) { if (!Objects.equals(renderTypes, lastRenderTypes)) { - if (quads.size() > 0) { + if (!quads.isEmpty()) { addLayer(lastRenderTypes, quads); quads.clear(); } @@ -264,7 +260,7 @@ public Builder addQuads(RenderTypeGroup renderTypes, Collection quads } public BakedModel build() { - if (quads.size() > 0) { + if (!quads.isEmpty()) { addLayer(lastRenderTypes, quads); } var childrenBuilder = ImmutableMap.builder(); @@ -274,7 +270,7 @@ public BakedModel build() { childrenBuilder.put("model_" + (i++), model); itemPassesBuilder.add(model); } - return new Baked(isGui3d, isSideLit, isAmbientOcclusion, particle, transforms, overrides, childrenBuilder.build(), itemPassesBuilder.build()); + return new Baked(isGui3d, isSideLit, isAmbientOcclusion, particle, transforms, childrenBuilder.build(), itemPassesBuilder.build()); } } } diff --git a/src/main/java/net/neoforged/neoforge/client/model/DynamicFluidContainerModel.java b/src/main/java/net/neoforged/neoforge/client/model/DynamicFluidContainerModel.java index 44f3e4343b..b15c779a95 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/DynamicFluidContainerModel.java +++ b/src/main/java/net/neoforged/neoforge/client/model/DynamicFluidContainerModel.java @@ -9,15 +9,18 @@ import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonObject; import com.mojang.math.Transformation; +import java.util.List; import java.util.Map; import java.util.function.Function; import net.minecraft.client.color.item.ItemColor; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.block.model.ItemOverrides; +import net.minecraft.client.renderer.block.model.BakedOverrides; +import net.minecraft.client.renderer.block.model.ItemOverride; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.BlockModelRotation; +import net.minecraft.client.resources.model.ItemModel; import net.minecraft.client.resources.model.Material; import net.minecraft.client.resources.model.ModelBaker; import net.minecraft.client.resources.model.ModelState; @@ -82,7 +85,7 @@ public DynamicFluidContainerModel withFluid(Fluid newFluid) { } @Override - public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, ItemOverrides overrides) { + public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, List overrides) { Material particleLocation = context.hasMaterial("particle") ? context.getMaterial("particle") : null; Material baseLocation = context.hasMaterial("base") ? context.getMaterial("base") : null; Material fluidMaskLocation = context.hasMaterial("fluid") ? context.getMaterial("fluid") : null; @@ -107,7 +110,7 @@ public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Functio // We need to disable GUI 3D and block lighting for this to render properly var itemContext = StandaloneGeometryBakingContext.builder(context).withGui3d(false).withUseBlockLight(false).build(ResourceLocation.fromNamespaceAndPath("neoforge", "dynamic_fluid_container")); - var modelBuilder = CompositeModel.Baked.builder(itemContext, particleSprite, new ContainedFluidOverrideHandler(overrides, baker, itemContext, this), context.getTransforms()); + var modelBuilder = CompositeModel.Baked.builder(itemContext, particleSprite, context.getTransforms()); var normalRenderTypes = getLayerRenderTypes(false); @@ -147,7 +150,9 @@ public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Functio modelBuilder.setParticle(particleSprite); - return modelBuilder.build(); + BakedModel bakedModel = modelBuilder.build(); + var bakedOverrides = new ContainedFluidOverrideHandler(new BakedOverrides(baker, overrides, spriteGetter), bakedModel, baker, itemContext, this); + return new ItemModel.BakedModelWithOverrides(bakedModel, bakedOverrides); } public static final class Loader implements IGeometryLoader { @@ -162,7 +167,7 @@ public DynamicFluidContainerModel read(JsonObject jsonObject, JsonDeserializatio ResourceLocation fluidName = ResourceLocation.parse(jsonObject.get("fluid").getAsString()); - Fluid fluid = BuiltInRegistries.FLUID.get(fluidName); + Fluid fluid = BuiltInRegistries.FLUID.getValue(fluidName); boolean flip = GsonHelper.getAsBoolean(jsonObject, "flip_gas", false); boolean coverIsMask = GsonHelper.getAsBoolean(jsonObject, "cover_is_mask", true); @@ -173,24 +178,28 @@ public DynamicFluidContainerModel read(JsonObject jsonObject, JsonDeserializatio } } - private static final class ContainedFluidOverrideHandler extends ItemOverrides { + private static final class ContainedFluidOverrideHandler extends BakedOverrides { private final Map cache = Maps.newHashMap(); // contains all the baked models since they'll never change - private final ItemOverrides nested; + private final BakedOverrides nested; + private final BakedModel baseModel; private final ModelBaker baker; private final IGeometryBakingContext owner; private final DynamicFluidContainerModel parent; - private ContainedFluidOverrideHandler(ItemOverrides nested, ModelBaker baker, IGeometryBakingContext owner, DynamicFluidContainerModel parent) { + private ContainedFluidOverrideHandler(BakedOverrides nested, BakedModel baseModel, ModelBaker baker, IGeometryBakingContext owner, DynamicFluidContainerModel parent) { this.nested = nested; + this.baseModel = baseModel; this.baker = baker; this.owner = owner; this.parent = parent; } @Override - public BakedModel resolve(BakedModel originalModel, ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed) { - BakedModel overridden = nested.resolve(originalModel, stack, level, entity, seed); - if (overridden != originalModel) return overridden; + @Nullable + public BakedModel findOverride(ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed) { + BakedModel overridden = nested.findOverride(stack, level, entity, seed); + if (overridden != null) return overridden; + return FluidUtil.getFluidContained(stack) .map(fluidStack -> { Fluid fluid = fluidStack.getFluid(); @@ -198,7 +207,7 @@ public BakedModel resolve(BakedModel originalModel, ItemStack stack, @Nullable C if (!cache.containsKey(name)) { DynamicFluidContainerModel unbaked = this.parent.withFluid(fluid); - BakedModel bakedModel = unbaked.bake(owner, baker, Material::sprite, BlockModelRotation.X0_Y0, this); + BakedModel bakedModel = unbaked.bake(owner, baker, Material::sprite, BlockModelRotation.X0_Y0, List.of()); cache.put(name, bakedModel); return bakedModel; } @@ -206,7 +215,7 @@ public BakedModel resolve(BakedModel originalModel, ItemStack stack, @Nullable C return cache.get(name); }) // not a fluid item apparently - .orElse(originalModel); // empty bucket + .orElse(baseModel); // empty bucket } } diff --git a/src/main/java/net/neoforged/neoforge/client/model/ElementsModel.java b/src/main/java/net/neoforged/neoforge/client/model/ElementsModel.java deleted file mode 100644 index 879ef812d3..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/ElementsModel.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; -import net.minecraft.client.renderer.block.model.BlockElement; -import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.Material; -import net.minecraft.client.resources.model.ModelBaker; -import net.minecraft.client.resources.model.ModelState; -import net.minecraft.core.Direction; -import net.minecraft.util.GsonHelper; -import net.neoforged.neoforge.client.model.geometry.IGeometryBakingContext; -import net.neoforged.neoforge.client.model.geometry.IGeometryLoader; -import net.neoforged.neoforge.client.model.geometry.SimpleUnbakedGeometry; -import net.neoforged.neoforge.client.model.geometry.UnbakedGeometryHelper; - -/** - * A model composed of vanilla {@linkplain BlockElement block elements}. - */ -public class ElementsModel extends SimpleUnbakedGeometry { - private final List elements; - - public ElementsModel(List elements) { - this.elements = elements; - } - - @Override - protected void addQuads(IGeometryBakingContext context, IModelBuilder modelBuilder, ModelBaker baker, Function spriteGetter, ModelState modelState) { - // If there is a root transform, undo the ModelState transform, apply it, then re-apply the ModelState transform. - // This is necessary because of things like UV locking, which should only respond to the ModelState, and as such - // that is the only transform that should be applied during face bake. - var postTransform = QuadTransformers.empty(); - var rootTransform = context.getRootTransform(); - if (!rootTransform.isIdentity()) - postTransform = UnbakedGeometryHelper.applyRootTransform(modelState, rootTransform); - - for (BlockElement element : elements) { - for (Direction direction : element.faces.keySet()) { - var face = element.faces.get(direction); - var sprite = spriteGetter.apply(context.getMaterial(face.texture())); - var quad = BlockModel.bakeFace(element, face, sprite, direction, modelState); - postTransform.processInPlace(quad); - - if (face.cullForDirection() == null) - modelBuilder.addUnculledFace(quad); - else - modelBuilder.addCulledFace(modelState.getRotation().rotateTransform(face.cullForDirection()), quad); - } - } - } - - public static final class Loader implements IGeometryLoader { - public static final Loader INSTANCE = new Loader(); - - private Loader() {} - - @Override - public ElementsModel read(JsonObject jsonObject, JsonDeserializationContext deserializationContext) throws JsonParseException { - if (!jsonObject.has("elements")) - throw new JsonParseException("An element model must have an \"elements\" member."); - - List elements = new ArrayList<>(); - for (JsonElement element : GsonHelper.getAsJsonArray(jsonObject, "elements")) { - elements.add(deserializationContext.deserialize(element, BlockElement.class)); - } - - return new ElementsModel(elements); - } - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/EmptyModel.java b/src/main/java/net/neoforged/neoforge/client/model/EmptyModel.java index fb598d9c06..f3e1084ed1 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/EmptyModel.java +++ b/src/main/java/net/neoforged/neoforge/client/model/EmptyModel.java @@ -10,7 +10,7 @@ import java.util.Map; import java.util.function.Function; import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.ItemOverrides; +import net.minecraft.client.renderer.block.model.ItemOverride; import net.minecraft.client.renderer.block.model.ItemTransforms; import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlas; @@ -46,7 +46,7 @@ protected void addQuads(IGeometryBakingContext owner, IModelBuilder modelBuil } @Override - public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, ItemOverrides overrides) { + public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, List overrides) { return BAKED; } @@ -63,7 +63,7 @@ private static Map> makeEmptyCulledFaces() { } public Baked() { - super(List.of(), makeEmptyCulledFaces(), false, false, false, UnitTextureAtlasSprite.INSTANCE, ItemTransforms.NO_TRANSFORMS, ItemOverrides.EMPTY, RenderTypeGroup.EMPTY); + super(List.of(), makeEmptyCulledFaces(), false, false, false, UnitTextureAtlasSprite.INSTANCE, ItemTransforms.NO_TRANSFORMS, RenderTypeGroup.EMPTY); } @Override diff --git a/src/main/java/net/neoforged/neoforge/client/model/IModelBuilder.java b/src/main/java/net/neoforged/neoforge/client/model/IModelBuilder.java index 9713bebecf..51111b4d0b 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/IModelBuilder.java +++ b/src/main/java/net/neoforged/neoforge/client/model/IModelBuilder.java @@ -7,7 +7,6 @@ import java.util.List; import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.ItemOverrides; import net.minecraft.client.renderer.block.model.ItemTransforms; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.BakedModel; @@ -18,7 +17,7 @@ /** * Base interface for any object that collects culled and unculled faces and bakes them into a model. *

- * Provides a generic base implementation via {@link #of(boolean, boolean, boolean, ItemTransforms, ItemOverrides, TextureAtlasSprite, RenderTypeGroup)} + * Provides a generic base implementation via {@link #of(boolean, boolean, boolean, ItemTransforms, TextureAtlasSprite, RenderTypeGroup)} * and a quad-collecting alternative via {@link #collecting(List)}. */ public interface IModelBuilder> { @@ -26,9 +25,9 @@ public interface IModelBuilder> { * Creates a new model builder that uses the provided attributes in the final baked model. */ static IModelBuilder of(boolean hasAmbientOcclusion, boolean usesBlockLight, boolean isGui3d, - ItemTransforms transforms, ItemOverrides overrides, TextureAtlasSprite particle, + ItemTransforms transforms, TextureAtlasSprite particle, RenderTypeGroup renderTypes) { - return new Simple(hasAmbientOcclusion, usesBlockLight, isGui3d, transforms, overrides, particle, renderTypes); + return new Simple(hasAmbientOcclusion, usesBlockLight, isGui3d, transforms, particle, renderTypes); } /** @@ -50,9 +49,9 @@ class Simple implements IModelBuilder { private final RenderTypeGroup renderTypes; private Simple(boolean hasAmbientOcclusion, boolean usesBlockLight, boolean isGui3d, - ItemTransforms transforms, ItemOverrides overrides, TextureAtlasSprite particle, + ItemTransforms transforms, TextureAtlasSprite particle, RenderTypeGroup renderTypes) { - this.builder = new SimpleBakedModel.Builder(hasAmbientOcclusion, usesBlockLight, isGui3d, transforms, overrides).particle(particle); + this.builder = new SimpleBakedModel.Builder(hasAmbientOcclusion, usesBlockLight, isGui3d, transforms).particle(particle); this.renderTypes = renderTypes; } diff --git a/src/main/java/net/neoforged/neoforge/client/model/IQuadTransformer.java b/src/main/java/net/neoforged/neoforge/client/model/IQuadTransformer.java index 9ee0b0a704..eaa5b26b89 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/IQuadTransformer.java +++ b/src/main/java/net/neoforged/neoforge/client/model/IQuadTransformer.java @@ -51,7 +51,7 @@ default IQuadTransformer andThen(IQuadTransformer other) { private static BakedQuad copy(BakedQuad quad) { var vertices = quad.getVertices(); - return new BakedQuad(Arrays.copyOf(vertices, vertices.length), quad.getTintIndex(), quad.getDirection(), quad.getSprite(), quad.isShade(), quad.hasAmbientOcclusion()); + return new BakedQuad(Arrays.copyOf(vertices, vertices.length), quad.getTintIndex(), quad.getDirection(), quad.getSprite(), quad.isShade(), quad.getLightEmission(), quad.hasAmbientOcclusion()); } private static int findOffset(VertexFormatElement element) { diff --git a/src/main/java/net/neoforged/neoforge/client/model/ItemLayerModel.java b/src/main/java/net/neoforged/neoforge/client/model/ItemLayerModel.java index f5fa386501..005c98f626 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/ItemLayerModel.java +++ b/src/main/java/net/neoforged/neoforge/client/model/ItemLayerModel.java @@ -13,13 +13,16 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import java.util.List; import java.util.Map; import java.util.function.Function; import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.block.model.BakedOverrides; import net.minecraft.client.renderer.block.model.ItemModelGenerator; -import net.minecraft.client.renderer.block.model.ItemOverrides; +import net.minecraft.client.renderer.block.model.ItemOverride; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ItemModel; import net.minecraft.client.resources.model.Material; import net.minecraft.client.resources.model.ModelBaker; import net.minecraft.client.resources.model.ModelState; @@ -51,7 +54,7 @@ private ItemLayerModel(@Nullable ImmutableList textures, Int2ObjectMap } @Override - public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, ItemOverrides overrides) { + public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, List overrides) { if (textures == null) { ImmutableList.Builder builder = ImmutableList.builder(); for (int i = 0; context.hasMaterial("layer" + i); i++) { @@ -67,7 +70,7 @@ public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Functio modelState = UnbakedGeometryHelper.composeRootTransformIntoModelState(modelState, rootTransform); var normalRenderTypes = new RenderTypeGroup(RenderType.translucent(), NeoForgeRenderTypes.ITEM_UNSORTED_TRANSLUCENT.get()); - CompositeModel.Baked.Builder builder = CompositeModel.Baked.builder(context, particle, overrides, context.getTransforms()); + CompositeModel.Baked.Builder builder = CompositeModel.Baked.builder(context, particle, context.getTransforms()); for (int i = 0; i < textures.size(); i++) { TextureAtlasSprite sprite = spriteGetter.apply(textures.get(i)); var unbaked = UnbakedGeometryHelper.createUnbakedItemElements(i, sprite, this.layerData.get(i)); @@ -77,7 +80,11 @@ public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Functio builder.addQuads(renderTypes != null ? renderTypes : normalRenderTypes, quads); } - return builder.build(); + BakedModel baked = builder.build(); + if (!overrides.isEmpty()) { + baked = new ItemModel.BakedModelWithOverrides(baked, new BakedOverrides(baker, overrides, spriteGetter)); + } + return baked; } public static final class Loader implements IGeometryLoader { @@ -97,7 +104,6 @@ public ItemLayerModel read(JsonObject jsonObject, JsonDeserializationContext des } var emissiveLayers = new Int2ObjectArrayMap(); - if (jsonObject.has("forge_data")) throw new JsonParseException("forge_data should be replaced by neoforge_data"); // TODO 1.22: Remove if (jsonObject.has("neoforge_data")) { JsonObject forgeData = jsonObject.get("neoforge_data").getAsJsonObject(); readLayerData(forgeData, "layers", renderTypeNames, emissiveLayers, false); diff --git a/src/main/java/net/neoforged/neoforge/client/model/RegistryAwareItemModelShaper.java b/src/main/java/net/neoforged/neoforge/client/model/RegistryAwareItemModelShaper.java deleted file mode 100644 index 33b033f88d..0000000000 --- a/src/main/java/net/neoforged/neoforge/client/model/RegistryAwareItemModelShaper.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.client.model; - -import com.google.common.collect.Maps; -import java.util.Map; -import net.minecraft.client.renderer.ItemModelShaper; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.ModelBakery; -import net.minecraft.client.resources.model.ModelManager; -import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Nullable; - -/** - * Wrapper around {@link ItemModelShaper} that cleans up the internal maps to respect ID remapping. - */ -@ApiStatus.Internal -public class RegistryAwareItemModelShaper extends ItemModelShaper { - private final Map locations = Maps.newIdentityHashMap(); - private final Map models = Maps.newIdentityHashMap(); - - public RegistryAwareItemModelShaper(ModelManager manager) { - super(manager); - } - - @Override - @Nullable - public BakedModel getItemModel(Item item) { - return models.get(item); - } - - @Override - public void register(Item item, ModelResourceLocation location) { - locations.put(item, location); - models.put(item, getModelManager().getModel(location)); - } - - @Override - public void rebuildCache() { - final ModelManager manager = this.getModelManager(); - for (var e : locations.entrySet()) { - models.put(e.getKey(), manager.getModel(e.getValue())); - } - } - - public ModelResourceLocation getLocation(ItemStack stack) { - ModelResourceLocation location = locations.get(stack.getItem()); - return location == null ? ModelBakery.MISSING_MODEL_VARIANT : location; - } -} diff --git a/src/main/java/net/neoforged/neoforge/client/model/SeparateTransformsModel.java b/src/main/java/net/neoforged/neoforge/client/model/SeparateTransformsModel.java index 4bb79b4e95..03e4d72b6a 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/SeparateTransformsModel.java +++ b/src/main/java/net/neoforged/neoforge/client/model/SeparateTransformsModel.java @@ -15,18 +15,19 @@ import java.util.Map; import java.util.function.Function; import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.block.model.BakedOverrides; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.renderer.block.model.ItemOverrides; +import net.minecraft.client.renderer.block.model.ItemOverride; import net.minecraft.client.renderer.block.model.ItemTransforms; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ItemModel; import net.minecraft.client.resources.model.Material; import net.minecraft.client.resources.model.ModelBaker; import net.minecraft.client.resources.model.ModelState; import net.minecraft.client.resources.model.UnbakedModel; import net.minecraft.core.Direction; -import net.minecraft.resources.ResourceLocation; import net.minecraft.util.GsonHelper; import net.minecraft.util.RandomSource; import net.minecraft.world.item.ItemDisplayContext; @@ -51,20 +52,22 @@ public SeparateTransformsModel(BlockModel baseModel, ImmutableMap spriteGetter, ModelState modelState, ItemOverrides overrides) { - return new Baked( + public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, List overrides) { + BakedModel baked = new Baked( context.useAmbientOcclusion(), context.isGui3d(), context.useBlockLight(), - spriteGetter.apply(context.getMaterial("particle")), overrides, - baseModel.bake(baker, baseModel, spriteGetter, modelState, context.useBlockLight()), - ImmutableMap.copyOf(Maps.transformValues(perspectives, value -> { - return value.bake(baker, value, spriteGetter, modelState, context.useBlockLight()); - }))); + spriteGetter.apply(context.getMaterial("particle")), + baseModel.bake(baker, spriteGetter, modelState), + ImmutableMap.copyOf(Maps.transformValues(perspectives, value -> value.bake(baker, spriteGetter, modelState)))); + if (!overrides.isEmpty()) { + baked = new ItemModel.BakedModelWithOverrides(baked, new BakedOverrides(baker, overrides, spriteGetter)); + } + return baked; } @Override - public void resolveParents(Function modelGetter, IGeometryBakingContext context) { - baseModel.resolveParents(modelGetter); - perspectives.values().forEach(model -> model.resolveParents(modelGetter)); + public void resolveDependencies(UnbakedModel.Resolver modelGetter, IGeometryBakingContext context) { + baseModel.resolveDependencies(modelGetter); + perspectives.values().forEach(model -> model.resolveDependencies(modelGetter)); } public static class Baked implements IDynamicBakedModel { @@ -72,16 +75,14 @@ public static class Baked implements IDynamicBakedModel { private final boolean isGui3d; private final boolean isSideLit; private final TextureAtlasSprite particle; - private final ItemOverrides overrides; private final BakedModel baseModel; private final ImmutableMap perspectives; - public Baked(boolean isAmbientOcclusion, boolean isGui3d, boolean isSideLit, TextureAtlasSprite particle, ItemOverrides overrides, BakedModel baseModel, ImmutableMap perspectives) { + public Baked(boolean isAmbientOcclusion, boolean isGui3d, boolean isSideLit, TextureAtlasSprite particle, BakedModel baseModel, ImmutableMap perspectives) { this.isAmbientOcclusion = isAmbientOcclusion; this.isGui3d = isGui3d; this.isSideLit = isSideLit; this.particle = particle; - this.overrides = overrides; this.baseModel = baseModel; this.perspectives = perspectives; } @@ -116,11 +117,6 @@ public TextureAtlasSprite getParticleIcon() { return particle; } - @Override - public ItemOverrides getOverrides() { - return overrides; - } - @Override public ItemTransforms getTransforms() { return ItemTransforms.NO_TRANSFORMS; diff --git a/src/main/java/net/neoforged/neoforge/client/model/data/ModelDataManager.java b/src/main/java/net/neoforged/neoforge/client/model/data/ModelDataManager.java index 65afdc7625..69e03a4391 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/data/ModelDataManager.java +++ b/src/main/java/net/neoforged/neoforge/client/model/data/ModelDataManager.java @@ -163,8 +163,8 @@ public static void onChunkUnload(ChunkEvent.Unload event) { var modelDataManager = level.getModelDataManager(); if (modelDataManager != null) { ChunkPos chunk = event.getChunk().getPos(); - int maxSection = level.getMaxSection(); - for (int y = level.getMinSection(); y < maxSection; y++) { + int maxSection = level.getMaxSectionY(); + for (int y = level.getMinSectionY(); y < maxSection; y++) { long section = SectionPos.asLong(chunk.x, y, chunk.z); modelDataManager.needModelDataRefresh.remove(section); modelDataManager.modelDataCache.remove(section); diff --git a/src/main/java/net/neoforged/neoforge/client/model/data/MultipartModelData.java b/src/main/java/net/neoforged/neoforge/client/model/data/MultipartModelData.java index a7320ca44e..d0e69f9ae2 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/data/MultipartModelData.java +++ b/src/main/java/net/neoforged/neoforge/client/model/data/MultipartModelData.java @@ -9,12 +9,11 @@ import java.util.IdentityHashMap; import java.util.List; import java.util.Map; -import java.util.function.Predicate; import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.MultiPartBakedModel; import net.minecraft.core.BlockPos; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.block.state.BlockState; -import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.ApiStatus; @ApiStatus.Internal @@ -36,13 +35,13 @@ public static ModelData resolve(ModelData modelData, BakedModel model) { return partData != null ? partData : modelData; } - public static ModelData create(List, BakedModel>> selectors, BitSet bitset, BlockAndTintGetter level, BlockPos pos, BlockState state, ModelData tileModelData) { + public static ModelData create(List selectors, BitSet bitset, BlockAndTintGetter level, BlockPos pos, BlockState state, ModelData tileModelData) { // Don't allocate memory if no submodel changes the model data Map dataMap = null; for (int i = 0; i < bitset.length(); ++i) { if (bitset.get(i)) { - var model = selectors.get(i).getRight(); + var model = selectors.get(i).model(); var data = model.getModelData(level, pos, state, tileModelData); if (data != tileModelData) { diff --git a/src/main/java/net/neoforged/neoforge/client/model/generators/ItemModelBuilder.java b/src/main/java/net/neoforged/neoforge/client/model/generators/ItemModelBuilder.java index 2f740123dd..eaadbae006 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/generators/ItemModelBuilder.java +++ b/src/main/java/net/neoforged/neoforge/client/model/generators/ItemModelBuilder.java @@ -14,8 +14,8 @@ import java.util.Map; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.armortrim.TrimMaterial; -import net.minecraft.world.item.armortrim.TrimMaterials; +import net.minecraft.world.item.equipment.trim.TrimMaterial; +import net.minecraft.world.item.equipment.trim.TrimMaterials; import net.neoforged.neoforge.common.data.ExistingFileHelper; /** diff --git a/src/main/java/net/neoforged/neoforge/client/model/generators/ModelBuilder.java b/src/main/java/net/neoforged/neoforge/client/model/generators/ModelBuilder.java index c96419f87f..9afe777b8a 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/generators/ModelBuilder.java +++ b/src/main/java/net/neoforged/neoforge/client/model/generators/ModelBuilder.java @@ -395,6 +395,7 @@ public class ElementBuilder { private final Map faces = new LinkedHashMap<>(); private RotationBuilder rotation; private boolean shade = true; + private int lightEmission = 0; private int color = 0xFFFFFFFF; private int blockLight = 0, skyLight = 0; private boolean hasAmbientOcclusion = true; @@ -558,6 +559,19 @@ public ElementBuilder emissivity(int blockLight, int skyLight) { return this; } + /** + * Set the light emission of the element (0-15) + *

+ * If block and sky light values should be different, use {@link #emissivity(int, int)} instead + * + * @param lightEmission the light value + * @return this builder + */ + public ElementBuilder lightEmission(int lightEmission) { + this.lightEmission = lightEmission; + return this; + } + /** * Sets the color of the element. * @@ -589,7 +603,7 @@ BlockElement build() { .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().build(), (k1, k2) -> { throw new IllegalArgumentException(); }, LinkedHashMap::new)); - return new BlockElement(from, to, faces, rotation == null ? null : rotation.build(), shade, new ExtraFaceData(this.color, this.blockLight, this.skyLight, this.hasAmbientOcclusion)); + return new BlockElement(from, to, faces, rotation == null ? null : rotation.build(), shade, lightEmission, new ExtraFaceData(this.color, this.blockLight, this.skyLight, this.hasAmbientOcclusion)); } public T end() { diff --git a/src/main/java/net/neoforged/neoforge/client/model/geometry/BlockGeometryBakingContext.java b/src/main/java/net/neoforged/neoforge/client/model/geometry/BlockGeometryBakingContext.java index a60eb84ec8..02c53783ae 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/geometry/BlockGeometryBakingContext.java +++ b/src/main/java/net/neoforged/neoforge/client/model/geometry/BlockGeometryBakingContext.java @@ -7,10 +7,11 @@ import com.mojang.math.Transformation; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.function.Function; import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.renderer.block.model.ItemOverrides; +import net.minecraft.client.renderer.block.model.ItemOverride; import net.minecraft.client.renderer.block.model.ItemTransforms; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.BakedModel; @@ -130,7 +131,7 @@ public void copyFrom(BlockGeometryBakingContext other) { this.gui3d = other.gui3d; } - public BakedModel bake(ModelBaker baker, Function bakedTextureGetter, ModelState modelTransform, ItemOverrides overrides) { + public BakedModel bake(ModelBaker baker, Function bakedTextureGetter, ModelState modelTransform, List overrides) { IUnbakedGeometry geometry = getCustomGeometry(); if (geometry == null) throw new IllegalStateException("Can not use custom baking without custom geometry"); diff --git a/src/main/java/net/neoforged/neoforge/client/model/geometry/IUnbakedGeometry.java b/src/main/java/net/neoforged/neoforge/client/model/geometry/IUnbakedGeometry.java index 2eb62ffefb..79be568a61 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/geometry/IUnbakedGeometry.java +++ b/src/main/java/net/neoforged/neoforge/client/model/geometry/IUnbakedGeometry.java @@ -5,17 +5,17 @@ package net.neoforged.neoforge.client.model.geometry; +import java.util.List; import java.util.Set; import java.util.function.Function; import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.renderer.block.model.ItemOverrides; +import net.minecraft.client.renderer.block.model.ItemOverride; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.Material; import net.minecraft.client.resources.model.ModelBaker; import net.minecraft.client.resources.model.ModelState; import net.minecraft.client.resources.model.UnbakedModel; -import net.minecraft.resources.ResourceLocation; /** * General interface for any model that can be baked, superset of vanilla {@link UnbakedModel}. @@ -26,14 +26,14 @@ * @see IGeometryBakingContext */ public interface IUnbakedGeometry> { - BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, ItemOverrides overrides); + BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, List overrides); /** * Resolve parents of nested {@link BlockModel}s which are later used in - * {@link IUnbakedGeometry#bake(IGeometryBakingContext, ModelBaker, Function, ModelState, ItemOverrides)} - * via {@link BlockModel#resolveParents(Function)} + * {@link IUnbakedGeometry#bake(IGeometryBakingContext, ModelBaker, Function, ModelState, List)} + * via {@link BlockModel#resolveDependencies(UnbakedModel.Resolver)} */ - default void resolveParents(Function modelGetter, IGeometryBakingContext context) {} + default void resolveDependencies(UnbakedModel.Resolver modelGetter, IGeometryBakingContext context) {} /** * {@return a set of all the components whose visibility may be configured via {@link IGeometryBakingContext}} diff --git a/src/main/java/net/neoforged/neoforge/client/model/geometry/SimpleUnbakedGeometry.java b/src/main/java/net/neoforged/neoforge/client/model/geometry/SimpleUnbakedGeometry.java index a07af2af5e..1c8ea09699 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/geometry/SimpleUnbakedGeometry.java +++ b/src/main/java/net/neoforged/neoforge/client/model/geometry/SimpleUnbakedGeometry.java @@ -5,9 +5,10 @@ package net.neoforged.neoforge.client.model.geometry; +import java.util.List; import java.util.function.Function; import net.minecraft.client.renderer.block.model.BakedQuad; -import net.minecraft.client.renderer.block.model.ItemOverrides; +import net.minecraft.client.renderer.block.model.ItemOverride; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.Material; @@ -22,13 +23,13 @@ */ public abstract class SimpleUnbakedGeometry> implements IUnbakedGeometry { @Override - public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, ItemOverrides overrides) { + public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, List overrides) { TextureAtlasSprite particle = spriteGetter.apply(context.getMaterial("particle")); var renderTypeHint = context.getRenderTypeHint(); var renderTypes = renderTypeHint != null ? context.getRenderType(renderTypeHint) : RenderTypeGroup.EMPTY; IModelBuilder builder = IModelBuilder.of(context.useAmbientOcclusion(), context.useBlockLight(), context.isGui3d(), - context.getTransforms(), overrides, particle, renderTypes); + context.getTransforms(), particle, renderTypes); addQuads(context, builder, baker, spriteGetter, modelState); diff --git a/src/main/java/net/neoforged/neoforge/client/model/geometry/UnbakedGeometryHelper.java b/src/main/java/net/neoforged/neoforge/client/model/geometry/UnbakedGeometryHelper.java index 04e74f51f1..e790cef41c 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/geometry/UnbakedGeometryHelper.java +++ b/src/main/java/net/neoforged/neoforge/client/model/geometry/UnbakedGeometryHelper.java @@ -25,22 +25,14 @@ import net.minecraft.client.renderer.texture.SpriteContents; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.BuiltInModel; import net.minecraft.client.resources.model.Material; -import net.minecraft.client.resources.model.ModelBaker; -import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.client.resources.model.ModelState; import net.minecraft.core.Direction; import net.minecraft.resources.ResourceLocation; import net.neoforged.neoforge.client.ClientHooks; -import net.neoforged.neoforge.client.model.ElementsModel; import net.neoforged.neoforge.client.model.ExtraFaceData; import net.neoforged.neoforge.client.model.IModelBuilder; -import net.neoforged.neoforge.client.model.IQuadTransformer; -import net.neoforged.neoforge.client.model.QuadTransformers; import net.neoforged.neoforge.client.model.SimpleModelState; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import org.joml.Vector3f; @@ -90,28 +82,6 @@ public static Material resolveDirtyMaterial(@Nullable String tex, IGeometryBakin return new Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.parse(tex)); } - /** - * Helper for baking {@link BlockModel} instances. Handles baking custom geometries and deferring item model baking. - */ - @ApiStatus.Internal - public static BakedModel bake(BlockModel blockModel, ModelBaker modelBaker, BlockModel owner, Function spriteGetter, ModelState modelState, boolean guiLight3d) { - IUnbakedGeometry customModel = blockModel.customData.getCustomGeometry(); - if (customModel != null) - return customModel.bake(blockModel.customData, modelBaker, spriteGetter, modelState, blockModel.getOverrides(modelBaker, owner, spriteGetter)); - - // Handle vanilla item models here, since vanilla has a shortcut for them - if (blockModel.getRootModel() == ModelBakery.GENERATION_MARKER) - return ITEM_MODEL_GENERATOR.generateBlockModel(spriteGetter, blockModel).bakeVanilla(modelBaker, blockModel, spriteGetter, modelState, guiLight3d); - - if (blockModel.getRootModel() == ModelBakery.BLOCK_ENTITY_MARKER) { - var particleSprite = spriteGetter.apply(blockModel.getMaterial("particle")); - return new BuiltInModel(blockModel.getTransforms(), blockModel.getOverrides(modelBaker, owner, spriteGetter), particleSprite, blockModel.getGuiLight().lightLikeBlock()); - } - - var elementsModel = new ElementsModel(blockModel.getElements()); - return elementsModel.bake(blockModel.customData, modelBaker, spriteGetter, modelState, blockModel.getOverrides(modelBaker, owner, spriteGetter)); - } - /** * @see #createUnbakedItemElements(int, TextureAtlasSprite, ExtraFaceData) */ @@ -198,7 +168,8 @@ public static List createUnbakedItemMaskElements(int layerIndex, T map.put(direction, new BlockElementFace(null, layerIndex, "layer" + layerIndex, new BlockFaceUV(null, 0))); }), null, - true)); + true, + 0)); // Reset xStart xStart = -1; @@ -215,7 +186,7 @@ public static void bakeElements(IModelBuilder builder, List ele for (BlockElement element : elements) { element.faces.forEach((side, face) -> { var sprite = spriteGetter.apply(new Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.parse(face.texture()))); - var quad = bakeElementFace(element, face, sprite, side, modelState); + BakedQuad quad = BlockModel.bakeFace(element, face, sprite, side, modelState); if (face.cullForDirection() == null) builder.addUnculledFace(quad); else @@ -235,29 +206,6 @@ public static List bakeElements(List elements, Function return list; } - /** - * Turns a single {@link BlockElementFace} into a {@link BakedQuad}. - */ - public static BakedQuad bakeElementFace(BlockElement element, BlockElementFace face, TextureAtlasSprite sprite, Direction direction, ModelState state) { - return FACE_BAKERY.bakeQuad(element.from, element.to, face, sprite, direction, state, element.rotation, element.shade); - } - - /** - * Create an {@link IQuadTransformer} to apply a {@link Transformation} that undoes the {@link ModelState} - * transform (blockstate transform), applies the given root transform and then re-applies the - * blockstate transform. - * - * @return an {@code IQuadTransformer} that applies the root transform to a baked quad that already has the - * transformation of the given {@code ModelState} applied to it - */ - public static IQuadTransformer applyRootTransform(ModelState modelState, Transformation rootTransform) { - // Move the origin of the ModelState transform and its inverse from the negative corner to the block center - // to replicate the way the ModelState transform is applied in the FaceBakery by moving the vertices such that - // the negative corner acts as the block center - Transformation transform = modelState.getRotation().applyOrigin(new Vector3f(.5F, .5F, .5F)); - return QuadTransformers.applying(transform.compose(rootTransform).compose(transform.inverse())); - } - /** * {@return a {@link ModelState} that combines the existing model state and the {@linkplain Transformation root transform}} */ diff --git a/src/main/java/net/neoforged/neoforge/client/model/lighting/LightPipelineAwareModelBlockRenderer.java b/src/main/java/net/neoforged/neoforge/client/model/lighting/LightPipelineAwareModelBlockRenderer.java index a17fbaf90d..bb5316d876 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/lighting/LightPipelineAwareModelBlockRenderer.java +++ b/src/main/java/net/neoforged/neoforge/client/model/lighting/LightPipelineAwareModelBlockRenderer.java @@ -83,7 +83,7 @@ public static boolean render(VertexConsumer vertexConsumer, QuadLighter lighter, } for (Direction side : SIDES) { - if (checkSides && !Block.shouldRenderFace(state, level, pos, side, pos.relative(side))) { + if (checkSides && !Block.shouldRenderFace(level, pos, state, level.getBlockState(pos.relative(side)), side)) { continue; } rand.setSeed(seed); diff --git a/src/main/java/net/neoforged/neoforge/client/model/lighting/SmoothQuadLighter.java b/src/main/java/net/neoforged/neoforge/client/model/lighting/SmoothQuadLighter.java index 57c3ff0e00..f9c5d7659d 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/lighting/SmoothQuadLighter.java +++ b/src/main/java/net/neoforged/neoforge/client/model/lighting/SmoothQuadLighter.java @@ -43,7 +43,7 @@ protected void computeLightingAt(BlockAndTintGetter level, BlockPos origin, Bloc for (int z = 0; z <= 2; z++) { pos.setWithOffset(origin, x - 1, y - 1, z - 1); BlockState neighborState = level.getBlockState(pos); - t[x][y][z] = neighborState.getLightBlock(level, pos) < 15; + t[x][y][z] = neighborState.getLightBlock() < 15; int brightness = LevelRenderer.getLightColor(level, neighborState, pos); s[x][y][z] = LightTexture.sky(brightness); b[x][y][z] = LightTexture.block(brightness); @@ -58,7 +58,7 @@ protected void computeLightingAt(BlockAndTintGetter level, BlockPos origin, Bloc BlockState thisStateShape = state.canOcclude() && state.useShapeForLightOcclusion() ? state : Blocks.AIR.defaultBlockState(); BlockState otherStateShape = neighborState.canOcclude() && neighborState.useShapeForLightOcclusion() ? neighborState : Blocks.AIR.defaultBlockState(); - if (neighborState.getLightBlock(level, pos) == 15 || Shapes.faceShapeOccludes(thisStateShape.getFaceOcclusionShape(level, origin, side), otherStateShape.getFaceOcclusionShape(level, pos, side.getOpposite()))) { + if (neighborState.getLightBlock() == 15 || Shapes.faceShapeOccludes(thisStateShape.getFaceOcclusionShape(side), otherStateShape.getFaceOcclusionShape(side.getOpposite()))) { int x = side.getStepX() + 1; int y = side.getStepY() + 1; int z = side.getStepZ() + 1; diff --git a/src/main/java/net/neoforged/neoforge/client/model/obj/ObjModel.java b/src/main/java/net/neoforged/neoforge/client/model/obj/ObjModel.java index 83f3496e1e..25404e5499 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/obj/ObjModel.java +++ b/src/main/java/net/neoforged/neoforge/client/model/obj/ObjModel.java @@ -377,7 +377,7 @@ private Pair makeQuad(int[][] indices, int tintIndex, Vect quadBaker.setLight(uv2); quadBaker.setNormal(normal.x(), normal.y(), normal.z()); if (i == 0) { - quadBaker.setDirection(Direction.getNearest(normal.x(), normal.y(), normal.z())); + quadBaker.setDirection(Direction.getApproximateNearest(normal.x(), normal.y(), normal.z())); } pos[i] = position; norm[i] = normal; diff --git a/src/main/java/net/neoforged/neoforge/client/model/pipeline/QuadBakingVertexConsumer.java b/src/main/java/net/neoforged/neoforge/client/model/pipeline/QuadBakingVertexConsumer.java index 72509ebf94..dd73612d87 100644 --- a/src/main/java/net/neoforged/neoforge/client/model/pipeline/QuadBakingVertexConsumer.java +++ b/src/main/java/net/neoforged/neoforge/client/model/pipeline/QuadBakingVertexConsumer.java @@ -41,6 +41,7 @@ public class QuadBakingVertexConsumer implements VertexConsumer { private Direction direction = Direction.DOWN; private TextureAtlasSprite sprite = UnitTextureAtlasSprite.INSTANCE; private boolean shade; + private int lightEmission; private boolean hasAmbientOcclusion; @Override @@ -128,6 +129,10 @@ public void setShade(boolean shade) { this.shade = shade; } + public void setLightEmission(int lightEmission) { + this.lightEmission = lightEmission; + } + public void setHasAmbientOcclusion(boolean hasAmbientOcclusion) { this.hasAmbientOcclusion = hasAmbientOcclusion; } @@ -137,7 +142,7 @@ public BakedQuad bakeQuad() { throw new IllegalStateException("Not enough vertices available. Vertices in buffer: " + vertexIndex); } - BakedQuad quad = new BakedQuad(quadData.clone(), tintIndex, direction, sprite, shade, hasAmbientOcclusion); + BakedQuad quad = new BakedQuad(quadData.clone(), tintIndex, direction, sprite, shade, lightEmission, hasAmbientOcclusion); vertexIndex = 0; building = false; Arrays.fill(quadData, 0); diff --git a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java index 5c7e2f992f..d81c78914c 100644 --- a/src/main/java/net/neoforged/neoforge/common/CommonHooks.java +++ b/src/main/java/net/neoforged/neoforge/common/CommonHooks.java @@ -47,7 +47,6 @@ import net.minecraft.core.HolderLookup.RegistryLookup; import net.minecraft.core.HolderSet; import net.minecraft.core.Registry; -import net.minecraft.core.SectionPos; import net.minecraft.core.component.DataComponentMap; import net.minecraft.core.component.DataComponents; import net.minecraft.core.dispenser.BlockSource; @@ -73,7 +72,6 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.packs.PackType; import net.minecraft.stats.Stats; -import net.minecraft.tags.BlockTags; import net.minecraft.tags.TagKey; import net.minecraft.util.CrudeIncrementalIntIdentityHashBiMap; import net.minecraft.util.Mth; @@ -106,15 +104,12 @@ import net.minecraft.world.inventory.RecipeBookType; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.AdventureModePredicate; -import net.minecraft.world.item.ArmorItem; import net.minecraft.world.item.BucketItem; import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.EnchantedBookItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.PotionItem; import net.minecraft.world.item.SpawnEggItem; -import net.minecraft.world.item.Tiers; import net.minecraft.world.item.TippedArrowItem; import net.minecraft.world.item.alchemy.Potion; import net.minecraft.world.item.alchemy.PotionContents; @@ -123,6 +118,7 @@ import net.minecraft.world.item.enchantment.Enchantment; import net.minecraft.world.item.enchantment.EnchantmentInstance; import net.minecraft.world.item.enchantment.ItemEnchantments; +import net.minecraft.world.item.equipment.Equippable; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.GameType; import net.minecraft.world.level.Level; @@ -269,7 +265,7 @@ public static LivingChangeTargetEvent onLivingChangeTarget(LivingEntity entity, /** * Creates and posts an {@link EntityInvulnerabilityCheckEvent}. This is invoked in - * {@link Entity#isInvulnerableTo(DamageSource)} and returns a post-listener result + * {@link Entity#isInvulnerableToBase(DamageSource)} and returns a post-listener result * to the invulnerability status of the entity to the damage source. * * @param entity the entity being checked for invulnerability @@ -349,7 +345,8 @@ public static void onArmorHurt(DamageSource source, EquipmentSlot[] slots, float for (EquipmentSlot slot : slots) { ItemStack armorPiece = armoredEntity.getItemBySlot(slot); if (armorPiece.isEmpty()) continue; - float damageAfterFireResist = (armorPiece.getItem() instanceof ArmorItem && armorPiece.canBeHurtBy(source)) ? damage : 0; + Equippable equippable = armorPiece.get(DataComponents.EQUIPPABLE); + float damageAfterFireResist = (equippable != null && equippable.damageOnHurt() && armorPiece.isDamageableItem() && armorPiece.canBeHurtBy(source)) ? damage : 0; armorMap.put(slot, new ArmorHurtEvent.ArmorEntry(armorPiece, damageAfterFireResist)); } @@ -741,16 +738,13 @@ public static Player getCraftingPlayer() { return craftingPlayer.get(); } - public static ItemStack getCraftingRemainingItem(ItemStack stack) { - if (stack.getItem().hasCraftingRemainingItem(stack)) { - stack = stack.getItem().getCraftingRemainingItem(stack); - if (!stack.isEmpty() && stack.isDamageableItem() && stack.getDamageValue() > stack.getMaxDamage()) { - EventHooks.onPlayerDestroyItem(craftingPlayer.get(), stack, null); - return ItemStack.EMPTY; - } - return stack; + public static ItemStack getCraftingRemainder(ItemStack stack) { + stack = stack.getCraftingRemainder(); + if (!stack.isEmpty() && stack.isDamageableItem() && stack.getDamageValue() > stack.getMaxDamage()) { + EventHooks.onPlayerDestroyItem(craftingPlayer.get(), stack, null); + return ItemStack.EMPTY; } - return ItemStack.EMPTY; + return stack; } public static boolean onPlayerAttackTarget(Player player, Entity target) { @@ -872,7 +866,8 @@ public static FluidType getVanillaFluidType(Fluid fluid) { throw new RuntimeException("Mod fluids must override getFluidType."); } - public static TagKey getTagFromVanillaTier(Tiers tier) { + // FIXME: is this still needed + /*public static TagKey getTagFromVanillaTier(Tiers tier) { return switch (tier) { case WOOD -> Tags.Blocks.NEEDS_WOOD_TOOL; case GOLD -> Tags.Blocks.NEEDS_GOLD_TOOL; @@ -881,7 +876,7 @@ public static TagKey getTagFromVanillaTier(Tiers tier) { case DIAMOND -> BlockTags.NEEDS_DIAMOND_TOOL; case NETHERITE -> Tags.Blocks.NEEDS_NETHERITE_TOOL; }; - } + }*/ public static Collection onCheckCreativeTabs(CreativeModeTab... vanillaTabs) { final List tabs = new ArrayList<>(Arrays.asList(vanillaTabs)); @@ -962,7 +957,7 @@ public static String getDefaultCreatorModId(ItemStack itemStack) { ResourceLocation registryName = BuiltInRegistries.ITEM.getKey(item); String modId = registryName == null ? null : registryName.getNamespace(); if ("minecraft".equals(modId)) { - if (item instanceof EnchantedBookItem) { + if (itemStack.has(DataComponents.STORED_ENCHANTMENTS)) { Set> enchantments = itemStack.getOrDefault(DataComponents.STORED_ENCHANTMENTS, ItemEnchantments.EMPTY).keySet(); if (enchantments.size() == 1) { Holder enchantmentHolder = enchantments.iterator().next(); @@ -988,8 +983,8 @@ public static String getDefaultCreatorModId(ItemStack itemStack) { return modId; } - public static boolean onFarmlandTrample(Level level, BlockPos pos, BlockState state, float fallDistance, Entity entity) { - if (entity.canTrample(state, pos, fallDistance)) { + public static boolean onFarmlandTrample(ServerLevel level, BlockPos pos, BlockState state, float fallDistance, Entity entity) { + if (entity.canTrample(level, state, pos, fallDistance)) { BlockEvent.FarmlandTrampleEvent event = new BlockEvent.FarmlandTrampleEvent(level, pos, state, fallDistance, entity); NeoForge.EVENT_BUS.post(event); return !event.isCanceled(); @@ -1026,7 +1021,7 @@ public static int getSerializerId(EntityDataSerializer serializer, CrudeIncre return id; } - public static boolean canEntityDestroy(Level level, BlockPos pos, LivingEntity entity) { + public static boolean canEntityDestroy(ServerLevel level, BlockPos pos, LivingEntity entity) { if (!level.isLoaded(pos)) return false; BlockState state = level.getBlockState(pos); @@ -1264,14 +1259,14 @@ public static MobEffect loadMobEffect(CompoundTag nbt, String key, @Nullable Mob return fallback; } try { - return BuiltInRegistries.MOB_EFFECT.get(ResourceLocation.parse(registryName)); + return BuiltInRegistries.MOB_EFFECT.getValue(ResourceLocation.parse(registryName)); } catch (ResourceLocationException e) { return fallback; } } - public static boolean shouldSuppressEnderManAnger(EnderMan enderMan, Player player, ItemStack mask) { - return mask.isEnderMask(player, enderMan) || NeoForge.EVENT_BUS.post(new EnderManAngerEvent(enderMan, player)).isCanceled(); + public static boolean shouldSuppressEnderManAnger(EnderMan enderMan, Player player) { + return NeoForge.EVENT_BUS.post(new EnderManAngerEvent(enderMan, player)).isCanceled(); } private static final Lazy> FORGE_CONVERSION_MAP = Lazy.of(() -> { @@ -1494,11 +1489,7 @@ public static void onChunkUnload(PoiManager poiManager, ChunkAccess chunkAccess) poiManager.flush(chunkPos); // Make sure all POI in chunk are saved to disk first. // Remove the cached POIs for this chunk's location. - int SectionPosMinY = SectionPos.blockToSectionCoord(chunkAccess.getMinBuildHeight()); - for (int currentSectionY = 0; currentSectionY < chunkAccess.getSectionsCount(); currentSectionY++) { - long sectionPosKey = SectionPos.asLong(chunkPos.x, SectionPosMinY + currentSectionY, chunkPos.z); - poiManager.remove(sectionPosKey); - } + poiManager.remove(chunkPos); } /** diff --git a/src/main/java/net/neoforged/neoforge/common/CreativeModeTabRegistry.java b/src/main/java/net/neoforged/neoforge/common/CreativeModeTabRegistry.java index 3f4de60706..00438cdd81 100644 --- a/src/main/java/net/neoforged/neoforge/common/CreativeModeTabRegistry.java +++ b/src/main/java/net/neoforged/neoforge/common/CreativeModeTabRegistry.java @@ -69,7 +69,7 @@ public static List getDefaultTabs() { */ @Nullable public static CreativeModeTab getTab(ResourceLocation name) { - return BuiltInRegistries.CREATIVE_MODE_TAB.get(name); + return BuiltInRegistries.CREATIVE_MODE_TAB.getValue(name); } /** @@ -173,13 +173,13 @@ private static void runInServerThreadIfPossible(BooleanConsumer runnable) { public static void sortTabs() { edges.clear(); - DEFAULT_TABS.add(BuiltInRegistries.CREATIVE_MODE_TAB.get(CreativeModeTabs.HOTBAR)); - DEFAULT_TABS.add(BuiltInRegistries.CREATIVE_MODE_TAB.get(CreativeModeTabs.SEARCH)); - DEFAULT_TABS.add(BuiltInRegistries.CREATIVE_MODE_TAB.get(CreativeModeTabs.OP_BLOCKS)); - DEFAULT_TABS.add(BuiltInRegistries.CREATIVE_MODE_TAB.get(CreativeModeTabs.INVENTORY)); + DEFAULT_TABS.add(BuiltInRegistries.CREATIVE_MODE_TAB.getValue(CreativeModeTabs.HOTBAR)); + DEFAULT_TABS.add(BuiltInRegistries.CREATIVE_MODE_TAB.getValue(CreativeModeTabs.SEARCH)); + DEFAULT_TABS.add(BuiltInRegistries.CREATIVE_MODE_TAB.getValue(CreativeModeTabs.OP_BLOCKS)); + DEFAULT_TABS.add(BuiltInRegistries.CREATIVE_MODE_TAB.getValue(CreativeModeTabs.INVENTORY)); final List> indexed = new ArrayList<>(); - BuiltInRegistries.CREATIVE_MODE_TAB.holders().filter(c -> !DEFAULT_TABS.contains(c.value())).forEach(indexed::add); + BuiltInRegistries.CREATIVE_MODE_TAB.listElements().filter(c -> !DEFAULT_TABS.contains(c.value())).forEach(indexed::add); int vanillaTabs = 10; for (int i = 0; i < vanillaTabs; i++) // Vanilla ordering diff --git a/src/main/java/net/neoforged/neoforge/common/DataMapHooks.java b/src/main/java/net/neoforged/neoforge/common/DataMapHooks.java index 5b61e8a4a2..5761d1a556 100644 --- a/src/main/java/net/neoforged/neoforge/common/DataMapHooks.java +++ b/src/main/java/net/neoforged/neoforge/common/DataMapHooks.java @@ -8,11 +8,16 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; +import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.item.HoneycombItem; +import net.minecraft.world.item.Item; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.WeatheringCopper; +import net.minecraft.world.level.block.entity.FuelValues; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.neoforge.registries.datamaps.DataMapsUpdatedEvent; import net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps; @@ -62,6 +67,14 @@ public static Block getBlockUnwaxed(Block block) { return INVERSE_WAXABLES_DATAMAP.containsKey(block) ? INVERSE_WAXABLES_DATAMAP.get(block) : HoneycombItem.WAX_OFF_BY_BLOCK.get().get(block); } + @ApiStatus.Internal + public static FuelValues populateFuelValues(RegistryAccess lookupProvider, FeatureFlagSet features) { + FuelValues.Builder builder = new FuelValues.Builder(lookupProvider, features); + Registry registry = lookupProvider.lookupOrThrow(Registries.ITEM); + registry.getDataMap(NeoForgeDataMaps.FURNACE_FUELS).forEach((key, fuel) -> builder.add(registry.getValue(key), fuel.burnTime())); + return builder.build(); + } + @SubscribeEvent static void onDataMapsUpdated(DataMapsUpdatedEvent event) { event.ifRegistry(Registries.BLOCK, registry -> { @@ -69,7 +82,7 @@ static void onDataMapsUpdated(DataMapsUpdatedEvent event) { INVERSE_WAXABLES_DATAMAP_INTERNAL.clear(); registry.getDataMap(NeoForgeDataMaps.OXIDIZABLES).forEach((resourceKey, oxidizable) -> { - INVERSE_OXIDIZABLES_DATAMAP_INTERNAL.put(oxidizable.nextOxidationStage(), BuiltInRegistries.BLOCK.get(resourceKey)); + INVERSE_OXIDIZABLES_DATAMAP_INTERNAL.put(oxidizable.nextOxidationStage(), BuiltInRegistries.BLOCK.getValue(resourceKey)); }); //noinspection deprecation @@ -81,7 +94,7 @@ static void onDataMapsUpdated(DataMapsUpdatedEvent event) { }); registry.getDataMap(NeoForgeDataMaps.WAXABLES).forEach((resourceKey, waxable) -> { - INVERSE_WAXABLES_DATAMAP_INTERNAL.put(waxable.waxed(), BuiltInRegistries.BLOCK.get(resourceKey)); + INVERSE_WAXABLES_DATAMAP_INTERNAL.put(waxable.waxed(), BuiltInRegistries.BLOCK.getValue(resourceKey)); }); //noinspection deprecation diff --git a/src/main/java/net/neoforged/neoforge/common/DeferredSpawnEggItem.java b/src/main/java/net/neoforged/neoforge/common/DeferredSpawnEggItem.java index 1b1ac206b7..67c84ef09a 100644 --- a/src/main/java/net/neoforged/neoforge/common/DeferredSpawnEggItem.java +++ b/src/main/java/net/neoforged/neoforge/common/DeferredSpawnEggItem.java @@ -12,10 +12,10 @@ import java.util.function.Supplier; import net.minecraft.core.Direction; import net.minecraft.core.dispenser.DispenseItemBehavior; -import net.minecraft.util.FastColor; +import net.minecraft.util.ARGB; +import net.minecraft.world.entity.EntitySpawnReason; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; -import net.minecraft.world.entity.MobSpawnType; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.SpawnEggItem; import net.minecraft.world.level.block.DispenserBlock; @@ -62,7 +62,7 @@ protected EntityType getDefaultType() { EntityType type = ((SpawnEggItem) stack.getItem()).getType(stack); try { - type.spawn(source.level(), stack, null, source.pos().relative(face), MobSpawnType.DISPENSER, face != Direction.UP, false); + type.spawn(source.level(), stack, null, source.pos().relative(face), EntitySpawnReason.DISPENSER, face != Direction.UP, false); } catch (Exception exception) { DispenseItemBehavior.LOGGER.error("Error while dispensing spawn egg from dispenser at {}", source.pos(), exception); return ItemStack.EMPTY; @@ -94,7 +94,7 @@ public static void onCommonSetup(FMLCommonSetupEvent event) { private static class ColorRegisterHandler { @SubscribeEvent(priority = EventPriority.HIGHEST) public static void registerSpawnEggColors(RegisterColorHandlersEvent.Item event) { - MOD_EGGS.forEach(egg -> event.register((stack, layer) -> FastColor.ARGB32.opaque(egg.getColor(layer)), egg)); + MOD_EGGS.forEach(egg -> event.register((stack, layer) -> ARGB.opaque(egg.getColor(layer)), egg)); } } } diff --git a/src/main/java/net/neoforged/neoforge/common/EffectCure.java b/src/main/java/net/neoforged/neoforge/common/EffectCure.java deleted file mode 100644 index e26da9f6b3..0000000000 --- a/src/main/java/net/neoforged/neoforge/common/EffectCure.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) NeoForged and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.common; - -import com.mojang.serialization.Codec; -import io.netty.buffer.ByteBuf; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import net.minecraft.network.codec.ByteBufCodecs; -import net.minecraft.network.codec.StreamCodec; -import net.minecraft.world.effect.MobEffect; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.entity.LivingEntity; -import net.neoforged.neoforge.event.entity.living.MobEffectEvent; - -/** - * Defines a cure that is used to remove {@link MobEffect}s from a {@link LivingEntity}. - *

Cures can be added to or removed from your own effects via {@link MobEffect#fillEffectCures(Set, MobEffectInstance)} - * or any effect by modifying the set of cures on the {@link MobEffectInstance} in {@link MobEffectEvent.Added} - */ -public final class EffectCure { - private static final Map CURES = new ConcurrentHashMap<>(); - - public static Codec CODEC = Codec.STRING.xmap(EffectCure::get, EffectCure::name); - public static final StreamCodec STREAM_CODEC = ByteBufCodecs.STRING_UTF8.map(EffectCure::get, EffectCure::name); - - /** - * {@return all registered cures} - * This collection can be kept around, and will update itself in response to changes to the map. - * See {@link ConcurrentHashMap#values()} for details. - */ - public static Collection getAllCures() { - return Collections.unmodifiableCollection(CURES.values()); - } - - /** - * Gets or creates a new EffectCure for the given name. - */ - public static EffectCure get(String name) { - return CURES.computeIfAbsent(name, EffectCure::new); - } - - /** - * {@return the name of this cure} - */ - public String name() { - return name; - } - - @Override - public String toString() { - return "EffectCure[" + name + "]"; - } - - private final String name; - - /** - * Use {@link #get(String)} to get or create an EffectCure - */ - private EffectCure(String name) { - this.name = name; - } -} diff --git a/src/main/java/net/neoforged/neoforge/common/EffectCures.java b/src/main/java/net/neoforged/neoforge/common/EffectCures.java deleted file mode 100644 index 4362015969..0000000000 --- a/src/main/java/net/neoforged/neoforge/common/EffectCures.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) NeoForged and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.common; - -import java.util.Set; - -public class EffectCures { - /** - * Cure used when a milk bucket is consumed. Cures any effect by default. - */ - public static final EffectCure MILK = EffectCure.get("milk"); - /** - * Cure used when a honey bottle is consumed. Only cures poison by default. - */ - public static final EffectCure HONEY = EffectCure.get("honey"); - /** - * Cure used when a totem of undying protects the player from death. Cures any effect by default. - */ - public static final EffectCure PROTECTED_BY_TOTEM = EffectCure.get("protected_by_totem"); - - public static final Set DEFAULT_CURES = Set.of(MILK, PROTECTED_BY_TOTEM); -} diff --git a/src/main/java/net/neoforged/neoforge/common/IShearable.java b/src/main/java/net/neoforged/neoforge/common/IShearable.java index ae5d51aabc..2be9098654 100644 --- a/src/main/java/net/neoforged/neoforge/common/IShearable.java +++ b/src/main/java/net/neoforged/neoforge/common/IShearable.java @@ -9,6 +9,7 @@ import java.util.Collections; import java.util.List; import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundSource; import net.minecraft.util.RandomSource; import net.minecraft.world.entity.Entity; @@ -64,9 +65,9 @@ default boolean isShearable(@Nullable Player player, ItemStack item, Level level @SuppressWarnings("deprecation") // Expected call to deprecated vanilla Shearable#shear default List onSheared(@Nullable Player player, ItemStack item, Level level, BlockPos pos) { if (this instanceof LivingEntity entity && this instanceof Shearable shearable) { - if (!level.isClientSide) { + if (level instanceof ServerLevel serverLevel) { entity.captureDrops(new ArrayList<>()); - shearable.shear(player == null ? SoundSource.BLOCKS : SoundSource.PLAYERS); + shearable.shear(serverLevel, player == null ? SoundSource.BLOCKS : SoundSource.PLAYERS, item); return entity.captureDrops(null).stream().map(ItemEntity::getItem).toList(); } } @@ -82,23 +83,23 @@ default List onSheared(@Nullable Player player, ItemStack item, Level * @param pos The block position of this object (if this is an entity, the value of {@link Entity#blockPosition()}. * @param drop The stack to drop, from the list of drops returned by {@link #onSheared}. */ - default void spawnShearedDrop(Level level, BlockPos pos, ItemStack drop) { + default void spawnShearedDrop(ServerLevel level, BlockPos pos, ItemStack drop) { if (this instanceof SnowGolem golem) { // SnowGolem#shear uses spawnAtLocation(..., this.getEyeHeight()); - golem.spawnAtLocation(drop, golem.getEyeHeight()); + golem.spawnAtLocation(level, drop, golem.getEyeHeight()); } else if (this instanceof Bogged bogged) { // Bogged#spawnShearedMushrooms uses spawnAtLocation(..., this.getBbHeight()); - bogged.spawnAtLocation(drop, bogged.getBbHeight()); + bogged.spawnAtLocation(level, drop, bogged.getBbHeight()); } else if (this instanceof MushroomCow cow) { // We patch Mooshrooms from using addFreshEntity to spawnAtLocation to spawnAtLocation to capture the drops. // In case a mod is also capturing drops, we also replicate that logic here. - ItemEntity itemEntity = cow.spawnAtLocation(drop, cow.getBbHeight()); + ItemEntity itemEntity = cow.spawnAtLocation(level, drop, cow.getBbHeight()); if (itemEntity != null) { itemEntity.setNoPickUpDelay(); } } else if (this instanceof Entity entity) { // Everything else uses the "default" rules invented by Sheep#shear, which uses a y-offset of 1 and these random delta movement values. - ItemEntity itemEntity = entity.spawnAtLocation(drop, 1); + ItemEntity itemEntity = entity.spawnAtLocation(level, drop, 1); if (itemEntity != null) { RandomSource rand = entity.getRandom(); Vec3 newDelta = itemEntity.getDeltaMovement().add( diff --git a/src/main/java/net/neoforged/neoforge/common/MonsterRoomHooks.java b/src/main/java/net/neoforged/neoforge/common/MonsterRoomHooks.java index dca24a231b..e2f08277a8 100644 --- a/src/main/java/net/neoforged/neoforge/common/MonsterRoomHooks.java +++ b/src/main/java/net/neoforged/neoforge/common/MonsterRoomHooks.java @@ -26,7 +26,7 @@ public class MonsterRoomHooks { @SubscribeEvent public static void onDataMapsUpdated(DataMapsUpdatedEvent event) { event.ifRegistry(Registries.ENTITY_TYPE, registry -> monsterRoomMobs = registry.getDataMap(NeoForgeDataMaps.MONSTER_ROOM_MOBS).entrySet().stream().map((entry) -> { - EntityType type = Objects.requireNonNull(registry.get(entry.getKey()), "Nonexistent entity " + entry.getKey() + " in monster room datamap!"); + EntityType type = Objects.requireNonNull(registry.getValue(entry.getKey()), "Nonexistent entity " + entry.getKey() + " in monster room datamap!"); return new MobEntry(type, entry.getValue().weight()); }).toList()); } diff --git a/src/main/java/net/neoforged/neoforge/common/NeoForgeConfig.java b/src/main/java/net/neoforged/neoforge/common/NeoForgeConfig.java index ebbe55f846..91a232a8ae 100644 --- a/src/main/java/net/neoforged/neoforge/common/NeoForgeConfig.java +++ b/src/main/java/net/neoforged/neoforge/common/NeoForgeConfig.java @@ -87,8 +87,6 @@ public static class Client { public final BooleanValue showLoadWarnings; - public final BooleanValue useCombinedDepthStencilAttachment; - public final BooleanValue logUntranslatedConfigurationWarnings; Client(ModConfigSpec.Builder builder) { @@ -102,11 +100,6 @@ public static class Client { .translation("neoforge.configgui.showLoadWarnings") .define("showLoadWarnings", true); - useCombinedDepthStencilAttachment = builder - .comment("Set to true to use a combined DEPTH_STENCIL attachment instead of two separate ones.") - .translation("neoforge.configgui.useCombinedDepthStencilAttachment") - .define("useCombinedDepthStencilAttachment", false); - logUntranslatedConfigurationWarnings = builder .comment("A config option mainly for developers. Logs out configuration values that do not have translations when running a client in a development environment.") .translation("neoforge.configgui.logUntranslatedConfigurationWarnings") diff --git a/src/main/java/net/neoforged/neoforge/common/NeoForgeEventHandler.java b/src/main/java/net/neoforged/neoforge/common/NeoForgeEventHandler.java index 2e2e14ab5f..d7440f1ea6 100644 --- a/src/main/java/net/neoforged/neoforge/common/NeoForgeEventHandler.java +++ b/src/main/java/net/neoforged/neoforge/common/NeoForgeEventHandler.java @@ -57,7 +57,7 @@ public void onEntityJoinWorld(EntityJoinLevelEvent event) { entity.discard(); event.setCanceled(true); var executor = LogicalSidedProvider.WORKQUEUE.get(event.getLevel().isClientSide ? LogicalSide.CLIENT : LogicalSide.SERVER); - executor.tell(new TickTask(0, () -> event.getLevel().addFreshEntity(newEntity))); + executor.schedule(new TickTask(0, () -> event.getLevel().addFreshEntity(newEntity))); } } } @@ -110,7 +110,7 @@ public void tagsUpdated(TagsUpdatedEvent event) { public void onDpSync(final OnDatapackSyncEvent event) { RegistryManager.getDataMaps().forEach((registry, values) -> { final var regOpt = event.getPlayerList().getServer().overworld().registryAccess() - .registry(registry); + .lookup(registry); if (regOpt.isEmpty()) return; event.getRelevantPlayers().forEach(player -> { if (!player.connection.hasChannel(RegistryDataMapSyncPayload.TYPE)) { diff --git a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java index 46b0696bf4..8f66013fcf 100644 --- a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java @@ -35,6 +35,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; import net.minecraft.server.packs.PackType; import net.minecraft.server.packs.metadata.pack.PackMetadataSection; import net.minecraft.sounds.SoundEvent; @@ -53,14 +54,12 @@ import net.minecraft.world.item.Items; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.GameRules; -import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.MobSpawnSettings; import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.PointedDripstoneBlock; -import net.minecraft.world.level.levelgen.GenerationStep; import net.minecraft.world.level.levelgen.GenerationStep.Decoration; import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver; import net.minecraft.world.level.levelgen.placement.PlacedFeature; @@ -99,6 +98,7 @@ import net.neoforged.neoforge.common.conditions.TrueCondition; import net.neoforged.neoforge.common.crafting.BlockTagIngredient; import net.neoforged.neoforge.common.crafting.CompoundIngredient; +import net.neoforged.neoforge.common.crafting.CustomDisplayIngredient; import net.neoforged.neoforge.common.crafting.DataComponentIngredient; import net.neoforged.neoforge.common.crafting.DifferenceIngredient; import net.neoforged.neoforge.common.crafting.IngredientType; @@ -196,7 +196,7 @@ public class NeoForgeMod { SingletonArgumentInfo.contextFree(ModIdArgument::modIdArgument))); public static final Holder SWIM_SPEED = ATTRIBUTES.register("swim_speed", () -> new PercentageAttribute("neoforge.swim_speed", 1.0D, 0.0D, 1024.0D).setSyncable(true)); - public static final Holder NAMETAG_DISTANCE = ATTRIBUTES.register("nametag_distance", () -> new RangedAttribute("neoforge.name_tag_distance", 64.0D, 0.0D, 64.0).setSyncable(true).setSentiment(Sentiment.NEUTRAL)); + public static final Holder NAMETAG_DISTANCE = ATTRIBUTES.register("nametag_distance", () -> new RangedAttribute("neoforge.name_tag_distance", 32.0D, 0.0D, 32.0).setSyncable(true).setSentiment(Sentiment.NEUTRAL)); /** * This attribute controls if the player may use creative flight when not in creative mode. @@ -273,18 +273,14 @@ public class NeoForgeMod { */ public static final DeferredHolder, MapCodec> ADD_CARVERS_BIOME_MODIFIER_TYPE = BIOME_MODIFIER_SERIALIZERS.register("add_carvers", () -> RecordCodecBuilder.mapCodec(builder -> builder.group( Biome.LIST_CODEC.fieldOf("biomes").forGetter(BiomeModifiers.AddCarversBiomeModifier::biomes), - ConfiguredWorldCarver.LIST_CODEC.fieldOf("carvers").forGetter(BiomeModifiers.AddCarversBiomeModifier::carvers), - GenerationStep.Carving.CODEC.fieldOf("step").forGetter(BiomeModifiers.AddCarversBiomeModifier::step)).apply(builder, BiomeModifiers.AddCarversBiomeModifier::new))); + ConfiguredWorldCarver.LIST_CODEC.fieldOf("carvers").forGetter(BiomeModifiers.AddCarversBiomeModifier::carvers)).apply(builder, BiomeModifiers.AddCarversBiomeModifier::new))); /** * Stock biome modifier for removing carvers from biomes. */ public static final DeferredHolder, MapCodec> REMOVE_CARVERS_BIOME_MODIFIER_TYPE = BIOME_MODIFIER_SERIALIZERS.register("remove_carvers", () -> RecordCodecBuilder.mapCodec(builder -> builder.group( Biome.LIST_CODEC.fieldOf("biomes").forGetter(BiomeModifiers.RemoveCarversBiomeModifier::biomes), - ConfiguredWorldCarver.LIST_CODEC.fieldOf("carvers").forGetter(BiomeModifiers.RemoveCarversBiomeModifier::carvers), - Codec.either(GenerationStep.Carving.CODEC.listOf(), GenerationStep.Carving.CODEC).xmap( - either -> either.map(Set::copyOf, Set::of), - set -> set.size() == 1 ? Either.right(set.toArray(GenerationStep.Carving[]::new)[0]) : Either.left(List.copyOf(set))).optionalFieldOf("steps", EnumSet.allOf(GenerationStep.Carving.class)).forGetter(BiomeModifiers.RemoveCarversBiomeModifier::steps)) + ConfiguredWorldCarver.LIST_CODEC.fieldOf("carvers").forGetter(BiomeModifiers.RemoveCarversBiomeModifier::carvers)) .apply(builder, BiomeModifiers.RemoveCarversBiomeModifier::new))); /** @@ -364,6 +360,7 @@ public class NeoForgeMod { public static final DeferredHolder, IngredientType> DIFFERENCE_INGREDIENT_TYPE = INGREDIENT_TYPES.register("difference", () -> new IngredientType<>(DifferenceIngredient.CODEC)); public static final DeferredHolder, IngredientType> INTERSECTION_INGREDIENT_TYPE = INGREDIENT_TYPES.register("intersection", () -> new IngredientType<>(IntersectionIngredient.CODEC)); public static final DeferredHolder, IngredientType> BLOCK_TAG_INGREDIENT = INGREDIENT_TYPES.register("block_tag", () -> new IngredientType<>(BlockTagIngredient.CODEC)); + public static final DeferredHolder, IngredientType> CUSTOM_DISPLAY_INGREDIENT = INGREDIENT_TYPES.register("custom_display", () -> new IngredientType<>(CustomDisplayIngredient.CODEC)); private static final DeferredRegister> FLUID_INGREDIENT_TYPES = DeferredRegister.create(NeoForgeRegistries.Keys.FLUID_INGREDIENT_TYPES, NeoForgeVersion.MOD_ID); public static final DeferredHolder, FluidIngredientType> SINGLE_FLUID_INGREDIENT_TYPE = FLUID_INGREDIENT_TYPES.register("single", () -> new FluidIngredientType<>(SingleFluidIngredient.CODEC)); @@ -424,7 +421,7 @@ public void setItemMovement(ItemEntity entity) { .addDripstoneDripping(PointedDripstoneBlock.WATER_TRANSFER_PROBABILITY_PER_RANDOM_TICK, ParticleTypes.DRIPPING_DRIPSTONE_WATER, Blocks.WATER_CAULDRON, SoundEvents.POINTED_DRIPSTONE_DRIP_WATER_INTO_CAULDRON)) { @Override public boolean canConvertToSource(FluidState state, LevelReader reader, BlockPos pos) { - if (reader instanceof Level level) { + if (reader instanceof ServerLevel level) { return level.getGameRules().getBoolean(GameRules.RULE_WATER_SOURCE_CONVERSION); } //Best guess fallback to default (true) @@ -451,7 +448,7 @@ public boolean canConvertToSource(FluidState state, LevelReader reader, BlockPos .addDripstoneDripping(PointedDripstoneBlock.LAVA_TRANSFER_PROBABILITY_PER_RANDOM_TICK, ParticleTypes.DRIPPING_DRIPSTONE_LAVA, Blocks.LAVA_CAULDRON, SoundEvents.POINTED_DRIPSTONE_DRIP_LAVA_INTO_CAULDRON)) { @Override public boolean canConvertToSource(FluidState state, LevelReader reader, BlockPos pos) { - if (reader instanceof Level level) { + if (reader instanceof ServerLevel level) { return level.getGameRules().getBoolean(GameRules.RULE_LAVA_SOURCE_CONVERSION); } //Best guess fallback to default (false) @@ -622,7 +619,7 @@ public void gatherData(GatherDataEvent event) { gen.addProvider(event.includeServer(), new NeoForgeEntityTypeTagsProvider(packOutput, lookupProvider, existingFileHelper)); gen.addProvider(event.includeServer(), new NeoForgeFluidTagsProvider(packOutput, lookupProvider, existingFileHelper)); gen.addProvider(event.includeServer(), new NeoForgeEnchantmentTagsProvider(packOutput, lookupProvider, existingFileHelper)); - gen.addProvider(event.includeServer(), new NeoForgeRecipeProvider(packOutput, lookupProvider)); + gen.addProvider(event.includeServer(), new NeoForgeRecipeProvider.Runner(packOutput, lookupProvider)); gen.addProvider(event.includeServer(), new NeoForgeLootTableProvider(packOutput, lookupProvider)); gen.addProvider(event.includeServer(), new NeoForgeBiomeTagsProvider(packOutput, lookupProvider, existingFileHelper)); gen.addProvider(event.includeServer(), new NeoForgeStructureTagsProvider(packOutput, lookupProvider, existingFileHelper)); diff --git a/src/main/java/net/neoforged/neoforge/common/SimpleTier.java b/src/main/java/net/neoforged/neoforge/common/SimpleTier.java index 73b4dfdd41..556ba03e6a 100644 --- a/src/main/java/net/neoforged/neoforge/common/SimpleTier.java +++ b/src/main/java/net/neoforged/neoforge/common/SimpleTier.java @@ -7,14 +7,14 @@ import java.util.function.Supplier; import net.minecraft.tags.TagKey; -import net.minecraft.world.item.Tier; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.level.block.Block; /** * Helper class to define a custom tier + * FIXME: is this still needed? */ -public class SimpleTier implements Tier { +public class SimpleTier /*implements Tier*/ { private final TagKey incorrectBlocksForDrops; private final int uses; private final float speed; @@ -32,35 +32,35 @@ public SimpleTier(TagKey incorrectBlocksForDrops, int uses, float speed, this.repairIngredient = repairIngredient; } - @Override + /*@Override public int getUses() { return this.uses; } - + @Override public float getSpeed() { return this.speed; } - + @Override public float getAttackDamageBonus() { return this.attackDamageBonus; } - + @Override public TagKey getIncorrectBlocksForDrops() { return incorrectBlocksForDrops; } - + @Override public int getEnchantmentValue() { return this.enchantmentValue; } - + @Override public Ingredient getRepairIngredient() { return this.repairIngredient.get(); - } + }*/ @Override public String toString() { diff --git a/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java b/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java index 854a826426..6f00ace767 100644 --- a/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java +++ b/src/main/java/net/neoforged/neoforge/common/TagConventionLogWarning.java @@ -10,6 +10,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import net.minecraft.core.HolderSet; import net.minecraft.core.Registry; import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; @@ -503,7 +504,7 @@ private static void setupLegacyTagWarning(IEventBus forgeBus) { // We only care about vanilla registries registryAccess.registries().forEach(registryEntry -> { if (registryEntry.key().location().getNamespace().equals("minecraft")) { - registryEntry.value().getTagNames().forEach(tagKey -> { + registryEntry.value().getTags().map(HolderSet.Named::key).forEach(tagKey -> { // Grab tags under 'forge' namespace if (LEGACY_FORGE_TAGS.containsKey(tagKey) || tagKey.location().getNamespace().equals("forge")) { legacyTags.add(tagKey); diff --git a/src/main/java/net/neoforged/neoforge/common/VillagerTradingManager.java b/src/main/java/net/neoforged/neoforge/common/VillagerTradingManager.java index b36bbdb53b..6bfebd3b73 100644 --- a/src/main/java/net/neoforged/neoforge/common/VillagerTradingManager.java +++ b/src/main/java/net/neoforged/neoforge/common/VillagerTradingManager.java @@ -11,8 +11,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import net.minecraft.core.HolderLookup; import net.minecraft.core.NonNullList; -import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.entity.npc.VillagerProfession; import net.minecraft.world.entity.npc.VillagerTrades; @@ -36,20 +36,20 @@ public class VillagerTradingManager { static void loadTrades(TagsUpdatedEvent e) { if (e.getUpdateCause() == TagsUpdatedEvent.UpdateCause.SERVER_DATA_LOAD) { - postWandererEvent(e.getRegistryAccess()); - postVillagerEvents(e.getRegistryAccess()); + postWandererEvent(e.getLookupProvider()); + postVillagerEvents(e.getLookupProvider()); } } /** * Posts the WandererTradesEvent. */ - private static void postWandererEvent(RegistryAccess registryAccess) { + private static void postWandererEvent(HolderLookup.Provider registries) { List generic = NonNullList.create(); List rare = NonNullList.create(); Arrays.stream(WANDERER_TRADES.get(1)).forEach(generic::add); Arrays.stream(WANDERER_TRADES.get(2)).forEach(rare::add); - NeoForge.EVENT_BUS.post(new WandererTradesEvent(generic, rare, registryAccess)); + NeoForge.EVENT_BUS.post(new WandererTradesEvent(generic, rare, registries)); VillagerTrades.WANDERING_TRADER_TRADES.put(1, generic.toArray(new ItemListing[0])); VillagerTrades.WANDERING_TRADER_TRADES.put(2, rare.toArray(new ItemListing[0])); } @@ -57,7 +57,7 @@ private static void postWandererEvent(RegistryAccess registryAccess) { /** * Posts a VillagerTradesEvent for each registered profession. */ - private static void postVillagerEvents(RegistryAccess registryAccess) { + private static void postVillagerEvents(HolderLookup.Provider registries) { for (VillagerProfession prof : BuiltInRegistries.VILLAGER_PROFESSION) { Int2ObjectMap trades = VANILLA_TRADES.getOrDefault(prof, new Int2ObjectOpenHashMap<>()); Int2ObjectMap> mutableTrades = new Int2ObjectOpenHashMap<>(); @@ -67,7 +67,7 @@ private static void postVillagerEvents(RegistryAccess registryAccess) { trades.int2ObjectEntrySet().forEach(e -> { Arrays.stream(e.getValue()).forEach(mutableTrades.get(e.getIntKey())::add); }); - NeoForge.EVENT_BUS.post(new VillagerTradesEvent(mutableTrades, prof, registryAccess)); + NeoForge.EVENT_BUS.post(new VillagerTradesEvent(mutableTrades, prof, registries)); Int2ObjectMap newTrades = new Int2ObjectOpenHashMap<>(); mutableTrades.int2ObjectEntrySet().forEach(e -> newTrades.put(e.getIntKey(), e.getValue().toArray(new ItemListing[0]))); VillagerTrades.TRADES.put(prof, newTrades); diff --git a/src/main/java/net/neoforged/neoforge/common/conditions/ConditionContext.java b/src/main/java/net/neoforged/neoforge/common/conditions/ConditionContext.java index 186cbb6347..de5b9b5d36 100644 --- a/src/main/java/net/neoforged/neoforge/common/conditions/ConditionContext.java +++ b/src/main/java/net/neoforged/neoforge/common/conditions/ConditionContext.java @@ -5,40 +5,32 @@ package net.neoforged.neoforge.common.conditions; -import java.util.Collection; -import java.util.Collections; import java.util.IdentityHashMap; +import java.util.List; import java.util.Map; -import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.TagManager; -import org.jetbrains.annotations.Nullable; +import net.minecraft.tags.TagKey; public class ConditionContext implements ICondition.IContext { - private final TagManager tagManager; - @Nullable - // TODO 1.20.5: Clear loaded tags after reloads complete. The context object may leak, but we still want to invalidate it. - private Map, Map>>> loadedTags = null; + private final Map>, HolderLookup.RegistryLookup> pendingTags; - public ConditionContext(TagManager tagManager) { - this.tagManager = tagManager; + public ConditionContext(List> pendingTags) { + this.pendingTags = new IdentityHashMap<>(); + for (var tags : pendingTags) { + this.pendingTags.put(tags.key(), tags.lookup()); + } } - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public Map>> getAllTags(ResourceKey> registry) { - if (loadedTags == null) { - var tags = tagManager.getResult(); - if (tags.isEmpty()) throw new IllegalStateException("Tags have not been loaded yet."); + public void clear() { + this.pendingTags.clear(); + } - loadedTags = new IdentityHashMap<>(); - for (var loadResult : tags) { - Map>> map = Collections.unmodifiableMap(loadResult.tags()); - loadedTags.put(loadResult.key(), (Map) map); - } - } - return (Map) loadedTags.getOrDefault(registry, Collections.emptyMap()); + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public boolean isTagLoaded(TagKey key) { + var lookup = pendingTags.get(key.registry()); + return lookup != null && lookup.get((TagKey) key).isPresent(); } } diff --git a/src/main/java/net/neoforged/neoforge/common/conditions/ICondition.java b/src/main/java/net/neoforged/neoforge/common/conditions/ICondition.java index 04e0ff5f02..1be7e0ce94 100644 --- a/src/main/java/net/neoforged/neoforge/common/conditions/ICondition.java +++ b/src/main/java/net/neoforged/neoforge/common/conditions/ICondition.java @@ -12,19 +12,11 @@ import com.mojang.serialization.DynamicOps; import com.mojang.serialization.JsonOps; import com.mojang.serialization.MapCodec; -import java.util.Collection; -import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.Optional; -import java.util.Set; import java.util.function.Function; -import net.minecraft.core.Holder; import net.minecraft.core.HolderLookup; -import net.minecraft.core.Registry; import net.minecraft.resources.RegistryOps; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.util.Unit; import net.neoforged.neoforge.registries.NeoForgeRegistries; @@ -80,32 +72,24 @@ static void writeConditions(DynamicOps jsonOps, JsonObject jsonObje MapCodec codec(); - interface IContext { + interface IContext { // TODO 1.21.2: potentially remove since all the info is available via RegistryOps IContext EMPTY = new IContext() { @Override - public Map>> getAllTags(ResourceKey> registry) { - return Collections.emptyMap(); + public boolean isTagLoaded(TagKey key) { + return false; } }; IContext TAGS_INVALID = new IContext() { @Override - public Map>> getAllTags(ResourceKey> registry) { + public boolean isTagLoaded(TagKey key) { throw new UnsupportedOperationException("Usage of tag-based conditions is not permitted in this context!"); } }; /** - * Return the requested tag if available, or an empty tag otherwise. + * Returns {@code true} if the requested tag is available. */ - default Collection> getTag(TagKey key) { - return getAllTags(key.registry()).getOrDefault(key.location(), Set.of()); - } - - /** - * Return all the loaded tags for the passed registry, or an empty map if none is available. - * Note that the map and the tags are unmodifiable. - */ - Map>> getAllTags(ResourceKey> registry); + boolean isTagLoaded(TagKey key); } } diff --git a/src/main/java/net/neoforged/neoforge/common/conditions/TagEmptyCondition.java b/src/main/java/net/neoforged/neoforge/common/conditions/TagEmptyCondition.java index b7ecc85151..6da7798cb6 100644 --- a/src/main/java/net/neoforged/neoforge/common/conditions/TagEmptyCondition.java +++ b/src/main/java/net/neoforged/neoforge/common/conditions/TagEmptyCondition.java @@ -33,7 +33,7 @@ public TagEmptyCondition(ResourceLocation tag) { @Override public boolean test(ICondition.IContext context) { - return context.getTag(tag).isEmpty(); + return !context.isTagLoaded(tag); } @Override diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/BlockTagIngredient.java b/src/main/java/net/neoforged/neoforge/common/crafting/BlockTagIngredient.java index 4994e80542..a99a2f1757 100644 --- a/src/main/java/net/neoforged/neoforge/common/crafting/BlockTagIngredient.java +++ b/src/main/java/net/neoforged/neoforge/common/crafting/BlockTagIngredient.java @@ -10,15 +10,16 @@ import java.util.List; import java.util.stream.Stream; import net.minecraft.core.Holder; -import net.minecraft.core.component.DataComponents; +import net.minecraft.core.HolderSet; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; -import net.minecraft.network.chat.Component; import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.display.SlotDisplay; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; import net.neoforged.neoforge.common.NeoForgeMod; import org.jetbrains.annotations.Nullable; @@ -26,7 +27,7 @@ * {@link Ingredient} that matches {@link ItemStack}s of {@link Block}s from a {@link TagKey}, useful in cases * like {@code "minecraft:convertable_to_mud"} where there isn't an accompanying item tag *

- * Notice: This should not be used as a replacement for the normal {@link Ingredient#of(TagKey)}, + * Notice: This should not be used as a replacement for the normal item tag ingredient. * This should only be used when there is no way an item tag can be used in your use case */ public class BlockTagIngredient implements ICustomIngredient { @@ -36,36 +37,30 @@ public class BlockTagIngredient implements ICustomIngredient { protected final TagKey tag; @Nullable - protected ItemStack[] itemStacks; + protected HolderSet items; public BlockTagIngredient(TagKey tag) { this.tag = tag; } - protected void dissolve() { - if (itemStacks == null) { - List list = new ArrayList<>(); + protected HolderSet dissolve() { + if (items == null) { + List> list = new ArrayList<>(); for (Holder block : BuiltInRegistries.BLOCK.getTagOrEmpty(tag)) { - ItemStack stack = new ItemStack(block.value()); - if (!stack.isEmpty()) { - list.add(stack); + var item = block.value().asItem(); + if (item != Items.AIR) { + list.add(item.builtInRegistryHolder()); } } - if (list.isEmpty()) { - ItemStack itemStack = new ItemStack(Blocks.BARRIER); - itemStack.set(DataComponents.CUSTOM_NAME, Component.literal("Empty Tag: " + this.tag.location())); - list.add(itemStack); - } - - itemStacks = list.toArray(ItemStack[]::new); + items = HolderSet.direct(list); } + return items; } @Override - public Stream getItems() { - dissolve(); - return Stream.of(itemStacks); + public Stream> items() { + return dissolve().stream(); } @Override @@ -73,14 +68,7 @@ public boolean test(@Nullable ItemStack stack) { if (stack == null) return false; - dissolve(); - for (ItemStack itemStack : itemStacks) { - if (itemStack.is(stack.getItem())) { - return true; - } - } - - return false; + return dissolve().contains(stack.getItemHolder()); } public TagKey getTag() { @@ -97,6 +85,13 @@ public IngredientType getType() { return NeoForgeMod.BLOCK_TAG_INGREDIENT.get(); } + @Override + public SlotDisplay display() { + return new SlotDisplay.Composite(dissolve().stream() + .map(Ingredient::displayForSingleItem) + .toList()); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/CompoundIngredient.java b/src/main/java/net/neoforged/neoforge/common/crafting/CompoundIngredient.java index e874d3e86b..f703027003 100644 --- a/src/main/java/net/neoforged/neoforge/common/crafting/CompoundIngredient.java +++ b/src/main/java/net/neoforged/neoforge/common/crafting/CompoundIngredient.java @@ -6,11 +6,13 @@ package net.neoforged.neoforge.common.crafting; import com.mojang.serialization.MapCodec; -import java.util.Arrays; import java.util.List; import java.util.stream.Stream; +import net.minecraft.core.Holder; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.display.SlotDisplay; import net.neoforged.neoforge.common.NeoForgeMod; import net.neoforged.neoforge.common.util.NeoForgeExtraCodecs; @@ -20,15 +22,13 @@ public record CompoundIngredient(List children) implements ICustomIn public CompoundIngredient { if (children.isEmpty()) { // Empty ingredients are always represented as Ingredient.EMPTY. - throw new IllegalArgumentException("Compound ingredient must have at least one child"); + throw new IllegalArgumentException("Compound ingredient must have at least one child."); } } - public static final MapCodec CODEC = NeoForgeExtraCodecs.aliasedFieldOf(Ingredient.LIST_CODEC_NONEMPTY, "children", "ingredients").xmap(CompoundIngredient::new, CompoundIngredient::children); + public static final MapCodec CODEC = NeoForgeExtraCodecs.aliasedFieldOf(Ingredient.CODEC.listOf(1, Integer.MAX_VALUE), "children", "ingredients").xmap(CompoundIngredient::new, CompoundIngredient::children); /** Creates a compound ingredient from the given list of ingredients */ public static Ingredient of(Ingredient... children) { - if (children.length == 0) - return Ingredient.EMPTY; if (children.length == 1) return children[0]; @@ -36,8 +36,8 @@ public static Ingredient of(Ingredient... children) { } @Override - public Stream getItems() { - return children.stream().flatMap(child -> Arrays.stream(child.getItems())); + public Stream> items() { + return children.stream().flatMap(child -> child.items().stream()); } @Override @@ -64,4 +64,9 @@ public boolean isSimple() { public IngredientType getType() { return NeoForgeMod.COMPOUND_INGREDIENT_TYPE.get(); } + + @Override + public SlotDisplay display() { + return new SlotDisplay.Composite(children.stream().map(Ingredient::display).toList()); + } } diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/ConditionalRecipeOutput.java b/src/main/java/net/neoforged/neoforge/common/crafting/ConditionalRecipeOutput.java index 3a7321e232..ad522261d9 100644 --- a/src/main/java/net/neoforged/neoforge/common/crafting/ConditionalRecipeOutput.java +++ b/src/main/java/net/neoforged/neoforge/common/crafting/ConditionalRecipeOutput.java @@ -8,7 +8,7 @@ import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementHolder; import net.minecraft.data.recipes.RecipeOutput; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.ResourceKey; import net.minecraft.world.item.crafting.Recipe; import net.neoforged.neoforge.common.conditions.ICondition; import org.apache.commons.lang3.ArrayUtils; @@ -35,7 +35,7 @@ public Advancement.Builder advancement() { } @Override - public void accept(ResourceLocation id, Recipe recipe, @Nullable AdvancementHolder advancement, ICondition... conditions) { + public void accept(ResourceKey> id, Recipe recipe, @Nullable AdvancementHolder advancement, ICondition... conditions) { ICondition[] innerConditions; if (conditions.length == 0) { innerConditions = this.conditions; @@ -46,4 +46,9 @@ public void accept(ResourceLocation id, Recipe recipe, @Nullable AdvancementH } inner.accept(id, recipe, advancement, innerConditions); } + + @Override + public void includeRootAdvancement() { + inner.includeRootAdvancement(); + } } diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/CraftingHelper.java b/src/main/java/net/neoforged/neoforge/common/crafting/CraftingHelper.java deleted file mode 100644 index e89e548098..0000000000 --- a/src/main/java/net/neoforged/neoforge/common/crafting/CraftingHelper.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.common.crafting; - -import com.mojang.datafixers.util.Either; -import com.mojang.serialization.Codec; -import com.mojang.serialization.DataResult; -import com.mojang.serialization.MapCodec; -import java.util.stream.Stream; -import net.minecraft.world.item.crafting.Ingredient; -import net.neoforged.neoforge.common.util.NeoForgeExtraCodecs; -import net.neoforged.neoforge.registries.NeoForgeRegistries; -import org.jetbrains.annotations.ApiStatus; - -@ApiStatus.Internal -public class CraftingHelper { - public static Codec makeIngredientCodec(boolean allowEmpty) { - var listCodec = Codec.lazyInitialized(() -> allowEmpty ? Ingredient.LIST_CODEC : Ingredient.LIST_CODEC_NONEMPTY); - return Codec.either(listCodec, makeIngredientMapCodec().codec()) - .xmap(either -> either.map(list -> { - // Use CompoundIngredient.of(...) to convert empty ingredients to Ingredient.EMPTY - return CompoundIngredient.of(list.toArray(Ingredient[]::new)); - }, i -> i), ingredient -> { - if (ingredient.isCustom()) { - if (ingredient.getCustomIngredient() instanceof CompoundIngredient compound) { - // Use [] syntax for CompoundIngredients. - return Either.left(compound.children()); - } - } else if (ingredient.getValues().length != 1) { - // Use [] syntax for vanilla ingredients that either 0 or 2+ values. - return Either.left(Stream.of(ingredient.getValues()).map(v -> Ingredient.fromValues(Stream.of(v))).toList()); - } - // Else use {} syntax. - return Either.right(ingredient); - }); - } - - public static MapCodec makeIngredientMapCodec() { - // Dispatch codec for custom ingredient types, else fallback to vanilla ingredient codec. - return NeoForgeExtraCodecs., ICustomIngredient, Ingredient.Value>dispatchMapOrElse( - NeoForgeRegistries.INGREDIENT_TYPES.byNameCodec(), - ICustomIngredient::getType, - IngredientType::codec, - Ingredient.Value.MAP_CODEC) - .xmap(either -> either.map(ICustomIngredient::toVanilla, v -> Ingredient.fromValues(Stream.of(v))), ingredient -> { - if (!ingredient.isCustom()) { - var values = ingredient.getValues(); - if (values.length == 1) { - return Either.right(values[0]); - } - // Convert vanilla ingredients with 2+ values to a CompoundIngredient. Empty ingredients are not allowed here. - return Either.left(new CompoundIngredient(Stream.of(ingredient.getValues()).map(v -> Ingredient.fromValues(Stream.of(v))).toList())); - } - return Either.left(ingredient.getCustomIngredient()); - }) - .validate(ingredient -> { - if (!ingredient.isCustom() && ingredient.getValues().length == 0) { - return DataResult.error(() -> "Cannot serialize empty ingredient using the map codec"); - } - return DataResult.success(ingredient); - }); - } -} diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/CustomDisplayIngredient.java b/src/main/java/net/neoforged/neoforge/common/crafting/CustomDisplayIngredient.java new file mode 100644 index 0000000000..2c88c2fa13 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/common/crafting/CustomDisplayIngredient.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.common.crafting; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import java.util.stream.Stream; +import net.minecraft.core.Holder; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.display.SlotDisplay; +import net.neoforged.neoforge.common.NeoForgeMod; + +/** + * Ingredient that wraps another ingredient to override its {@link SlotDisplay}. + */ +public record CustomDisplayIngredient(Ingredient base, SlotDisplay display) implements ICustomIngredient { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( + instance -> instance + .group( + Ingredient.CODEC.fieldOf("base").forGetter(CustomDisplayIngredient::base), + SlotDisplay.CODEC.fieldOf("display").forGetter(CustomDisplayIngredient::display)) + .apply(instance, CustomDisplayIngredient::new)); + + public static Ingredient of(Ingredient base, SlotDisplay display) { + return new CustomDisplayIngredient(base, display).toVanilla(); + } + + @Override + public boolean test(ItemStack stack) { + return base.test(stack); + } + + @Override + public Stream> items() { + return base.items().stream(); + } + + @Override + public boolean isSimple() { + return base.isSimple(); + } + + @Override + public IngredientType getType() { + return NeoForgeMod.CUSTOM_DISPLAY_INGREDIENT.get(); + } +} diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/DataComponentIngredient.java b/src/main/java/net/neoforged/neoforge/common/crafting/DataComponentIngredient.java index 7d8951e751..b83d5c32ae 100644 --- a/src/main/java/net/neoforged/neoforge/common/crafting/DataComponentIngredient.java +++ b/src/main/java/net/neoforged/neoforge/common/crafting/DataComponentIngredient.java @@ -22,6 +22,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.display.SlotDisplay; import net.minecraft.world.level.ItemLike; import net.neoforged.neoforge.common.NeoForgeMod; @@ -35,7 +36,7 @@ public class DataComponentIngredient implements ICustomIngredient { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( builder -> builder .group( - HolderSetCodec.create(Registries.ITEM, BuiltInRegistries.ITEM.holderByNameCodec(), false).fieldOf("items").forGetter(DataComponentIngredient::items), + HolderSetCodec.create(Registries.ITEM, BuiltInRegistries.ITEM.holderByNameCodec(), false).fieldOf("items").forGetter(DataComponentIngredient::itemSet), DataComponentPredicate.CODEC.fieldOf("components").forGetter(DataComponentIngredient::components), Codec.BOOL.optionalFieldOf("strict", false).forGetter(DataComponentIngredient::isStrict)) .apply(builder, DataComponentIngredient::new)); @@ -67,8 +68,8 @@ public boolean test(ItemStack stack) { } @Override - public Stream getItems() { - return Stream.of(stacks); + public Stream> items() { + return items.stream(); } @Override @@ -81,7 +82,23 @@ public IngredientType getType() { return NeoForgeMod.DATA_COMPONENT_INGREDIENT_TYPE.get(); } - public HolderSet items() { + @Override + public SlotDisplay display() { + return new SlotDisplay.Composite(Stream.of(stacks) + .map(stack -> { + SlotDisplay display = new SlotDisplay.ItemStackSlotDisplay(stack); + ItemStack remainder = stack.getCraftingRemainder(); + if (!remainder.isEmpty()) { + SlotDisplay remainderDisplay = new SlotDisplay.ItemStackSlotDisplay(remainder); + return new SlotDisplay.WithRemainder(display, remainderDisplay); + } else { + return display; + } + }) + .toList()); + } + + public HolderSet itemSet() { return items; } diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/DifferenceIngredient.java b/src/main/java/net/neoforged/neoforge/common/crafting/DifferenceIngredient.java index 2fed470d18..3ce8c7d3c5 100644 --- a/src/main/java/net/neoforged/neoforge/common/crafting/DifferenceIngredient.java +++ b/src/main/java/net/neoforged/neoforge/common/crafting/DifferenceIngredient.java @@ -8,6 +8,8 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.stream.Stream; +import net.minecraft.core.Holder; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.neoforged.neoforge.common.NeoForgeMod; @@ -22,8 +24,8 @@ public record DifferenceIngredient(Ingredient base, Ingredient subtracted) imple .apply(builder, DifferenceIngredient::new)); @Override - public Stream getItems() { - return Stream.of(base.getItems()).filter(subtracted.negate()); + public Stream> items() { + return base.items().stream().filter(i -> !subtracted.test(i.value().getDefaultInstance())); } @Override diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/ICustomIngredient.java b/src/main/java/net/neoforged/neoforge/common/crafting/ICustomIngredient.java index dc213aee67..ee93d08a16 100644 --- a/src/main/java/net/neoforged/neoforge/common/crafting/ICustomIngredient.java +++ b/src/main/java/net/neoforged/neoforge/common/crafting/ICustomIngredient.java @@ -6,9 +6,11 @@ package net.neoforged.neoforge.common.crafting; import java.util.stream.Stream; +import net.minecraft.core.Holder; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.display.SlotDisplay; import net.neoforged.neoforge.registries.NeoForgeRegistries; import org.jetbrains.annotations.ApiStatus; @@ -35,21 +37,21 @@ public interface ICustomIngredient { boolean test(ItemStack stack); /** - * {@return the list of stacks that this ingredient accepts} + * {@return the list of items that this ingredient accepts} * *

The following guidelines should be followed for good compatibility: *

    - *
  • These stacks are generally used for display purposes, and need not be exhaustive or perfectly accurate.
  • - *
  • An exception is ingredients that {@linkplain #isSimple() are simple}, - * for which it is important that the returned stacks correspond exactly to all the accepted {@link Item}s.
  • - *
  • At least one stack must be returned for the ingredient not to be considered {@linkplain Ingredient#hasNoItems() accidentally empty}.
  • - *
  • The ingredient should try to return at least one stack with each accepted {@link Item}. + *
  • At least one item must be returned for the ingredient not to be considered empty. Empty ingredients invalidate the entire recipe.
  • + *
  • The ingredient should return all {@link Item}s it might possible accept. * This allows mods that inspect the ingredient to figure out which stacks it might accept.
  • + *
  • Returned items might not always be accepted by the ingredient, as an ingredient might still perform additional NBT-dependent tests.
  • + *
  • An exception is ingredients that {@linkplain #isSimple() are simple}, + * for which {@link #test testing a stack} is equivalent to testing if the item is in the returned list.
  • *
* *

Note: no caching needs to be done by the implementation, this is already handled by the ingredient itself. */ - Stream getItems(); + Stream> items(); /** * Returns whether this ingredient always requires {@linkplain #test direct stack testing}. @@ -66,6 +68,22 @@ public interface ICustomIngredient { */ IngredientType getType(); + /** + * Returns the display for this ingredient. + * + *

The display is synced to the client, and is also used to retrieve the {@link ItemStack}s that are shown to the client. + * + * @implNote The default implementation just constructs a list of stacks from {@link #items()}. + * This is generally suitable for {@link #isSimple() simple} ingredients. + * Non-simple ingredients can either override this method to provide a more customized display, + * or let data pack writers use {@link CustomDisplayIngredient} to override the display of an ingredient. + */ + default SlotDisplay display() { + return new SlotDisplay.Composite(items() + .map(Ingredient::displayForSingleItem) + .toList()); + } + /** * {@return a new {@link Ingredient} behaving as defined by this custom ingredient} */ diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/IngredientCodecs.java b/src/main/java/net/neoforged/neoforge/common/crafting/IngredientCodecs.java new file mode 100644 index 0000000000..8f174f9864 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/common/crafting/IngredientCodecs.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.common.crafting; + +import com.mojang.datafixers.util.Either; +import com.mojang.serialization.Codec; +import java.util.Optional; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.item.crafting.Ingredient; +import net.neoforged.neoforge.registries.NeoForgeRegistries; +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +public class IngredientCodecs { + public static Codec codec(Codec vanillaCodec) { + var customIngredientCodec = NeoForgeRegistries.INGREDIENT_TYPES.byNameCodec().dispatch( + "neoforge:ingredient_type", ICustomIngredient::getType, IngredientType::codec); + return Codec.xor(customIngredientCodec, vanillaCodec) + .xmap( + either -> either.map(ICustomIngredient::toVanilla, i -> i), + ingredient -> { + if (ingredient.isCustom()) { + return Either.left(ingredient.getCustomIngredient()); + } else { + return Either.right(ingredient); + } + }); + } + + private static final int CUSTOM_INGREDIENT_MARKER = -1000; + private static final StreamCodec CUSTOM_INGREDIENT_CODEC = ByteBufCodecs.registry(NeoForgeRegistries.Keys.INGREDIENT_TYPES) + .dispatch(ICustomIngredient::getType, IngredientType::streamCodec); + + public static StreamCodec streamCodec(StreamCodec vanillaCodec) { + return new StreamCodec<>() { + @Override + public Ingredient decode(RegistryFriendlyByteBuf buf) { + var readerIndex = buf.readerIndex(); + var length = buf.readVarInt(); + if (length == CUSTOM_INGREDIENT_MARKER) { + return CUSTOM_INGREDIENT_CODEC.decode(buf).toVanilla(); + } else { + buf.readerIndex(readerIndex); + return vanillaCodec.decode(buf); + } + }; + + @Override + public void encode(RegistryFriendlyByteBuf buf, Ingredient ingredient) { + if (ingredient.isCustom() && buf.getConnectionType().isNeoForge()) { + buf.writeVarInt(CUSTOM_INGREDIENT_MARKER); + CUSTOM_INGREDIENT_CODEC.encode(buf, ingredient.getCustomIngredient()); + } else { + vanillaCodec.encode(buf, ingredient); + } + } + }; + } + + public static StreamCodec> optionalStreamCodec(StreamCodec> vanillaCodec) { + return new StreamCodec<>() { + @Override + public Optional decode(RegistryFriendlyByteBuf buf) { + var readerIndex = buf.readerIndex(); + var length = buf.readVarInt(); + if (length == CUSTOM_INGREDIENT_MARKER) { + return Optional.of(CUSTOM_INGREDIENT_CODEC.decode(buf).toVanilla()); + } else { + buf.readerIndex(readerIndex); + return vanillaCodec.decode(buf); + } + } + + @Override + public void encode(RegistryFriendlyByteBuf buf, Optional ingredient) { + if (ingredient.isPresent() && ingredient.get().isCustom() && buf.getConnectionType().isNeoForge()) { + buf.writeVarInt(CUSTOM_INGREDIENT_MARKER); + CUSTOM_INGREDIENT_CODEC.encode(buf, ingredient.get().getCustomIngredient()); + } else { + vanillaCodec.encode(buf, ingredient); + } + } + }; + } +} diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/IntersectionIngredient.java b/src/main/java/net/neoforged/neoforge/common/crafting/IntersectionIngredient.java index e8830c559c..b41dc85070 100644 --- a/src/main/java/net/neoforged/neoforge/common/crafting/IntersectionIngredient.java +++ b/src/main/java/net/neoforged/neoforge/common/crafting/IntersectionIngredient.java @@ -10,6 +10,8 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Stream; +import net.minecraft.core.Holder; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.neoforged.neoforge.common.NeoForgeMod; @@ -19,13 +21,13 @@ public record IntersectionIngredient(List children) implements ICust public IntersectionIngredient { if (children.isEmpty()) { - throw new IllegalArgumentException("Cannot create an IntersectionIngredient with no children, use Ingredient.of() to create an empty ingredient"); + throw new IllegalArgumentException("Intersection ingredient must have at least one child."); } } public static final MapCodec CODEC = RecordCodecBuilder.mapCodec( builder -> builder .group( - Ingredient.LIST_CODEC_NONEMPTY.fieldOf("children").forGetter(IntersectionIngredient::children)) + Ingredient.CODEC.listOf(1, Integer.MAX_VALUE).fieldOf("children").forGetter(IntersectionIngredient::children)) .apply(builder, IntersectionIngredient::new)); /** @@ -35,8 +37,6 @@ public record IntersectionIngredient(List children) implements ICust * @return Ingredient that only matches if all the passed ingredients match */ public static Ingredient of(Ingredient... ingredients) { - if (ingredients.length == 0) - throw new IllegalArgumentException("Cannot create an IntersectionIngredient with no children, use Ingredient.of() to create an empty ingredient"); if (ingredients.length == 1) return ingredients[0]; @@ -54,10 +54,10 @@ public boolean test(ItemStack stack) { } @Override - public Stream getItems() { + public Stream> items() { return children.stream() - .flatMap(child -> Arrays.stream(child.getItems())) - .filter(this::test); + .flatMap(child -> child.items().stream()) + .filter(i -> test(i.value().getDefaultInstance())); } @Override diff --git a/src/main/java/net/neoforged/neoforge/common/crafting/SizedIngredient.java b/src/main/java/net/neoforged/neoforge/common/crafting/SizedIngredient.java index a712886557..ec241d7d9e 100644 --- a/src/main/java/net/neoforged/neoforge/common/crafting/SizedIngredient.java +++ b/src/main/java/net/neoforged/neoforge/common/crafting/SizedIngredient.java @@ -8,18 +8,14 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Objects; -import java.util.stream.Stream; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; -import net.minecraft.tags.TagKey; import net.minecraft.util.ExtraCodecs; -import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.level.ItemLike; import net.neoforged.neoforge.common.util.NeoForgeExtraCodecs; -import org.jetbrains.annotations.Nullable; /** * Standard implementation for an ingredient and a count. @@ -28,38 +24,6 @@ * and provide a standard serialization format. */ public final class SizedIngredient { - /** - * The "flat" codec for {@link SizedIngredient}. - * - *

The count is serialized inline with the rest of the ingredient, for example: - * - *

{@code
-     * {
-     *     "item": "minecraft:apple",
-     *     "count": 3
-     * }
-     * }
- * - * Array ingredients are serialized using the compound ingredient type: - * - *
{@code
-     * {
-     *     "type": "neoforge:compound",
-     *     "ingredients": [
-     *         { "item": "minecraft:coal" },
-     *         { "item": "minecraft:charcoal" }
-     *     ],
-     *     "count": 2
-     * }
-     * }
- * - * See {@link Ingredient#MAP_CODEC_NONEMPTY} for details of the ingredient serialization. - */ - public static final Codec FLAT_CODEC = RecordCodecBuilder.create(instance -> instance.group( - Ingredient.MAP_CODEC_NONEMPTY.forGetter(SizedIngredient::ingredient), - NeoForgeExtraCodecs.optionalFieldAlwaysWrite(ExtraCodecs.POSITIVE_INT, "count", 1).forGetter(SizedIngredient::count)) - .apply(instance, SizedIngredient::new)); - /** * The "nested" codec for {@link SizedIngredient}. * @@ -67,15 +31,13 @@ public final class SizedIngredient { * *
{@code
      * {
-     *     "ingredient": {
-     *         "item": "minecraft:apple"
-     *     },
+     *     "ingredient": "minecraft:apple",
      *     "count": 3
      * }
      * }
*/ public static final Codec NESTED_CODEC = RecordCodecBuilder.create(instance -> instance.group( - Ingredient.CODEC_NONEMPTY.fieldOf("ingredient").forGetter(SizedIngredient::ingredient), + Ingredient.CODEC.fieldOf("ingredient").forGetter(SizedIngredient::ingredient), NeoForgeExtraCodecs.optionalFieldAlwaysWrite(ExtraCodecs.POSITIVE_INT, "count", 1).forGetter(SizedIngredient::count)) .apply(instance, SizedIngredient::new)); @@ -93,17 +55,8 @@ public static SizedIngredient of(ItemLike item, int count) { return new SizedIngredient(Ingredient.of(item), count); } - /** - * Helper method to create a simple sized ingredient that matches items in a tag. - */ - public static SizedIngredient of(TagKey tag, int count) { - return new SizedIngredient(Ingredient.of(tag), count); - } - private final Ingredient ingredient; private final int count; - @Nullable - private ItemStack[] cachedStacks; public SizedIngredient(Ingredient ingredient, int count) { if (count <= 0) { @@ -130,20 +83,6 @@ public boolean test(ItemStack stack) { return ingredient.test(stack) && stack.getCount() >= count; } - /** - * Returns a list of the stacks from this {@link #ingredient}, with an updated {@link #count}. - * - * @implNote the array is cached and should not be modified, just like {@link Ingredient#getItems()}. - */ - public ItemStack[] getItems() { - if (cachedStacks == null) { - cachedStacks = Stream.of(ingredient.getItems()) - .map(s -> s.copyWithCount(count)) - .toArray(ItemStack[]::new); - } - return cachedStacks; - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/net/neoforged/neoforge/common/data/DataMapProvider.java b/src/main/java/net/neoforged/neoforge/common/data/DataMapProvider.java index feb26716cc..4c32559074 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/DataMapProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/DataMapProvider.java @@ -60,9 +60,9 @@ protected DataMapProvider(PackOutput packOutput, CompletableFuture run(CachedOutput cache) { - gather(); - return lookupProvider.thenCompose(provider -> { + gather(provider); + final DynamicOps dynamicOps = RegistryOps.create(JsonOps.INSTANCE, provider); return CompletableFuture.allOf(this.builders.entrySet().stream().map(entry -> { @@ -83,7 +83,7 @@ private CompletableFuture generate(Path out, CachedOutput cache, Build /** * Generate data map entries. */ - protected abstract void gather(); + protected abstract void gather(HolderLookup.Provider provider); @SuppressWarnings("unchecked") public Builder builder(DataMapType type) { diff --git a/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java b/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java index c7a64d6499..196484b16a 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/LanguageProvider.java @@ -83,7 +83,7 @@ public void addItemStack(Supplier key, String name) { } public void add(ItemStack key, String name) { - add(key.getDescriptionId(), name); + add(key.getItem().getDescriptionId(), name); } /* diff --git a/src/main/java/net/neoforged/neoforge/common/data/SoundDefinitionsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/SoundDefinitionsProvider.java index d71360a998..fba916e81a 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/SoundDefinitionsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/SoundDefinitionsProvider.java @@ -145,7 +145,7 @@ protected void add(final Supplier soundEvent, final SoundDefinition * @param definition The {@link SoundDefinition} that defines the given event. */ protected void add(final SoundEvent soundEvent, final SoundDefinition definition) { - this.add(soundEvent.getLocation(), definition); + this.add(soundEvent.location(), definition); } /** diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeAdvancementProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeAdvancementProvider.java index e5fec339d6..55477b729a 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeAdvancementProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeAdvancementProvider.java @@ -9,6 +9,7 @@ import com.google.gson.JsonObject; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; +import com.mojang.serialization.DynamicOps; import com.mojang.serialization.JsonOps; import java.util.ArrayList; import java.util.List; @@ -18,6 +19,7 @@ import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.UnaryOperator; +import java.util.stream.Stream; import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementHolder; import net.minecraft.advancements.Criterion; @@ -30,12 +32,18 @@ import net.minecraft.advancements.critereon.PlayerInteractTrigger; import net.minecraft.advancements.critereon.SimpleCriterionTrigger; import net.minecraft.core.HolderLookup; +import net.minecraft.core.HolderOwner; import net.minecraft.core.HolderSet; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.data.PackOutput; import net.minecraft.data.advancements.AdvancementSubProvider; import net.minecraft.data.advancements.packs.VanillaAdvancementProvider; import net.minecraft.data.advancements.packs.VanillaHusbandryAdvancements; import net.minecraft.resources.RegistryOps; +import net.minecraft.resources.ResourceKey; +import net.minecraft.tags.ItemTags; +import net.minecraft.tags.TagKey; import net.minecraft.world.entity.monster.piglin.PiglinAi; import net.minecraft.world.item.Item; import net.minecraft.world.item.Items; @@ -66,14 +74,14 @@ private static List getVanillaAdvancementProviders(PackOut criteriaReplacers.add(replaceInteractCriteria(ItemPredicate.Builder.item().withSubPredicate(ItemAbilityPredicate.TYPE, new ItemAbilityPredicate(ItemAbilities.SHEARS_REMOVE_ARMOR)).build(), Items.SHEARS)); criteriaReplacers.add(replaceInteractCriteria(ItemPredicate.Builder.item().withSubPredicate(PiglinCurrencyItemPredicate.TYPE, PiglinCurrencyItemPredicate.INSTANCE).build(), PiglinAi.BARTERING_ITEM)); criteriaReplacers.add(replaceWearingPredicate(PiglinNeutralArmorEntityPredicate.INSTANCE, predicate -> { - if (predicate.head().filter(item -> predicateMatches(item, Items.GOLDEN_HELMET)).isPresent()) { + if (predicate.head().filter(item -> predicateMatches(item, ItemTags.PIGLIN_SAFE_ARMOR)).isPresent()) { return true; - } else if (predicate.chest().filter(item -> predicateMatches(item, Items.GOLDEN_CHESTPLATE)).isPresent()) { + } else if (predicate.chest().filter(item -> predicateMatches(item, ItemTags.PIGLIN_SAFE_ARMOR)).isPresent()) { return true; - } else if (predicate.legs().filter(item -> predicateMatches(item, Items.GOLDEN_LEGGINGS)).isPresent()) { + } else if (predicate.legs().filter(item -> predicateMatches(item, ItemTags.PIGLIN_SAFE_ARMOR)).isPresent()) { return true; } - return predicate.feet().filter(item -> predicateMatches(item, Items.GOLDEN_BOOTS)).isPresent(); + return predicate.feet().filter(item -> predicateMatches(item, ItemTags.PIGLIN_SAFE_ARMOR)).isPresent(); })); //Walk on powdered snow criteriaReplacers.add(replaceWearingPredicate(SnowBootsEntityPredicate.INSTANCE, predicate -> predicate.feet().filter(item -> predicateMatches(item, Items.LEATHER_BOOTS)).isPresent())); @@ -127,6 +135,13 @@ private static boolean predicateMatches(ItemPredicate predicate, ItemLike... tar return true; } + private static boolean predicateMatches(ItemPredicate predicate, TagKey tagKey) { + return predicate.items().orElse(HolderSet.empty()) + .unwrapKey() + .map(k -> k == tagKey) + .orElse(false); + } + private static BiFunction, HolderLookup.Provider, Criterion> replaceWearingPredicate(EntitySubPredicate subPredicate, Predicate shouldReplace) { return replacePlayerPredicate(condition -> { boolean invert = false; @@ -235,8 +250,53 @@ private static T getPrivateValue(Class clazz, @Nullable C inst, String private record NeoForgeAdvancementGenerator(AdvancementSubProvider vanillaProvider, List, HolderLookup.Provider, Criterion>> criteriaReplacers) implements AdvancementGenerator { @Override public void generate(HolderLookup.Provider registries, Consumer saver, ExistingFileHelper existingFileHelper) { - vanillaProvider.generate(registries, advancementHolder -> { - Advancement.Builder newBuilder = findAndReplaceInHolder(advancementHolder, registries); + // Warning: ugly code here. + // Wrap the registries to allow using any tag. This is used to make decoding using the codec work in `replacePlayerPredicate`. + var registriesWithAnyTag = new HolderLookup.Provider() { + @Override + public Stream>> listRegistryKeys() { + return registries.listRegistryKeys(); + } + + @Override + public Optional> lookup(ResourceKey> p_256285_) { + return registries.lookup(p_256285_); + } + + @Override + public RegistryOps createSerializationContext(DynamicOps p_326817_) { + return RegistryOps.create(p_326817_, new RegistryOps.RegistryInfoLookup() { + @Override + public Optional> lookup(ResourceKey> registry) { + var builtInRegistry = (Registry) BuiltInRegistries.REGISTRY.getValue(registry.location()); + return registries.lookup(registry) + // Need to pass the builtin registry as the holder owner to make deserialization work! + .map(lookup -> new RegistryOps.RegistryInfo<>(builtInRegistry, new HolderLookup.RegistryLookup.Delegate<>() { + @Override + public RegistryLookup parent() { + return lookup; + } + + @Override + public boolean canSerializeIn(HolderOwner p_255875_) { + return parent().canSerializeIn(p_255875_); + } + + @Override + public Optional> get(TagKey tagKey) { + var ret = Delegate.super.get(tagKey); + if (ret.isEmpty()) { + ret = Optional.of(HolderSet.emptyNamed(lookup, tagKey)); + } + return ret; + } + }, lookup.registryLifecycle())); + } + }); + } + }; + vanillaProvider.generate(registriesWithAnyTag, advancementHolder -> { + Advancement.Builder newBuilder = findAndReplaceInHolder(advancementHolder, registriesWithAnyTag); if (newBuilder != null) { newBuilder.save(saver, advancementHolder.id(), existingFileHelper); } diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java index ca4fde00ba..a1959d5aa8 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeBlockTagsProvider.java @@ -294,7 +294,7 @@ private void addColored(TagKey group, String pattern) { for (DyeColor color : DyeColor.values()) { ResourceLocation key = ResourceLocation.fromNamespaceAndPath("minecraft", pattern.replace("{color}", color.getName())); TagKey tag = getForgeTag(prefix + color.getName()); - Block block = BuiltInRegistries.BLOCK.get(key); + Block block = BuiltInRegistries.BLOCK.getValue(key); if (block == null || block == Blocks.AIR) throw new IllegalStateException("Unknown vanilla block: " + key); tag(tag).add(block); diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeDataMapsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeDataMapsProvider.java index 9e5604aa69..1dd3b1d0a8 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeDataMapsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeDataMapsProvider.java @@ -17,18 +17,21 @@ import net.minecraft.data.PackOutput; import net.minecraft.resources.ResourceKey; import net.minecraft.sounds.SoundEvent; -import net.minecraft.tags.ItemTags; +import net.minecraft.tags.TagKey; import net.minecraft.util.random.Weight; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.ai.behavior.GiveGiftToHero; import net.minecraft.world.entity.ai.behavior.WorkAtComposter; import net.minecraft.world.entity.animal.Parrot; import net.minecraft.world.entity.npc.VillagerProfession; +import net.minecraft.world.flag.FeatureFlags; import net.minecraft.world.item.HoneycombItem; import net.minecraft.world.item.Item; +import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.block.ComposterBlock; import net.minecraft.world.level.block.WeatheringCopper; import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity; +import net.minecraft.world.level.block.entity.FuelValues; import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.gameevent.vibrations.VibrationSystem; import net.minecraft.world.level.levelgen.feature.MonsterRoomFeature; @@ -51,16 +54,13 @@ public NeoForgeDataMapsProvider(PackOutput packOutput, CompletableFuture villagerCompostables = ObfuscationReflectionHelper.getPrivateValue(WorkAtComposter.class, null, "COMPOSTABLE_ITEMS"); ComposterBlock.COMPOSTABLES.forEach((item, chance) -> compostables.add(item.asItem().builtInRegistryHolder(), new Compostable(chance, villagerCompostables.contains(item.asItem())), false)); final var fuels = builder(NeoForgeDataMaps.FURNACE_FUELS); - AbstractFurnaceBlockEntity.buildFuels((value, time) -> value.ifLeft(item -> fuels.add(item.builtInRegistryHolder(), new FurnaceFuel(time), false)) - .ifRight(tag -> fuels.add(tag, new FurnaceFuel(time), false))); - // Mojang decided to use an exclusion tag for nether wood - fuels.remove(ItemTags.NON_FLAMMABLE_WOOD); + FuelValues.vanillaBurnTimes(new FuelValuesDataMapBuilder(provider, fuels), AbstractFurnaceBlockEntity.BURN_TIME_STANDARD); final var vibrationFrequencies = builder(NeoForgeDataMaps.VIBRATION_FREQUENCIES); ((Reference2IntMap>) VibrationSystem.VIBRATION_FREQUENCY_FOR_EVENT) @@ -89,4 +89,31 @@ protected void gather() { waxables.add(now.builtInRegistryHolder(), new Waxable(after), false); }); } + + private static class FuelValuesDataMapBuilder extends FuelValues.Builder { + private final Builder builder; + + public FuelValuesDataMapBuilder(HolderLookup.Provider lookupProvider, DataMapProvider.Builder builder) { + super(lookupProvider, FeatureFlags.DEFAULT_FLAGS); + this.builder = builder; + } + + @Override + public FuelValuesDataMapBuilder add(TagKey tagKey, int burnTime) { + this.builder.add(tagKey, new FurnaceFuel(burnTime), false); + return this; + } + + @Override + public FuelValuesDataMapBuilder add(ItemLike item, int burnTime) { + this.builder.add(item.asItem().builtInRegistryHolder(), new FurnaceFuel(burnTime), false); + return this; + } + + @Override + public FuelValuesDataMapBuilder remove(TagKey tagKey) { + this.builder.remove(tagKey); + return this; + } + } } diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeEntityTypeTagsProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeEntityTypeTagsProvider.java index 16a951bedd..e12f911f8f 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeEntityTypeTagsProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeEntityTypeTagsProvider.java @@ -10,6 +10,7 @@ import net.minecraft.data.PackOutput; import net.minecraft.data.tags.EntityTypeTagsProvider; import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.EntityTypeTags; import net.minecraft.world.entity.EntityType; import net.neoforged.neoforge.common.Tags; import net.neoforged.neoforge.common.data.ExistingFileHelper; @@ -23,7 +24,17 @@ public NeoForgeEntityTypeTagsProvider(PackOutput output, CompletableFuture group, String pattern) { for (DyeColor color : DyeColor.values()) { ResourceLocation key = ResourceLocation.fromNamespaceAndPath("minecraft", pattern.replace("{color}", color.getName())); TagKey tag = getForgeItemTag(prefix + color.getName()); - Item item = BuiltInRegistries.ITEM.get(key); + Item item = BuiltInRegistries.ITEM.getValue(key); if (item == null || item == Items.AIR) throw new IllegalStateException("Unknown vanilla item: " + key); tag(tag).add(item); diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeRecipeProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeRecipeProvider.java index cfbefe02f5..7a1394c489 100644 --- a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeRecipeProvider.java +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeRecipeProvider.java @@ -5,7 +5,6 @@ package net.neoforged.neoforge.common.data.internal; -import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -15,21 +14,20 @@ import java.util.concurrent.CompletableFuture; import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementHolder; +import net.minecraft.core.HolderGetter; import net.minecraft.core.HolderLookup; import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.data.CachedOutput; +import net.minecraft.core.registries.Registries; import net.minecraft.data.PackOutput; import net.minecraft.data.recipes.RecipeOutput; +import net.minecraft.data.recipes.RecipeProvider; import net.minecraft.data.recipes.packs.VanillaRecipeProvider; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.item.crafting.Ingredient.ItemValue; -import net.minecraft.world.item.crafting.Ingredient.TagValue; -import net.minecraft.world.item.crafting.Ingredient.Value; import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.ShapedRecipe; import net.minecraft.world.item.crafting.ShapedRecipePattern; @@ -43,28 +41,27 @@ import org.jetbrains.annotations.Nullable; public final class NeoForgeRecipeProvider extends VanillaRecipeProvider { - private final Map> replacements = new HashMap<>(); - private final Map specialReplacements = new HashMap<>(); - private final Set excludes = new HashSet<>(); + private final InterceptingRecipeOutput output; - public NeoForgeRecipeProvider(PackOutput packOutput, CompletableFuture provider) { - super(packOutput, provider); + private NeoForgeRecipeProvider(HolderLookup.Provider provider, InterceptingRecipeOutput output) { + super(provider, output); + this.output = output; } private void exclude(ItemLike item) { - excludes.add(BuiltInRegistries.ITEM.getKey(item.asItem())); + output.excludes.add(ResourceKey.create(Registries.RECIPE, BuiltInRegistries.ITEM.getKey(item.asItem()))); } private void exclude(String name) { - excludes.add(ResourceLocation.parse(name)); + output.excludes.add(ResourceKey.create(Registries.RECIPE, ResourceLocation.parse(name))); } private void replace(ItemLike item, TagKey tag) { - replacements.put(item.asItem(), tag); + output.replacements.put(item.asItem(), tag); } @Override - protected void buildRecipes(RecipeOutput recipeOutput) { + protected void buildRecipes() { replace(Items.STICK, Tags.Items.RODS_WOODEN); replace(Items.GOLD_INGOT, Tags.Items.INGOTS_GOLD); replace(Items.GOLD_NUGGET, Tags.Items.NUGGETS_GOLD); @@ -76,6 +73,23 @@ protected void buildRecipes(RecipeOutput recipeOutput) { replace(Items.DIAMOND, Tags.Items.GEMS_DIAMOND); replace(Items.EMERALD, Tags.Items.GEMS_EMERALD); + replace(Items.WHITE_DYE, Tags.Items.DYES_WHITE); + replace(Items.ORANGE_DYE, Tags.Items.DYES_ORANGE); + replace(Items.MAGENTA_DYE, Tags.Items.DYES_MAGENTA); + replace(Items.LIGHT_BLUE_DYE, Tags.Items.DYES_LIGHT_BLUE); + replace(Items.YELLOW_DYE, Tags.Items.DYES_YELLOW); + replace(Items.LIME_DYE, Tags.Items.DYES_LIME); + replace(Items.PINK_DYE, Tags.Items.DYES_PINK); + replace(Items.GRAY_DYE, Tags.Items.DYES_GRAY); + replace(Items.LIGHT_GRAY_DYE, Tags.Items.DYES_LIGHT_GRAY); + replace(Items.CYAN_DYE, Tags.Items.DYES_CYAN); + replace(Items.PURPLE_DYE, Tags.Items.DYES_PURPLE); + replace(Items.BLUE_DYE, Tags.Items.DYES_BLUE); + replace(Items.BROWN_DYE, Tags.Items.DYES_BROWN); + replace(Items.GREEN_DYE, Tags.Items.DYES_GREEN); + replace(Items.RED_DYE, Tags.Items.DYES_RED); + replace(Items.BLACK_DYE, Tags.Items.DYES_BLACK); + replace(Blocks.COBBLESTONE, Tags.Items.COBBLESTONES_NORMAL); replace(Blocks.COBBLED_DEEPSLATE, Tags.Items.COBBLESTONES_DEEPSLATE); @@ -99,97 +113,123 @@ protected void buildRecipes(RecipeOutput recipeOutput) { exclude(Blocks.COBBLED_DEEPSLATE_SLAB); exclude(Blocks.COBBLED_DEEPSLATE_WALL); - specialReplacements.put(Items.CHEST, DifferenceIngredient.of(Ingredient.of(Tags.Items.CHESTS_WOODEN), Ingredient.of(Tags.Items.CHESTS_TRAPPED))); - - super.buildRecipes(new RecipeOutput() { - @Override - public void accept(ResourceLocation id, Recipe recipe, @Nullable AdvancementHolder advancement, ICondition... conditions) { - Recipe modified = enhance(id, recipe); - if (modified != null) - recipeOutput.accept(id, modified, null, conditions); - } + output.specialReplacements.put(Items.CHEST, DifferenceIngredient.of(tag(Tags.Items.CHESTS_WOODEN), tag(Tags.Items.CHESTS_TRAPPED))); - @Override - public Advancement.Builder advancement() { - return recipeOutput.advancement(); - } - }); + super.buildRecipes(); } - @Nullable - private Recipe enhance(ResourceLocation id, Recipe vanilla) { - if (vanilla instanceof ShapelessRecipe shapeless) - return enhance(id, shapeless); - if (vanilla instanceof ShapedRecipe shaped) - return enhance(id, shaped); - return null; - } + private static class InterceptingRecipeOutput implements RecipeOutput { + private final HolderGetter items; + private final RecipeOutput output; + private final Map> replacements = new HashMap<>(); + private final Map specialReplacements = new HashMap<>(); + private final Set>> excludes = new HashSet<>(); - @Nullable - private ShapelessRecipe enhance(ResourceLocation id, ShapelessRecipe vanilla) { - List ingredients = vanilla.getIngredients(); - boolean modified = false; - for (int x = 0; x < ingredients.size(); x++) { - Ingredient ing = enhance(id, ingredients.get(x)); - if (ing != null) { - ingredients.set(x, ing); - modified = true; - } + private InterceptingRecipeOutput(HolderGetter items, RecipeOutput output) { + this.items = items; + this.output = output; } - return modified ? vanilla : null; - } - @Override - protected CompletableFuture buildAdvancement(CachedOutput p_253674_, HolderLookup.Provider p_323646_, AdvancementHolder p_301116_) { - // NOOP - We don't replace any of the advancement things yet... - return CompletableFuture.allOf(); - } + @Override + public Advancement.Builder advancement() { + return output.advancement(); + } - @Nullable - private ShapedRecipe enhance(ResourceLocation id, ShapedRecipe vanilla) { - ShapedRecipePattern pattern = ObfuscationReflectionHelper.getPrivateValue(ShapedRecipe.class, vanilla, "pattern"); - if (pattern == null) throw new IllegalStateException(ShapedRecipe.class.getName() + " has no field pattern"); - ShapedRecipePattern.Data data = ((Optional) ObfuscationReflectionHelper.getPrivateValue(ShapedRecipePattern.class, pattern, "data")).orElseThrow(() -> new IllegalArgumentException("recipe " + id + " does not have pattern data")); - Map ingredients = data.key(); - boolean modified = false; - for (Character x : ingredients.keySet()) { - Ingredient ing = enhance(id, ingredients.get(x)); - if (ing != null) { - ingredients.put(x, ing); - modified = true; - } + @Override + public void includeRootAdvancement() { + // Let's not + } + + @Override + public void accept(ResourceKey> id, Recipe recipe, @Nullable AdvancementHolder advancement, ICondition... conditions) { + Recipe modified = enhance(id, recipe); + if (modified != null) + output.accept(id, modified, null, conditions); } - return modified ? vanilla : null; - } - @Nullable - private Ingredient enhance(ResourceLocation name, Ingredient vanilla) { - if (excludes.contains(name)) + @Nullable + private Recipe enhance(ResourceKey> id, Recipe vanilla) { + if (vanilla instanceof ShapelessRecipe shapeless) + return enhance(id, shapeless); + if (vanilla instanceof ShapedRecipe shaped) + return enhance(id, shaped); return null; + } - boolean modified = false; - List items = new ArrayList<>(); - Value[] vanillaItems = vanilla.getValues(); - if (vanillaItems.length == 1 && vanillaItems[0] instanceof ItemValue itemValue) { - Item item = itemValue.item().getItem(); - Ingredient replacement = specialReplacements.get(item); - if (replacement != null) { - return replacement; + @Nullable + private ShapelessRecipe enhance(ResourceKey> id, ShapelessRecipe vanilla) { + List ingredients = ObfuscationReflectionHelper.getPrivateValue(ShapelessRecipe.class, vanilla, "ingredients"); + boolean modified = false; + for (int x = 0; x < ingredients.size(); x++) { + Ingredient ing = enhance(id, ingredients.get(x)); + if (ing != null) { + ingredients.set(x, ing); + modified = true; + } } + return modified ? vanilla : null; } - for (Value entry : vanillaItems) { - if (entry instanceof ItemValue) { - ItemStack stack = entry.getItems().stream().findFirst().orElse(ItemStack.EMPTY); - TagKey replacement = replacements.get(stack.getItem()); - if (replacement != null) { - items.add(new TagValue(replacement)); + @Nullable + private ShapedRecipe enhance(ResourceKey> id, ShapedRecipe vanilla) { + ShapedRecipePattern pattern = ObfuscationReflectionHelper.getPrivateValue(ShapedRecipe.class, vanilla, "pattern"); + if (pattern == null) throw new IllegalStateException(ShapedRecipe.class.getName() + " has no field pattern"); + ShapedRecipePattern.Data data = ((Optional) ObfuscationReflectionHelper.getPrivateValue(ShapedRecipePattern.class, pattern, "data")).orElseThrow(() -> new IllegalArgumentException("recipe " + id + " does not have pattern data")); + Map ingredients = data.key(); + boolean modified = false; + for (Character x : ingredients.keySet()) { + Ingredient ing = enhance(id, ingredients.get(x)); + if (ing != null) { + ingredients.put(x, ing); modified = true; - } else - items.add(entry); - } else - items.add(entry); + } + } + return modified ? vanilla : null; + } + + @Nullable + private Ingredient enhance(ResourceKey> name, Ingredient vanilla) { + if (excludes.contains(name)) + return null; + + return vanilla.getValues().unwrap().map( + tagKey -> null, + items -> { + if (items.size() == 1) { + var specialReplacement = specialReplacements.get(items.getFirst().value()); + if (specialReplacement != null) { + return specialReplacement; + } + + var replacement = replacements.get(items.getFirst().value()); + if (replacement != null) { + return Ingredient.of(this.items.getOrThrow(replacement)); + } + } + + for (var holder : items) { + if (replacements.containsKey(holder.value())) { + throw new IllegalArgumentException("Cannot replace '%s' which is part of a multi-item ingredient.".formatted(holder.value())); + } + } + return null; + }); + } + } + + public static final class Runner extends RecipeProvider.Runner { + public Runner(PackOutput output, CompletableFuture lookupProvider) { + super(output, lookupProvider); + } + + @Override + protected RecipeProvider createRecipeProvider(HolderLookup.Provider lookupProvider, RecipeOutput output) { + return new NeoForgeRecipeProvider(lookupProvider, new InterceptingRecipeOutput(lookupProvider.lookupOrThrow(Registries.ITEM), output)); + } + + @Override + public String getName() { + return "NeoForge recipes"; } - return modified ? Ingredient.fromValues(items.stream()) : null; } } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IBoatExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IAbstractBoatExtension.java similarity index 83% rename from src/main/java/net/neoforged/neoforge/common/extensions/IBoatExtension.java rename to src/main/java/net/neoforged/neoforge/common/extensions/IAbstractBoatExtension.java index f3b90e3937..b7b896d1fc 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IBoatExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IAbstractBoatExtension.java @@ -5,13 +5,13 @@ package net.neoforged.neoforge.common.extensions; -import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.entity.vehicle.AbstractBoat; import net.minecraft.world.level.material.FluidState; import net.neoforged.neoforge.fluids.FluidType; -public interface IBoatExtension { - private Boat self() { - return (Boat) this; +public interface IAbstractBoatExtension { + private AbstractBoat self() { + return (AbstractBoat) this; } /** diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IAbstractMinecartExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IAbstractMinecartExtension.java deleted file mode 100644 index fa1f2f3644..0000000000 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IAbstractMinecartExtension.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.common.extensions; - -import net.minecraft.core.BlockPos; -import net.minecraft.tags.BlockTags; -import net.minecraft.util.Mth; -import net.minecraft.world.entity.vehicle.AbstractMinecart; - -public interface IAbstractMinecartExtension { - public static float DEFAULT_MAX_SPEED_AIR_LATERAL = 0.4f; - public static float DEFAULT_MAX_SPEED_AIR_VERTICAL = -1.0f; - public static double DEFAULT_AIR_DRAG = 0.95f; - - private AbstractMinecart self() { - return (AbstractMinecart) this; - } - - /** - * Internal, returns the current spot to look for the attached rail. - */ - default BlockPos getCurrentRailPosition() { - int x = Mth.floor(self().getX()); - int y = Mth.floor(self().getY()); - int z = Mth.floor(self().getZ()); - BlockPos pos = new BlockPos(x, y, z); - if (self().level().getBlockState(pos.below()).is(BlockTags.RAILS)) pos = pos.below(); - return pos; - } - - double getMaxSpeedWithRail(); - - /** - * Moved to allow overrides. - * This code handles minecart movement and speed capping when on a rail. - */ - void moveMinecartOnRail(BlockPos pos); - - /** - * Returns true if this cart can currently use rails. - * This function is mainly used to gracefully detach a minecart from a rail. - * - * @return True if the minecart can use rails. - */ - boolean canUseRail(); - - /** - * Set whether the minecart can use rails. - * This function is mainly used to gracefully detach a minecart from a rail. - * - * @param use Whether the minecart can currently use rails. - */ - void setCanUseRail(boolean use); - - /** - * Return false if this cart should not call onMinecartPass() and should ignore Powered Rails. - * - * @return True if this cart should call onMinecartPass(). - */ - default boolean shouldDoRailFunctions() { - return true; - } - - /** - * Returns true if this cart is self propelled. - * - * @return True if powered. - */ - default boolean isPoweredCart() { - return self().getMinecartType() == AbstractMinecart.Type.FURNACE; - } - - /** - * Returns true if this cart can be ridden by an Entity. - * - * @return True if this cart can be ridden. - */ - default boolean canBeRidden() { - return self().getMinecartType() == AbstractMinecart.Type.RIDEABLE; - } - - /** - * Returns the carts max speed when traveling on rails. Carts going faster - * than 1.1 cause issues with chunk loading. Carts cant traverse slopes or - * corners at greater than 0.5 - 0.6. This value is compared with the rails - * max speed and the carts current speed cap to determine the carts current - * max speed. A normal rail's max speed is 0.4. - * - * @return Carts max speed. - */ - default float getMaxCartSpeedOnRail() { - return 1.2f; - } - - /** - * Returns the current speed cap for the cart when traveling on rails. This - * functions differs from getMaxCartSpeedOnRail() in that it controls - * current movement and cannot be overridden. The value however can never be - * higher than getMaxCartSpeedOnRail(). - */ - float getCurrentCartSpeedCapOnRail(); - - void setCurrentCartSpeedCapOnRail(float value); - - float getMaxSpeedAirLateral(); - - void setMaxSpeedAirLateral(float value); - - float getMaxSpeedAirVertical(); - - void setMaxSpeedAirVertical(float value); - - double getDragAir(); - - void setDragAir(double value); - - default double getSlopeAdjustment() { - return 0.0078125D; - } - - /** - * Called from Detector Rails to retrieve a redstone power level for comparators. - */ - default int getComparatorLevel() { - return -1; - } -} diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockAndTintGetterExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockAndTintGetterExtension.java index c177f3b878..b6bcf97ab8 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockAndTintGetterExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockAndTintGetterExtension.java @@ -21,6 +21,6 @@ private BlockAndTintGetter self() { * Alternate version of the vanilla method taking in a {@link Direction}. */ default float getShade(float normalX, float normalY, float normalZ, boolean shade) { - return self().getShade(Direction.getNearest(normalX, normalY, normalZ), shade); + return self().getShade(Direction.getApproximateNearest(normalX, normalY, normalZ), shade); } } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockEntityExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockEntityExtension.java index c76d91ab7d..4dfa896b19 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockEntityExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockEntityExtension.java @@ -11,7 +11,6 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.network.Connection; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; -import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.chunk.LevelChunk; @@ -96,16 +95,6 @@ default ModelData getModelData() { return ModelData.EMPTY; } - /** - * Returns whether this {@link BlockEntity} has custom outline rendering behavior. - * - * @param player the local player currently viewing this {@code BlockEntity} - * @return {@code true} to enable outline processing - */ - default boolean hasCustomOutlineRendering(Player player) { - return false; - } - /** * Notify all listeners that the capabilities at the positions of this block entity might have changed. * This includes new capabilities becoming available. diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockExtension.java index f193bfff1e..813b8a398f 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockExtension.java @@ -723,7 +723,7 @@ default boolean canDropFromExplosion(BlockState state, BlockGetter level, BlockP * @param pos Block position in level * @param explosion The explosion instance affecting the block */ - default void onBlockExploded(BlockState state, Level level, BlockPos pos, Explosion explosion) { + default void onBlockExploded(BlockState state, ServerLevel level, BlockPos pos, Explosion explosion) { level.setBlock(pos, Blocks.AIR.defaultBlockState(), 3); self().wasExploded(level, pos, explosion); } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockStateExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockStateExtension.java index b1f5b3a2a5..3e08a8b5b0 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IBlockStateExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IBlockStateExtension.java @@ -596,7 +596,7 @@ default boolean canDropFromExplosion(BlockGetter level, BlockPos pos, Explosion * @param pos Block position in level * @param explosion The explosion instance affecting the block */ - default void onBlockExploded(Level level, BlockPos pos, Explosion explosion) { + default void onBlockExploded(ServerLevel level, BlockPos pos, Explosion explosion) { self().getBlock().onBlockExploded(self(), level, pos, explosion); } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/ICommandSourceStackExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/ICommandSourceStackExtension.java index 5cb998740a..19e3beaf23 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/ICommandSourceStackExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/ICommandSourceStackExtension.java @@ -8,9 +8,9 @@ import net.minecraft.advancements.AdvancementHolder; import net.minecraft.commands.CommandSourceStack; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.crafting.RecipeManager; import net.minecraft.world.level.Level; import net.minecraft.world.scores.Scoreboard; +import org.jetbrains.annotations.Nullable; /** * Additional methods for {@link CommandSourceStack} so that commands and arguments can access various things without directly referencing using server specific classes @@ -30,17 +30,11 @@ default Scoreboard getScoreboard() { /** * @return the advancement from the id */ + @Nullable default AdvancementHolder getAdvancement(ResourceLocation id) { return self().getServer().getAdvancements().get(id); } - /** - * @return the recipe manager - */ - default RecipeManager getRecipeManager() { - return self().getServer().getRecipeManager(); - } - /** * @return the level but without being specifically the server side level */ diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IEntityExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IEntityExtension.java index a3a2234ba4..3b495ea523 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IEntityExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IEntityExtension.java @@ -12,6 +12,7 @@ import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.entity.Entity; @@ -128,7 +129,7 @@ default boolean canBeRiddenUnderFluidType(FluidType type, Entity rider) { * @param fallDistance The fall distance * @return {@code true} if this entity can trample, {@code false} otherwise */ - boolean canTrample(BlockState state, BlockPos pos, float fallDistance); + boolean canTrample(ServerLevel level, BlockState state, BlockPos pos, float fallDistance); /** * Returns The classification of this entity diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IFluidExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IFluidExtension.java index f8749b3a8f..b2d9c49874 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IFluidExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IFluidExtension.java @@ -6,12 +6,12 @@ package net.neoforged.neoforge.common.extensions; import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.Mob; -import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.entity.vehicle.AbstractBoat; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Explosion; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; @@ -72,7 +72,7 @@ default boolean move(FluidState state, LivingEntity entity, Vec3 movementVector, * @param pos the location of the fluid * @return {@code true} if the fluid can create a source, {@code false} otherwise */ - default boolean canConvertToSource(FluidState state, Level level, BlockPos pos) { + default boolean canConvertToSource(FluidState state, ServerLevel level, BlockPos pos) { return getFluidType().canConvertToSource(state, level, pos); } @@ -83,7 +83,7 @@ default boolean canConvertToSource(FluidState state, Level level, BlockPos pos) * @param boat the boat trying to be used on the fluid * @return {@code true} if the boat can be used, {@code false} otherwise */ - default boolean supportsBoating(FluidState state, Boat boat) { + default boolean supportsBoating(FluidState state, AbstractBoat boat) { return getFluidType().supportsBoating(state, boat); } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IFluidStateExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IFluidStateExtension.java index a8082fcae7..97f9a158fc 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IFluidStateExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IFluidStateExtension.java @@ -6,12 +6,12 @@ package net.neoforged.neoforge.common.extensions; import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.Mob; -import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.entity.vehicle.AbstractBoat; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Explosion; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.pathfinder.PathType; @@ -66,7 +66,7 @@ default boolean move(LivingEntity entity, Vec3 movementVector, double gravity) { * @param pos the location of the fluid * @return {@code true} if the fluid can create a source, {@code false} otherwise */ - default boolean canConvertToSource(Level level, BlockPos pos) { + default boolean canConvertToSource(ServerLevel level, BlockPos pos) { return self().getType().canConvertToSource(self(), level, pos); } @@ -76,7 +76,7 @@ default boolean canConvertToSource(Level level, BlockPos pos) { * @param boat the boat trying to be used on the fluid * @return {@code true} if the boat can be used, {@code false} otherwise */ - default boolean supportsBoating(Boat boat) { + default boolean supportsBoating(AbstractBoat boat) { return self().getType().supportsBoating(self(), boat); } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IHolderLookupProviderExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IHolderLookupProviderExtension.java index b80b29e4e5..0c2037fed9 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IHolderLookupProviderExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IHolderLookupProviderExtension.java @@ -28,7 +28,7 @@ default Holder holderOrThrow(ResourceKey key) { * Shortcut method to get an optional holder from a ResourceKey. */ default Optional> holder(ResourceKey key) { - Optional> registry = this.self().lookup(key.registryKey()); + Optional> registry = this.self().lookup(key.registryKey()); return registry.flatMap(tRegistryLookup -> tRegistryLookup.get(key)); } } diff --git a/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java b/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java index 0ae0cb4bc3..b4cc31de7d 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java @@ -20,6 +20,8 @@ import net.minecraft.core.component.DataComponents; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.tags.ItemTags; import net.minecraft.util.Mth; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; @@ -31,15 +33,10 @@ import net.minecraft.world.entity.animal.Wolf; import net.minecraft.world.entity.animal.horse.Horse; import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.entity.monster.EnderMan; import net.minecraft.world.entity.monster.piglin.PiglinAi; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.food.FoodProperties; import net.minecraft.world.item.AnimalArmorItem; -import net.minecraft.world.item.ArmorItem; -import net.minecraft.world.item.ArmorMaterial; -import net.minecraft.world.item.ArmorMaterials; import net.minecraft.world.item.AxeItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -51,14 +48,13 @@ import net.minecraft.world.item.enchantment.Enchantment.EnchantmentDefinition; import net.minecraft.world.item.enchantment.EnchantmentInstance; import net.minecraft.world.item.enchantment.ItemEnchantments; +import net.minecraft.world.item.equipment.EquipmentModel; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.FuelValues; import net.minecraft.world.phys.AABB; import net.neoforged.neoforge.common.CommonHooks; import net.neoforged.neoforge.common.ItemAbilities; import net.neoforged.neoforge.common.ItemAbility; -import net.neoforged.neoforge.registries.datamaps.builtin.FurnaceFuel; -import net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; @@ -75,7 +71,7 @@ private Item self() { */ @SuppressWarnings("deprecation") default ItemAttributeModifiers getDefaultAttributeModifiers(ItemStack stack) { - return self().getDefaultAttributeModifiers(); + return ItemAttributeModifiers.EMPTY; } /** @@ -130,7 +126,7 @@ default boolean isPiglinCurrency(ItemStack stack) { * @return True if piglins are neutral to players wearing this item in an armor slot */ default boolean makesPiglinsNeutral(ItemStack stack, LivingEntity wearer) { - return stack.getItem() instanceof ArmorItem && ((ArmorItem) stack.getItem()).getMaterial() == ArmorMaterials.GOLD; + return stack.is(ItemTags.PIGLIN_SAFE_ARMOR); } /** @@ -154,7 +150,7 @@ default float getXpRepairRatio(ItemStack stack) { * * Note that if you break an item while using it (that is, it becomes empty without swapping the stack instance), this hook may not be called on the serverside as you are * technically still using the empty item (thus this hook is called on air instead). It is necessary to call {@link LivingEntity#stopUsingItem()} as part of your - * {@link ItemStack#hurtAndBreak(int, LivingEntity, Consumer)} callback to prevent this issue. + * {@link ItemStack#hurtAndBreak(int, ServerLevel, LivingEntity, Consumer)} callback to prevent this issue. * * For most uses, you likely want one of the following: *