diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 7b20132959e..b5719940f58 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -1,4 +1,4 @@ -Contributing to Forge +Contributing to NeoForge ===================== 1) Keep patches to Minecraft classes together. If you need a lot of things done, you may either add to relevant forge classes or make a new class. Try not to spread out your patches across multiple disjoint lines, as this makes maintenance of your patches difficult. @@ -7,14 +7,10 @@ Contributing to Forge 3) Follow the code style of the class you're working in (braces on newlines & spaces instead of tabs in Forge classes, inline brackets in patches, etc). -For more information, refer to [the wiki][Wiki]. - Contributor License Agreement ============================= -- You grant Forge a license to use your code contributed to the primary codebase (everything **not** under patches) in Forge, under the LGPLv2.1 license. -- You assign copyright ownership of your contributions to the patches codebase (everything under patches) to Forge, where it will be licensed under the LGPLv2.1 license. - -"Forge" is Forge Development LLC, a legally incorporated entity in Oregon, USA. +- You grant NeoForged a license to use your code contributed to the primary codebase (everything **not** under patches) in NeoForge, under the LGPLv2.1 license. +- You assign copyright ownership of your contributions to the patches codebase (everything under patches) to NeoForged, where it will be licensed under the LGPLv2.1 license. -[Wiki]: https://github.com/MinecraftForge/MinecraftForge/wiki/If-you-want-to-contribute-to-Forge +This is intended as a **legally binding copyright assignment** to the NeoForged project for contributions under the patches codebase. However you retain your copyright for all other contributions. diff --git a/docs/README.md b/docs/README.md index fce52b5743d..ae4d492561c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -47,7 +47,7 @@ Please ensure you have a valid email address associated with your GitHub account [CLA]: https://cla-assistant.io/neoforged/NeoForge [Crowdin]: https://crowdin.neoforged.net/neoforge -[Contributing]: ../../NeoForge/docs/CONTRIBUTING.md +[Contributing]: ../docs/CONTRIBUTING.md [Discord]: https://discord.neoforged.net/ [Documentation]: https://docs.neoforged.net/ [Download]: https://neoforged.net/ diff --git a/patches/net/minecraft/core/MappedRegistry.java.patch b/patches/net/minecraft/core/MappedRegistry.java.patch index 293b0c82b81..804bd08b05a 100644 --- a/patches/net/minecraft/core/MappedRegistry.java.patch +++ b/patches/net/minecraft/core/MappedRegistry.java.patch @@ -9,20 +9,7 @@ private static final Logger LOGGER = LogUtils.getLogger(); final ResourceKey> key; private final ObjectList> byId = new ObjectArrayList<>(256); -@@ -123,10 +_,22 @@ - } - } - -+ private static final Set KNOWN = new java.util.LinkedHashSet<>(); -+ public static Set getKnownRegistries() { -+ return java.util.Collections.unmodifiableSet(KNOWN); -+ } -+ protected final void markKnown() { -+ KNOWN.add(key().location()); -+ } -+ - public Holder.Reference registerMapping(int p_256563_, ResourceKey p_256594_, T p_256374_, Lifecycle p_256469_) { -+ markKnown(); +@@ -127,6 +_,9 @@ this.validateWrite(p_256594_); Validate.notNull(p_256594_); Validate.notNull(p_256374_); diff --git a/patches/net/minecraft/core/registries/BuiltInRegistries.java.patch b/patches/net/minecraft/core/registries/BuiltInRegistries.java.patch new file mode 100644 index 00000000000..9c3a8ba12de --- /dev/null +++ b/patches/net/minecraft/core/registries/BuiltInRegistries.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/core/registries/BuiltInRegistries.java ++++ b/net/minecraft/core/registries/BuiltInRegistries.java +@@ -346,6 +_,10 @@ + }); + } + ++ public static java.util.Set getVanillaRegistrationOrder() { ++ return java.util.Collections.unmodifiableSet(LOADERS.keySet()); ++ } ++ + @FunctionalInterface + interface RegistryBootstrap { + T run(Registry p_260128_); diff --git a/patches/net/minecraft/world/entity/LivingEntity.java.patch b/patches/net/minecraft/world/entity/LivingEntity.java.patch index 041747659c8..5c808a64656 100644 --- a/patches/net/minecraft/world/entity/LivingEntity.java.patch +++ b/patches/net/minecraft/world/entity/LivingEntity.java.patch @@ -563,7 +563,7 @@ ItemStack itemstack = this.getItemInHand(p_21159_); if (!itemstack.isEmpty() && !this.isUsingItem()) { + int duration = net.neoforged.neoforge.event.EventHooks.onItemUseStart(this, itemstack, itemstack.getUseDuration()); -+ if (duration <= 0) return; ++ if (duration < 0) return; // Neo: Early return for negative values, as that indicates event cancellation. this.useItem = itemstack; - this.useItemRemaining = itemstack.getUseDuration(); + this.useItemRemaining = duration; 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 733c3198aaa..ec57d9585b7 100644 --- a/patches/net/minecraft/world/entity/animal/horse/AbstractHorse.java.patch +++ b/patches/net/minecraft/world/entity/animal/horse/AbstractHorse.java.patch @@ -12,6 +12,19 @@ } if (this.isVehicle() && this.canGallop) { +@@ -669,6 +_,12 @@ + this.mouthAnim = 0.0F; + } + } ++ ++ // Neo: Horse armor tick patch ++ if (this.canWearArmor()) { ++ ItemStack stack = this.inventory.getItem(1); ++ if (isArmor(stack)) stack.onHorseArmorTick(level(), this); ++ } + } + + @Override @@ -802,6 +_,7 @@ this.setDeltaMovement(vec3.x, d1, vec3.z); this.setIsJumping(true); diff --git a/patches/net/minecraft/world/entity/animal/horse/Horse.java.patch b/patches/net/minecraft/world/entity/animal/horse/Horse.java.patch deleted file mode 100644 index 779070b9b1b..00000000000 --- a/patches/net/minecraft/world/entity/animal/horse/Horse.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/entity/animal/horse/Horse.java -+++ b/net/minecraft/world/entity/animal/horse/Horse.java -@@ -148,6 +_,8 @@ - if (this.random.nextInt(10) == 0) { - this.playSound(SoundEvents.HORSE_BREATHE, p_30709_.getVolume() * 0.6F, p_30709_.getPitch()); - } -+ ItemStack stack = this.inventory.getItem(1); -+ if (isArmor(stack)) stack.onHorseArmorTick(level(), this); - } - - @Override diff --git a/src/generated/resources/reports/registry_order.json b/src/generated/resources/reports/registry_order.json new file mode 100644 index 00000000000..6f99757db1e --- /dev/null +++ b/src/generated/resources/reports/registry_order.json @@ -0,0 +1,74 @@ +{ + "order": [ + "minecraft:game_event", + "minecraft:sound_event", + "minecraft:fluid", + "minecraft:mob_effect", + "minecraft:block", + "minecraft:enchantment", + "minecraft:entity_type", + "minecraft:item", + "minecraft:potion", + "minecraft:particle_type", + "minecraft:block_entity_type", + "minecraft:painting_variant", + "minecraft:custom_stat", + "minecraft:chunk_status", + "minecraft:rule_test", + "minecraft:rule_block_entity_modifier", + "minecraft:pos_rule_test", + "minecraft:menu", + "minecraft:recipe_type", + "minecraft:recipe_serializer", + "minecraft:attribute", + "minecraft:position_source_type", + "minecraft:command_argument_type", + "minecraft:stat_type", + "minecraft:villager_type", + "minecraft:villager_profession", + "minecraft:point_of_interest_type", + "minecraft:memory_module_type", + "minecraft:sensor_type", + "minecraft:schedule", + "minecraft:activity", + "minecraft:loot_pool_entry_type", + "minecraft:loot_function_type", + "minecraft:loot_condition_type", + "minecraft:loot_number_provider_type", + "minecraft:loot_nbt_provider_type", + "minecraft:loot_score_provider_type", + "minecraft:float_provider_type", + "minecraft:int_provider_type", + "minecraft:height_provider_type", + "minecraft:block_predicate_type", + "minecraft:worldgen/carver", + "minecraft:worldgen/feature", + "minecraft:worldgen/structure_placement", + "minecraft:worldgen/structure_piece", + "minecraft:worldgen/structure_type", + "minecraft:worldgen/placement_modifier_type", + "minecraft:worldgen/block_state_provider_type", + "minecraft:worldgen/foliage_placer_type", + "minecraft:worldgen/trunk_placer_type", + "minecraft:worldgen/root_placer_type", + "minecraft:worldgen/tree_decorator_type", + "minecraft:worldgen/feature_size_type", + "minecraft:worldgen/biome_source", + "minecraft:worldgen/chunk_generator", + "minecraft:worldgen/material_condition", + "minecraft:worldgen/material_rule", + "minecraft:worldgen/density_function_type", + "minecraft:block_type", + "minecraft:worldgen/structure_processor", + "minecraft:worldgen/structure_pool_element", + "minecraft:worldgen/pool_alias_binding", + "minecraft:cat_variant", + "minecraft:frog_variant", + "minecraft:banner_pattern", + "minecraft:instrument", + "minecraft:decorated_pot_patterns", + "minecraft:creative_mode_tab", + "minecraft:trigger_type", + "minecraft:number_format_type" + ] +} \ No newline at end of file diff --git a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java index bce9d6643fd..7ec1c385d7b 100644 --- a/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java +++ b/src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java @@ -118,6 +118,7 @@ import net.neoforged.neoforge.common.data.internal.NeoForgeItemTagsProvider; import net.neoforged.neoforge.common.data.internal.NeoForgeLootTableProvider; import net.neoforged.neoforge.common.data.internal.NeoForgeRecipeProvider; +import net.neoforged.neoforge.common.data.internal.NeoForgeRegistryOrderReportProvider; import net.neoforged.neoforge.common.data.internal.NeoForgeSpriteSourceProvider; import net.neoforged.neoforge.common.data.internal.VanillaSoundDefinitionsProvider; import net.neoforged.neoforge.common.extensions.IEntityExtension; @@ -642,6 +643,7 @@ public void gatherData(GatherDataEvent event) { gen.addProvider(event.includeServer(), new NeoForgeLootTableProvider(packOutput)); gen.addProvider(event.includeServer(), new NeoForgeBiomeTagsProvider(packOutput, lookupProvider, existingFileHelper)); gen.addProvider(event.includeServer(), new NeoForgeDamageTypeTagsProvider(packOutput, lookupProvider, existingFileHelper)); + gen.addProvider(event.includeServer(), new NeoForgeRegistryOrderReportProvider(packOutput)); gen.addProvider(event.includeClient(), new NeoForgeSpriteSourceProvider(packOutput, lookupProvider, existingFileHelper)); gen.addProvider(event.includeClient(), new VanillaSoundDefinitionsProvider(packOutput, existingFileHelper)); diff --git a/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeRegistryOrderReportProvider.java b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeRegistryOrderReportProvider.java new file mode 100644 index 00000000000..67bb6ade87c --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/common/data/internal/NeoForgeRegistryOrderReportProvider.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.common.data.internal; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import java.nio.file.Path; +import java.util.concurrent.CompletableFuture; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.data.CachedOutput; +import net.minecraft.data.DataProvider; +import net.minecraft.data.PackOutput; + +public final class NeoForgeRegistryOrderReportProvider implements DataProvider { + private final PackOutput output; + + public NeoForgeRegistryOrderReportProvider(PackOutput output) { + this.output = output; + } + + @Override + public CompletableFuture run(CachedOutput output) { + JsonObject json = new JsonObject(); + + JsonArray array = new JsonArray(); + BuiltInRegistries.getVanillaRegistrationOrder().forEach(name -> array.add(name.toString())); + json.add("order", array); + + Path path = this.output.getOutputFolder(PackOutput.Target.REPORTS).resolve("registry_order.json"); + return DataProvider.saveStable(output, json, path); + } + + @Override + public String getName() { + return "registry_order_report"; + } +} 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 3a168138053..f8248174c4c 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IItemExtension.java @@ -22,6 +22,8 @@ import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.Attribute; import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.animal.horse.AbstractHorse; +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; @@ -31,6 +33,7 @@ import net.minecraft.world.item.ArmorItem; import net.minecraft.world.item.ArmorMaterials; import net.minecraft.world.item.AxeItem; +import net.minecraft.world.item.HorseArmorItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; @@ -595,13 +598,16 @@ default int getBurnTime(ItemStack itemStack, @Nullable RecipeType recipeType) } /** - * Called every tick from {@code Horse#playGallopSound(SoundEvent)} on the item in the - * armor slot. + * Called every tick when this item is equipped {@linkplain AbstractHorse#isArmor(ItemStack) as an armor item} by a horse {@linkplain AbstractHorse#canWearArmor() that can wear armor}. + *

+ * In vanilla, only {@linkplain Horse horses} can wear armor, and they can only equip items that extend {@link HorseArmorItem}. * - * @param stack the armor itemstack - * @param level the level the horse is in - * @param horse the horse wearing this armor + * @param stack The armor stack + * @param level The level the horse is in + * @param horse The horse wearing this item + * @apiNote Call from {@link IItemStackExtension#onHorseArmorTick(Level, Mob)}. */ + @ApiStatus.OverrideOnly default void onHorseArmorTick(ItemStack stack, Level level, Mob horse) {} /** 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 2518e244ebb..f790d803296 100644 --- a/src/main/java/net/neoforged/neoforge/common/extensions/IItemStackExtension.java +++ b/src/main/java/net/neoforged/neoforge/common/extensions/IItemStackExtension.java @@ -17,11 +17,14 @@ import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.animal.horse.AbstractHorse; +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.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.item.HorseArmorItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.UseOnContext; @@ -275,11 +278,12 @@ default void onArmorTick(Level level, Player player) { } /** - * Called every tick from {@code Horse#playGallopSound(SoundEvent)} on the item in the - * armor slot. + * Called every tick when this item is equipped {@linkplain AbstractHorse#isArmor(ItemStack) as an armor item} by a horse {@linkplain AbstractHorse#canWearArmor() that can wear armor}. + *

+ * In vanilla, only {@linkplain Horse horses} can wear armor, and they can only equip items that extend {@link HorseArmorItem}. * - * @param level the level the horse is in - * @param horse the horse wearing this armor + * @param level The level the horse is in + * @param horse The horse wearing this item */ default void onHorseArmorTick(Level level, Mob horse) { self().getItem().onHorseArmorTick(self(), level, horse); diff --git a/src/main/java/net/neoforged/neoforge/registries/GameData.java b/src/main/java/net/neoforged/neoforge/registries/GameData.java index 1e08a6d9d3b..c4c7d8b81bc 100644 --- a/src/main/java/net/neoforged/neoforge/registries/GameData.java +++ b/src/main/java/net/neoforged/neoforge/registries/GameData.java @@ -78,7 +78,7 @@ public static void freezeData() { } public static void postRegisterEvents() { - Set ordered = new LinkedHashSet<>(MappedRegistry.getKnownRegistries()); + Set ordered = new LinkedHashSet<>(BuiltInRegistries.getVanillaRegistrationOrder()); ordered.retainAll(RegistryManager.getVanillaRegistryKeys()); ordered.addAll(BuiltInRegistries.REGISTRY.keySet().stream().sorted(ResourceLocation::compareNamespaced).toList()); diff --git a/tests/src/main/java/net/neoforged/neoforge/oldtest/world/LoginPacketSplitTest.java b/tests/src/main/java/net/neoforged/neoforge/oldtest/world/LoginPacketSplitTest.java index abefd666953..d2b4880fe91 100644 --- a/tests/src/main/java/net/neoforged/neoforge/oldtest/world/LoginPacketSplitTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/oldtest/world/LoginPacketSplitTest.java @@ -51,7 +51,6 @@ import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.common.Mod; import net.neoforged.fml.loading.FMLLoader; -import net.neoforged.fml.util.ObfuscationReflectionHelper; import net.neoforged.neoforge.client.event.RegisterClientCommandsEvent; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.event.AddPackFindersEvent; @@ -131,9 +130,6 @@ record RegistryData(Registry registry) {} final int size = buf.writerIndex(); LOG.warn("Dummy big registry size: " + size + ", or " + ((double) size / CompressionDecoder.MAXIMUM_UNCOMPRESSED_LENGTH * 100) + "% of the maximum packet size."); - - final Set known = ObfuscationReflectionHelper.getPrivateValue(MappedRegistry.class, null, "KNOWN"); - known.remove(dummyRegistry.key().location()); } private String randomString(Random random, int length) {