From 2bc9649bd66c25598552f748da11f73fb6e6547a Mon Sep 17 00:00:00 2001 From: LexManos Date: Fri, 18 Sep 2026 20:37:14 -0700 Subject: [PATCH] 26.3 - Initial update --- .github/workflows/publish.yml | 2 +- build.gradle | 61 +-- docs/README.md | 2 +- .../java/net/minecraftforge/fml/Bindings.java | 4 +- .../java/net/minecraftforge/fml/ModList.java | 2 +- fmlearlydisplay/build.gradle | 4 +- .../fml/earlydisplay/DisplayWindow.java | 402 ++++++++++-------- .../fml/earlydisplay/RenderElement.java | 14 - .../fml/common/asm/RuntimeEnumExtender.java | 2 +- .../fml/loading/ImmediateWindowHandler.java | 8 +- .../fml/loading/ImmediateWindowProvider.java | 3 +- .../FieldToMethodTransformer.java | 6 - .../coremods/finalize_spawn_targets.json | 2 +- .../net/minecraftforge/fml/common/Mod.java | 3 +- .../javafmlmod/AutomaticEventSubscriber.java | 2 +- minecraft.versions.toml | 8 +- .../blaze3d/opengl/GlTexture.java.patch | 30 -- .../blaze3d/pipeline/RenderTarget.java.patch | 14 +- .../mojang/blaze3d/platform/Window.java.patch | 42 +- .../systems/GpuDeviceBackend.java.patch | 20 - .../blaze3d/textures/GpuTexture.java.patch | 11 - .../blaze3d/vertex/PoseStack.java.patch | 2 +- .../RealmsGenericErrorScreen.java.patch | 2 +- .../api/device/GpuDevice.java.patch | 20 + .../api/textures/GpuTexture.java.patch | 11 + .../api}/vertex/VertexFormat.java.patch | 16 +- .../backend/api/GpuDeviceBackend.java.patch | 13 + .../backend/common/BaseGpuTexture.java.patch | 43 ++ .../backend/opengl/GlBackend.java.patch | 11 + .../opengl/GlCommandEncoder.java.patch | 10 +- .../backend}/opengl/GlConst.java.patch | 4 +- .../backend}/opengl/GlDebug.java.patch | 4 +- .../backend}/opengl/GlDevice.java.patch | 24 +- .../backend}/opengl/GlStateManager.java.patch | 14 +- .../backend/opengl/GlTexture.java.patch | 15 + .../backend/vulkan/VulkanDevice.java.patch | 25 ++ .../vulkan/VulkanGpuTexture.java.patch | 25 ++ .../frontend/FrontendGpuDevice.java.patch} | 25 +- .../net/minecraft/SharedConstants.java.patch | 2 +- .../advancements/Advancement.java.patch | 55 ++- .../AdvancementRewards.java.patch | 2 +- .../net/minecraft/client/Camera.java.patch | 6 +- .../minecraft/client/KeyMapping.java.patch | 4 +- .../client/KeyboardHandler.java.patch | 12 +- .../net/minecraft/client/Minecraft.java.patch | 164 ++++--- .../minecraft/client/MouseHandler.java.patch | 26 +- .../net/minecraft/client/Options.java.patch | 39 +- .../models/ItemModelGenerators.java.patch | 2 +- .../net/minecraft/client/gui/Gui.java.patch | 20 +- .../gui/GuiGraphicsExtractor.java.patch | 64 +-- .../net/minecraft/client/gui/Hud.java.patch | 18 +- .../client/gui/screens/PauseScreen.java.patch | 6 +- .../client/gui/screens/Screen.java.patch | 12 +- .../advancements/AdvancementTab.java.patch | 25 +- .../AdvancementsScreen.java.patch | 6 +- .../AbstractContainerScreen.java.patch | 30 +- .../CreativeModeInventoryScreen.java.patch | 42 +- .../HangingSignEditScreen.java.patch | 6 +- .../options/controls/KeyBindsList.java.patch | 6 +- .../controls/KeyBindsScreen.java.patch | 4 +- .../worldselection/WorldOpenFlows.java.patch | 6 +- .../client/model/HumanoidModel.java.patch | 16 +- .../model/geom/LayerDefinitions.java.patch | 6 +- .../multiplayer/ClientChunkCache.java.patch | 4 +- .../ClientCommonPacketListenerImpl.java.patch | 2 +- .../client/multiplayer/ClientLevel.java.patch | 65 ++- .../ClientPacketListener.java.patch | 20 +- .../MultiPlayerGameMode.java.patch | 45 +- .../multiplayer/chat/ChatListener.java.patch | 6 +- .../particle/FireworkParticles.java.patch | 2 +- .../particle/ParticleResources.java.patch | 4 +- .../FirstPersonHandsAndItems.java.patch | 23 + .../client/player/LocalPlayer.java.patch | 22 +- ...irstPersonHandsAndItemsRenderer.java.patch | 35 ++ .../client/renderer/GameRenderer.java.patch | 36 +- .../renderer/ItemInHandRenderer.java.patch | 57 --- .../renderer/LevelEventHandler.java.patch | 2 +- .../client/renderer/LevelRenderer.java.patch | 14 +- .../renderer/ScreenEffectRenderer.java.patch | 91 ++-- .../client/renderer/Sheets.java.patch | 2 +- .../SpriteCoordinateExpander.java.patch | 50 --- .../renderer/culling/Frustum.java.patch | 2 +- .../EntityHitboxDebugRenderer.java.patch | 2 +- .../entity/EntityRenderDispatcher.java.patch | 6 +- .../entity/HumanoidMobRenderer.java.patch | 2 +- .../entity/ItemFrameRenderer.java.patch | 6 +- .../entity/LivingEntityRenderer.java.patch | 4 +- .../entity/player/AvatarRenderer.java.patch | 26 +- .../extract/LevelExtractor.java.patch | 75 +++- .../renderer/fog/FogRenderer.java.patch | 6 +- .../rendertype/RenderTypes.java.patch | 14 +- .../state/level/PlayerRenderState.java.patch | 22 + .../texture/TextureAtlasSprite.java.patch | 4 +- .../language/ClientLanguage.java.patch | 2 +- .../language/LanguageManager.java.patch | 10 +- .../resources/model/ModelManager.java.patch | 22 +- .../cuboid/UnbakedCuboidGeometry.java.patch | 6 +- .../resources/sounds/SoundInstance.java.patch | 2 +- .../client/server/IntegratedServer.java.patch | 2 +- .../client/sounds/SoundEngine.java.patch | 20 +- .../minecraft/commands/Commands.java.patch | 8 +- .../ArgumentTypeInfos.java.patch | 2 +- .../net/minecraft/core/BlockPos.java.patch | 4 +- .../net/minecraft/core/Holder.java.patch | 2 +- .../net/minecraft/core/HolderSet.java.patch | 2 +- .../minecraft/core/MappedRegistry.java.patch | 4 +- .../core/RegistrySetBuilder.java.patch | 98 ++--- .../dispenser/DispenseItemBehavior.java.patch | 2 +- ...intAndSteelDispenseItemBehavior.java.patch | 2 +- .../registries/BuiltInRegistries.java.patch | 4 +- .../registries/PatchedRegistry.java.patch | 30 ++ .../core/registries/Registries.java.patch | 2 +- .../codec/HolderSetCodec.java.patch | 51 +++ .../net/minecraft/data/Main.java.patch | 2 +- .../AdvancementProvider.java.patch | 14 - .../data/loot/BlockLootSubProvider.java.patch | 6 +- .../loot/EntityLootSubProvider.java.patch | 10 +- .../data/loot/LootTableProvider.java.patch | 48 +-- .../data/recipes/RecipeOutput.java.patch | 23 - .../data/recipes/RecipeProvider.java.patch | 59 +-- .../packs/VanillaBrewingProvider.java.patch | 11 + .../packs/VanillaRecipeProvider.java.patch | 11 + .../RegistriesDatapackGenerator.java.patch | 60 +-- .../RegistryPatchGenerator.java.patch | 18 +- .../registries/VanillaRegistries.java.patch | 27 +- .../tags/BlockItemTagsProvider.java.patch | 2 +- .../tags/VanillaBlockTagsProvider.java.patch | 2 +- .../data/worldgen/BootstrapContext.java.patch | 9 - .../BootstrapContextAccess.java.patch | 11 + .../framework/GameTestHelper.java.patch | 8 +- .../gametest/framework/TestCommand.java.patch | 4 +- .../minecraft/network/Connection.java.patch | 24 +- .../network/FriendlyByteBuf.java.patch | 2 +- .../syncher/EntityDataSerializers.java.patch | 4 +- .../resources/HolderSetCodec.java.patch | 60 --- .../resources/RegistryDataLoader.java.patch | 27 +- .../resources/RegistryOps.java.patch | 22 +- .../resources/ResourceKey.java.patch | 6 +- ...ResourceManagerRegistryLoadTask.java.patch | 3 +- .../net/minecraft/server/Bootstrap.java.patch | 2 +- .../net/minecraft/server/Main.java.patch | 8 +- .../server/MinecraftServer.java.patch | 42 +- .../server/PlayerAdvancements.java.patch | 8 +- .../ReloadableServerResources.java.patch | 22 +- .../ServerAdvancementManager.java.patch | 10 +- .../commands/TeleportCommand.java.patch | 2 +- .../server/level/ChunkMap.java.patch | 8 +- .../server/level/ServerChunkCache.java.patch | 2 +- .../server/level/ServerEntity.java.patch | 4 +- .../server/level/ServerLevel.java.patch | 65 +-- .../server/level/ServerPlayer.java.patch | 53 ++- .../level/ServerPlayerGameMode.java.patch | 24 +- .../server/level/WorldGenRegion.java.patch | 2 +- .../ServerConnectionListener.java.patch | 8 +- .../ServerGamePacketListenerImpl.java.patch | 6 +- .../ServerLoginPacketListenerImpl.java.patch | 6 +- ... AbstractPackMetadataResources.java.patch} | 4 +- .../server/packs/PackResources.java.patch | 6 +- .../server/packs/repository/Pack.java.patch | 17 +- .../repository/ServerPacksSource.java.patch | 2 +- .../FallbackResourceManager.java.patch | 4 +- .../ReloadableResourceManager.java.patch | 2 +- ...impleJsonResourceReloadListener.java.patch | 30 +- .../server/players/PlayerList.java.patch | 28 +- .../server/rcon/RconConsoleSource.java.patch | 2 +- .../net/minecraft/tags/BiomeTags.java.patch | 2 +- .../net/minecraft/tags/BlockTags.java.patch | 2 +- .../minecraft/tags/DamageTypeTags.java.patch | 2 +- .../minecraft/tags/EntityTypeTags.java.patch | 2 +- .../net/minecraft/tags/FluidTags.java.patch | 2 +- .../net/minecraft/tags/ItemTags.java.patch | 2 +- .../minecraft/tags/StructureTags.java.patch | 2 +- .../net/minecraft/util/Util.java.patch | 2 +- .../util/context/ContextMap.java.patch | 8 +- .../EnvironmentAttributeMap.java.patch | 27 ++ .../world/clock/ServerClockManager.java.patch | 4 +- .../world/entity/ConversionTracker.java.patch | 15 + .../minecraft/world/entity/Entity.java.patch | 64 +-- .../world/entity/EntityEquipment.java.patch | 4 +- .../entity/EntityFluidInteraction.java.patch | 231 +++++----- .../world/entity/EntityType.java.patch | 42 +- .../world/entity/ExperienceOrb.java.patch | 4 +- .../world/entity/LightningBolt.java.patch | 2 +- .../world/entity/LivingEntity.java.patch | 232 ++++++---- .../net/minecraft/world/entity/Mob.java.patch | 24 +- .../world/entity/ai/behavior/Swim.java.patch | 12 +- .../world/entity/ai/goal/FloatGoal.java.patch | 6 +- .../ai/navigation/PathNavigation.java.patch | 2 +- .../world/entity/animal/Animal.java.patch | 2 +- .../entity/animal/allay/Allay.java.patch | 2 +- .../world/entity/animal/bee/Bee.java.patch | 4 +- .../entity/animal/cow/MushroomCow.java.patch | 6 +- .../animal/equine/AbstractHorse.java.patch | 10 +- .../animal/equine/SkeletonTrapGoal.java.patch | 2 +- .../entity/animal/feline/Ocelot.java.patch | 2 +- .../world/entity/animal/fox/Fox.java.patch | 4 +- .../entity/animal/golem/SnowGolem.java.patch | 2 +- .../entity/animal/rabbit/Rabbit.java.patch | 4 +- .../entity/animal/sheep/Sheep.java.patch | 2 +- .../entity/animal/sniffer/Sniffer.java.patch | 12 +- .../world/entity/animal/wolf/Wolf.java.patch | 2 +- .../boss/enderdragon/EnderDragon.java.patch | 11 +- .../decoration/HangingEntity.java.patch | 16 +- .../entity/item/FallingBlockEntity.java.patch | 4 +- .../world/entity/item/ItemEntity.java.patch | 22 +- .../monster/CrossbowAttackMob.java.patch | 2 +- .../world/entity/monster/EnderMan.java.patch | 32 +- .../world/entity/monster/Monster.java.patch | 2 +- .../world/entity/monster/Ravager.java.patch | 2 +- .../world/entity/monster/Shulker.java.patch | 10 +- .../entity/monster/Silverfish.java.patch | 2 +- .../monster/creaking/Creaking.java.patch | 2 +- .../entity/monster/hoglin/Hoglin.java.patch | 4 +- .../entity/monster/piglin/Piglin.java.patch | 4 +- .../entity/monster/piglin/PiglinAi.java.patch | 6 +- .../monster/skeleton/Skeleton.java.patch | 10 - .../entity/monster/zombie/Husk.java.patch | 10 - .../entity/monster/zombie/Zombie.java.patch | 24 +- .../entity/npc/villager/Villager.java.patch | 4 +- .../world/entity/player/Inventory.java.patch | 8 +- .../world/entity/player/Player.java.patch | 82 ++-- .../FireworkRocketEntity.java.patch | 2 +- .../entity/projectile/FishingHook.java.patch | 10 +- .../entity/projectile/Projectile.java.patch | 4 +- .../projectile/ProjectileUtil.java.patch | 2 +- .../projectile/ThrowableProjectile.java.patch | 2 +- .../projectile/arrow/AbstractArrow.java.patch | 6 +- .../ThrownEnderpearl.java.patch | 2 +- .../vehicle/boat/AbstractBoat.java.patch | 14 +- .../minecart/AbstractMinecart.java.patch | 12 +- .../minecart/MinecartSpawner.java.patch | 2 +- .../minecart/OldMinecartBehavior.java.patch | 16 +- .../AbstractContainerMenu.java.patch | 4 +- .../world/inventory/BeaconMenu.java.patch | 2 +- .../inventory/BrewingStandMenu.java.patch | 54 +-- .../world/inventory/ResultSlot.java.patch | 4 +- .../minecraft/world/item/AxeItem.java.patch | 56 --- .../minecraft/world/item/BlockItem.java.patch | 4 +- .../world/item/BoneMealItem.java.patch | 8 +- .../world/item/BucketItem.java.patch | 55 +-- .../world/item/BundleItem.java.patch | 2 +- .../world/item/CrossbowItem.java.patch | 2 +- .../minecraft/world/item/HoeItem.java.patch | 36 -- .../net/minecraft/world/item/Item.java.patch | 18 +- .../minecraft/world/item/ItemStack.java.patch | 38 +- .../net/minecraft/world/item/Items.java.patch | 4 +- .../world/item/ShovelItem.java.patch | 30 -- .../item/alchemy/PotionBrewing.java.patch | 134 ------ .../world/item/crafting/Ingredient.java.patch | 22 +- .../item/crafting/RecipeManager.java.patch | 34 -- .../world/item/crafting/RecipeType.java.patch | 2 +- .../enchantment/EnchantmentHelper.java.patch | 2 +- .../effects/ReplaceDisk.java.patch | 2 +- .../world/level/BaseSpawner.java.patch | 4 +- .../minecraft/world/level/Level.java.patch | 24 +- .../world/level/LevelReader.java.patch | 2 +- .../world/level/NaturalSpawner.java.patch | 36 +- .../world/level/biome/Biome.java.patch | 59 ++- .../biome/BiomeGenerationSettings.java.patch | 4 +- .../level/biome/MobSpawnSettings.java.patch | 35 +- .../level/block/AbstractBedBlock.java.patch | 16 + .../level/block/AttachedStemBlock.java.patch | 4 +- .../level/block/BambooStalkBlock.java.patch | 8 +- .../level/block/BaseFireBlock.java.patch | 16 +- .../level/block/BaseRailBlock.java.patch | 10 +- .../world/level/block/BeehiveBlock.java.patch | 2 +- .../world/level/block/Block.java.patch | 23 +- .../world/level/block/Blocks.java.patch | 18 +- .../world/level/block/CactusBlock.java.patch | 14 +- .../level/block/CactusFlowerBlock.java.patch | 2 +- .../level/block/CampfireBlock.java.patch | 2 +- .../world/level/block/ChestBlock.java.patch | 2 +- .../level/block/ChorusFlowerBlock.java.patch | 4 +- .../world/level/block/CocoaBlock.java.patch | 2 +- .../level/block/ComparatorBlock.java.patch | 2 +- .../block/ConcretePowderBlock.java.patch | 8 +- .../world/level/block/CoralBlock.java.patch | 2 +- .../world/level/block/CrafterBlock.java.patch | 4 +- .../world/level/block/CropBlock.java.patch | 8 +- .../level/block/DetectorRailBlock.java.patch | 6 +- .../world/level/block/DiodeBlock.java.patch | 2 +- .../level/block/DoublePlantBlock.java.patch | 2 +- .../block/DropExperienceBlock.java.patch | 2 +- .../world/level/block/DropperBlock.java.patch | 2 +- .../block/EnchantingTableBlock.java.patch | 2 +- .../level/block/FarmlandBlock.java.patch | 35 +- .../level/block/FenceGateBlock.java.patch | 13 +- .../world/level/block/FireBlock.java.patch | 18 +- .../level/block/FlowerPotBlock.java.patch | 18 +- .../block/GrowingPlantHeadBlock.java.patch | 2 +- .../world/level/block/LiquidBlock.java.patch | 23 +- .../level/block/MushroomBlock.java.patch | 4 +- .../level/block/NetherFungusBlock.java.patch | 4 +- .../level/block/NetherWartBlock.java.patch | 2 +- .../world/level/block/NoteBlock.java.patch | 6 +- .../level/block/PitcherCropBlock.java.patch | 2 +- .../level/block/PoweredRailBlock.java.patch | 19 +- .../world/level/block/PumpkinBlock.java.patch | 2 +- .../level/block/RedStoneOreBlock.java.patch | 4 +- .../level/block/RedStoneWireBlock.java.patch | 14 +- .../world/level/block/SaplingBlock.java.patch | 2 +- .../level/block/SculkCatalystBlock.java.patch | 2 +- .../level/block/SculkSensorBlock.java.patch | 2 +- .../level/block/SculkShriekerBlock.java.patch | 4 +- .../world/level/block/SoundType.java.patch | 2 +- .../world/level/block/SpawnerBlock.java.patch | 2 +- .../world/level/block/SpongeBlock.java.patch | 4 +- .../block/SpreadingSnowyBlock.java.patch | 2 +- .../world/level/block/StemBlock.java.patch | 8 +- .../level/block/SugarCaneBlock.java.patch | 12 +- .../block/SweetBerryBushBlock.java.patch | 2 +- .../world/level/block/TntBlock.java.patch | 37 +- .../level/block/TrapDoorBlock.java.patch | 2 +- .../level/block/TripWireBlock.java.patch | 2 +- .../level/block/TurtleEggBlock.java.patch | 10 +- .../level/block/VegetationBlock.java.patch | 8 +- .../world/level/block/VineBlock.java.patch | 2 +- .../AbstractFurnaceBlockEntity.java.patch | 106 +++-- .../BaseContainerBlockEntity.java.patch | 10 +- .../entity/BrewingStandBlockEntity.java.patch | 21 +- .../entity/ConduitBlockEntity.java.patch | 14 +- .../level/block/entity/FuelValues.java.patch | 33 -- .../block/entity/SignBlockEntity.java.patch | 2 +- .../entity/SpawnerBlockEntity.java.patch | 2 +- .../level/block/grower/TreeGrower.java.patch | 12 +- .../block/piston/PistonBaseBlock.java.patch | 8 +- .../piston/PistonMovingBlockEntity.java.patch | 6 +- .../block/state/BlockBehaviour.java.patch | 24 +- .../level/block/state/BlockState.java.patch | 8 +- .../level/blockscan/BlockScanUtils.java.patch | 33 ++ .../world/level/chunk/ChunkAccess.java.patch | 24 +- .../level/chunk/ChunkGenerator.java.patch | 4 +- .../level/chunk/ImposterProtoChunk.java.patch | 2 +- .../world/level/chunk/LevelChunk.java.patch | 30 +- .../chunk/status/ChunkStatusTasks.java.patch | 2 +- .../dimension/end/EnderDragonFight.java.patch | 2 +- .../level/levelgen/Beardifier.java.patch | 2 +- .../levelgen/DebugLevelSource.java.patch | 2 +- .../feature/MonsterRoomFeature.java.patch | 2 +- .../AlterGroundDecorator.java.patch | 4 +- .../trunkplacers/TrunkPlacer.java.patch | 6 +- .../levelgen/structure/Structure.java.patch | 8 +- .../structure/StructurePiece.java.patch | 2 +- .../StructureTemplate.java.patch | 14 +- .../level/material/FlowingFluid.java.patch | 6 +- .../level/material/FluidState.java.patch | 2 +- .../world/level/material/LavaFluid.java.patch | 16 +- .../level/pathfinder/PathType.java.patch | 15 +- .../pathfinder/WalkNodeEvaluator.java.patch | 8 +- .../world/level/portal/PortalShape.java.patch | 48 ++- .../level/storage/PrimaryLevelData.java.patch | 14 +- .../level/storage/loot/LootContext.java.patch | 16 +- .../level/storage/loot/LootParams.java.patch | 8 +- .../level/storage/loot/LootPool.java.patch | 81 ++-- .../level/storage/loot/LootTable.java.patch | 14 +- .../EnchantedCountIncreaseFunction.java.patch | 6 +- .../LootContextParamSets.java.patch | 10 +- ...anceWithEnchantedBonusCondition.java.patch | 4 +- server_files/args.txt | 2 +- settings.gradle | 16 +- .../loot_table/blocks/acacia_leaves.json | 129 ------ .../loot_table/blocks/azalea_leaves.json | 129 ------ .../loot_table/blocks/birch_leaves.json | 129 ------ .../minecraft/loot_table/blocks/bush.json | 41 -- .../loot_table/blocks/cherry_leaves.json | 129 ------ .../minecraft/loot_table/blocks/cobweb.json | 55 --- .../loot_table/blocks/dark_oak_leaves.json | 183 -------- .../loot_table/blocks/dead_bush.json | 43 -- .../minecraft/loot_table/blocks/fern.json | 49 --- .../blocks/flowering_azalea_leaves.json | 129 ------ .../loot_table/blocks/glow_lichen.json | 115 ----- .../loot_table/blocks/hanging_roots.json | 21 - .../loot_table/blocks/jungle_leaves.json | 130 ------ .../loot_table/blocks/large_fern.json | 126 ------ .../loot_table/blocks/mangrove_leaves.json | 76 ---- .../loot_table/blocks/nether_sprouts.json | 21 - .../loot_table/blocks/oak_leaves.json | 183 -------- .../loot_table/blocks/pale_hanging_moss.json | 41 -- .../loot_table/blocks/pale_oak_leaves.json | 129 ------ .../minecraft/loot_table/blocks/seagrass.json | 21 - .../loot_table/blocks/short_dry_grass.json | 41 -- .../loot_table/blocks/short_grass.json | 49 --- .../loot_table/blocks/small_dripleaf.json | 21 - .../loot_table/blocks/spruce_leaves.json | 129 ------ .../loot_table/blocks/tall_dry_grass.json | 41 -- .../loot_table/blocks/tall_grass.json | 126 ------ .../loot_table/blocks/tall_seagrass.json | 27 -- .../loot_table/blocks/twisting_vines.json | 62 --- .../minecraft/loot_table/blocks/vine.json | 21 - .../loot_table/blocks/weeping_vines.json | 62 --- .../minecraft/predicate/tool/can_shear.json | 4 + .../minecraft/recipe/poplar_chest_boat.json | 11 + .../data/minecraft/recipe/poplar_fence.json | 16 + .../minecraft/recipe/poplar_fence_gate.json | 16 + .../data/minecraft/recipe/poplar_sign.json | 17 + src/main/generated/pack.mcmeta | 7 +- .../client/ClientCommandHandler.java | 2 - .../client/ClientCommandSourceStack.java | 4 +- .../client/ForgeHooksClient.java | 22 +- .../client/ForgeRenderTypes.java | 16 +- .../client/FramePassManager.java | 20 +- .../client/IRenderCallback.java | 19 + .../client/event/AddFramePassEvent.java | 3 +- .../client/event/ClientChatEvent.java | 3 +- .../client/event/ClientChatReceivedEvent.java | 7 +- .../event/ClientPlayerNetworkEvent.java | 13 +- .../client/event/ComputeFovModifierEvent.java | 4 +- .../client/event/ContainerScreenEvent.java | 12 +- .../event/CustomizeGuiOverlayEvent.java | 9 +- .../client/event/ForgeEventFactoryClient.java | 4 +- .../client/event/InputEvent.java | 117 ++--- .../client/event/RecipesUpdatedEvent.java | 4 +- .../client/event/RenderArmEvent.java | 11 +- .../event/RenderBlockScreenEffectEvent.java | 119 ++++-- .../client/event/RenderGuiEvent.java | 91 ---- .../client/event/RenderGuiOverlayEvent.java | 102 ----- .../client/event/RenderHandEvent.java | 3 - .../client/event/RenderItemInFrameEvent.java | 11 +- .../client/event/RenderLivingEvent.java | 6 +- .../client/event/RenderTooltipEvent.java | 8 +- .../client/event/ScreenEvent.java | 88 ++-- .../client/event/ScreenshotEvent.java | 3 +- .../client/event/ToastAddEvent.java | 3 +- .../client/event/ViewportEvent.java | 16 +- .../event/sound/PlaySoundSourceEvent.java | 4 +- .../event/sound/PlayStreamingSourceEvent.java | 4 +- .../client/event/sound/SoundEvent.java | 9 +- .../client/extensions/IForgeGpuTexture.java | 7 - .../client/extensions/IForgePoseStack.java | 4 +- .../common/IClientBlockExtensions.java | 6 +- .../common/IClientFluidTypeExtensions.java | 11 +- .../common/IClientItemExtensions.java | 2 +- .../client/gui/LoadingErrorScreen.java | 21 +- .../client/gui/ModListScreen.java | 5 +- .../gui/ModMismatchDisconnectedScreen.java | 7 +- .../client/gui/overlay/IGuiOverlay.java | 21 - .../client/gui/widget/ForgeSlider.java | 7 +- .../client/loading/ForgeLoadingOverlay.java | 3 +- .../client/loading/NoVizFallback.java | 22 +- .../model/DynamicFluidContainerModel.java | 2 +- .../client/model/obj/ObjMaterialLibrary.java | 3 +- .../client/model/obj/ObjModel.java | 4 +- .../model/pipeline/BakedQuadBuilder.java | 12 +- .../model/pipeline/VertexConsumerWrapper.java | 6 + .../model/renderable/CompositeRenderable.java | 35 +- .../client/settings/KeyModifier.java | 5 +- .../net/minecraftforge/common/ForgeHooks.java | 20 +- .../net/minecraftforge/common/ForgeMod.java | 16 +- .../java/net/minecraftforge/common/Tags.java | 12 - .../minecraftforge/common/ToolActions.java | 60 +-- .../common/brewing/BrewingRecipe.java | 49 --- .../common/brewing/BrewingRecipeRegistry.java | 72 ---- .../common/brewing/IBrewingRecipe.java | 31 -- .../common/brewing/VanillaBrewingRecipe.java | 61 --- .../common/brewing/package-info.java | 9 - .../crafting/ConditionalAdvancement.java | 166 ++++++-- .../common/crafting/ConditionalRecipe.java | 257 ++++++----- .../crafting/conditions/ICondition.java | 6 +- .../conditions/TagEmptyCondition.java | 2 + .../ingredients/CompoundIngredient.java | 23 +- .../ingredients/DifferenceIngredient.java | 25 +- .../ingredients/IIngredientSerializer.java | 10 +- .../ingredients/IntersectionIngredient.java | 23 +- .../crafting/ingredients/NBTIngredient.java | 31 +- .../data/DatapackBuiltinEntriesProvider.java | 90 ---- .../common/data/ExistingFileHelper.java | 66 ++- .../common/data/ForgeAdvancementProvider.java | 65 --- .../common/data/ForgeLootTableProvider.java | 207 --------- .../common/data/ForgeRecipeProvider.java | 111 ++--- .../common/data/RegistryDataBuilder.java | 233 ++++++++++ .../common/extensions/IForgeBlock.java | 72 +--- .../common/extensions/IForgeBlockState.java | 36 +- .../common/extensions/IForgeItem.java | 7 +- .../common/extensions/IForgeItemStack.java | 2 +- .../extensions/IForgeRegistrySetBuilder.java | 13 +- .../common/loot/CanToolPerformAction.java | 2 +- .../common/world/BiomeModifier.java | 7 +- .../common/world/ClimateSettingsBuilder.java | 39 +- .../common/world/ForgeBiomeModifiers.java | 44 +- .../common/world/MobSpawnSettingsBuilder.java | 11 +- .../common/world/ModifiableBiomeInfo.java | 93 ++-- .../common/world/StructureModifier.java | 7 +- .../data/loading/DatagenModLoader.java | 3 +- .../event/AddPackFindersEvent.java | 18 +- .../event/AddReloadListenerEvent.java | 31 +- .../event/DifficultyChangeEvent.java | 10 +- .../event/ForgeEventFactory.java | 64 +-- .../event/PlayLevelSoundEvent.java | 8 - .../net/minecraftforge/event/TickEvent.java | 18 +- .../brewing/BrewingRecipeRegisterEvent.java | 51 --- .../event/brewing/PotionBrewEvent.java | 4 - .../event/entity/EntityEvent.java | 69 ++- .../event/entity/EntityJoinLevelEvent.java | 6 +- .../event/entity/EntityLeaveLevelEvent.java | 5 +- .../event/entity/EntityMountEvent.java | 16 +- .../event/entity/EntityTeleportEvent.java | 8 +- .../event/entity/ProjectileImpactEvent.java | 2 - .../entity/living/BabyEntitySpawnEvent.java | 7 +- .../event/entity/living/LivingEvent.java | 39 +- .../event/entity/living/LivingHealEvent.java | 19 +- .../entity/living/LivingUseTotemEvent.java | 41 +- .../event/entity/living/MobEffectEvent.java | 2 - .../event/entity/living/MobSpawnEvent.java | 14 +- .../event/entity/living/ZombieEvent.java | 7 +- .../event/entity/player/AdvancementEvent.java | 51 +-- .../event/entity/player/ArrowNockEvent.java | 8 +- .../entity/player/AttackEntityEvent.java | 15 +- .../event/entity/player/ItemFishedEvent.java | 39 +- .../event/entity/player/ItemTooltipEvent.java | 99 +---- .../player/PermissionsChangedEvent.java | 25 +- .../event/entity/player/PlayerEvent.java | 6 +- .../entity/player/PlayerFlyableFallEvent.java | 4 +- .../entity/player/PlayerInteractEvent.java | 4 +- .../entity/player/PlayerSetSpawnEvent.java | 34 +- .../entity/player/PlayerWakeUpEvent.java | 20 +- .../event/entity/player/PlayerXpEvent.java | 28 +- .../entity/player/TradeWithVillagerEvent.java | 15 +- .../event/level/AlterGroundEvent.java | 4 +- .../event/level/BlockEvent.java | 227 ++-------- .../event/level/BlockFeatureGrowEvent.java | 18 +- .../level/ChunkTicketLevelUpdatedEvent.java | 4 +- .../event/level/ChunkWatchEvent.java | 16 +- .../event/level/LevelEvent.java | 19 +- .../event/level/PistonEvent.java | 38 +- .../event/village/VillageSiegeEvent.java | 10 +- .../gametest/ForgeGameTestHooks.java | 7 + .../net/minecraftforge/gametest/GameTest.java | 2 + .../network/NetworkContext.java | 5 +- .../network/packets/ChannelVersions.java | 15 +- .../network/packets/MismatchData.java | 43 +- .../network/packets/ModVersions.java | 34 +- .../network/packets/RegistryData.java | 18 +- .../network/packets/RegistryList.java | 21 +- .../registries/DataPackRegistriesHooks.java | 51 ++- .../registries/DataPackRegistryEvent.java | 57 ++- .../registries/DeferredRegisterData.java | 6 +- .../registries/ForgeRegistries.java | 12 +- .../registries/ForgeRegistry.java | 104 ++--- .../minecraftforge/registries/GameData.java | 3 - .../registries/MissingMappingsEvent.java | 3 - .../registries/holdersets/AndHolderSet.java | 2 +- .../registries/holdersets/AnyHolderSet.java | 2 +- .../registries/holdersets/NotHolderSet.java | 4 +- .../registries/holdersets/OrHolderSet.java | 2 +- .../resource/DelegatingPackResources.java | 13 +- .../resource/ResourcePackLoader.java | 2 +- .../server/timings/ForgeTimings.java | 4 +- .../server/timings/TimeTracker.java | 2 +- .../resources/META-INF/accesstransformer.cfg | 63 +-- .../configured_feature/configured.json | 4 - .../worldgen/feature/configured.json | 3 + .../client_command_test.json | 7 - .../loot_table/blocks/test.json | 4 +- .../conditional_doesnt_load_empty.json | 66 ++- .../recipes/conditional_recipe_choice.json | 118 ++--- .../recipes/cooking_false_conditions.json | 66 ++- .../recipes/cooking_true_conditions.json | 66 ++- .../recipes/shaped_false_conditions.json | 66 ++- .../recipes/shaped_true_conditions.json | 66 ++- .../recipes/shapeless_false_conditions.json | 66 ++- .../recipes/shapeless_true_conditions.json | 66 ++- .../recipes/singe_item_true_conditions.json | 66 ++- .../recipes/single_item_false_conditions.json | 66 ++- .../tag_empty_condition_doesnt_load.json | 68 ++- .../recipes/tag_empty_condition_loads.json | 68 ++- .../recipes/test_encode_all_conditions.json | 116 +++-- .../recipe/cooking_false_conditions.json | 1 + .../recipe/cooking_true_conditions.json | 1 + .../recipes/misc/compound_ingredient.json | 2 +- .../recipes/misc/difference_ingredient.json | 2 +- .../recipes/misc/intersection_ingredient.json | 2 +- .../recipes/misc/partial_nbt_damage_only.json | 2 +- .../recipes/misc/partial_nbt_name_only.json | 2 +- .../recipes/misc/strict_nbt_ingredient.json | 2 +- .../biome_modifier/mossy_stone_modifier.json | 6 + .../worldgen/feature/mossy_stone.json | 23 + .../worldgen/placed_feature/mossy_stone.json | 27 ++ .../configured_feature/mossy_stone.json | 27 -- .../worldgen/feature/mossy_stone.json | 23 + .../loot_modifiers/bamboo_silk.json | 2 +- .../loot_modifiers/multiply_loot.json | 2 +- .../loot_modifiers/smelting.json | 2 +- .../loot_modifiers/wheat_harvest.json | 6 +- .../loot_table/blocks/test.json | 10 +- .../loot_events/loot_table/blocks/test.json | 10 +- src/test/generated/mdk_datagen/pack.mcmeta | 7 +- .../blockstates/cutout_block.json | 7 - .../blockstates/old_leaves.json | 7 - .../model_render_type/items/cutout_block.json | 6 - .../model_render_type/items/old_leaves.json | 6 - .../models/block/cutout_block.json | 8 - .../models/block/old_leaves.json | 7 - .../models/item/cutout_block.json | 6 - .../old_leaves_render_type.json | 7 - .../model_render_type/type_from_model.json | 7 - .../plant_type_placement/vegetation.json | 2 +- .../generated/test_helper_mod/pack.mcmeta | 7 +- .../debug/client/FluidBucketModelTest.java | 2 +- .../debug/client/ModelRenderLayerTest.java | 213 ---------- .../debug/client/RenderFrameLayerTest.java | 5 +- .../debug/gameplay/biome/BiomeTestMod.java | 9 +- .../gameplay/block/CrafterBlockTest.java | 9 - .../block/PlantTypePlacementTest.java | 9 +- .../crafting/ConditionalRecipeTest.java | 78 ++-- .../crafting/CustomIngredientsTest.java | 55 ++- .../criterion/BreakWithItemCriterion.java | 5 +- .../gameplay/criterion/CriterionTest.java | 81 ++-- .../DatapackBuiltinEntriesProviderTest.java | 48 +-- .../gameplay/item/PreventItemDamageTest.java | 6 +- .../debug/gameplay/level/TrySleepTest.java | 2 +- .../gameplay/loot/ConditionalLootPools.java | 34 +- .../loot/GlobalLootModifiersTest.java | 61 +-- .../debug/gameplay/loot/LootEventsTest.java | 33 +- .../net/minecraftforge/test/BaseTestMod.java | 81 ++-- 614 files changed, 5650 insertions(+), 9403 deletions(-) delete mode 100644 patches/minecraft/com/mojang/blaze3d/opengl/GlTexture.java.patch delete mode 100644 patches/minecraft/com/mojang/blaze3d/systems/GpuDeviceBackend.java.patch delete mode 100644 patches/minecraft/com/mojang/blaze3d/textures/GpuTexture.java.patch create mode 100644 patches/minecraft/com/mojang/renderpearl/api/device/GpuDevice.java.patch create mode 100644 patches/minecraft/com/mojang/renderpearl/api/textures/GpuTexture.java.patch rename patches/minecraft/com/mojang/{blaze3d => renderpearl/api}/vertex/VertexFormat.java.patch (76%) create mode 100644 patches/minecraft/com/mojang/renderpearl/backend/api/GpuDeviceBackend.java.patch create mode 100644 patches/minecraft/com/mojang/renderpearl/backend/common/BaseGpuTexture.java.patch create mode 100644 patches/minecraft/com/mojang/renderpearl/backend/opengl/GlBackend.java.patch rename patches/minecraft/com/mojang/{blaze3d => renderpearl/backend}/opengl/GlCommandEncoder.java.patch (67%) rename patches/minecraft/com/mojang/{blaze3d => renderpearl/backend}/opengl/GlConst.java.patch (93%) rename patches/minecraft/com/mojang/{blaze3d => renderpearl/backend}/opengl/GlDebug.java.patch (93%) rename patches/minecraft/com/mojang/{blaze3d => renderpearl/backend}/opengl/GlDevice.java.patch (62%) rename patches/minecraft/com/mojang/{blaze3d => renderpearl/backend}/opengl/GlStateManager.java.patch (72%) create mode 100644 patches/minecraft/com/mojang/renderpearl/backend/opengl/GlTexture.java.patch create mode 100644 patches/minecraft/com/mojang/renderpearl/backend/vulkan/VulkanDevice.java.patch create mode 100644 patches/minecraft/com/mojang/renderpearl/backend/vulkan/VulkanGpuTexture.java.patch rename patches/minecraft/com/mojang/{blaze3d/systems/GpuDevice.java.patch => renderpearl/frontend/FrontendGpuDevice.java.patch} (62%) create mode 100644 patches/minecraft/net/minecraft/client/player/FirstPersonHandsAndItems.java.patch create mode 100644 patches/minecraft/net/minecraft/client/renderer/FirstPersonHandsAndItemsRenderer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/ItemInHandRenderer.java.patch delete mode 100644 patches/minecraft/net/minecraft/client/renderer/SpriteCoordinateExpander.java.patch create mode 100644 patches/minecraft/net/minecraft/client/renderer/state/level/PlayerRenderState.java.patch create mode 100644 patches/minecraft/net/minecraft/core/registries/PatchedRegistry.java.patch create mode 100644 patches/minecraft/net/minecraft/core/registries/codec/HolderSetCodec.java.patch delete mode 100644 patches/minecraft/net/minecraft/data/advancements/AdvancementProvider.java.patch delete mode 100644 patches/minecraft/net/minecraft/data/recipes/RecipeOutput.java.patch create mode 100644 patches/minecraft/net/minecraft/data/recipes/packs/VanillaBrewingProvider.java.patch create mode 100644 patches/minecraft/net/minecraft/data/recipes/packs/VanillaRecipeProvider.java.patch delete mode 100644 patches/minecraft/net/minecraft/data/worldgen/BootstrapContext.java.patch create mode 100644 patches/minecraft/net/minecraft/data/worldgen/BootstrapContextAccess.java.patch delete mode 100644 patches/minecraft/net/minecraft/resources/HolderSetCodec.java.patch rename patches/minecraft/net/minecraft/server/packs/{AbstractPackResources.java.patch => AbstractPackMetadataResources.java.patch} (65%) create mode 100644 patches/minecraft/net/minecraft/world/attribute/EnvironmentAttributeMap.java.patch create mode 100644 patches/minecraft/net/minecraft/world/entity/ConversionTracker.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/entity/monster/skeleton/Skeleton.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/entity/monster/zombie/Husk.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/item/AxeItem.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/item/HoeItem.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/item/ShovelItem.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/item/alchemy/PotionBrewing.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/item/crafting/RecipeManager.java.patch create mode 100644 patches/minecraft/net/minecraft/world/level/block/AbstractBedBlock.java.patch delete mode 100644 patches/minecraft/net/minecraft/world/level/block/entity/FuelValues.java.patch create mode 100644 patches/minecraft/net/minecraft/world/level/blockscan/BlockScanUtils.java.patch delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/acacia_leaves.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/azalea_leaves.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/birch_leaves.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/bush.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/cherry_leaves.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/cobweb.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/dark_oak_leaves.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/dead_bush.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/fern.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/flowering_azalea_leaves.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/glow_lichen.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/hanging_roots.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/jungle_leaves.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/large_fern.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/mangrove_leaves.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/nether_sprouts.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/oak_leaves.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/pale_hanging_moss.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/pale_oak_leaves.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/seagrass.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/short_dry_grass.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/short_grass.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/small_dripleaf.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/spruce_leaves.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/tall_dry_grass.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/tall_grass.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/tall_seagrass.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/twisting_vines.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/vine.json delete mode 100644 src/main/generated/data/minecraft/loot_table/blocks/weeping_vines.json create mode 100644 src/main/generated/data/minecraft/predicate/tool/can_shear.json create mode 100644 src/main/generated/data/minecraft/recipe/poplar_chest_boat.json create mode 100644 src/main/generated/data/minecraft/recipe/poplar_fence.json create mode 100644 src/main/generated/data/minecraft/recipe/poplar_fence_gate.json create mode 100644 src/main/generated/data/minecraft/recipe/poplar_sign.json create mode 100644 src/main/java/net/minecraftforge/client/IRenderCallback.java delete mode 100644 src/main/java/net/minecraftforge/client/event/RenderGuiEvent.java delete mode 100644 src/main/java/net/minecraftforge/client/event/RenderGuiOverlayEvent.java delete mode 100644 src/main/java/net/minecraftforge/client/gui/overlay/IGuiOverlay.java delete mode 100644 src/main/java/net/minecraftforge/common/brewing/BrewingRecipe.java delete mode 100644 src/main/java/net/minecraftforge/common/brewing/BrewingRecipeRegistry.java delete mode 100644 src/main/java/net/minecraftforge/common/brewing/IBrewingRecipe.java delete mode 100644 src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java delete mode 100644 src/main/java/net/minecraftforge/common/brewing/package-info.java delete mode 100644 src/main/java/net/minecraftforge/common/data/DatapackBuiltinEntriesProvider.java delete mode 100644 src/main/java/net/minecraftforge/common/data/ForgeAdvancementProvider.java delete mode 100644 src/main/java/net/minecraftforge/common/data/ForgeLootTableProvider.java create mode 100644 src/main/java/net/minecraftforge/common/data/RegistryDataBuilder.java delete mode 100644 src/main/java/net/minecraftforge/event/brewing/BrewingRecipeRegisterEvent.java delete mode 100644 src/test/generated/biome_test/data/biome_test/worldgen/configured_feature/configured.json create mode 100644 src/test/generated/biome_test/data/biome_test/worldgen/feature/configured.json delete mode 100644 src/test/generated/client_command_test/data/forge/test_instance/client_command_test/client_command_test.json create mode 100644 src/test/generated/data/datapack_builtin_entries_provider_test/forge/biome_modifier/mossy_stone_modifier.json create mode 100644 src/test/generated/data/datapack_builtin_entries_provider_test/worldgen/feature/mossy_stone.json create mode 100644 src/test/generated/data/datapack_builtin_entries_provider_test/worldgen/placed_feature/mossy_stone.json delete mode 100644 src/test/generated/datapack_builtin_entries_provider_test/data/datapack_builtin_entries_provider_test/worldgen/configured_feature/mossy_stone.json create mode 100644 src/test/generated/datapack_builtin_entries_provider_test/data/datapack_builtin_entries_provider_test/worldgen/feature/mossy_stone.json delete mode 100644 src/test/generated/model_render_type/assets/model_render_type/blockstates/cutout_block.json delete mode 100644 src/test/generated/model_render_type/assets/model_render_type/blockstates/old_leaves.json delete mode 100644 src/test/generated/model_render_type/assets/model_render_type/items/cutout_block.json delete mode 100644 src/test/generated/model_render_type/assets/model_render_type/items/old_leaves.json delete mode 100644 src/test/generated/model_render_type/assets/model_render_type/models/block/cutout_block.json delete mode 100644 src/test/generated/model_render_type/assets/model_render_type/models/block/old_leaves.json delete mode 100644 src/test/generated/model_render_type/assets/model_render_type/models/item/cutout_block.json delete mode 100644 src/test/generated/model_render_type/data/forge/test_instance/model_render_type/old_leaves_render_type.json delete mode 100644 src/test/generated/model_render_type/data/forge/test_instance/model_render_type/type_from_model.json delete mode 100644 src/test/java/net/minecraftforge/debug/client/ModelRenderLayerTest.java diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ea7d5307b8..7fe03be73e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -2,7 +2,7 @@ name: Publish on: push: - branches: [ '26.2' ] + branches: [ '26.3' ] permissions: contents: read diff --git a/build.gradle b/build.gradle index 76f7de0ad6..762fc532af 100644 --- a/build.gradle +++ b/build.gradle @@ -29,6 +29,9 @@ jarSigner.autoDetect('forge') // We have to tell ForgeDev to use the exact versions of tools we ship in the installer fdtools { + configure('mavenizer') { + version = '0.5.22' + } configure('binpatcher') { version = buildLibs.binarypatcher.get().version } @@ -182,17 +185,12 @@ forgedev.runs { mainClass = 'net.minecraftforge.bootstrap.ForgeBootstrap' args '--gameDir', '.' - jvmArgs '-Djava.net.preferIPv6Addresses=system', '-XX:+UseCompactObjectHeaders' + jvmArgs '-Djava.net.preferIPv6Addresses=system', '-XX:+UseCompactObjectHeaders', '-XX:StackShadowPages=32' systemProperty 'bsl.debug', 'true' systemProperty 'terminal.jline', 'true' - with(sourceSets.test) { - systemProperty 'forge.enableGameTest', 'true' - systemProperty 'forgedev.enableTestMods', 'true' - } } } - create('client') { options { systemProperty 'eventbus.api.strictRuntimeChecks', 'true' @@ -206,6 +204,11 @@ forgedev.runs { '--versionType', 'release', '--assetsDir', '{assets_root}', '--assetIndex', '{asset_index}' + + with(sourceSets.test) { + systemProperty 'forge.enableGameTest', 'true' + systemProperty 'forgedev.enableTestMods', 'true' + } } } @@ -217,8 +220,13 @@ forgedev.runs { create('gameTestServer') { options { + systemProperty 'forge.enableGameTest', 'true' args '--launchTarget', 'forge_dev_server_gametest' args '--uniqueWorld' // Unique world is used so that the world regenerates, as well as the world config isn't influenced by other runs + + with(sourceSets.test) { + systemProperty 'forgedev.enableTestMods', 'true' + } } } @@ -236,6 +244,8 @@ forgedev.runs { } with(sourceSets.test) { + systemProperty 'forge.enableGameTest', 'true' + systemProperty 'forgedev.enableTestMods', 'true' args '--mod', '.+', '--existing', sourceSets.test.resources.srcDirs[0], '--output', rootProject.file('src/test/generated/') @@ -245,23 +255,20 @@ forgedev.runs { create('clientData') { options { - args '--all', - '--existing', sourceSets.main.resources.srcDirs[0], - '--assetsDir', '{assets_root}', - '--assetIndex', '{asset_index}' + args '--launchTarget', 'forge_dev_client_data', + '--all', + '--existing', sourceSets.main.resources.srcDirs[0], + '--assetsDir', '{assets_root}', + '--assetIndex', '{asset_index}' with(sourceSets.main) { - args '--launchTarget', 'forge_dev_client_data', - '--mod', 'forge', - '--output', rootProject.file('src/main/generated/'), - '--mod', 'forge' + args '--mod', 'forge', + '--output', rootProject.file('src/main/generated/') } with(sourceSets.test) { - args '--launchTarget', 'forge_dev', - '--launchEntry', 'minecraft/net.minecraft.client.data.Main', - '--launchData', - '--mod', '.+', + systemProperty 'forgedev.enableTestMods', 'true' + args '--mod', '.+', '--existing', sourceSets.test.resources.srcDirs[0], '--output', rootProject.file('src/test/generated/') } @@ -400,7 +407,7 @@ forgedev.userDev { parents = [] main = 'net.minecraftforge.bootstrap.ForgeBootstrap' args '--gameDir', '.' - jvmArgs '-Djava.net.preferIPv6Addresses=system', '-XX:+UseCompactObjectHeaders' + jvmArgs '-Djava.net.preferIPv6Addresses=system', '-XX:+UseCompactObjectHeaders', '-XX:StackShadowPages=32' client = it.name.containsIgnoreCase('client') environment 'MCP_MAPPINGS', '{mcp_mappings}' } @@ -454,8 +461,8 @@ forgedev.userdevCompatibility(minecraftVersion) { final clientBinPatches = forgedev.binaryPatches('client') { clean = minecraftFiles.client // Workaround for 3rd party launcher issues, marker needed to locate MC, store needed to fix zlib-ng issues - apply { - store = true + apply { + store = true marker = '.forge_patched_minecraft' } } @@ -595,12 +602,12 @@ forgedev.installer { inheritsFrom = minecraftVersion mainClass = 'net.minecraftforge.bootstrap.ForgeBootstrap' gameArgs = [ '--launchTarget', 'forge_client' ] - jvmArgs = [ '-Djava.net.preferIPv6Addresses=system', '-XX:+UseCompactObjectHeaders' ] + jvmArgs = [ '-Djava.net.preferIPv6Addresses=system', '-XX:+UseCompactObjectHeaders', '-XX:StackShadowPages=32' ] } } final mdkGradleWrapper = tasks.register('mdkGradleWrapper', Wrapper) { - gradleVersion = '9.5.0' + gradleVersion = '9.7.1' scriptFile = layout.buildDirectory.dir("wrapper/" + gradleVersion + "/gradlew") jarFile = layout.buildDirectory.dir("wrapper/" + gradleVersion + "/gradle/wrapper/gradle-wrapper.jar") } @@ -759,16 +766,16 @@ publishing { def all = tasks.register('all') {} afterEvaluate { if (gradle.startParameter.taskNames.contains('all')) { - tasks.forEach { task -> // This forces everything to be realized, which is why we have the startParameter check - if (!gradle.startParameter.isTaskGraph() && task.name.startsWith('run')) return + tasks.forEach { task -> // This forces everything to be realized, which is why we have the startParameter check + if (!gradle.startParameter.isTaskGraph() && task.name.startsWith('run')) return if (task.name in [all.name, 'dependencyInsight', 'dependencies', 'dependencyUpdates', 'init', 'buildEnvironment', 'idea', 'eclipse', 'javaToolchains', 'outgoingVariants', 'projects', 'properties', 'resolvableConfigurations', 'tasks', 'updateDaemonJvm', 'generateActionsWorkflow' ]) return if (task.name.startsWith('clean')) return if (task.name == 'checkJarCompatibility') return // This doesn't work in FG6 dev, I think it's cuz we check vs srg names. Will need to look at later - all.configure { dependsOn(task) } - } + all.configure { dependsOn(task) } + } } } */ diff --git a/docs/README.md b/docs/README.md index e4082e7eac..ccd1a627fa 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,7 +3,7 @@ MinecraftForge ============= [![Stable Release](https://img.shields.io/badge/dynamic/json?url=https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json&label=Stable&prefix=26.2-&query=$.promos["26.2-recommended"]&color=brightgreen&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtc3RhciBmYS13LTE4IiBhcmlhLWhpZGRlbj0idHJ1ZSIgZGF0YS1pY29uPSJzdGFyIiBkYXRhLXByZWZpeD0iZmFzIiBmb2N1c2FibGU9ImZhbHNlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCA1NzYgNTEyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNMjU5LjMgMTcuOEwxOTQgMTUwLjIgNDcuOSAxNzEuNWMtMjYuMiAzLjgtMzYuNyAzNi4xLTE3LjcgNTQuNmwxMDUuNyAxMDMtMjUgMTQ1LjVjLTQuNSAyNi4zIDIzLjIgNDYgNDYuNCAzMy43TDI4OCA0MzkuNmwxMzAuNyA2OC43YzIzLjIgMTIuMiA1MC45LTcuNCA0Ni40LTMzLjdsLTI1LTE0NS41IDEwNS43LTEwM2MxOS0xOC41IDguNS01MC44LTE3LjctNTQuNkwzODIgMTUwLjIgMzE2LjcgMTcuOGMtMTEuNy0yMy42LTQ1LjYtMjMuOS01Ny40IDB6IiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K)][Download] -[![Latest Release](https://img.shields.io/badge/dynamic/json?url=https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json&label=Latest&prefix=26.2-&query=$.promos["26.2-latest"]&color=blue&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtYnVnIGZhLXctMTYiIGFyaWEtaGlkZGVuPSJ0cnVlIiBkYXRhLWljb249ImJ1ZyIgZGF0YS1wcmVmaXg9ImZhcyIgZm9jdXNhYmxlPSJmYWxzZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTUxMS45ODggMjg4LjljLS40NzggMTcuNDMtMTUuMjE3IDMxLjEtMzIuNjUzIDMxLjFINDI0djE2YzAgMjEuODY0LTQuODgyIDQyLjU4NC0xMy42IDYxLjE0NWw2MC4yMjggNjAuMjI4YzEyLjQ5NiAxMi40OTcgMTIuNDk2IDMyLjc1OCAwIDQ1LjI1NS0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDBsLTU0LjczNi01NC43MzZDMzQ1Ljg4NiA0NjcuOTY1IDMxNC4zNTEgNDgwIDI4MCA0ODBWMjM2YzAtNi42MjctNS4zNzMtMTItMTItMTJoLTI0Yy02LjYyNyAwLTEyIDUuMzczLTEyIDEydjI0NGMtMzQuMzUxIDAtNjUuODg2LTEyLjAzNS05MC42MzYtMzIuMTA4bC01NC43MzYgNTQuNzM2Yy0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDAtMTIuNDk2LTEyLjQ5Ny0xMi40OTYtMzIuNzU4IDAtNDUuMjU1bDYwLjIyOC02MC4yMjhDOTIuODgyIDM3OC41ODQgODggMzU3Ljg2NCA4OCAzMzZ2LTE2SDMyLjY2NkMxNS4yMyAzMjAgLjQ5MSAzMDYuMzMuMDEzIDI4OC45LS40ODQgMjcwLjgxNiAxNC4wMjggMjU2IDMyIDI1Nmg1NnYtNTguNzQ1bC00Ni42MjgtNDYuNjI4Yy0xMi40OTYtMTIuNDk3LTEyLjQ5Ni0zMi43NTggMC00NS4yNTUgMTIuNDk4LTEyLjQ5NyAzMi43NTgtMTIuNDk3IDQ1LjI1NiAwTDE0MS4yNTUgMTYwaDIyOS40ODlsNTQuNjI3LTU0LjYyN2MxMi40OTgtMTIuNDk3IDMyLjc1OC0xMi40OTcgNDUuMjU2IDAgMTIuNDk2IDEyLjQ5NyAxMi40OTYgMzIuNzU4IDAgNDUuMjU1TDQyNCAxOTcuMjU1VjI1Nmg1NmMxNy45NzIgMCAzMi40ODQgMTQuODE2IDMxLjk4OCAzMi45ek0yNTcgMGMtNjEuODU2IDAtMTEyIDUwLjE0NC0xMTIgMTEyaDIyNEMzNjkgNTAuMTQ0IDMxOC44NTYgMCAyNTcgMHoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo= +[![Latest Release](https://img.shields.io/badge/dynamic/json?url=https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json&label=Latest&prefix=26.3-&query=$.promos["26.3-latest"]&color=blue&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBjbGFzcz0ic3ZnLWlubGluZS0tZmEgZmEtYnVnIGZhLXctMTYiIGFyaWEtaGlkZGVuPSJ0cnVlIiBkYXRhLWljb249ImJ1ZyIgZGF0YS1wcmVmaXg9ImZhcyIgZm9jdXNhYmxlPSJmYWxzZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTUxMS45ODggMjg4LjljLS40NzggMTcuNDMtMTUuMjE3IDMxLjEtMzIuNjUzIDMxLjFINDI0djE2YzAgMjEuODY0LTQuODgyIDQyLjU4NC0xMy42IDYxLjE0NWw2MC4yMjggNjAuMjI4YzEyLjQ5NiAxMi40OTcgMTIuNDk2IDMyLjc1OCAwIDQ1LjI1NS0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDBsLTU0LjczNi01NC43MzZDMzQ1Ljg4NiA0NjcuOTY1IDMxNC4zNTEgNDgwIDI4MCA0ODBWMjM2YzAtNi42MjctNS4zNzMtMTItMTItMTJoLTI0Yy02LjYyNyAwLTEyIDUuMzczLTEyIDEydjI0NGMtMzQuMzUxIDAtNjUuODg2LTEyLjAzNS05MC42MzYtMzIuMTA4bC01NC43MzYgNTQuNzM2Yy0xMi40OTggMTIuNDk3LTMyLjc1OSAxMi40OTYtNDUuMjU2IDAtMTIuNDk2LTEyLjQ5Ny0xMi40OTYtMzIuNzU4IDAtNDUuMjU1bDYwLjIyOC02MC4yMjhDOTIuODgyIDM3OC41ODQgODggMzU3Ljg2NCA4OCAzMzZ2LTE2SDMyLjY2NkMxNS4yMyAzMjAgLjQ5MSAzMDYuMzMuMDEzIDI4OC45LS40ODQgMjcwLjgxNiAxNC4wMjggMjU2IDMyIDI1Nmg1NnYtNTguNzQ1bC00Ni42MjgtNDYuNjI4Yy0xMi40OTYtMTIuNDk3LTEyLjQ5Ni0zMi43NTggMC00NS4yNTUgMTIuNDk4LTEyLjQ5NyAzMi43NTgtMTIuNDk3IDQ1LjI1NiAwTDE0MS4yNTUgMTYwaDIyOS40ODlsNTQuNjI3LTU0LjYyN2MxMi40OTgtMTIuNDk3IDMyLjc1OC0xMi40OTcgNDUuMjU2IDAgMTIuNDk2IDEyLjQ5NyAxMi40OTYgMzIuNzU4IDAgNDUuMjU1TDQyNCAxOTcuMjU1VjI1Nmg1NmMxNy45NzIgMCAzMi40ODQgMTQuODE2IDMxLjk4OCAzMi45ek0yNTcgMGMtNjEuODU2IDAtMTEyIDUwLjE0NC0xMTIgMTEyaDIyNEMzNjkgNTAuMTQ0IDMxOC44NTYgMCAyNTcgMHoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo= )][Download] [![Discord](https://img.shields.io/discord/313125603924639766.svg?color=%237289da&label=Discord&logo=discord&logoColor=%237289da)][Discord] [![Support](https://img.shields.io/badge/Patreon-Support-orange.svg?logo=Patreon)][Patreon] Forge is a free, open-source modding API all of your favourite mods use! diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/Bindings.java b/fmlcore/src/main/java/net/minecraftforge/fml/Bindings.java index e51b34d98f..d832948176 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/Bindings.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/Bindings.java @@ -16,7 +16,7 @@ import java.util.function.Supplier; /** * Used to allow access to certain things from the game layer */ -public class Bindings { +public final class Bindings { private Bindings() {} /** @@ -27,7 +27,7 @@ public class Bindings { .findFirst().orElseThrow(() -> new IllegalStateException("Could not find bindings provider")); /** - * @return A supplier of net.minecraftforge.common.MinecraftForge#EVENT_BUS + * @return A supplier of {@link BusGroup#DEFAULT} */ public static Supplier getForgeBus() { return PROVIDER.getForgeBusSupplier(); diff --git a/fmlcore/src/main/java/net/minecraftforge/fml/ModList.java b/fmlcore/src/main/java/net/minecraftforge/fml/ModList.java index 438609e6b6..b9e65ba47e 100644 --- a/fmlcore/src/main/java/net/minecraftforge/fml/ModList.java +++ b/fmlcore/src/main/java/net/minecraftforge/fml/ModList.java @@ -101,7 +101,7 @@ public final class ModList { } public static Optional getModContainerById(String modId) { - return Optional.ofNullable(indexedMods.get(modId)); + return Optional.ofNullable(indexedMods == null ? null : indexedMods.get(modId)); } public static Optional getModContainerByObject(Object obj) { diff --git a/fmlearlydisplay/build.gradle b/fmlearlydisplay/build.gradle index b3316d0262..a682731335 100644 --- a/fmlearlydisplay/build.gradle +++ b/fmlearlydisplay/build.gradle @@ -55,9 +55,9 @@ dependencies { // We are making the list of providers first BEFORE mapping them to a provider of the resolved objects so that they can be finalized after configuration. var lwjglTestLibs = [ dependencies.variantOf(earlyDisplayTestLibs.lwjgl) { classifier lwjglNatives }, - dependencies.variantOf(earlyDisplayTestLibs.lwjgl.glfw) { classifier lwjglNatives }, dependencies.variantOf(earlyDisplayTestLibs.lwjgl.opengl) { classifier lwjglNatives }, - dependencies.variantOf(earlyDisplayTestLibs.lwjgl.stb) { classifier lwjglNatives } + dependencies.variantOf(earlyDisplayTestLibs.lwjgl.stb) { classifier lwjglNatives }, + dependencies.variantOf(earlyDisplayTestLibs.lwjgl.sdl) { classifier lwjglNatives } ].with { list -> provider { list.collect { it.get() } } } diff --git a/fmlearlydisplay/src/main/java/net/minecraftforge/fml/earlydisplay/DisplayWindow.java b/fmlearlydisplay/src/main/java/net/minecraftforge/fml/earlydisplay/DisplayWindow.java index df45aadd56..6d8bd4a3e5 100644 --- a/fmlearlydisplay/src/main/java/net/minecraftforge/fml/earlydisplay/DisplayWindow.java +++ b/fmlearlydisplay/src/main/java/net/minecraftforge/fml/earlydisplay/DisplayWindow.java @@ -13,10 +13,12 @@ import net.minecraftforge.fml.loading.ImmediateWindowHandler; import net.minecraftforge.fml.loading.ImmediateWindowProvider; import net.minecraftforge.fml.loading.progress.StartupNotificationManager; import org.jetbrains.annotations.Nullable; -import org.lwjgl.PointerBuffer; -import org.lwjgl.glfw.GLFWVidMode; +import org.lwjgl.opengl.GL; +import org.lwjgl.sdl.SDLError; +import org.lwjgl.sdl.SDLVideo; +import org.lwjgl.sdl.SDL_Event; +import org.lwjgl.sdl.SDL_Rect; import org.lwjgl.system.MemoryStack; -import org.lwjgl.system.MemoryUtil; import org.lwjgl.util.tinyfd.TinyFileDialogs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,12 +31,10 @@ import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; -import java.util.Arrays; import java.util.Calendar; import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.StringJoiner; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -43,17 +43,18 @@ import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.IntConsumer; import java.util.function.Supplier; -import java.util.stream.Collector; -import java.util.stream.Collectors; -import static org.lwjgl.glfw.GLFW.*; -import static org.lwjgl.opengl.GL.createCapabilities; import static org.lwjgl.opengl.GL32C.*; +import static org.lwjgl.sdl.SDLError.*; +import static org.lwjgl.sdl.SDLEvents.*; +import static org.lwjgl.sdl.SDLHints.*; +import static org.lwjgl.sdl.SDLInit.*; +import static org.lwjgl.sdl.SDLVideo.*; + /** * The Loading Window that is opened Immediately after Forge starts. * It is called from the ModDirTransformerDiscoverer, the soonest method that ModLauncher calls into Forge code. @@ -83,10 +84,10 @@ public class DisplayWindow implements ImmediateWindowProvider { private ScheduledFuture initializationFuture; private PerformanceInfo performanceInfo; - @SuppressWarnings("unused") - private ScheduledFuture performanceTick; // The GL ID of the window. Used for all operations private long window; + // The SDL Context we use for switching between threads + private long sdlContext; // The thread that contains and ticks the window while Forge is loading mods private static final ScheduledExecutorService renderScheduler = Executors.newSingleThreadScheduledExecutor(r -> { final var thread = Executors.defaultThreadFactory().newThread(r); @@ -116,8 +117,8 @@ public class DisplayWindow implements ImmediateWindowProvider { @Override public ImmediateWindowProvider selectBackend(String backend) { // We only support opengl - if ("default".equals(backend) || "opengl".equals(backend)) - return this; + //if ("default".equals(backend) || "opengl".equals(backend)) + // return this; return ImmediateWindowProvider.getFallbackHandler(); } @@ -184,7 +185,7 @@ public class DisplayWindow implements ImmediateWindowProvider { return; } nextFrameTime = nt + MINFRAMETIME; - glfwMakeContextCurrent(window); + SDL_GL_MakeCurrent(window, sdlContext); framebuffer.activate(); glViewport(0, 0, this.context.scaledWidth(), this.context.scaledHeight()); this.context.elementShader().activate(); @@ -196,11 +197,12 @@ public class DisplayWindow implements ImmediateWindowProvider { glViewport(0, 0, fbWidth, fbHeight); framebuffer.draw(this.fbWidth, this.fbHeight); // Swap buffers; we're done - glfwSwapBuffers(window); + SDL_GL_SwapWindow(window); } catch (Throwable t) { LOGGER.error("BARF", t); } finally { - if (this.windowTick != null) glfwMakeContextCurrent(0); // we release the gl context IF we're running off the main thread + if (this.windowTick != null) + SDL_GL_MakeCurrent(window, 0); // we release the gl context IF we're running off the main thread renderLock.release(); } } @@ -212,12 +214,18 @@ public class DisplayWindow implements ImmediateWindowProvider { * Nothing fancy, we just want to draw and render text. */ private void initRender(final @Nullable String mcVersion, final String forgeVersion) { + this.sdlContext = SDL_GL_CreateContext(window); + if (sdlContext == 0) + throw new IllegalStateException("Failed to create OpenGL context: " + SDL_GetError()); + // This thread owns the GL render context now. We should make a note of that. - glfwMakeContextCurrent(window); + bindGlContext(); + GL.createCapabilities(); + // Wait for one frame to be complete before swapping; enable vsync in other words. - glfwSwapInterval(1); - createCapabilities(); - LOGGER.info("GL info: "+ glGetString(GL_RENDERER) + " GL version " + glGetString(GL_VERSION) + ", " + glGetString(GL_VENDOR)); + SDL_GL_SetSwapInterval(1); + + LOGGER.info("GL info: " + glGetString(GL_RENDERER) + " GL version " + glGetString(GL_VERSION) + ", " + glGetString(GL_VENDOR)); elementShader = new ElementShader(); try { @@ -227,7 +235,7 @@ public class DisplayWindow implements ImmediateWindowProvider { crashElegantly("An error occurred initializing shaders."); } - // Set the clear color based on the colour scheme + // Set the clear color based on the color scheme glClearColor(colourScheme.background().redf(), colourScheme.background().greenf(), colourScheme.background().bluef(), 1f); // we always render to an 854x480 texture and then fit that to the screen - with a scale factor @@ -253,11 +261,15 @@ public class DisplayWindow implements ImmediateWindowProvider { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glfwMakeContextCurrent(0); + + releaseGlContext(); + this.windowTick = renderScheduler.scheduleAtFixedRate(this::renderThreadFunc, 50, 50, TimeUnit.MILLISECONDS); - this.performanceTick = renderScheduler.scheduleAtFixedRate(performanceInfo::update, 0, 500, TimeUnit.MILLISECONDS); + + // Update the performance information every 1/2 second + renderScheduler.scheduleAtFixedRate(performanceInfo::update, 0, 500, TimeUnit.MILLISECONDS); // schedule a 50 ms ticker to try and smooth out the rendering - renderScheduler.scheduleAtFixedRate(()-> animationTimerTrigger.set(true), 1, 50, TimeUnit.MILLISECONDS); + //renderScheduler.scheduleAtFixedRate(() -> animationTimerTrigger.set(true), 1, 50, TimeUnit.MILLISECONDS); } /** @@ -294,6 +306,7 @@ public class DisplayWindow implements ImmediateWindowProvider { glBindVertexArray(currentVAO); glBindFramebuffer(GL_FRAMEBUFFER, currentFB); } + /** * Start the window and Render Thread; we're ready to go. */ @@ -342,71 +355,65 @@ public class DisplayWindow implements ImmediateWindowProvider { * As long as we can verify that, then GL (and things like OS X) have no complaints with doing this. * * @param mcVersion Minecraft Version - * @return The selected GL profile as an integer pair */ public void initWindow(@Nullable String mcVersion) { - // Initialize GLFW with a time guard, in case something goes wrong - long glfwInitBegin = System.nanoTime(); - if (!glfwInit()) { - crashElegantly("We are unable to initialize the graphics system.\nglfwInit failed.\n"); - throw new IllegalStateException("Unable to initialize GLFW"); + // Initialize a time guard, in case something goes wrong + long initBegin = System.nanoTime(); + if (!SDL_Init(SDL_INIT_VIDEO)) { + crashElegantly("We are unable to initialize the graphics system.\nSDL_Init failed.\n"); + throw new IllegalStateException("Unable to initialize SDL"); } - long glfwInitEnd = System.nanoTime(); + long initEnd = System.nanoTime(); - if (glfwInitEnd - glfwInitBegin > 1e9) { - LOGGER.error("WARNING : glfwInit took {} seconds to start.", (glfwInitEnd - glfwInitBegin) / 1.0e9); - } - - // Clear the Last Exception (#7285 - Prevent Vanilla throwing an IllegalStateException due to invalid controller mappings) - handleLastGLFWError((error, description) -> LOGGER.error(String.format("Suppressing Last GLFW error: [0x%X]%s", error, description))); + if (initEnd - initBegin > 1e9) + LOGGER.error("WARNING : Window init took {} seconds to start.", (initEnd - initBegin) / 1.0e9); // Set window hints for the new window we're gonna create. - glfwDefaultWindowHints(); - glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); - glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API); - glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); - glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); + SDL_ResetHints(); String vanillaWindowTitle = "Minecraft* "; - if (mcVersion != null) vanillaWindowTitle += mcVersion; + if (mcVersion != null) + vanillaWindowTitle += mcVersion; - // this emulates what we would get without early progress window - // as vanilla never sets these, so GLFW uses the first window title - // set them explicitly to avoid it using "FML early loading progress" as the class - glfwWindowHintString(GLFW_X11_CLASS_NAME, vanillaWindowTitle); - glfwWindowHintString(GLFW_X11_INSTANCE_NAME, vanillaWindowTitle); - - long primaryMonitor = glfwGetPrimaryMonitor(); + var primaryMonitor = SDL_GetPrimaryDisplay(); if (primaryMonitor == 0) { LOGGER.error("Failed to find a primary monitor - this means LWJGL isn't working properly"); - crashElegantly("Failed to locate a primary monitor.\nglfwGetPrimaryMonitor failed.\n"); + crashElegantly("Failed to locate a primary monitor.\nSDL_GetPrimaryDisplay failed.\n"); throw new IllegalStateException("Can't find a primary monitor"); } - GLFWVidMode vidmode = glfwGetVideoMode(primaryMonitor); + var vidmode = SDL_GetDesktopDisplayMode(primaryMonitor); if (vidmode == null) { LOGGER.error("Failed to get the current display video mode."); - crashElegantly("Failed to get current display resolution.\nglfwGetVideoMode failed.\n"); + crashElegantly("Failed to get current display resolution.\nSDL_GetDesktopDisplayMode failed.\n"); throw new IllegalStateException("Can't get a resolution"); } + long window = 0; var successfulWindow = new AtomicBoolean(false); - var windowFailFuture = renderScheduler.schedule(()->{ - if (!successfulWindow.get()) crashElegantly("Timed out trying to setup the Game Window."); + var windowFailFuture = renderScheduler.schedule(() -> { + if (!successfulWindow.get()) + crashElegantly("Timed out trying to setup the Game Window."); }, 10, TimeUnit.SECONDS); - int versidx = 0; + var skipVersions = FMLConfig.getListConfigValue(FMLConfig.ConfigValue.EARLY_WINDOW_SKIP_GL_VERSIONS); boolean showHelpLog = FMLConfig.getBoolConfigValue(FMLConfig.ConfigValue.EARLY_WINDOW_LOG_HELP_MSG); - final String[] lastGLError = new String[GL_VERSIONS.length]; - do { - final var glVersionToTry = GL_VERSIONS[versidx][0] + "." + GL_VERSIONS[versidx][1]; - if (skipVersions.contains(glVersionToTry)) { - LOGGER.info("Skipping GL version "+ glVersionToTry+" because of configuration"); - versidx++; + + record Attempt(String vesion, String error) {} + final List attempts = new ArrayList<>(); + String requestedVersion = null; + + for (int x = 0; x < GL_VERSIONS.length; x++) { + var version = GL_VERSIONS[x]; + requestedVersion = version[0] + "." + version[1]; + + if (skipVersions.contains(requestedVersion)) { + LOGGER.info("Skipping GL version " + requestedVersion + " because of configuration"); continue; } - LOGGER.info("Trying GL version " + glVersionToTry); - if (showHelpLog && versidx == 0) { + + LOGGER.info("Trying GL version " + requestedVersion); + if (showHelpLog && x == 0) { LOGGER.info(""" If this message is the only thing at the bottom of your log before a crash, you probably have a driver issue. @@ -418,132 +425,105 @@ public class DisplayWindow implements ImmediateWindowProvider { You can safely ignore this message if the game starts up successfully."""); } - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, GL_VERSIONS[versidx][0]); // we try our versions one at a time - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, GL_VERSIONS[versidx][1]); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); - window = glfwCreateWindow(winWidth, winHeight, vanillaWindowTitle, 0L, 0L); - var erridx = versidx; - handleLastGLFWError((error, description) -> lastGLError[erridx] = String.format("Trying %d.%d: GLFW error: [0x%X]%s", GL_VERSIONS[erridx][0], GL_VERSIONS[erridx][1], error, description)); - if (lastGLError[versidx] != null) { - LOGGER.trace(lastGLError[versidx]); - } - versidx++; - } while (window == 0 && versidx < GL_VERSIONS.length); -// LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(12)); - if (versidx== GL_VERSIONS.length && window == 0) { - LOGGER.error("Failed to find any valid GLFW profile. "+lastGLError[0]); - crashElegantly("Failed to find a valid GLFW profile.\nWe tried "+ - Arrays.stream(GL_VERSIONS).map(p->p[0]+"."+p[1]).filter(o -> !skipVersions.contains(o)) - .collect(Collector.of(()->new StringJoiner(", ").setEmptyValue("no versions"), StringJoiner::add, StringJoiner::merge, StringJoiner::toString))+ - " but none of them worked.\n"+ Arrays.stream(lastGLError).filter(Objects::nonNull).collect(Collectors.joining("\n"))); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, version[0]); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, version[1]); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); + SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, GL_TRUE); + window = SDL_CreateWindow(vanillaWindowTitle, winWidth, winHeight, + SDL_WINDOW_OPENGL + | SDL_WINDOW_RESIZABLE + | SDL_WINDOW_HIGH_PIXEL_DENSITY + ); + + if (window == 0) { + var error = Objects.requireNonNullElse(SDLError.SDL_GetError(), ""); + attempts.add(new Attempt(requestedVersion, error)); + LOGGER.trace("Failed to create window using %d.%d: %s", version[0], version[1], error); + } else { + SDLVideo.SDL_SetWindowMinimumSize(window, 320, 240); + LOGGER.info("Created window using SDL video driver: {}", SDLVideo.SDL_GetCurrentVideoDriver()); + break; // We got a valid window! + } + } + + if (window == 0) { + LOGGER.error("Failed to find any valid GLFW profile."); + var message = new StringBuilder() + .append("Failed to find a valid GLFW profile.\n"); + + if (attempts.isEmpty()) { + message.append("All GL Versions were skipped"); + } else { + message.append("We tried:"); + for (var attempt : attempts) + message.append("\n\t").append(attempt.vesion).append(':').append(attempt.error); + } + + crashElegantly(message.toString()); throw new IllegalStateException("Failed to create a GLFW window with any profile"); } + successfulWindow.set(true); - if (!windowFailFuture.cancel(true)) throw new IllegalStateException("We died but didn't somehow?"); - var requestedVersion = GL_VERSIONS[versidx-1][0]+"."+GL_VERSIONS[versidx-1][1]; - var maj = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR); - var min = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR); - var gotVersion = maj+"."+min; - LOGGER.info("Requested GL version "+requestedVersion+" got version "+gotVersion); - this.glVersion = gotVersion; + if (!windowFailFuture.cancel(true)) + throw new IllegalStateException("We died but didn't somehow?"); + + try (var stack = org.lwjgl.system.MemoryStack.stackPush()) { + var majBuf = stack.mallocInt(1); + var minBuf = stack.mallocInt(1); + SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, majBuf); + SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minBuf); + this.glVersion = majBuf.get(0) + "." + minBuf.get(0); + } + + LOGGER.info("Requested GL version " + requestedVersion + " got version " + this.glVersion); this.window = window; if (showHelpLog) FMLConfig.updateConfig(FMLConfig.ConfigValue.EARLY_WINDOW_LOG_HELP_MSG, false); - int[] x = new int[1]; - int[] y = new int[1]; - glfwGetMonitorPos(primaryMonitor, x, y); - int monitorX = x[0]; - int monitorY = y[0]; -// glfwSetWindowSizeLimits(window, 854, 480, GLFW_DONT_CARE, GLFW_DONT_CARE); - if (this.maximized) { - glfwMaximizeWindow(window); - } + if (this.maximized) + SDL_MaximizeWindow(window); - glfwGetWindowSize(window, x, y); - this.winWidth = x[0]; - this.winHeight = y[0]; + var size = getWindowSize(window); + this.onWindowResize(size.x, size.y); - // Setting the window position isn't supported on wayland, so check the error here - glfwSetWindowPos(window, (vidmode.width() - this.winWidth) / 2 + monitorX, (vidmode.height() - this.winHeight) / 2 + monitorY); - handleLastGLFWError(); + var monitor = getMonitorSize(primaryMonitor); + if (monitor != null) + SDL_SetWindowPosition(window, (monitor.width - size.x) / 2 + monitor.x, (monitor.height - size.y) / 2 + monitor.y); - // Attempt setting the icon -// int[] channels = new int[1]; -// try (var glfwImgBuffer = GLFWImage.create(MemoryUtil.getAllocator().malloc(GLFWImage.SIZEOF), 1)) { -// final ByteBuffer imgBuffer; -// try (GLFWImage glfwImages = GLFWImage.malloc()) { -// imgBuffer = STBHelper.loadImageFromClasspath("forge_logo.png", 20000, x, y, channels); -// glfwImgBuffer.put(glfwImages.set(x[0], y[0], imgBuffer)); -// glfwSetWindowIcon(window, glfwImgBuffer); -// STBImage.stbi_image_free(imgBuffer); -// } -// } catch (NullPointerException e) { -// System.err.println("Failed to load forge logo"); -// } -// handleLastGLFWError((error, description) -> LOGGER.debug(String.format("Suppressing GLFW icon error: [0x%X]%s", error, description))); + pollEvents(); - glfwSetFramebufferSizeCallback(window, this::fbResize); - glfwSetWindowPosCallback(window, this::winMove); - glfwSetWindowSizeCallback(window, this::winResize); - - // Show the window - glfwShowWindow(window); - // Getting the window position isn't supported on wayland, so check the error here - glfwGetWindowPos(window, x, y); - handleLastGLFWError(); - - this.winX = x[0]; - this.winY = y[0]; - glfwGetFramebufferSize(window, x, y); - this.fbWidth = x[0]; - this.fbHeight = y[0]; - glfwPollEvents(); + SDL_ShowWindow(window); } - private static void handleLastGLFWError() { - handleLastGLFWError((error, description) -> { - if (error == GLFW_FEATURE_UNAVAILABLE) { - // suppress window pos errors for unsupported platforms (wayland) - LOGGER.debug(String.format("Suppressing GLFW error: [0x%X]%s", error, description)); - return; + private record Point(int x, int y) {} + private record Rect(int x, int y, int width, int height) {} + + private static @Nullable Rect getMonitorSize(int monitor) { + try (var bounds = SDL_Rect.malloc()) { + // Fetch the display bounds for the current index + if (SDL_GetDisplayBounds(monitor, bounds)) { + int x = bounds.x(); + int y = bounds.y(); + int width = bounds.w(); + int height = bounds.h(); + LOGGER.info("Display {} Bounds -> X: {}, Y: {}, Width: {}, Height: {}", monitor, x, y, width, height); + return new Rect(x, y, width, height); + } else { + LOGGER.warn("Could not get bounds for display: " + SDL_GetError()); + return null; } - - throw new IllegalStateException(String.format("GLFW error: [0x%X]%s", error, description)); - }); - } - - private void winResize(long window, int width, int height) { - if (window == this.window && width != 0 && height != 0) { - this.winWidth = width; - this.winHeight = height; - } - } - private void fbResize(long window, int width, int height) { - if (window == this.window && width != 0 && height != 0) { - this.fbWidth = width; - this.fbHeight = height; } } - private void winMove(long window, int x, int y) { - if (window == this.window) { - this.winX = x; - this.winY = y; - } - } - private static void handleLastGLFWError(BiConsumer handler) { - try (MemoryStack memorystack = MemoryStack.stackPush()) { - PointerBuffer pointerbuffer = memorystack.mallocPointer(1); - int error = glfwGetError(pointerbuffer); - if (error != GLFW_NO_ERROR) { - long pDescription = pointerbuffer.get(); - String description = pDescription == 0L ? "" : MemoryUtil.memUTF8(pDescription); - handler.accept(error, description); - } + private static Point getWindowSize(long window) { + try (var stack = MemoryStack.stackPush()) { + var width = stack.mallocInt(1); + var height = stack.mallocInt(1); + SDL_GetWindowSize(window, width, height); + return new Point(width.get(0), height.get(0)); } } @@ -553,7 +533,8 @@ public class DisplayWindow implements ImmediateWindowProvider { * * @return the Window we own. */ - public long setupMinecraftWindow(final int width, final int height, final String title, final long monitorSupplier, final Supplier backend) { + @Override + public long setupMinecraftWindow(final int width, final int height, final String title, final Supplier backend) { // wait for the window to actually be initialized try { this.initializationFuture.get(30, TimeUnit.SECONDS); @@ -585,14 +566,10 @@ public class DisplayWindow implements ImmediateWindowProvider { // we don't want the lock, just making sure it's back on the main thread renderLock.release(); - glfwMakeContextCurrent(window); + SDL_GL_MakeCurrent(window, sdlContext); // Set the title to what the game wants - glfwSetWindowTitle(window, title); - glfwSwapInterval(0); - // Clean up our hooks - glfwSetFramebufferSizeCallback(window, null).free(); - glfwSetWindowPosCallback(window, null).free(); - glfwSetWindowSizeCallback(window, null).free(); + SDL_SetWindowTitle(window, title); + SDL_GL_SetSwapInterval(0); // Disable vsync, let Minecraft control it this.repaintTick = this::renderThreadFunc; // the repaint will continue to be called until the overlay takes over this.windowTick = null; // this tells the render thread that the async ticker is done return window; @@ -658,7 +635,7 @@ public class DisplayWindow implements ImmediateWindowProvider { @Override public void periodicTick() { - glfwPollEvents(); + pollEvents(); repaintTick.run(); } @@ -673,4 +650,67 @@ public class DisplayWindow implements ImmediateWindowProvider { this.context.elementShader().close(); SimpleBufferBuilder.destroy(); } + + private void bindGlContext() { + SDL_GL_MakeCurrent(window, sdlContext); + //if (!SDL_GL_MakeCurrent(window, sdlContext)) + // throw new IllegalStateException("Failed to make OpenGL context current: " + SDL_GetError()); + } + + private void releaseGlContext() { + SDL_GL_MakeCurrent(window, 0); + } + + + private void pollEvents() { + try (var event = SDL_Event.malloc()) { + while (SDL_PollEvent(event)) { + switch (event.type()) { + case SDL_EVENT_WINDOW_MOVED: + this.onWindowMove(event.window().data1(), event.window().data2()); + break; + case SDL_EVENT_WINDOW_RESIZED: + this.onWindowResize(event.window().data1(), event.window().data2()); + break; + case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: + this.onFrameBufferResize(event.window().data1(), event.window().data2()); + break; + + /* + We were told to quit for some reason, find a way to abort? + case SDL_EVENT_QUIT: + case SDL_EVENT_WINDOW_CLOSE_REQUESTED: + case SDL_EVENT_TERMINATING: + + Window was minimized or restored, maybe stop rendering? + case SDL_EVENT_WINDOW_MINIMIZED: + case SDL_EVENT_WINDOW_MAXIMIZED: + case SDL_EVENT_WINDOW_RESTORED: + */ + } + } + } + } + + private void onWindowResize(int width, int height) { + if (width == 0 || height == 0) + return; + + this.winWidth = width; + this.winHeight = height; + } + + private void onFrameBufferResize(int width, int height) { + if (width == 0 || height == 0) + return; + + this.fbWidth = width; + this.fbHeight = height; + } + + private void onWindowMove(int x, int y) { + this.winX = x; + this.winY = y; + } + } diff --git a/fmlearlydisplay/src/main/java/net/minecraftforge/fml/earlydisplay/RenderElement.java b/fmlearlydisplay/src/main/java/net/minecraftforge/fml/earlydisplay/RenderElement.java index e0cd43e72c..303f709003 100644 --- a/fmlearlydisplay/src/main/java/net/minecraftforge/fml/earlydisplay/RenderElement.java +++ b/fmlearlydisplay/src/main/java/net/minecraftforge/fml/earlydisplay/RenderElement.java @@ -11,8 +11,6 @@ import net.minecraftforge.fml.loading.progress.StartupNotificationManager; import java.util.ArrayList; import java.util.List; -import java.util.function.Supplier; - import static org.lwjgl.opengl.GL32C.*; public class RenderElement { @@ -39,11 +37,6 @@ public class RenderElement { void accept(SimpleBufferBuilder bb, DisplayContext context, int[] size, int frame); } - /** @deprecated Use {@link Renderer} directly. This was always eagerly resolved, making it an unnecessary wrapper. */ - @Deprecated(since = "1.21.5", forRemoval = true) - @FunctionalInterface - interface Initializer extends Supplier {} - @FunctionalInterface interface TextGenerator { void accept(SimpleBufferBuilder bb, SimpleFont fh, DisplayContext ctx); @@ -59,13 +52,6 @@ public class RenderElement { } } - /** @deprecated Use {@link RenderElement#RenderElement(Renderer)} instead */ - @Deprecated(since = "1.21.5", forRemoval = true) - public RenderElement(final Initializer rendererInitializer) { - this.bb = new SimpleBufferBuilder(1); - this.renderer = rendererInitializer.get(); - } - public RenderElement(Renderer renderer) { this.bb = new SimpleBufferBuilder(1); this.renderer = renderer; diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/RuntimeEnumExtender.java b/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/RuntimeEnumExtender.java index e861ed43f2..39d5d23204 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/RuntimeEnumExtender.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/common/asm/RuntimeEnumExtender.java @@ -136,7 +136,7 @@ public class RuntimeEnumExtender implements ILaunchPluginService { classNode.methods.stream().filter(m -> m.name.equals("")).forEach(m -> sb.append(" : ").append(m.desc).append("\n")); LOGGER.error(LogUtils.FATAL_MARKER, sb.toString()); } - throw new IllegalStateException("Enum has create method with no matching constructor: " + desc); + throw new IllegalStateException("Enum has create method with no matching constructor: " + classType.getClassName() + " " + desc); } if (values == null) diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/ImmediateWindowHandler.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ImmediateWindowHandler.java index c704a3fd7d..918b2d153b 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/ImmediateWindowHandler.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ImmediateWindowHandler.java @@ -102,8 +102,8 @@ public class ImmediateWindowHandler { return "default"; } - public static long setupMinecraftWindow(final int width, final int height, final String title, final long monitor, final Supplier backend) { - return provider.setupMinecraftWindow(width, height, title, monitor, backend); + public static long setupMinecraftWindow(final int width, final int height, final String title, final Supplier backend) { + return provider.setupMinecraftWindow(width, height, title, backend); } public static boolean positionWindow(Optional monitor,IntConsumer widthSetter, IntConsumer heightSetter, IntConsumer xSetter, IntConsumer ySetter) { @@ -155,9 +155,9 @@ public class ImmediateWindowHandler { } @Override - public long setupMinecraftWindow(final int width, final int height, final String title, final long monitor, final Supplier backend) { + public long setupMinecraftWindow(final int width, final int height, final String title, final Supplier backend) { try { - var longsupplier = (LongSupplier)NV_HANDOFF.invoke(null, width, height, title, monitor, backend); + var longsupplier = (LongSupplier)NV_HANDOFF.invoke(null, width, height, title, backend); return longsupplier.getAsLong(); } catch (Throwable e) { throw new IllegalStateException("How did you get here?", e); diff --git a/fmlloader/src/main/java/net/minecraftforge/fml/loading/ImmediateWindowProvider.java b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ImmediateWindowProvider.java index d15c3629da..421017124b 100644 --- a/fmlloader/src/main/java/net/minecraftforge/fml/loading/ImmediateWindowProvider.java +++ b/fmlloader/src/main/java/net/minecraftforge/fml/loading/ImmediateWindowProvider.java @@ -86,10 +86,9 @@ public interface ImmediateWindowProvider { * @param width This is the width of the window Mojang expects * @param height This is the height of the Window Mojang expects. * @param title This is the title for the window. - * @param monitor This is the monitor it should appear on. * @return The window id */ - long setupMinecraftWindow(final int width, final int height, final String title, final long monitor, final Supplier backend); + long setupMinecraftWindow(final int width, final int height, final String title, final Supplier backend); /** * This is called after window handoff to allow us to tell Mojang about our window's position. This might give a diff --git a/forge-transformers/src/main/java/net/minecraftforge/forge/transformers/FieldToMethodTransformer.java b/forge-transformers/src/main/java/net/minecraftforge/forge/transformers/FieldToMethodTransformer.java index 113dac1e5c..b35dfb6104 100644 --- a/forge-transformers/src/main/java/net/minecraftforge/forge/transformers/FieldToMethodTransformer.java +++ b/forge-transformers/src/main/java/net/minecraftforge/forge/transformers/FieldToMethodTransformer.java @@ -32,12 +32,6 @@ record FieldToMethodTransformer(String className, Map fields) im // TODO [Forge][Transformer] Make this properly data driven or configurable. // It was hard-coded like this before when using JS CoreMods, though. static final Map> TARGETS = Map.of( - "net.minecraft.world.level.biome.Biome", - Map.of( - "climateSettings", "getModifiedClimateSettings", - "specialEffects", "getModifiedSpecialEffects" - ), - "net.minecraft.world.effect.MobEffectInstance", Map.of( "effect", "getEffect" diff --git a/forge-transformers/src/main/resources/coremods/finalize_spawn_targets.json b/forge-transformers/src/main/resources/coremods/finalize_spawn_targets.json index 555238cf0c..a7ac961707 100644 --- a/forge-transformers/src/main/resources/coremods/finalize_spawn_targets.json +++ b/forge-transformers/src/main/resources/coremods/finalize_spawn_targets.json @@ -95,7 +95,7 @@ "class": "net/minecraft/world/level/NaturalSpawner", "methods": [ "spawnCategoryForPosition(Lnet/minecraft/world/entity/MobCategory;Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/chunk/ChunkAccess;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/NaturalSpawner$SpawnPredicate;Lnet/minecraft/world/level/NaturalSpawner$AfterSpawnCallback;)V", - "spawnMobsForChunkGeneration(Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/core/Holder;Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/util/RandomSource;)V" + "spawnMobsForChunkGeneration(Lnet/minecraft/world/level/ServerLevelAccessor;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/ChunkPos;Lnet/minecraft/util/RandomSource;)V" ] }, { diff --git a/javafmllanguage/src/main/java/net/minecraftforge/fml/common/Mod.java b/javafmllanguage/src/main/java/net/minecraftforge/fml/common/Mod.java index b284de160b..dadb218304 100644 --- a/javafmllanguage/src/main/java/net/minecraftforge/fml/common/Mod.java +++ b/javafmllanguage/src/main/java/net/minecraftforge/fml/common/Mod.java @@ -37,8 +37,7 @@ public @interface Mod { /** * Annotate a class which will be subscribed to an Event Bus at mod construction time. - * Defaults to subscribing the current modid to the {@code MinecraftForge#EVENT_BUS} - * on both sides. + * Defaults to subscribing the current modid to the {@link Bus#BOTH} on both sides. * * @see Bus */ diff --git a/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/AutomaticEventSubscriber.java b/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/AutomaticEventSubscriber.java index 5743a70a51..cc4f4c0a97 100644 --- a/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/AutomaticEventSubscriber.java +++ b/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/AutomaticEventSubscriber.java @@ -45,7 +45,7 @@ import java.util.stream.Collectors; /** * Automatic eventbus subscriber - reads {@link EventBusSubscriber} * annotations and passes the class instances to the {@link Bus} - * defined by the annotation. Defaults to {@code MinecraftForge#EVENT_BUS} + * defined by the annotation. Defaults to {@code Bus.BOTH} if not specified. */ public final class AutomaticEventSubscriber { private static final Logger LOGGER = LogManager.getLogger(); diff --git a/minecraft.versions.toml b/minecraft.versions.toml index a2a4d47b43..9055dc8baa 100644 --- a/minecraft.versions.toml +++ b/minecraft.versions.toml @@ -1,6 +1,6 @@ [versions] java = "25" -minecraft = "26.2" -minecraft-next = "26.3" -mcp = "20260616.103818" -changelog-base = "65.0" +minecraft = "26.3" +minecraft-next = "26.4" +mcp = "20260918.230105" +changelog-base = "66.0" diff --git a/patches/minecraft/com/mojang/blaze3d/opengl/GlTexture.java.patch b/patches/minecraft/com/mojang/blaze3d/opengl/GlTexture.java.patch deleted file mode 100644 index a46d2a3d47..0000000000 --- a/patches/minecraft/com/mojang/blaze3d/opengl/GlTexture.java.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/com/mojang/blaze3d/opengl/GlTexture.java -+++ b/com/mojang/blaze3d/opengl/GlTexture.java -@@ -27,9 +_,14 @@ - final int id, - final FrameBufferCache frameBufferCache - ) { -+ this(usage, label, format, width, height, depthOrLayers, mipLevels, id, frameBufferCache, false); -+ } -+ -+ protected GlTexture(@GpuTexture.Usage int usage, String label, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels, int id, FrameBufferCache frameBufferCache, boolean stencil) { - super(usage, label, format, width, height, depthOrLayers, mipLevels); - this.id = id; - this.frameBufferCache = frameBufferCache; -+ this.stencilEnabled = stencil; - } - - @Override -@@ -84,5 +_,12 @@ - if (this.closed && this.views == 0) { - this.destroyImmediately(); - } -+ } -+ -+ private final boolean stencilEnabled; -+ -+ @Override -+ public boolean isStencilEnabled() { -+ return this.stencilEnabled; - } - } diff --git a/patches/minecraft/com/mojang/blaze3d/pipeline/RenderTarget.java.patch b/patches/minecraft/com/mojang/blaze3d/pipeline/RenderTarget.java.patch index 0c3e099fc8..daef9b4a63 100644 --- a/patches/minecraft/com/mojang/blaze3d/pipeline/RenderTarget.java.patch +++ b/patches/minecraft/com/mojang/blaze3d/pipeline/RenderTarget.java.patch @@ -1,18 +1,18 @@ --- a/com/mojang/blaze3d/pipeline/RenderTarget.java +++ b/com/mojang/blaze3d/pipeline/RenderTarget.java -@@ -83,7 +_,7 @@ +@@ -96,7 +_,7 @@ this.width = width; this.height = height; - if (this.useDepth) { -- this.depthTexture = device.createTexture(() -> this.label + " / Depth", 15, GpuFormat.D32_FLOAT, width, height, 1, 1); -+ this.depthTexture = device.createTexture(() -> this.label + " / Depth", 15, GpuFormat.D32_FLOAT, width, height, 1, 1, this.stencilEnabled); + if (this.depthFormat != null) { +- this.depthTexture = device.createTexture(() -> this.label + " / Depth", 15, this.depthFormat, width, height, 1, 1); ++ this.depthTexture = device.createTexture(() -> this.label + " / Depth", 15, this.depthFormat, width, height, 1, 1, this.stencilEnabled); this.depthTextureView = device.createTextureView(this.depthTexture); } -@@ -121,5 +_,26 @@ +@@ -140,5 +_,26 @@ - public @Nullable GpuTextureView getDepthTextureView() { - return this.depthTextureView; + public boolean hasDepth() { + return this.depthFormat != null; + } + + private boolean stencilEnabled = false; diff --git a/patches/minecraft/com/mojang/blaze3d/platform/Window.java.patch b/patches/minecraft/com/mojang/blaze3d/platform/Window.java.patch index e7a00bd35a..e3462d7f07 100644 --- a/patches/minecraft/com/mojang/blaze3d/platform/Window.java.patch +++ b/patches/minecraft/com/mojang/blaze3d/platform/Window.java.patch @@ -1,31 +1,33 @@ --- a/com/mojang/blaze3d/platform/Window.java +++ b/com/mojang/blaze3d/platform/Window.java -@@ -101,8 +_,9 @@ - Monitor initialMonitor = monitorManager.getMonitor(GLFW.glfwGetPrimaryMonitor()); - this.windowedWidth = this.width = allowedWindowMinSize(displayData.width()); - this.windowedHeight = this.height = allowedWindowMinSize(displayData.height()); -- this.handle = this.createWindow(backend, this.width, this.height, title, this.fullscreen && initialMonitor != null ? initialMonitor.monitor() : 0L); -+ this.handle = net.minecraftforge.fml.loading.ImmediateWindowHandler.setupMinecraftWindow(this.width, this.height, title, this.fullscreen && initialMonitor != null ? initialMonitor.monitor() : 0L, () -> backend); - this.backend = backend; +@@ -114,9 +_,10 @@ + Monitor initialMonitor = monitorManager.getMonitor(SDLVideo.SDL_GetPrimaryDisplay()); + this.windowedWidth = this.width = allowedWindowMinSize(displayData.width(), 320); + this.windowedHeight = this.height = allowedWindowMinSize(displayData.height(), 240); +- this.handle = this.createWindow(backend, this.width, this.height, title); ++ this.handle = net.minecraftforge.fml.loading.ImmediateWindowHandler.setupMinecraftWindow(this.width, this.height, title, () -> backend); + this.setWindowMaxSize(maximumSize, maximumSize); + MacosUtil.disableCloseWindowMenuItem(); + if (!net.minecraftforge.fml.loading.ImmediateWindowHandler.positionWindow(Optional.ofNullable(initialMonitor), w->this.width = this.windowedWidth = w, h->this.height = this.windowedHeight = h, x->this.x = this.windowedX = x, y->this.y = this.windowedY = y)) { if (initialMonitor != null) { - VideoMode mode = initialMonitor.getPreferredVidMode(this.fullscreen ? this.preferredFullscreenVideoMode : Optional.empty()); - this.windowedX = this.x = initialMonitor.x() + mode.getWidth() / 2 - this.width / 2; -@@ -114,6 +_,7 @@ - this.windowedX = this.x = actualX[0]; - this.windowedY = this.y = actualY[0]; + this.windowedX = this.x = initialMonitor.x() + (initialMonitor.w() - this.width) / 2; + this.windowedY = this.y = initialMonitor.y() + (initialMonitor.h() - this.height) / 2; +@@ -132,6 +_,7 @@ + this.windowedY = this.y = actualY.get(0); + } } + } this.setMode(); this.refreshFramebufferSize(); -@@ -306,6 +_,9 @@ - outHeight[0] = this.isSoftScreen() ? outHeight[0] - 1 : outHeight[0]; - this.framebufferWidth = outWidth[0] > 0 ? outWidth[0] : 1; - this.framebufferHeight = outHeight[0] > 0 ? outHeight[0] : 1; -+ if (this.framebufferHeight == 0 || this.framebufferWidth == 0) { -+ net.minecraftforge.fml.loading.ImmediateWindowHandler.updateFBSize(w -> this.framebufferWidth = w, h -> this.framebufferHeight = h); -+ } +@@ -148,6 +_,10 @@ } - private void onResize(final long handle, final int newWidth, final int newHeight) { + private long createWindow(final GpuBackend backend, final int width, final int height, final String title) { ++ return createWindowStatic(backend, width, height, title); ++ } ++ ++ public static long createWindowStatic(final GpuBackend backend, final int width, final int height, final String title) { + long flags = 8224L; + long windowHandle = backend.createWindow(title, width, height, 8224L); + if (windowHandle == 0L) { diff --git a/patches/minecraft/com/mojang/blaze3d/systems/GpuDeviceBackend.java.patch b/patches/minecraft/com/mojang/blaze3d/systems/GpuDeviceBackend.java.patch deleted file mode 100644 index d39e0b3864..0000000000 --- a/patches/minecraft/com/mojang/blaze3d/systems/GpuDeviceBackend.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/com/mojang/blaze3d/systems/GpuDeviceBackend.java -+++ b/com/mojang/blaze3d/systems/GpuDeviceBackend.java -@@ -32,7 +_,17 @@ - @Nullable Supplier label, @GpuTexture.Usage int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels - ); - -+ /** Forge: same as {@link #createTexture(Supplier, int, GpuFormat, int, int, int)} but with stencil support */ -+ default GpuTexture createTexture(@Nullable Supplier label, @GpuTexture.Usage final int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels, boolean stencil) { -+ return createTexture(label, usage, format, width, height, depthOrLayers, mipLevels); -+ } -+ - GpuTexture createTexture(@Nullable String label, @GpuTexture.Usage int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels); -+ -+ /** Forge: same as {@link #createTexture(String, int, GpuFormat, int, int, int)} but with stencil support */ -+ default GpuTexture createTexture(@Nullable String label, @GpuTexture.Usage final int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels, boolean stencil) { -+ return createTexture(label, usage, format, width, height, depthOrLayers, mipLevels); -+ } - - GpuTextureView createTextureView(GpuTexture texture); - diff --git a/patches/minecraft/com/mojang/blaze3d/textures/GpuTexture.java.patch b/patches/minecraft/com/mojang/blaze3d/textures/GpuTexture.java.patch deleted file mode 100644 index e1acf98c71..0000000000 --- a/patches/minecraft/com/mojang/blaze3d/textures/GpuTexture.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/com/mojang/blaze3d/textures/GpuTexture.java -+++ b/com/mojang/blaze3d/textures/GpuTexture.java -@@ -9,7 +_,7 @@ - import net.minecraftforge.api.distmarker.OnlyIn; - - @OnlyIn(Dist.CLIENT) --public abstract class GpuTexture implements AutoCloseable { -+public abstract class GpuTexture implements AutoCloseable, net.minecraftforge.client.extensions.IForgeGpuTexture { - public static final int USAGE_COPY_DST = 1; - public static final int USAGE_COPY_SRC = 2; - public static final int USAGE_TEXTURE_BINDING = 4; diff --git a/patches/minecraft/com/mojang/blaze3d/vertex/PoseStack.java.patch b/patches/minecraft/com/mojang/blaze3d/vertex/PoseStack.java.patch index b74e45535d..a13682fd7d 100644 --- a/patches/minecraft/com/mojang/blaze3d/vertex/PoseStack.java.patch +++ b/patches/minecraft/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 -@@ -16,7 +_,7 @@ +@@ -17,7 +_,7 @@ import org.joml.Vector3fc; @OnlyIn(Dist.CLIENT) diff --git a/patches/minecraft/com/mojang/realmsclient/gui/screens/RealmsGenericErrorScreen.java.patch b/patches/minecraft/com/mojang/realmsclient/gui/screens/RealmsGenericErrorScreen.java.patch index f7cb1fe45c..17e2bba2fd 100644 --- a/patches/minecraft/com/mojang/realmsclient/gui/screens/RealmsGenericErrorScreen.java.patch +++ b/patches/minecraft/com/mojang/realmsclient/gui/screens/RealmsGenericErrorScreen.java.patch @@ -5,7 +5,7 @@ @Override + public boolean keyPressed(net.minecraft.client.input.KeyEvent event) { -+ if (event.key() == org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE) { ++ if (event.isEscape()) { + minecraft.gui.setScreen(this.nextScreen); + return true; + } diff --git a/patches/minecraft/com/mojang/renderpearl/api/device/GpuDevice.java.patch b/patches/minecraft/com/mojang/renderpearl/api/device/GpuDevice.java.patch new file mode 100644 index 0000000000..99b3350a9d --- /dev/null +++ b/patches/minecraft/com/mojang/renderpearl/api/device/GpuDevice.java.patch @@ -0,0 +1,20 @@ +--- a/com/mojang/renderpearl/api/device/GpuDevice.java ++++ b/com/mojang/renderpearl/api/device/GpuDevice.java +@@ -37,7 +_,17 @@ + @Nullable Supplier label, @GpuTexture.Usage int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels + ); + ++ default GpuTexture createTexture( ++ @Nullable Supplier label, @GpuTexture.Usage int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels, boolean stencil ++ ) { ++ return createTexture(label, usage, format, width, height, depthOrLayers, mipLevels); ++ } ++ + GpuTexture createTexture(@Nullable String label, @GpuTexture.Usage int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels); ++ ++ default GpuTexture createTexture(@Nullable String label, @GpuTexture.Usage int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels, boolean stencil) { ++ return createTexture(label, usage, format, width, height, depthOrLayers, mipLevels, stencil); ++ } + + GpuTextureView createTextureView(GpuTexture texture); + diff --git a/patches/minecraft/com/mojang/renderpearl/api/textures/GpuTexture.java.patch b/patches/minecraft/com/mojang/renderpearl/api/textures/GpuTexture.java.patch new file mode 100644 index 0000000000..921db3f09d --- /dev/null +++ b/patches/minecraft/com/mojang/renderpearl/api/textures/GpuTexture.java.patch @@ -0,0 +1,11 @@ +--- a/com/mojang/renderpearl/api/textures/GpuTexture.java ++++ b/com/mojang/renderpearl/api/textures/GpuTexture.java +@@ -10,7 +_,7 @@ + import net.minecraftforge.api.distmarker.OnlyIn; + + @OnlyIn(Dist.CLIENT) +-public interface GpuTexture extends UncheckedAutoCloseable { ++public interface GpuTexture extends UncheckedAutoCloseable, net.minecraftforge.client.extensions.IForgeGpuTexture { + int USAGE_COPY_DST = 1; + int USAGE_COPY_SRC = 2; + int USAGE_TEXTURE_BINDING = 4; diff --git a/patches/minecraft/com/mojang/blaze3d/vertex/VertexFormat.java.patch b/patches/minecraft/com/mojang/renderpearl/api/vertex/VertexFormat.java.patch similarity index 76% rename from patches/minecraft/com/mojang/blaze3d/vertex/VertexFormat.java.patch rename to patches/minecraft/com/mojang/renderpearl/api/vertex/VertexFormat.java.patch index d181b3f0bb..a3d09cd0e8 100644 --- a/patches/minecraft/com/mojang/blaze3d/vertex/VertexFormat.java.patch +++ b/patches/minecraft/com/mojang/renderpearl/api/vertex/VertexFormat.java.patch @@ -1,5 +1,5 @@ ---- a/com/mojang/blaze3d/vertex/VertexFormat.java -+++ b/com/mojang/blaze3d/vertex/VertexFormat.java +--- a/com/mojang/renderpearl/api/vertex/VertexFormat.java ++++ b/com/mojang/renderpearl/api/vertex/VertexFormat.java @@ -19,6 +_,7 @@ private final int vertexSize; private final int stepRate; @@ -8,7 +8,7 @@ private VertexFormat(final List elements, final int vertexSize, final int stepRate) { this.vertexSize = vertexSize; -@@ -29,6 +_,11 @@ +@@ -29,7 +_,14 @@ } this.elementValues = elements; @@ -18,14 +18,8 @@ + elementMapping.put(element.name(), element); + this.elementMapping = elementMapping.buildOrThrow(); } - - public static VertexFormat.Builder builder(final int stepRate) { -@@ -69,6 +_,8 @@ - public int hashCode() { - return this.elementValues.hashCode(); - } + + public com.google.common.collect.ImmutableMap getElementMapping() { return elementMapping; } - @OnlyIn(Dist.CLIENT) - public static class Builder { + public static VertexFormat.Builder builder(final int stepRate) { + return new VertexFormat.Builder(stepRate); diff --git a/patches/minecraft/com/mojang/renderpearl/backend/api/GpuDeviceBackend.java.patch b/patches/minecraft/com/mojang/renderpearl/backend/api/GpuDeviceBackend.java.patch new file mode 100644 index 0000000000..04b09de125 --- /dev/null +++ b/patches/minecraft/com/mojang/renderpearl/backend/api/GpuDeviceBackend.java.patch @@ -0,0 +1,13 @@ +--- a/com/mojang/renderpearl/backend/api/GpuDeviceBackend.java ++++ b/com/mojang/renderpearl/backend/api/GpuDeviceBackend.java +@@ -30,6 +_,10 @@ + + GpuTexture createTexture(@Nullable String label, @GpuTexture.Usage int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels); + ++ default GpuTexture createTexture(@Nullable String label, @GpuTexture.Usage int usage, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels, boolean stencil) { ++ return createTexture(label, usage, format, width, height, depthOrLayers, mipLevels); ++ } ++ + GpuTextureView createTextureView(GpuTexture texture, int baseMipLevel, int mipLevels); + + GpuBuffer createBuffer(@Nullable Supplier label, @GpuBuffer.Usage int usage, long size); diff --git a/patches/minecraft/com/mojang/renderpearl/backend/common/BaseGpuTexture.java.patch b/patches/minecraft/com/mojang/renderpearl/backend/common/BaseGpuTexture.java.patch new file mode 100644 index 0000000000..4c82a65fe8 --- /dev/null +++ b/patches/minecraft/com/mojang/renderpearl/backend/common/BaseGpuTexture.java.patch @@ -0,0 +1,43 @@ +--- a/com/mojang/renderpearl/backend/common/BaseGpuTexture.java ++++ b/com/mojang/renderpearl/backend/common/BaseGpuTexture.java +@@ -24,6 +_,19 @@ + final int depthOrLayers, + final int mipLevels + ) { ++ this(usage, label, format, width, height, depthOrLayers, mipLevels, false); ++ } ++ ++ public BaseGpuTexture( ++ final @GpuTexture.Usage int usage, ++ final String label, ++ final GpuFormat format, ++ final int width, ++ final int height, ++ final int depthOrLayers, ++ final int mipLevels, ++ final boolean stencil ++ ) { + this.usage = usage; + this.label = label; + this.format = format; +@@ -31,6 +_,7 @@ + this.height = height; + this.depthOrLayers = depthOrLayers; + this.mipLevels = mipLevels; ++ this.stencilEnabled = stencil; + } + + @Override +@@ -66,5 +_,12 @@ + @Override + public String getLabel() { + return this.label; ++ } ++ ++ private final boolean stencilEnabled; ++ ++ @Override ++ public boolean isStencilEnabled() { ++ return this.stencilEnabled; + } + } diff --git a/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlBackend.java.patch b/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlBackend.java.patch new file mode 100644 index 0000000000..092a010242 --- /dev/null +++ b/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlBackend.java.patch @@ -0,0 +1,11 @@ +--- a/com/mojang/renderpearl/backend/opengl/GlBackend.java ++++ b/com/mojang/renderpearl/backend/opengl/GlBackend.java +@@ -38,6 +_,8 @@ + "OpenGL is not supported: " + Objects.requireNonNullElse(SDLError.SDL_GetError(), ""), + BackendCreationException.Reason.OPENGL_MISSING + ); ++ // If we have loaded the early loading screen, we expect the libraries to be loaded, so don't actually error ++ if (!"OpenGL is not supported: OpenGL library already loaded".equals(this.libraryLoadFailure.getMessage())) + throw this.libraryLoadFailure; + } + diff --git a/patches/minecraft/com/mojang/blaze3d/opengl/GlCommandEncoder.java.patch b/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlCommandEncoder.java.patch similarity index 67% rename from patches/minecraft/com/mojang/blaze3d/opengl/GlCommandEncoder.java.patch rename to patches/minecraft/com/mojang/renderpearl/backend/opengl/GlCommandEncoder.java.patch index 8ef6350531..eb3ba9ebf5 100644 --- a/patches/minecraft/com/mojang/blaze3d/opengl/GlCommandEncoder.java.patch +++ b/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlCommandEncoder.java.patch @@ -1,8 +1,8 @@ ---- a/com/mojang/blaze3d/opengl/GlCommandEncoder.java -+++ b/com/mojang/blaze3d/opengl/GlCommandEncoder.java -@@ -201,6 +_,9 @@ - GlStateManager._colorMask(15); - GlStateManager._clear(16384); +--- a/com/mojang/renderpearl/backend/opengl/GlCommandEncoder.java ++++ b/com/mojang/renderpearl/backend/opengl/GlCommandEncoder.java +@@ -208,6 +_,9 @@ + } + GlStateManager._glFramebufferTexture2D(36160, 36064, 3553, 0, 0); + // Forge: if using stencil, clear it as well (3553 = GlConst.GL_TEXTURE_2D) + if (colorTexture.isStencilEnabled()) diff --git a/patches/minecraft/com/mojang/blaze3d/opengl/GlConst.java.patch b/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlConst.java.patch similarity index 93% rename from patches/minecraft/com/mojang/blaze3d/opengl/GlConst.java.patch rename to patches/minecraft/com/mojang/renderpearl/backend/opengl/GlConst.java.patch index 19c0803e0c..0aaf4a8bbf 100644 --- a/patches/minecraft/com/mojang/blaze3d/opengl/GlConst.java.patch +++ b/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlConst.java.patch @@ -1,5 +1,5 @@ ---- a/com/mojang/blaze3d/opengl/GlConst.java -+++ b/com/mojang/blaze3d/opengl/GlConst.java +--- a/com/mojang/renderpearl/backend/opengl/GlConst.java ++++ b/com/mojang/renderpearl/backend/opengl/GlConst.java @@ -239,6 +_,10 @@ } diff --git a/patches/minecraft/com/mojang/blaze3d/opengl/GlDebug.java.patch b/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlDebug.java.patch similarity index 93% rename from patches/minecraft/com/mojang/blaze3d/opengl/GlDebug.java.patch rename to patches/minecraft/com/mojang/renderpearl/backend/opengl/GlDebug.java.patch index 5f5f2a7781..c67d131924 100644 --- a/patches/minecraft/com/mojang/blaze3d/opengl/GlDebug.java.patch +++ b/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlDebug.java.patch @@ -1,5 +1,5 @@ ---- a/com/mojang/blaze3d/opengl/GlDebug.java -+++ b/com/mojang/blaze3d/opengl/GlDebug.java +--- a/com/mojang/renderpearl/backend/opengl/GlDebug.java ++++ b/com/mojang/renderpearl/backend/opengl/GlDebug.java @@ -22,6 +_,14 @@ @OnlyIn(Dist.CLIENT) diff --git a/patches/minecraft/com/mojang/blaze3d/opengl/GlDevice.java.patch b/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlDevice.java.patch similarity index 62% rename from patches/minecraft/com/mojang/blaze3d/opengl/GlDevice.java.patch rename to patches/minecraft/com/mojang/renderpearl/backend/opengl/GlDevice.java.patch index 6700394d6b..a7e827339c 100644 --- a/patches/minecraft/com/mojang/blaze3d/opengl/GlDevice.java.patch +++ b/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlDevice.java.patch @@ -1,20 +1,6 @@ ---- a/com/mojang/blaze3d/opengl/GlDevice.java -+++ b/com/mojang/blaze3d/opengl/GlDevice.java -@@ -150,7 +_,12 @@ - final int depthOrLayers, - final int mipLevels - ) { -- return this.createTexture(this.debugLabels.exists() && label != null ? label.get() : null, usage, format, width, height, depthOrLayers, mipLevels); -+ return this.createTexture(label, usage, format, width, height, depthOrLayers, mipLevels, false); -+ } -+ -+ @Override -+ public GpuTexture createTexture(final @Nullable Supplier label, @GpuTexture.Usage final int usage, final GpuFormat format, final int width, final int height, final int depthOrLayers, final int mipLevels, final boolean stencil) { -+ return this.createTexture(this.debugLabels.exists() && label != null ? label.get() : null, usage, format, width, height, depthOrLayers, mipLevels, stencil); - } - - @Override -@@ -163,6 +_,11 @@ +--- a/com/mojang/renderpearl/backend/opengl/GlDevice.java ++++ b/com/mojang/renderpearl/backend/opengl/GlDevice.java +@@ -200,6 +_,11 @@ final int depthOrLayers, final int mipLevels ) { @@ -26,7 +12,7 @@ GlStateManager.clearGlErrors(); int id = GlStateManager._genTexture(); if (label == null) { -@@ -186,9 +_,9 @@ +@@ -223,9 +_,9 @@ GlStateManager._texParameter(target, 34892, 0); } @@ -39,7 +25,7 @@ if (glInternalID != 0 && glExternalID != 0 && glType != 0) { if (isCubemap) { for (int cubeTarget : GlConst.CUBEMAP_TARGETS) { -@@ -211,7 +_,7 @@ +@@ -248,7 +_,7 @@ throw new IllegalStateException("OpenGL error " + error); } diff --git a/patches/minecraft/com/mojang/blaze3d/opengl/GlStateManager.java.patch b/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlStateManager.java.patch similarity index 72% rename from patches/minecraft/com/mojang/blaze3d/opengl/GlStateManager.java.patch rename to patches/minecraft/com/mojang/renderpearl/backend/opengl/GlStateManager.java.patch index 11e9b24586..e208c22ead 100644 --- a/patches/minecraft/com/mojang/blaze3d/opengl/GlStateManager.java.patch +++ b/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlStateManager.java.patch @@ -1,18 +1,18 @@ ---- a/com/mojang/blaze3d/opengl/GlStateManager.java -+++ b/com/mojang/blaze3d/opengl/GlStateManager.java -@@ -80,6 +_,11 @@ +--- a/com/mojang/renderpearl/backend/opengl/GlStateManager.java ++++ b/com/mojang/renderpearl/backend/opengl/GlStateManager.java +@@ -82,6 +_,11 @@ } } + public static boolean _isBlendEnabled(int index) { + RenderSystem.assertOnRenderThread(); -+ return BLEND[index].mode.enabled; ++ return BLEND_ENABLE[index]; + } + - public static void _disableBlend(int index) { + public static void _disableBlend(final int index) { RenderSystem.assertOnRenderThread(); - BLEND[index].mode.disable(); -@@ -390,9 +_,17 @@ + if (BLEND_ENABLE[index]) { +@@ -401,9 +_,17 @@ } } diff --git a/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlTexture.java.patch b/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlTexture.java.patch new file mode 100644 index 0000000000..2d098f4399 --- /dev/null +++ b/patches/minecraft/com/mojang/renderpearl/backend/opengl/GlTexture.java.patch @@ -0,0 +1,15 @@ +--- a/com/mojang/renderpearl/backend/opengl/GlTexture.java ++++ b/com/mojang/renderpearl/backend/opengl/GlTexture.java +@@ -28,7 +_,11 @@ + final int id, + final FrameBufferCache frameBufferCache + ) { +- super(usage, label, format, width, height, depthOrLayers, mipLevels); ++ this(usage, label, format, width, height, depthOrLayers, mipLevels, id, frameBufferCache, false); ++ } ++ ++ protected GlTexture(@GpuTexture.Usage int usage, String label, GpuFormat format, int width, int height, int depthOrLayers, int mipLevels, int id, FrameBufferCache frameBufferCache, boolean stencil) { ++ super(usage, label, format, width, height, depthOrLayers, mipLevels, stencil); + this.id = id; + this.frameBufferCache = frameBufferCache; + } diff --git a/patches/minecraft/com/mojang/renderpearl/backend/vulkan/VulkanDevice.java.patch b/patches/minecraft/com/mojang/renderpearl/backend/vulkan/VulkanDevice.java.patch new file mode 100644 index 0000000000..7d369f6736 --- /dev/null +++ b/patches/minecraft/com/mojang/renderpearl/backend/vulkan/VulkanDevice.java.patch @@ -0,0 +1,25 @@ +--- a/com/mojang/renderpearl/backend/vulkan/VulkanDevice.java ++++ b/com/mojang/renderpearl/backend/vulkan/VulkanDevice.java +@@ -213,7 +_,21 @@ + final int depthOrLayers, + final int mipLevels + ) { +- return new VulkanGpuTexture(this, usage, this.isDebuggingEnabled() && label != null ? label : "", format, width, height, depthOrLayers, mipLevels); ++ return createTexture(label, usage, format, width, height, depthOrLayers, mipLevels, false); ++ } ++ ++ @Override ++ public GpuTexture createTexture( ++ final @Nullable String label, ++ final @GpuTexture.Usage int usage, ++ final GpuFormat format, ++ final int width, ++ final int height, ++ final int depthOrLayers, ++ final int mipLevels, ++ final boolean stencil ++ ) { ++ return new VulkanGpuTexture(this, usage, this.isDebuggingEnabled() && label != null ? label : "", format, width, height, depthOrLayers, mipLevels, stencil); + } + + @Override diff --git a/patches/minecraft/com/mojang/renderpearl/backend/vulkan/VulkanGpuTexture.java.patch b/patches/minecraft/com/mojang/renderpearl/backend/vulkan/VulkanGpuTexture.java.patch new file mode 100644 index 0000000000..8d91689add --- /dev/null +++ b/patches/minecraft/com/mojang/renderpearl/backend/vulkan/VulkanGpuTexture.java.patch @@ -0,0 +1,25 @@ +--- a/com/mojang/renderpearl/backend/vulkan/VulkanGpuTexture.java ++++ b/com/mojang/renderpearl/backend/vulkan/VulkanGpuTexture.java +@@ -34,7 +_,21 @@ + final int depthOrLayers, + final int mipLevels + ) { +- super(usage, label, format, width, height, depthOrLayers, mipLevels); ++ this(device, usage, label, format, width, height, depthOrLayers, mipLevels, false); ++ } ++ ++ public VulkanGpuTexture( ++ final VulkanDevice device, ++ final @GpuTexture.Usage int usage, ++ final String label, ++ final GpuFormat format, ++ final int width, ++ final int height, ++ final int depthOrLayers, ++ final int mipLevels, ++ final boolean stencil ++ ) { ++ super(usage, label, format, width, height, depthOrLayers, mipLevels, stencil); + this.device = device; + + try (MemoryStack stack = MemoryStack.stackPush()) { diff --git a/patches/minecraft/com/mojang/blaze3d/systems/GpuDevice.java.patch b/patches/minecraft/com/mojang/renderpearl/frontend/FrontendGpuDevice.java.patch similarity index 62% rename from patches/minecraft/com/mojang/blaze3d/systems/GpuDevice.java.patch rename to patches/minecraft/com/mojang/renderpearl/frontend/FrontendGpuDevice.java.patch index 056d0582eb..b9f8a0952d 100644 --- a/patches/minecraft/com/mojang/blaze3d/systems/GpuDevice.java.patch +++ b/patches/minecraft/com/mojang/renderpearl/frontend/FrontendGpuDevice.java.patch @@ -1,13 +1,14 @@ ---- a/com/mojang/blaze3d/systems/GpuDevice.java -+++ b/com/mojang/blaze3d/systems/GpuDevice.java -@@ -73,6 +_,21 @@ - return this.backend.createTexture(label, usage, format, width, height, depthOrLayers, mipLevels); +--- a/com/mojang/renderpearl/frontend/FrontendGpuDevice.java ++++ b/com/mojang/renderpearl/frontend/FrontendGpuDevice.java +@@ -94,6 +_,21 @@ + return this.createTexture(this.isDebuggingEnabled() && label != null ? label.get() : null, usage, format, width, height, depthOrLayers, mipLevels); } -+ /** Forge: same as {@link #createTexture(Supplier, int, GpuFormat, int, int, int)} but with stencil support */ ++ /** Forge: same as {@link #createTexture(Supplier, int, GpuFormat, int, int, int, int)} but with stencil support */ ++ @Override + public GpuTexture createTexture( + final @Nullable Supplier label, -+ @GpuTexture.Usage final int usage, ++ final @GpuTexture.Usage int usage, + final GpuFormat format, + final int width, + final int height, @@ -15,23 +16,23 @@ + final int mipLevels, + final boolean stencil + ) { -+ this.verifyTextureCreationArgs(usage, width, height, depthOrLayers, mipLevels); -+ return this.backend.createTexture(label, usage, format, width, height, depthOrLayers, mipLevels, stencil); ++ return this.createTexture(this.isDebuggingEnabled() && label != null ? label.get() : null, usage, format, width, height, depthOrLayers, mipLevels, stencil); + } + + @Override public GpuTexture createTexture( final @Nullable String label, - final @GpuTexture.Usage int usage, -@@ -84,6 +_,21 @@ +@@ -106,6 +_,22 @@ ) { this.verifyTextureCreationArgs(usage, width, height, depthOrLayers, mipLevels); return this.backend.createTexture(label, usage, format, width, height, depthOrLayers, mipLevels); + } + -+ /** Forge: same as {@link #createTexture(Supplier, int, GpuFormat, int, int, int)} but with stencil support */ ++ /** Forge: same as {@link #createTexture(String, int, GpuFormat, int, int, int, int)} but with stencil support */ ++ @Override + public GpuTexture createTexture( + final @Nullable String label, -+ @GpuTexture.Usage final int usage, ++ final @GpuTexture.Usage int usage, + final GpuFormat format, + final int width, + final int height, diff --git a/patches/minecraft/net/minecraft/SharedConstants.java.patch b/patches/minecraft/net/minecraft/SharedConstants.java.patch index 661c3eada0..ec602970b1 100644 --- a/patches/minecraft/net/minecraft/SharedConstants.java.patch +++ b/patches/minecraft/net/minecraft/SharedConstants.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/SharedConstants.java +++ b/net/minecraft/SharedConstants.java -@@ -218,6 +_,7 @@ +@@ -219,6 +_,7 @@ } static { diff --git a/patches/minecraft/net/minecraft/advancements/Advancement.java.patch b/patches/minecraft/net/minecraft/advancements/Advancement.java.patch index ededdcc34c..50c7afa3ed 100644 --- a/patches/minecraft/net/minecraft/advancements/Advancement.java.patch +++ b/patches/minecraft/net/minecraft/advancements/Advancement.java.patch @@ -1,15 +1,62 @@ --- a/net/minecraft/advancements/Advancement.java +++ b/net/minecraft/advancements/Advancement.java -@@ -220,7 +_,11 @@ +@@ -31,11 +_,12 @@ + Map> criteria, + AdvancementRequirements requirements, + boolean sendsTelemetryEvent, +- Optional name ++ Optional name, ++ Optional> forgeConditions + ) { + private static final Codec>> CRITERIA_CODEC = Codec.unboundedMap(Codec.STRING, Criterion.CODEC) + .validate(criteria -> criteria.isEmpty() ? DataResult.error(() -> "Advancement criteria cannot be empty") : DataResult.success(criteria)); +- public static final Codec CODEC = RecordCodecBuilder.create( ++ public static final Codec CODEC = net.minecraftforge.common.crafting.ConditionalAdvancement.wrapCodec(RecordCodecBuilder.mapCodec( + i -> i.group( + Identifier.CODEC.optionalFieldOf("parent").forGetter(Advancement::parent), + DisplayInfo.CODEC.optionalFieldOf("display").forGetter(Advancement::display), +@@ -49,7 +_,7 @@ + return new Advancement(parent, display, rewards, criteria, requirements, sendsTelemetryEvent); + }) + ) +- .validate(Advancement::validate); ++ .validate(Advancement::validate)); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + Identifier.STREAM_CODEC.apply(ByteBufCodecs::optional), + Advancement::parent, +@@ -70,9 +_,21 @@ + final AdvancementRewards rewards, + final Map> criteria, + final AdvancementRequirements requirements, ++ final boolean sendsTelemetryEvent, ++ final Optional name ++ ) { ++ this(parent, display, rewards, criteria, requirements, sendsTelemetryEvent, name, Optional.empty()); ++ } ++ ++ public Advancement( ++ final Optional parent, ++ final Optional display, ++ final AdvancementRewards rewards, ++ final Map> criteria, ++ final AdvancementRequirements requirements, + final boolean sendsTelemetryEvent + ) { +- this(parent, display, rewards, Map.copyOf(criteria), requirements, sendsTelemetryEvent, display.map(Advancement::decorateName)); ++ this(parent, display, rewards, Map.copyOf(criteria), requirements, sendsTelemetryEvent, display.map(Advancement::decorateName), Optional.empty()); + } + + private static DataResult validate(final Advancement advancement) { +@@ -235,7 +_,11 @@ } - public AdvancementHolder save(final Consumer output, final String name) { + public AdvancementHolder save(final BootstrapContext output, final String name) { - AdvancementHolder advancement = this.build(Identifier.parse(name)); + return save(output, Identifier.parse(name)); + } + -+ public AdvancementHolder save(Consumer output, Identifier id) { ++ public AdvancementHolder save(final BootstrapContext output, final Identifier id) { + AdvancementHolder advancement = this.build(id); - output.accept(advancement); + advancement.register(output); return advancement; } diff --git a/patches/minecraft/net/minecraft/advancements/AdvancementRewards.java.patch b/patches/minecraft/net/minecraft/advancements/AdvancementRewards.java.patch index 24a7b0abf3..adc00ad6a0 100644 --- a/patches/minecraft/net/minecraft/advancements/AdvancementRewards.java.patch +++ b/patches/minecraft/net/minecraft/advancements/AdvancementRewards.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/advancements/AdvancementRewards.java +++ b/net/minecraft/advancements/AdvancementRewards.java -@@ -43,6 +_,7 @@ +@@ -46,6 +_,7 @@ LootParams params = new LootParams.Builder(level) .withParameter(LootContextParams.THIS_ENTITY, player) .withParameter(LootContextParams.ORIGIN, player.position()) diff --git a/patches/minecraft/net/minecraft/client/Camera.java.patch b/patches/minecraft/net/minecraft/client/Camera.java.patch index 2b21b2469f..ad62181c3a 100644 --- a/patches/minecraft/net/minecraft/client/Camera.java.patch +++ b/patches/minecraft/net/minecraft/client/Camera.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/Camera.java +++ b/net/minecraft/client/Camera.java -@@ -224,11 +_,13 @@ +@@ -228,11 +_,13 @@ } float fov = this.minecraft.options.fov().get().intValue() * Mth.lerp(partialTicks, this.oldFovModifier, this.fovModifier); @@ -16,7 +16,7 @@ } private float modifyFovBasedOnDeathOrFluid(final float partialTicks, float fov) { -@@ -337,9 +_,13 @@ +@@ -341,9 +_,13 @@ } protected void setRotation(final float yRot, final float xRot) { @@ -31,7 +31,7 @@ FORWARDS.rotate(this.rotation, this.forwards); UP.rotate(this.rotation, this.up); LEFT.rotate(this.rotation, this.left); -@@ -370,6 +_,13 @@ +@@ -374,6 +_,13 @@ public float yRot() { return this.yRot; diff --git a/patches/minecraft/net/minecraft/client/KeyMapping.java.patch b/patches/minecraft/net/minecraft/client/KeyMapping.java.patch index ef8d086d33..2027ca672f 100644 --- a/patches/minecraft/net/minecraft/client/KeyMapping.java.patch +++ b/patches/minecraft/net/minecraft/client/KeyMapping.java.patch @@ -70,7 +70,7 @@ return this.key.equals(that.key); } -@@ -179,11 +_,13 @@ +@@ -177,11 +_,13 @@ } public Component getTranslatedKeyMessage() { @@ -85,7 +85,7 @@ } public String saveString() { -@@ -195,11 +_,94 @@ +@@ -193,11 +_,94 @@ } private void registerMapping(final InputConstants.Key key) { diff --git a/patches/minecraft/net/minecraft/client/KeyboardHandler.java.patch b/patches/minecraft/net/minecraft/client/KeyboardHandler.java.patch index 121ab8fa48..fb69f5135e 100644 --- a/patches/minecraft/net/minecraft/client/KeyboardHandler.java.patch +++ b/patches/minecraft/net/minecraft/client/KeyboardHandler.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/client/KeyboardHandler.java +++ b/net/minecraft/client/KeyboardHandler.java -@@ -478,7 +_,7 @@ +@@ -496,7 +_,7 @@ if (screen != null) { try { - if (action != 1 && action != 2) { + if (action != 1 && action != -1) { - if (action == 0 && screen.keyReleased(event)) { + if (action == 0 && net.minecraftforge.client.ForgeHooksClient.onScreenKeyReleased(screen, event)) { if (options.keyDebugModifier.matches(event)) { this.usedDebugKeyAsModifier = false; } -@@ -487,7 +_,7 @@ +@@ -505,7 +_,7 @@ } } else { screen.afterKeyboardAction(); @@ -18,7 +18,7 @@ if (this.minecraft.gui.screen() == null) { InputConstants.Key key = InputConstants.getKey(event); KeyMapping.set(key, false); -@@ -562,6 +_,7 @@ +@@ -578,6 +_,7 @@ } } } @@ -26,7 +26,7 @@ } } -@@ -570,7 +_,7 @@ +@@ -586,7 +_,7 @@ Screen screen = this.minecraft.gui.screen(); if (screen != null && this.minecraft.gui.overlay() == null) { try { @@ -34,4 +34,4 @@ + net.minecraftforge.client.ForgeHooksClient.onScreenCharTyped(screen, event); } catch (Throwable t) { CrashReport report = CrashReport.forThrowable(t, "charTyped event handler"); - screen.fillCrashDetails(report); + CrashReportCategory keyDetails = report.addCategory("Key"); diff --git a/patches/minecraft/net/minecraft/client/Minecraft.java.patch b/patches/minecraft/net/minecraft/client/Minecraft.java.patch index 1986a3b198..58848412c5 100644 --- a/patches/minecraft/net/minecraft/client/Minecraft.java.patch +++ b/patches/minecraft/net/minecraft/client/Minecraft.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/Minecraft.java +++ b/net/minecraft/client/Minecraft.java -@@ -258,7 +_,7 @@ +@@ -265,7 +_,7 @@ import org.slf4j.Logger; @OnlyIn(Dist.CLIENT) @@ -8,8 +8,8 @@ +public class Minecraft extends ReentrantBlockableEventLoop implements WindowEventHandler, net.minecraftforge.client.extensions.IForgeMinecraft { private static Minecraft instance; private static final Logger LOGGER = LogUtils.getLogger(); - private static final int MAX_TICKS_PER_UPDATE = 10; -@@ -410,7 +_,6 @@ + private static final SectionCategory TRACY_CURRENT_LEVEL = TracyClient.createSectionCategory("Level"); +@@ -420,7 +_,6 @@ } }, Util.nonCriticalIoPool()); LOGGER.info("Setting user: {}", this.user.getName()); @@ -17,30 +17,23 @@ this.demo = gameConfig.game.demo; this.allowsMultiplayer = !gameConfig.game.disableMultiplayer; this.allowsChat = !gameConfig.game.disableChat; -@@ -547,12 +_,12 @@ - LOGGER.error("Couldn't set icon", e); - } - -+ // FORGE: Move mouse and keyboard handler setup further below - this.mouseHandler = new MouseHandler(this); -- this.mouseHandler.setup(this.window); +@@ -568,6 +_,7 @@ this.keyboardHandler = new KeyboardHandler(this); -- this.keyboardHandler.setup(this.window); this.options.applyGraphicsPreset(this.options.graphicsPreset().get()); this.resourceManager = new ReloadableResourceManager(PackType.CLIENT_RESOURCES); + net.minecraftforge.client.loading.ClientModLoader.begin(this, this.resourcePackRepository, this.resourceManager); this.resourcePackRepository.reload(); this.options.loadSelectedResourcePacks(this.resourcePackRepository); - this.languageManager = new LanguageManager(this.options.languageCode, var1 -> { -@@ -630,6 +_,7 @@ + this.languageManager = new LanguageManager(this, this.options.languageCode, var1 -> { +@@ -645,6 +_,7 @@ ParticleResources particleResources = new ParticleResources(); this.resourceManager.registerReloadListener(particleResources); this.particleEngine = new ParticleEngine(this.level, particleResources); + net.minecraftforge.client.ForgeHooksClient.onRegisterParticleProviders(particleResources); particleResources.onReload(this.particleEngine::clearParticles); - this.gameRenderer = new GameRenderer(this, this.entityRenderDispatcher.getItemInHandRenderer(), this.modelManager); - WindowRenderState windowRenderState = this.gameRenderer.gameRenderState().windowRenderState; -@@ -647,6 +_,7 @@ + this.gameRenderer = new GameRenderer(this, new FirstPersonHandsAndItemsRenderer(this), this.modelManager, this.itemModelResolver); + this.resourceManager.registerReloadListener(this.gameRenderer); +@@ -663,6 +_,7 @@ this.window.getHeight() ); this.levelExtractor = new LevelExtractor(this, this.gameRenderer.gameRenderState().levelRenderState, this.levelRenderer); @@ -48,25 +41,15 @@ this.resourceManager.registerReloadListener(this.levelExtractor); this.resourceManager.registerReloadListener(this.levelRenderer.cloudRenderer()); this.gpuWarnlistManager = new GpuWarnlistManager(); -@@ -654,6 +_,9 @@ - this.resourceManager.registerReloadListener(this.regionalCompliancies); - this.gui = new Gui(this, new Hud(this), this.gameRenderer.gameRenderState().guiRenderState); - this.gui.registerReloadListeners(this.resourceManager); -+ // FORGE: Moved keyboard and mouse handler setup below ingame gui creation to prevent NPEs in them. -+ this.mouseHandler.setup(this.window); -+ this.keyboardHandler.setup(this.window); - RealmsClient realmsClient = RealmsClient.getOrCreate(this); - this.realmsDataFetcher = new RealmsDataFetcher(realmsClient); - RenderSystem.setErrorCallback(this::onFullscreenError); -@@ -686,6 +_,7 @@ - } +@@ -694,6 +_,7 @@ + MessageBox.error(message.toString()); } + net.minecraftforge.client.ForgeHooksClient.initClientHooks(this, this.resourceManager); - this.window.updateRawMouseInput(this.options.rawMouseInput().get()); this.window.setAllowCursorChanges(this.options.allowCursorChanges().get()); - this.window.setDefaultErrorCallback(); -@@ -710,14 +_,15 @@ + this.window.setQuitShortcuts(this.options.quitShortcuts().get()); + if (InputQuirks.EMULATE_RIGHT_CLICK_WITH_CTRL_KEY) { +@@ -721,14 +_,15 @@ .createReload(Util.backgroundExecutor().forName("resourceLoad"), this, RESOURCE_RELOAD_INITIAL_TASK, packs); GameLoadTimesEvent.INSTANCE.beginStep(TelemetryProperty.LOAD_TIME_LOADING_OVERLAY_MS); GameLoadCookie loadCookie = new GameLoadCookie(realmsClient, gameConfig.quickPlay); @@ -84,7 +67,7 @@ this.quickPlayLog = QuickPlayLog.of(gameConfig.quickPlay.logPath()); this.framerateLimitTracker = new FramerateLimitTracker(this.options, this); this.fpsPieProfiler = new ContinuousProfiler(Util.timeSource(), () -> this.fpsPieRenderTicks, this.framerateLimitTracker::isHeavilyThrottled); -@@ -801,6 +_,7 @@ +@@ -812,6 +_,7 @@ StringBuilder builder = new StringBuilder("Minecraft"); if (checkModStatus().shouldReportAsModified()) { builder.append("*"); @@ -92,16 +75,16 @@ } builder.append(" "); -@@ -824,6 +_,8 @@ +@@ -835,6 +_,8 @@ } - private static UserApiService createUserApiService(final YggdrasilAuthenticationService authService, final GameConfig config) { + private static UserApiService createUserApiService(final MinecraftServicesDiscoveryService discoveryService, final GameConfig config) { + if ("0".equals(config.user.user.getAccessToken())) // Forge: We use "0" in dev. Short circuit to stop exception spam. + return UserApiService.OFFLINE; - return config.game.offlineDeveloperMode ? UserApiService.OFFLINE : authService.createUserApiService(config.user.user.getAccessToken()); + return config.game.offlineDeveloperMode ? UserApiService.OFFLINE : discoveryService.createUserApiService(config.user.user.getAccessToken()); } -@@ -840,7 +_,7 @@ +@@ -851,7 +_,7 @@ } private void rollbackResourcePacks(final Throwable t, final @Nullable GameLoadCookie loadCookie) { @@ -110,33 +93,33 @@ this.clearResourcePacksOnError(t, null, loadCookie); } else { Util.throwAsRuntime(t); -@@ -1141,6 +_,7 @@ - Util.shutdownExecutors(); +@@ -1148,6 +_,7 @@ + FreeTypeUtil.destroy(); this.windowSurface.close(); RenderSystem.shutdownRenderer(); + net.minecraftforge.fml.config.ConfigTracker.forceUnload(); } catch (Throwable t) { LOGGER.error("Shutdown failure!", t); throw t; -@@ -1301,7 +_,9 @@ +@@ -1305,7 +_,9 @@ profiler.popPush("gpuAsync"); RenderSystem.executePendingTasks(); profiler.pop(); + net.minecraftforge.client.event.ForgeEventFactoryClient.onRenderTickStart(this.deltaTracker); - this.gameRenderer.render(this.deltaTracker, advanceGameTime); + this.gameRenderer.render(); + net.minecraftforge.client.event.ForgeEventFactoryClient.onRenderTickEnd(this.deltaTracker); } - profiler.push("present"); -@@ -1425,6 +_,7 @@ + profiler.push("swapchainBlit"); +@@ -1432,6 +_,7 @@ this.window.setGuiScale(guiScale); if (this.gui.screen() != null) { this.gui.screen().resize(this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight()); + this.gui.resizeLayers(this.window.getGuiScaledWidth(), this.window.getGuiScaledHeight()); } - this.mouseHandler.setIgnoreFirstMove(); -@@ -1576,6 +_,7 @@ + this.mouseHandler.resyncMousePosition(); +@@ -1595,6 +_,7 @@ } public void stop() { @@ -144,38 +127,35 @@ this.running = false; } -@@ -1599,10 +_,18 @@ +@@ -1622,9 +_,16 @@ if (down && this.hitResult != null && this.hitResult.getType() == HitResult.Type.BLOCK) { BlockHitResult blockHit = (BlockHitResult)this.hitResult; BlockPos pos = blockHit.getBlockPos(); - if (!this.level.getBlockState(pos).isAir()) { + if (!this.level.isEmptyBlock(pos)) { -+ var inputEvent = new net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered(0, this.options.keyAttack, InteractionHand.MAIN_HAND); -+ if (net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.BUS.post(inputEvent)) { ++ var inputEvent = new net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.Attack(this.options.keyAttack, InteractionHand.MAIN_HAND); ++ if (net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.Attack.BUS.post(inputEvent)) { + if (inputEvent.shouldSwingHand()) { -+ this.level.addBreakingBlockEffect(pos, blockHit); -+ this.player.swing(InteractionHand.MAIN_HAND); ++ this.player.swing(InteractionHand.MAIN_HAND, swingAnimation, false); + } + return; + } Direction direction = blockHit.getDirection(); - if (this.gameMode.continueDestroyBlock(pos, direction)) { -- this.level.addBreakingBlockEffect(pos, direction); + if (this.gameMode.continueDestroyBlock(pos, direction) && inputEvent.shouldSwingHand()) { -+ this.level.addBreakingBlockEffect(pos, blockHit); - this.player.swing(InteractionHand.MAIN_HAND); + this.player.swing(InteractionHand.MAIN_HAND, swingAnimation, false); + this.player.connection.send(ServerboundPunchPacket.INSTANCE); } - } -@@ -1656,6 +_,8 @@ +@@ -1679,6 +_,8 @@ return true; } -+ var inputEvent = new net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered(0, this.options.keyAttack, InteractionHand.MAIN_HAND); -+ if (!net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.BUS.post(inputEvent)) ++ var inputEvent = new net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.Attack(this.options.keyAttack, InteractionHand.MAIN_HAND); ++ if (!net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.Attack.BUS.post(inputEvent)) switch (this.hitResult.getType()) { case ENTITY: AttackRange customItemRange = heldItem.get(DataComponents.ATTACK_RANGE); -@@ -1666,7 +_,7 @@ +@@ -1689,7 +_,7 @@ case BLOCK: BlockHitResult blockHit = (BlockHitResult)this.hitResult; BlockPos pos = blockHit.getBlockPos(); @@ -184,49 +164,53 @@ this.gameMode.startDestroyBlock(pos, blockHit.getDirection()); if (this.level.getBlockState(pos).isAir()) { endAttack = true; -@@ -1679,8 +_,10 @@ +@@ -1702,10 +_,13 @@ } this.player.resetAttackStrengthTicker(); + net.minecraftforge.event.ForgeEventFactory.onLeftClickEmpty(this.player); } -+ if (inputEvent.shouldSwingHand()) - this.player.swing(InteractionHand.MAIN_HAND); ++ if (inputEvent.shouldSwingHand()) { + this.player.swing(InteractionHand.MAIN_HAND, attackAnimation, false); + this.player.connection.send(ServerboundPunchPacket.INSTANCE); ++ } return endAttack; } -@@ -1696,6 +_,12 @@ - } + } +@@ -1726,6 +_,13 @@ + } - for (InteractionHand hand : InteractionHand.values()) { -+ var inputEvent = new net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered(1, this.options.keyUse, hand); -+ if (net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.BUS.post(inputEvent)) { -+ if (inputEvent.shouldSwingHand()) this.player.swing(hand); + SwingAnimation swingAnimation = heldItem.getInteractAnimation(); ++ ++ var inputEvent = new net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.UseItem(this.options.keyUse, hand); ++ if (net.minecraftforge.client.event.InputEvent.InteractionKeyMappingTriggered.UseItem.BUS.post(inputEvent)) { ++ if (inputEvent.shouldSwingHand()) this.player.swing(hand, swingAnimation, false); + return; + } + - ItemStack heldItem = this.player.getItemInHand(hand); - if (!heldItem.isItemEnabled(this.level.enabledFeatures())) { - return; -@@ -1712,7 +_,7 @@ + if (this.hitResult != null) { + switch (this.hitResult.getType()) { + case ENTITY: +@@ -1737,7 +_,7 @@ if (this.player.isWithinEntityInteractionRange(entity, 0.0) && this.gameMode.interact(this.player, entity, entityHit, hand) instanceof InteractionResult.Success success) { -- if (success.swingSource() == InteractionResult.SwingSource.CLIENT) { -+ if (success.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) { - this.player.swing(hand); +- if (success.swingSource() == InteractionResult.SwingSource.PREDICTED) { ++ if (success.swingSource() == InteractionResult.SwingSource.PREDICTED && inputEvent.shouldSwingHand()) { + this.player.swing(hand, swingAnimation, false); } -@@ -1724,7 +_,7 @@ +@@ -1749,7 +_,7 @@ int oldCount = heldItem.getCount(); InteractionResult useResult = this.gameMode.useItemOn(this.player, hand, blockHit); if (useResult instanceof InteractionResult.Success success) { -- if (success.swingSource() == InteractionResult.SwingSource.CLIENT) { -+ if (success.swingSource() == InteractionResult.SwingSource.CLIENT && inputEvent.shouldSwingHand()) { - this.player.swing(hand); +- if (success.swingSource() == InteractionResult.SwingSource.PREDICTED) { ++ if (success.swingSource() == InteractionResult.SwingSource.PREDICTED && inputEvent.shouldSwingHand()) { + this.player.swing(hand, swingAnimation, false); if (!heldItem.isEmpty() && (heldItem.getCount() != oldCount || this.player.hasInfiniteMaterials())) { - this.gameRenderer.itemInHandRenderer.itemUsed(hand); -@@ -1740,6 +_,9 @@ + this.player.itemUsed(hand); +@@ -1765,6 +_,9 @@ } } @@ -234,9 +218,9 @@ + net.minecraftforge.event.ForgeEventFactory.onRightClickEmpty(this.player, hand); + if (!heldItem.isEmpty() && this.gameMode.useItem(this.player, hand) instanceof InteractionResult.Success success) { - if (success.swingSource() == InteractionResult.SwingSource.CLIENT) { - this.player.swing(hand); -@@ -1768,6 +_,8 @@ + if (success.swingSource() == InteractionResult.SwingSource.PREDICTED) { + this.player.swing(hand, swingAnimation, false); +@@ -1793,6 +_,8 @@ } ProfilerFiller profiler = Profiler.get(); @@ -245,7 +229,7 @@ profiler.push("gameMode"); if (!this.pause && this.level != null) { this.gameMode.tick(); -@@ -1817,6 +_,7 @@ +@@ -1845,6 +_,7 @@ this.tutorial.tick(); @@ -253,7 +237,7 @@ try { this.level.tick(() -> true); } catch (Throwable t) { -@@ -1830,6 +_,7 @@ +@@ -1858,6 +_,7 @@ throw new ReportedException(report); } @@ -261,7 +245,7 @@ } profiler.popPush("animateTick"); -@@ -1854,6 +_,7 @@ +@@ -1882,6 +_,7 @@ profiler.popPush("keyboard"); this.keyboardHandler.tick(); profiler.pop(); @@ -269,7 +253,7 @@ } private boolean isLevelRunningNormally() { -@@ -2059,6 +_,7 @@ +@@ -2088,6 +_,7 @@ } public void setLevel(final ClientLevel level) { @@ -277,7 +261,7 @@ this.level = level; this.updateLevelInEngines(level); } -@@ -2120,6 +_,7 @@ +@@ -2149,6 +_,7 @@ IntegratedServer server = this.singleplayerServer; this.singleplayerServer = null; this.gameRenderer.resetData(); @@ -285,7 +269,7 @@ this.gameMode = null; this.narrator.clear(); this.gui.setClientLevelTeardownInProgress(true); -@@ -2127,6 +_,7 @@ +@@ -2156,6 +_,7 @@ try { if (this.level != null) { this.gui.hud.onDisconnected(); @@ -293,7 +277,7 @@ } this.level = null; -@@ -2141,6 +_,7 @@ +@@ -2171,6 +_,7 @@ } profiler.pop(); @@ -301,7 +285,7 @@ } this.setScreenAndShow(screen); -@@ -2354,6 +_,7 @@ +@@ -2403,6 +_,7 @@ private void pickBlockOrEntity() { if (this.hitResult != null && this.hitResult.getType() != HitResult.Type.MISS) { diff --git a/patches/minecraft/net/minecraft/client/MouseHandler.java.patch b/patches/minecraft/net/minecraft/client/MouseHandler.java.patch index 7be4daacb7..d24a5c7827 100644 --- a/patches/minecraft/net/minecraft/client/MouseHandler.java.patch +++ b/patches/minecraft/net/minecraft/client/MouseHandler.java.patch @@ -1,23 +1,23 @@ --- a/net/minecraft/client/MouseHandler.java +++ b/net/minecraft/client/MouseHandler.java -@@ -77,6 +_,7 @@ +@@ -79,6 +_,7 @@ this.activeButton = null; } -+ if (net.minecraftforge.client.event.ForgeEventFactoryClient.onMouseButtonPre(buttonInfo, action)) return; ++ if (net.minecraftforge.client.event.ForgeEventFactoryClient.onMouseButtonPre(rawButtonInfo, action)) return; if (this.minecraft.gui.overlay() == null) { if (pressed - && this.minecraft.handleGlobalKeyPress(InputConstants.Type.MOUSE.getOrCreate(buttonInfo.button()), buttonInfo.hasControlDownWithQuirk())) { -@@ -101,7 +_,7 @@ + && this.minecraft +@@ -104,7 +_,7 @@ && currentTime - this.lastClick.time() < 250L && this.lastClick.screen() == screen && this.lastClickButton == event.button(); - if (screen.mouseClicked(event, doubleClick)) { + if (net.minecraftforge.client.event.ForgeEventFactoryClient.onScreenMouseClicked(screen, xm, ym, event, doubleClick)) { this.lastClick = new MouseHandler.LastClick(currentTime, screen); - this.lastClickButton = buttonInfo.button(); + this.lastClickButton = rawButtonInfo.button(); return; -@@ -116,7 +_,7 @@ +@@ -118,7 +_,7 @@ } } else { try { @@ -26,15 +26,15 @@ return; } } catch (Throwable t) { -@@ -146,6 +_,7 @@ +@@ -147,6 +_,7 @@ KeyMapping.click(mouseKey); } } -+ net.minecraftforge.client.event.ForgeEventFactoryClient.onMouseButtonPost(buttonInfo, action); ++ net.minecraftforge.client.event.ForgeEventFactoryClient.onMouseButtonPost(rawButtonInfo, action); } } -@@ -197,7 +_,9 @@ +@@ -182,7 +_,9 @@ if (this.minecraft.gui.screen() != null) { double xm = this.getScaledXPos(this.minecraft.getWindow()); double ym = this.getScaledYPos(this.minecraft.getWindow()); @@ -45,7 +45,7 @@ this.minecraft.gui.screen().afterMouseAction(); } else if (this.minecraft.player != null) { Vector2i wheelXY = this.scrollWheelHandler.onMouseScroll(scaledXOffset, scaledYOffset); -@@ -206,6 +_,7 @@ +@@ -191,6 +_,7 @@ } int wheel = wheelXY.y == 0 ? -wheelXY.x : wheelXY.y; @@ -53,7 +53,7 @@ if (this.minecraft.player.isSpectator()) { if (this.minecraft.gui.hud.getSpectatorGui().isMenuActive()) { this.minecraft.gui.hud.getSpectatorGui().onMouseScrolled(-wheel); -@@ -312,7 +_,7 @@ +@@ -285,7 +_,7 @@ double dy = getScaledYPos(window, this.accumulatedDY); try { @@ -61,8 +61,8 @@ + net.minecraftforge.client.ForgeHooksClient.onScreenMouseDrag(screen, new MouseButtonEvent(xm, ym, this.activeButton), dx, dy); } catch (Throwable t) { CrashReport report = CrashReport.forThrowable(t, "mouseDragged event handler"); - screen.fillCrashDetails(report); -@@ -397,6 +_,14 @@ + CrashReportCategory mouseDetails = report.addCategory("Mouse"); +@@ -369,6 +_,14 @@ public double ypos() { return this.ypos; diff --git a/patches/minecraft/net/minecraft/client/Options.java.patch b/patches/minecraft/net/minecraft/client/Options.java.patch index 165bac1558..b0f225bd40 100644 --- a/patches/minecraft/net/minecraft/client/Options.java.patch +++ b/patches/minecraft/net/minecraft/client/Options.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/Options.java +++ b/net/minecraft/client/Options.java -@@ -986,6 +_,7 @@ +@@ -1011,6 +_,7 @@ ); public boolean syncWrites; public boolean startedCleanly = true; @@ -8,7 +8,7 @@ public static boolean isSoundDeviceDefault(final String deviceName) { return deviceName.equals(""); -@@ -1474,6 +_,7 @@ +@@ -1510,6 +_,7 @@ } public Options(final Minecraft minecraft, final File workingDirectory) { @@ -16,7 +16,7 @@ this.minecraft = minecraft; this.optionsFile = new File(workingDirectory, "options.txt"); boolean largeDistances = Runtime.getRuntime().maxMemory() >= 1000000000L; -@@ -1624,15 +_,28 @@ +@@ -1663,20 +_,32 @@ this.startedCleanly = access.process("startedCleanly", this.startedCleanly); access.process("musicToast", this.musicToast); access.process("musicFrequency", this.musicFrequency); @@ -31,13 +31,18 @@ + String currentValue = keyMapping.saveString() + (keyMapping.getKeyModifier() != net.minecraftforge.client.settings.KeyModifier.NONE ? ":" + keyMapping.getKeyModifier() : ""); String newValue = access.process("key_" + keyMapping.getName(), currentValue); if (!currentValue.equals(newValue)) { - keyMapping.setKey(InputConstants.getKey(newValue)); -+ if (newValue.indexOf(':') != -1) { -+ String[] pts = newValue.split(":"); -+ keyMapping.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.valueFromString(pts[1]), InputConstants.getKey(pts[0])); -+ } else { -+ keyMapping.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.NONE, InputConstants.getKey(newValue)); -+ } + try { +- keyMapping.setKey(InputConstants.getKey(newValue)); ++ if (newValue.indexOf(':') != -1) { ++ String[] pts = newValue.split(":"); ++ keyMapping.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.valueFromString(pts[1]), InputConstants.getKey(pts[0])); ++ } else { ++ keyMapping.setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier.NONE, InputConstants.getKey(newValue)); ++ } + } catch (IllegalArgumentException e) { + LOGGER.warn("Invalid keyMapping {} = {}, unbinding", keyMapping.getName(), newValue, e); + keyMapping.setKey(InputConstants.UNKNOWN); + } } } + } @@ -46,7 +51,7 @@ for (SoundSource source : SoundSource.values()) { access.process("soundCategory_" + source.getName(), this.soundSourceVolumes.get(source)); } -@@ -1647,6 +_,10 @@ +@@ -1691,6 +_,10 @@ } public void load() { @@ -57,7 +62,7 @@ try { if (!this.optionsFile.exists()) { return; -@@ -1666,7 +_,8 @@ +@@ -1710,7 +_,8 @@ } final CompoundTag options = this.dataFix(rawOptions); @@ -67,7 +72,7 @@ new Options.FieldAccess() { private @Nullable String getValue(final String name) { Tag tag = options.get(name); -@@ -1748,6 +_,17 @@ +@@ -1792,6 +_,17 @@ ); options.getString("fullscreenResolution").ifPresent(fullscreenResolution -> this.fullscreenVideoModeString = fullscreenResolution); KeyMapping.resetMapping(); @@ -85,7 +90,7 @@ } catch (Exception e) { LOGGER.error("Failed to load options", e); } -@@ -1778,9 +_,11 @@ +@@ -1821,9 +_,11 @@ public void save() { try (final PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(this.optionsFile), StandardCharsets.UTF_8))) { writer.println("version:" + SharedConstants.getCurrentVersion().dataVersion().version()); @@ -97,7 +102,7 @@ writer.print(name); writer.print(':'); } -@@ -1836,6 +_,12 @@ +@@ -1879,6 +_,12 @@ if (fullscreenVideoModeString != null) { writer.println("fullscreenResolution:" + fullscreenVideoModeString); } @@ -110,7 +115,7 @@ } catch (Exception e) { LOGGER.error("Failed to save options", e); } -@@ -1873,6 +_,7 @@ +@@ -1916,6 +_,7 @@ } public void broadcastOptions() { @@ -118,7 +123,7 @@ if (this.minecraft.player != null) { this.minecraft.player.connection.broadcastClientInformation(this.buildPlayerInformation()); } -@@ -1986,6 +_,23 @@ +@@ -2029,6 +_,23 @@ public static Component genericValueLabel(final Component caption, final int value) { return genericValueLabel(caption, Component.literal(Integer.toString(value))); diff --git a/patches/minecraft/net/minecraft/client/data/models/ItemModelGenerators.java.patch b/patches/minecraft/net/minecraft/client/data/models/ItemModelGenerators.java.patch index bc85a58c04..ceca52caef 100644 --- a/patches/minecraft/net/minecraft/client/data/models/ItemModelGenerators.java.patch +++ b/patches/minecraft/net/minecraft/client/data/models/ItemModelGenerators.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/data/models/ItemModelGenerators.java +++ b/net/minecraft/client/data/models/ItemModelGenerators.java -@@ -868,6 +_,9 @@ +@@ -921,6 +_,9 @@ this.declareCustomModelItem(Items.COD); this.declareCustomModelItem(Items.FEATHER); this.declareCustomModelItem(Items.LEAD); diff --git a/patches/minecraft/net/minecraft/client/gui/Gui.java.patch b/patches/minecraft/net/minecraft/client/gui/Gui.java.patch index 8aeebcebc3..e36820f8a2 100644 --- a/patches/minecraft/net/minecraft/client/gui/Gui.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/Gui.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/client/gui/Gui.java +++ b/net/minecraft/client/gui/Gui.java -@@ -64,7 +_,7 @@ +@@ -67,7 +_,7 @@ import org.slf4j.Logger; @OnlyIn(Dist.CLIENT) -public class Gui { +public class Gui extends net.minecraftforge.client.gui.overlay.ForgeLayerInstance { private static final Logger LOGGER = LogUtils.getLogger(); + private static final SectionCategory TRACY_CURRENT_SCREEN = TracyClient.createSectionCategory("Current Screen"); private static final Component SOCIAL_INTERACTIONS_NOT_AVAILABLE = Component.translatable("multiplayer.socialInteractions.not_available"); - public static final Component SAVING_LEVEL = Component.translatable("menu.savingLevel"); -@@ -80,6 +_,7 @@ +@@ -85,6 +_,7 @@ private @Nullable TutorialToast socialInteractionsToast; public Gui(final Minecraft minecraft, final Hud hud, final GuiRenderState guiRenderState) { @@ -17,7 +17,7 @@ this.minecraft = minecraft; this.hud = hud; this.splashManager = new SplashManager(minecraft.getUser()); -@@ -175,7 +_,7 @@ +@@ -174,7 +_,7 @@ profiler.push("screen"); try { @@ -26,11 +26,13 @@ } catch (Throwable t) { CrashReport report = CrashReport.forThrowable(t, "Rendering screen"); CrashReportCategory category = report.addCategory("Screen render details"); -@@ -224,12 +_,6 @@ - LOGGER.error("setScreen called from non-game thread"); +@@ -228,14 +_,6 @@ + this.screenTracySection = null; } - if (this.screen != null) { +- this.screen.clearFocus(); +- this.minecraft.textInputManager().stopTextInput(); - this.screen.removed(); - } else { - this.minecraft.setLastInputType(InputType.NONE); @@ -39,7 +41,7 @@ if (screen == null) { if (this.clientLevelTeardownInProgress) { throw new IllegalStateException("Trying to return to in-game GUI during disconnection"); -@@ -248,6 +_,22 @@ +@@ -254,6 +_,24 @@ } } @@ -54,6 +56,8 @@ + if (screen != old) { + if (old != null) { + net.minecraftforge.client.event.ForgeEventFactoryClient.onScreenClose(old); ++ this.screen.clearFocus(); ++ this.minecraft.textInputManager().stopTextInput(); + old.removed(); + } else { + this.minecraft.setLastInputType(InputType.NONE); @@ -62,7 +66,7 @@ this.screen = screen; if (this.screen != null) { this.screen.added(); -@@ -465,5 +_,10 @@ +@@ -474,5 +_,10 @@ } ) ); diff --git a/patches/minecraft/net/minecraft/client/gui/GuiGraphicsExtractor.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiGraphicsExtractor.java.patch index 3f0f48e0ba..9db12c558f 100644 --- a/patches/minecraft/net/minecraft/client/gui/GuiGraphicsExtractor.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/GuiGraphicsExtractor.java.patch @@ -9,7 +9,7 @@ private static final int EXTRA_SPACE_AFTER_FIRST_TOOLTIP_LINE = 2; private final Minecraft minecraft; private final Matrix3x2fStack pose; -@@ -912,6 +_,7 @@ +@@ -914,6 +_,7 @@ CrashReport report = CrashReport.forThrowable(t, "Rendering item"); CrashReportCategory category = report.addCategory("Item being rendered"); category.setDetail("Item Type", () -> String.valueOf(itemStack.getItem())); @@ -17,7 +17,7 @@ category.setDetail("Item Components", () -> String.valueOf(itemStack.getComponents())); category.setDetail("Item Foil", () -> String.valueOf(itemStack.hasFoil())); throw new ReportedException(report); -@@ -938,6 +_,7 @@ +@@ -940,6 +_,7 @@ this.itemCooldown(itemStack, x, y); this.itemCount(font, itemStack, x, y, countText); this.pose.popMatrix(); @@ -25,7 +25,7 @@ } } -@@ -1106,16 +_,25 @@ +@@ -1109,16 +_,29 @@ this.setTooltipForNextFrame(this.minecraft.font, formattedCharSequences, DefaultTooltipPositioner.INSTANCE, x, y, false); } @@ -33,7 +33,7 @@ public void setTooltipForNextFrame(final Font font, final ItemStack itemStack, final int xo, final int yo) { + this.tooltipStack = itemStack; this.setTooltipForNextFrame( - font, Screen.getTooltipFromItem(this.minecraft, itemStack), itemStack.getTooltipImage(), xo, yo, itemStack.get(DataComponents.TOOLTIP_STYLE) + font, Screen.getTooltipFromItem(this.minecraft, itemStack), itemStack.getTooltipImage(), xo, yo, itemStack.get(DataComponents.TOOLTIP_STYLE), true ); + this.tooltipStack = ItemStack.EMPTY; } @@ -43,17 +43,21 @@ } + public void setTooltipForNextFrame(Font font, List texts, Optional optionalImage, ItemStack stack, int xo, int yo) { -+ this.tooltipStack = stack; -+ this.setTooltipForNextFrame(font, texts, optionalImage, xo, yo, stack.get(DataComponents.TOOLTIP_STYLE)); -+ this.tooltipStack = ItemStack.EMPTY; ++ this.setTooltipForNextFrame(font, texts, optionalImage, stack, xo, yo, false); ++ } ++ ++ public void setTooltipForNextFrame(Font font, List texts, Optional optionalImage, ItemStack stack, int xo, int yo, final boolean extraSpaceAfterFirstLine) { ++ this.tooltipStack = stack; ++ this.setTooltipForNextFrame(font, texts, optionalImage, xo, yo, stack.get(DataComponents.TOOLTIP_STYLE), extraSpaceAfterFirstLine); ++ this.tooltipStack = ItemStack.EMPTY; + } + public void setTooltipForNextFrame( final Font font, final List texts, -@@ -1124,11 +_,7 @@ - final int yo, - final @Nullable Identifier style +@@ -1139,11 +_,7 @@ + final @Nullable Identifier style, + final boolean extraSpaceAfterFirstLine ) { - List components = texts.stream() - .map(Component::getVisualOrderText) @@ -61,10 +65,10 @@ - .collect(Util.toMutableList()); - optionalImage.ifPresent(image -> components.add(components.isEmpty() ? 0 : 1, ClientTooltipComponent.create(image))); + List components = net.minecraftforge.client.ForgeHooksClient.gatherTooltipComponents(this.tooltipStack, texts, optionalImage, xo, guiWidth(), guiHeight(), font); - this.setTooltipForNextFrameInternal(font, components, xo, yo, DefaultTooltipPositioner.INSTANCE, style, false); + this.setTooltipForNextFrameInternal(font, components, xo, yo, DefaultTooltipPositioner.INSTANCE, style, false, extraSpaceAfterFirstLine); } -@@ -1156,7 +_,22 @@ +@@ -1171,7 +_,22 @@ } public void setComponentTooltipForNextFrame(final Font font, final List lines, final int xo, final int yo) { @@ -88,36 +92,34 @@ } public void setComponentTooltipForNextFrame(final Font font, final List lines, final int xo, final int yo, final @Nullable Identifier style) { -@@ -1207,10 +_,16 @@ +@@ -1235,9 +_,14 @@ ) { if (!lines.isEmpty()) { if (this.deferredTooltip == null || replaceExisting) { -- this.deferredTooltip = () -> this.tooltip(font, lines, xo, yo, positioner, style); +- this.deferredTooltip = () -> this.tooltip(font, lines, xo, yo, positioner, style, extraSpaceAfterFirstLine); + final var stackContext = this.tooltipStack; -+ this.deferredTooltip = () -> this.tooltip(font, lines, xo, yo, positioner, style, stackContext); ++ this.deferredTooltip = () -> this.tooltip(font, lines, xo, yo, positioner, style, extraSpaceAfterFirstLine, stackContext); } } - } -+ -+ public void tooltip(Font font, List lines, int xo, int yo, ClientTooltipPositioner positioner, @Nullable Identifier style) { -+ tooltip(font, lines, xo, yo, positioner, style, ItemStack.EMPTY); + } + ++ public void tooltip(Font font, List lines, int xo, int yo, ClientTooltipPositioner positioner, @Nullable Identifier style, boolean extraSpaceAfterFirstLine) { ++ tooltip(font, lines, xo, yo, positioner, style, extraSpaceAfterFirstLine, ItemStack.EMPTY); + } public void tooltip( - final Font font, -@@ -1218,13 +_,16 @@ - final int xo, +@@ -1247,13 +_,16 @@ final int yo, final ClientTooltipPositioner positioner, -- final @Nullable Identifier style -+ final @Nullable Identifier style, + final @Nullable Identifier style, +- boolean extraSpaceAfterFirstLine ++ boolean extraSpaceAfterFirstLine, + ItemStack itemstack ) { + var preEvent = net.minecraftforge.client.ForgeHooksClient.onRenderTooltipPre(itemstack, this, xo, yo, guiWidth(), guiHeight(), lines, font, positioner, style); + if (preEvent == null) return; int textWidth = 0; - int tempHeight = lines.size() == 1 ? -2 : 0; + int tempHeight = extraSpaceAfterFirstLine && lines.size() != 1 ? 0 : -2; for (ClientTooltipComponent line : lines) { - int lineWidth = line.getWidth(font); @@ -125,7 +127,7 @@ if (lineWidth > textWidth) { textWidth = lineWidth; } -@@ -1234,25 +_,25 @@ +@@ -1263,25 +_,25 @@ int w = textWidth; int h = tempHeight; @@ -141,9 +143,9 @@ for (int i = 0; i < lines.size(); i++) { ClientTooltipComponent line = lines.get(i); - line.extractText(this, font, x, localY); -- localY += line.getHeight(font) + (i == 0 ? 2 : 0); +- localY += line.getHeight(font) + (extraSpaceAfterFirstLine && i == 0 ? 2 : 0); + line.extractText(this, preEvent.getFont(), x, localY); -+ localY += line.getHeight(preEvent.getFont()) + (i == 0 ? 2 : 0); ++ localY += line.getHeight(preEvent.getFont()) + (extraSpaceAfterFirstLine && i == 0 ? 2 : 0); } localY = y; @@ -151,13 +153,13 @@ for (int i = 0; i < lines.size(); i++) { ClientTooltipComponent line = lines.get(i); - line.extractImage(font, x, localY, w, h, this); -- localY += line.getHeight(font) + (i == 0 ? 2 : 0); +- localY += line.getHeight(font) + (extraSpaceAfterFirstLine && i == 0 ? 2 : 0); + line.extractImage(preEvent.getFont(), x, localY, w, h, this); -+ localY += line.getHeight(preEvent.getFont()) + (i == 0 ? 2 : 0); ++ localY += line.getHeight(preEvent.getFont()) + (extraSpaceAfterFirstLine && i == 0 ? 2 : 0); } this.pose.popMatrix(); -@@ -1326,6 +_,14 @@ +@@ -1355,6 +_,14 @@ private ActiveTextCollector.Parameters createDefaultTextParameters(final float opacity) { return new ActiveTextCollector.Parameters(new Matrix3x2f(this.pose), opacity, this.scissorStack.peek()); diff --git a/patches/minecraft/net/minecraft/client/gui/Hud.java.patch b/patches/minecraft/net/minecraft/client/gui/Hud.java.patch index 52f4edb8f3..bd3b9a089d 100644 --- a/patches/minecraft/net/minecraft/client/gui/Hud.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/Hud.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/Hud.java +++ b/net/minecraft/client/gui/Hud.java -@@ -156,7 +_,7 @@ +@@ -157,7 +_,7 @@ public float vignetteBrightness = 1.0F; private int toolHighlightTimer; private ItemStack lastToolHighlight = ItemStack.EMPTY; @@ -9,7 +9,7 @@ private final SubtitleOverlay subtitleOverlay; private final SpectatorGui spectatorGui; private final PlayerTabOverlay tabList; -@@ -198,6 +_,7 @@ +@@ -199,6 +_,7 @@ () -> new JumpableVehicleBar(minecraft) ); this.resetTitleTimes(); @@ -17,7 +17,7 @@ } public void registerReloadListeners(final ReloadableResourceManager resourceManager) { -@@ -221,6 +_,10 @@ +@@ -222,6 +_,10 @@ public void extractRenderState(final GuiGraphicsExtractor graphics, final DeltaTracker deltaTracker) { this.minecraft.gameRenderer.gameRenderState().guiRenderState.isHudHidden = this.isHidden; if (!(this.minecraft.gui.screen() instanceof LevelLoadingScreen)) { @@ -28,7 +28,7 @@ if (!this.isHidden) { this.extractCameraOverlays(graphics, deltaTracker); this.extractCrosshair(graphics, deltaTracker); -@@ -404,7 +_,7 @@ +@@ -405,7 +_,7 @@ int mouseX = Mth.floor(this.minecraft.mouseHandler.getScaledXPos(window)); int mouseY = Mth.floor(this.minecraft.mouseHandler.getScaledYPos(window)); graphics.nextStratum(); @@ -37,7 +37,7 @@ } } -@@ -497,6 +_,8 @@ +@@ -500,6 +_,8 @@ for (MobEffectInstance instance : Ordering.natural().reverse().sortedCopy(activeEffects)) { Holder effect = instance.getEffect(); @@ -46,7 +46,7 @@ if (instance.showIcon()) { int x = graphics.guiWidth(); int y = 1; -@@ -527,6 +_,7 @@ +@@ -530,6 +_,7 @@ } } @@ -54,7 +54,7 @@ graphics.blitSprite(RenderPipelines.GUI_TEXTURED, getMobEffectSprite(effect), x + 3, y + 3, 18, 18, ARGB.white(alpha)); } } -@@ -629,15 +_,37 @@ +@@ -632,15 +_,37 @@ } public void extractSelectedItemName(final GuiGraphicsExtractor graphics) { @@ -94,7 +94,7 @@ if (!this.minecraft.gameMode.canHurtPlayer()) { y += 14; } -@@ -648,7 +_,7 @@ +@@ -651,7 +_,7 @@ } if (alpha > 0) { @@ -103,7 +103,7 @@ } } } -@@ -1216,7 +_,9 @@ +@@ -1219,7 +_,9 @@ this.toolHighlightTimer = 0; } else if (this.lastToolHighlight.isEmpty() || !selected.is(this.lastToolHighlight.getItem()) diff --git a/patches/minecraft/net/minecraft/client/gui/screens/PauseScreen.java.patch b/patches/minecraft/net/minecraft/client/gui/screens/PauseScreen.java.patch index 7e40bbe1dc..ea515d9dfe 100644 --- a/patches/minecraft/net/minecraft/client/gui/screens/PauseScreen.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/screens/PauseScreen.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/client/gui/screens/PauseScreen.java +++ b/net/minecraft/client/gui/screens/PauseScreen.java -@@ -165,6 +_,7 @@ - Button.builder(OPTIONS, var1x -> this.minecraft.gui.setScreen(new OptionsScreen(this, this.minecraft.options, true))).width(204).build(), 2 - ); +@@ -163,6 +_,7 @@ + helper.addChild(this.openScreenButton(OPTIONS, () -> new OptionsScreen(this, this.minecraft.options))); + helper.addChild(this.openScreenButton(WORLD_OPTIONS, () -> new WorldOptionsScreen(this, this.minecraft.level))); } + helper.addChild(Button.builder(Component.translatable("fml.menu.mods"), button -> this.minecraft.gui.setScreen(new net.minecraftforge.client.gui.ModListScreen(this))).width(BUTTON_WIDTH_FULL).build(), 2); diff --git a/patches/minecraft/net/minecraft/client/gui/screens/Screen.java.patch b/patches/minecraft/net/minecraft/client/gui/screens/Screen.java.patch index 9ec2c33b30..fbf78a2eab 100644 --- a/patches/minecraft/net/minecraft/client/gui/screens/Screen.java.patch +++ b/patches/minecraft/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 -@@ -196,7 +_,7 @@ +@@ -202,7 +_,7 @@ } public void onClose() { @@ -9,7 +9,7 @@ } protected T addRenderableWidget(final T widget) { -@@ -327,8 +_,10 @@ +@@ -333,8 +_,10 @@ this.width = width; this.height = height; if (!this.initialized) { @@ -20,7 +20,7 @@ } else { this.repositionElements(); } -@@ -345,8 +_,10 @@ +@@ -351,8 +_,10 @@ protected void rebuildWidgets() { this.clearWidgets(); this.clearFocus(); @@ -31,7 +31,7 @@ } protected void fadeWidgets(final float widgetFade) { -@@ -386,6 +_,8 @@ +@@ -392,6 +_,8 @@ this.extractMenuBackground(graphics); } @@ -40,7 +40,7 @@ this.minecraft.gui.hud.extractDeferredSubtitles(); } -@@ -471,6 +_,19 @@ +@@ -472,6 +_,19 @@ } public void onFilesDrop(final List files) { @@ -59,4 +59,4 @@ + this.children.add(guiEventListener); } - private void scheduleNarration(final long delay, final boolean ignoreSuppression) { + private void scheduleNarration(final long delay, final boolean ignoreSuppression, final NarrationTrigger narrationTrigger) { diff --git a/patches/minecraft/net/minecraft/client/gui/screens/advancements/AdvancementTab.java.patch b/patches/minecraft/net/minecraft/client/gui/screens/advancements/AdvancementTab.java.patch index a76516fffd..4f4a8f551c 100644 --- a/patches/minecraft/net/minecraft/client/gui/screens/advancements/AdvancementTab.java.patch +++ b/patches/minecraft/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 -@@ -41,6 +_,7 @@ +@@ -38,6 +_,7 @@ private float fade; private boolean centered; private @Nullable AdvancementWidget hovered; @@ -8,15 +8,22 @@ public AdvancementTab( final Minecraft minecraft, -@@ -62,6 +_,15 @@ - this.addWidget(this.root, rootNode.holder()); +@@ -60,6 +_,11 @@ + this.addWidget(root); } -+ public AdvancementTab(Minecraft mc, AdvancementsScreen screen, AdvancementTabType type, int index, int page, AdvancementNode adv, DisplayInfo info) { -+ this(mc, screen, type, index, adv, info); ++ public AdvancementTab(Minecraft mc, AdvancementsScreen screen, AdvancementTabType type, int index, int page, AdvancementWidget root, ItemStackTemplate icon, Component title, Identifier background) { ++ this(mc, screen, type, index, root, icon, title, background); + this.page = page; + } + + public void copyPosition(final AdvancementTab source) { + this.scrollX = source.scrollX; + this.scrollY = source.scrollY; +@@ -70,6 +_,10 @@ + this.centered = source.centered; + } + + public int getPage() { + return this.page; + } @@ -24,14 +31,14 @@ public AdvancementTabType getType() { return this.type; } -@@ -169,8 +_,8 @@ - } +@@ -179,8 +_,8 @@ + Identifier background = rootDisplay.background().get().texturePath(); for (AdvancementTabType type : AdvancementTabType.values()) { - if (index < type.getMax()) { -- return new AdvancementTab(minecraft, screen, type, index, root, display.get()); +- return new AdvancementTab(minecraft, screen, type, index, rootWidget, rootDisplay.icon(), rootDisplay.title(), background); + if ((index % AdvancementTabType.MAX_TABS) < type.getMax()) { -+ return new AdvancementTab(minecraft, screen, type, index % AdvancementTabType.MAX_TABS, index / AdvancementTabType.MAX_TABS, root, display.get()); ++ return new AdvancementTab(minecraft, screen, type, index % AdvancementTabType.MAX_TABS, index / AdvancementTabType.MAX_TABS, rootWidget, rootDisplay.icon(), rootDisplay.title(), background); } index -= type.getMax(); diff --git a/patches/minecraft/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java.patch b/patches/minecraft/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java.patch index a1e863e50a..4b35d2228d 100644 --- a/patches/minecraft/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/screens/advancements/AdvancementsScreen.java.patch @@ -34,10 +34,10 @@ for (AdvancementTab tab : this.tabs.values()) { - if (tab.isMouseOver(xo, yo, event.x(), event.y())) { + if (tab.getPage() == tabPage && tab.isMouseOver(xo, yo, event.x(), event.y())) { - this.advancements.setSelectedTab(tab.getRootNode().holder(), true); + this.advancements.setSelectedTab(tab.getRootAdvancement(), true); break; } -@@ -208,10 +_,12 @@ +@@ -212,10 +_,12 @@ graphics.blit(RenderPipelines.GUI_TEXTURED, WINDOW_LOCATION, this.leftPos, this.topPos, 0.0F, 0.0F, 252, 140, 256, 256); if (this.tabs.size() > 1) { for (AdvancementTab tab : this.tabs.values()) { @@ -50,7 +50,7 @@ tab.extractIcon(graphics, this.leftPos, this.topPos); } } -@@ -230,6 +_,7 @@ +@@ -234,6 +_,7 @@ if (this.tabs.size() > 1) { for (AdvancementTab tab : this.tabs.values()) { diff --git a/patches/minecraft/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java.patch b/patches/minecraft/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java.patch index 54657e5031..9b19f5330e 100644 --- a/patches/minecraft/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/screens/inventory/AbstractContainerScreen.java.patch @@ -20,8 +20,8 @@ ItemStack item = this.hoveredSlot.getItem(); if (this.menu.getCarried().isEmpty() || this.showTooltipWithItemInHand(item)) { graphics.setTooltipForNextFrame( -- this.font, this.getTooltipFromContainerItem(item), item.getTooltipImage(), mouseX, mouseY, item.get(DataComponents.TOOLTIP_STYLE) -+ this.font, this.getTooltipFromContainerItem(item), item.getTooltipImage(), item, mouseX, mouseY +- this.font, this.getTooltipFromContainerItem(item), item.getTooltipImage(), mouseX, mouseY, item.get(DataComponents.TOOLTIP_STYLE), true ++ this.font, this.getTooltipFromContainerItem(item), item.getTooltipImage(), item, mouseX, mouseY, true ); } } @@ -35,7 +35,7 @@ } protected void extractLabels(final GuiGraphicsExtractor graphics, final int xm, final int ym) { -@@ -285,7 +_,8 @@ +@@ -297,7 +_,8 @@ return true; } @@ -45,7 +45,7 @@ Slot slot = this.getHoveredSlot(event.x(), event.y()); this.doubleclick = this.lastClickSlot == slot && doubleClick; this.skipNextRelease = false; -@@ -295,6 +_,7 @@ +@@ -307,6 +_,7 @@ int xo = this.leftPos; int yo = this.topPos; boolean clickedOutside = this.hasClickedOutside(event.x(), event.y(), xo, yo); @@ -53,25 +53,25 @@ int slotId = -1; if (slot != null) { slotId = slot.index; -@@ -306,7 +_,7 @@ +@@ -318,7 +_,7 @@ if (slotId != -1 && !this.isQuickCrafting) { if (this.menu.getCarried().isEmpty()) { - if (cloning) { + if (this.minecraft.options.keyPickItem.isActiveAndMatches(mouseKey)) { - this.slotClicked(slot, slotId, event.button(), ContainerInput.CLONE); + this.slotClicked(slot, slotId, event, ContainerInput.CLONE); } else { boolean quickKey = slotId != -999 && event.hasShiftDown(); -@@ -330,7 +_,7 @@ +@@ -342,7 +_,7 @@ this.quickCraftingType = 0; - } else if (event.button() == 1) { + } else if (event.button() == 3) { this.quickCraftingType = 1; - } else if (cloning) { + } else if (this.minecraft.options.keyPickItem.isActiveAndMatches(mouseKey)) { this.quickCraftingType = 2; } } -@@ -374,10 +_,13 @@ +@@ -386,10 +_,13 @@ @Override public boolean mouseReleased(final MouseButtonEvent event) { @@ -85,25 +85,25 @@ int slotId = -1; if (slot != null) { slotId = slot.index; -@@ -394,7 +_,7 @@ +@@ -406,7 +_,7 @@ if (target != null && target.mayPickup(this.minecraft.player) && target.hasItem() - && target.container == slot.container + && target.isSameInventory(slot) && AbstractContainerMenu.canItemQuickReplace(target, this.lastQuickMoved, true)) { - this.slotClicked(target, target.index, event.button(), ContainerInput.QUICK_MOVE); + this.slotClicked(target, target.index, event, ContainerInput.QUICK_MOVE); } -@@ -421,7 +_,7 @@ +@@ -433,7 +_,7 @@ if (this.isQuickCrafting && !this.quickCraftSlots.isEmpty()) { this.quickCraftToSlots(); } else if (!this.menu.getCarried().isEmpty()) { - if (this.minecraft.options.keyPickItem.matchesMouse(event)) { + if (this.minecraft.options.keyPickItem.isActiveAndMatches(mouseKey)) { - this.slotClicked(slot, slotId, event.button(), ContainerInput.CLONE); + this.slotClicked(slot, slotId, event, ContainerInput.CLONE); } else { boolean quickKey = slotId != -999 && event.hasShiftDown(); -@@ -489,7 +_,7 @@ +@@ -501,7 +_,7 @@ return true; } @@ -112,7 +112,7 @@ this.onClose(); return true; } -@@ -587,4 +_,11 @@ +@@ -599,4 +_,11 @@ super.onClose(); } diff --git a/patches/minecraft/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch b/patches/minecraft/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch index 89c9860fb0..74a03606cb 100644 --- a/patches/minecraft/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java +++ b/net/minecraft/client/gui/screens/inventory/CreativeModeInventoryScreen.java -@@ -116,6 +_,8 @@ +@@ -117,6 +_,8 @@ private final Set> visibleTags = new HashSet<>(); private final boolean displayOperatorCreativeTab; private final EffectsInInventory effects; @@ -9,7 +9,7 @@ public CreativeModeInventoryScreen(final LocalPlayer player, final FeatureFlagSet enabledFeatures, final boolean displayOperatorCreativeTab) { super(new CreativeModeInventoryScreen.ItemPickerMenu(player), player.getInventory(), CommonComponents.EMPTY, 195, 136); -@@ -164,7 +_,7 @@ +@@ -165,7 +_,7 @@ private void refreshCurrentTabContents(final Collection displayList) { int oldRowIndex = this.menu.getRowIndexForScroll(this.scrollOffs); this.menu.items.clear(); @@ -18,7 +18,7 @@ this.refreshSearchResults(); } else { this.menu.items.addAll(displayList); -@@ -330,6 +_,36 @@ +@@ -331,6 +_,36 @@ protected void init() { if (this.minecraft.player.hasInfiniteMaterials()) { super.init(); @@ -55,7 +55,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); -@@ -379,7 +_,7 @@ +@@ -380,7 +_,7 @@ return false; } @@ -64,7 +64,7 @@ return false; } -@@ -407,7 +_,7 @@ +@@ -408,7 +_,7 @@ @Override public boolean keyPressed(final KeyEvent event) { this.ignoreTextInput = false; @@ -73,7 +73,7 @@ if (this.minecraft.options.keyChat.matches(event)) { this.ignoreTextInput = true; this.selectTab(CreativeModeTabs.searchTab()); -@@ -443,6 +_,7 @@ +@@ -449,6 +_,7 @@ } private void refreshSearchResults() { @@ -81,7 +81,7 @@ this.menu.items.clear(); this.visibleTags.clear(); String searchTerm = this.searchBox.getValue(); -@@ -455,10 +_,10 @@ +@@ -461,10 +_,10 @@ SearchTree tree; if (searchTerm.startsWith("#")) { searchTerm = searchTerm.substring(1); @@ -94,7 +94,7 @@ } this.menu.items.addAll(tree.search(searchTerm.toLowerCase(Locale.ROOT))); -@@ -486,7 +_,7 @@ +@@ -492,7 +_,7 @@ @Override protected void extractLabels(final GuiGraphicsExtractor graphics, final int xm, final int ym) { if (selectedTab.showTitle()) { @@ -103,7 +103,7 @@ } } -@@ -496,7 +_,7 @@ +@@ -502,7 +_,7 @@ double xm = event.x() - this.leftPos; double ym = event.y() - this.topPos; @@ -112,7 +112,7 @@ if (this.checkTabClicked(tab, xm, ym)) { return true; } -@@ -518,7 +_,7 @@ +@@ -524,7 +_,7 @@ double ym = event.y() - this.topPos; this.scrolling = false; @@ -121,7 +121,7 @@ if (this.checkTabClicked(tab, xm, ym)) { this.selectTab(tab); return true; -@@ -611,13 +_,15 @@ +@@ -617,13 +_,15 @@ this.originalSlots = null; } @@ -138,7 +138,7 @@ this.refreshSearchResults(); } else { -@@ -682,7 +_,14 @@ +@@ -688,7 +_,14 @@ this.effects.extractRenderState(graphics, mouseX, mouseY); super.extractRenderState(graphics, mouseX, mouseY, a); @@ -154,7 +154,7 @@ if (this.checkTabHovering(graphics, tab, mouseX, mouseY)) { break; } -@@ -704,7 +_,7 @@ +@@ -710,7 +_,7 @@ public List getTooltipFromContainerItem(final ItemStack itemStack) { boolean isCreativeSlot = this.hoveredSlot != null && this.hoveredSlot instanceof CreativeModeInventoryScreen.CustomCreativeSlot; boolean isSingleCategoryTab = selectedTab.getType() == CreativeModeTab.Type.CATEGORY; @@ -163,7 +163,7 @@ TooltipFlag.Default originalTooltipStyle = this.minecraft.options.advancedItemTooltips ? TooltipFlag.Default.ADVANCED : TooltipFlag.Default.NORMAL; TooltipFlag tooltipStyle = isCreativeSlot ? originalTooltipStyle.asCreative() : originalTooltipStyle; List originalLines = itemStack.getTooltipLines(Item.TooltipContext.of(this.minecraft.level), this.minecraft.player, tooltipStyle); -@@ -728,7 +_,7 @@ +@@ -734,7 +_,7 @@ int i = 1; for (CreativeModeTab tab : CreativeModeTabs.tabs()) { @@ -172,7 +172,7 @@ linesToDisplay.add(i++, tab.getDisplayName().copy().withStyle(ChatFormatting.BLUE)); } } -@@ -740,7 +_,7 @@ +@@ -746,7 +_,7 @@ public void extractBackground(final GuiGraphicsExtractor graphics, final int mouseX, final int mouseY, final float a) { super.extractBackground(graphics, mouseX, mouseY, a); @@ -181,7 +181,7 @@ if (tab != selectedTab) { this.extractTabButton(graphics, mouseX, mouseY, tab); } -@@ -775,6 +_,7 @@ +@@ -781,6 +_,7 @@ graphics.blitSprite(RenderPipelines.GUI_TEXTURED, sprite, xscr, yscr + (int)((yscr2 - yscr - 17) * this.scrollOffs), 12, 15); } @@ -189,7 +189,7 @@ this.extractTabButton(graphics, mouseX, mouseY, selectedTab); if (selectedTab.getType() == CreativeModeTab.Type.INVENTORY) { InventoryScreen.extractEntityInInventoryFollowsMouse( -@@ -784,7 +_,7 @@ +@@ -790,7 +_,7 @@ } private int getTabX(final CreativeModeTab tab) { @@ -198,7 +198,7 @@ int spacing = 27; int x = 27 * pos; if (tab.isAlignedRight()) { -@@ -796,7 +_,7 @@ +@@ -802,7 +_,7 @@ private int getTabY(final CreativeModeTab tab) { int y = 0; @@ -207,7 +207,7 @@ y -= 32; } else { y += this.imageHeight; -@@ -824,8 +_,8 @@ +@@ -830,8 +_,8 @@ protected void extractTabButton(final GuiGraphicsExtractor graphics, final int mouseX, final int mouseY, final CreativeModeTab tab) { boolean selected = tab == selectedTab; @@ -218,7 +218,7 @@ int x = this.leftPos + this.getTabX(tab); int y = this.topPos - (isTop ? 28 : -(this.imageHeight - 4)); Identifier[] sprites; -@@ -875,6 +_,14 @@ +@@ -881,6 +_,14 @@ } } @@ -233,7 +233,7 @@ @OnlyIn(Dist.CLIENT) private static class CustomCreativeSlot extends Slot { public CustomCreativeSlot(final Container container, final int slot, final int x, final int y) { -@@ -1055,6 +_,22 @@ +@@ -1061,6 +_,22 @@ @Override public boolean mayPickup(final Player player) { return this.target.mayPickup(player); diff --git a/patches/minecraft/net/minecraft/client/gui/screens/inventory/HangingSignEditScreen.java.patch b/patches/minecraft/net/minecraft/client/gui/screens/inventory/HangingSignEditScreen.java.patch index 617ada3af3..72bb3a6e42 100644 --- a/patches/minecraft/net/minecraft/client/gui/screens/inventory/HangingSignEditScreen.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/screens/inventory/HangingSignEditScreen.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/client/gui/screens/inventory/HangingSignEditScreen.java +++ b/net/minecraft/client/gui/screens/inventory/HangingSignEditScreen.java -@@ -16,7 +_,7 @@ +@@ -17,7 +_,7 @@ private static final Vector3fc TEXT_SCALE = new Vector3f(1.0F, 1.0F, 1.0F); private static final int TEXTURE_WIDTH = 16; private static final int TEXTURE_HEIGHT = 16; - private final Identifier texture = Identifier.withDefaultNamespace("textures/gui/hanging_signs/" + this.woodType.name() + ".png"); + private final Identifier texture = Identifier.parse(this.woodType.name() + ".png").withPrefix("textures/gui/hanging_signs/"); - public HangingSignEditScreen(final SignBlockEntity sign, final boolean isFrontText, final boolean shouldFilter) { - super(sign, isFrontText, shouldFilter, Component.translatable("hanging_sign.edit")); + public HangingSignEditScreen(final SignBlockEntity sign, final SignTextSlot slot, final boolean shouldFilter) { + super(sign, slot, shouldFilter, Component.translatable("hanging_sign.edit")); diff --git a/patches/minecraft/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java.patch b/patches/minecraft/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java.patch index c377afcffa..b0107c45ec 100644 --- a/patches/minecraft/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java +++ b/net/minecraft/client/gui/screens/options/controls/KeyBindsList.java -@@ -116,9 +_,10 @@ +@@ -118,9 +_,10 @@ this.name = name; this.changeButton = Button.builder(name, button -> { KeyBindsList.this.keyBindsScreen.selectedKey = key; @@ -12,7 +12,7 @@ .createNarration( defaultNarrationSupplier -> key.isUnbound() ? Component.translatable("narrator.controls.unbound", name) -@@ -126,7 +_,7 @@ +@@ -128,7 +_,7 @@ ) .build(); this.resetButton = Button.builder(RESET_BUTTON_TITLE, button -> { @@ -21,7 +21,7 @@ KeyBindsList.this.resetMappingAndUpdateButtons(); }).bounds(0, 0, 50, 20).createNarration(defaultNarrationSupplier -> Component.translatable("narrator.controls.reset", name)).build(); this.refreshEntry(); -@@ -167,7 +_,8 @@ +@@ -169,7 +_,8 @@ MutableComponent tooltip = Component.empty(); if (!this.key.isUnbound()) { for (KeyMapping otherKey : KeyBindsList.this.minecraft.options.keyMappings) { diff --git a/patches/minecraft/net/minecraft/client/gui/screens/options/controls/KeyBindsScreen.java.patch b/patches/minecraft/net/minecraft/client/gui/screens/options/controls/KeyBindsScreen.java.patch index 8558529b3e..6997fb251b 100644 --- a/patches/minecraft/net/minecraft/client/gui/screens/options/controls/KeyBindsScreen.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/screens/options/controls/KeyBindsScreen.java.patch @@ -9,7 +9,7 @@ } this.keyBindsList.resetMappingAndUpdateButtons(); -@@ -74,11 +_,12 @@ +@@ -78,11 +_,12 @@ public boolean keyPressed(final KeyEvent event) { if (this.selectedKey != null) { if (event.isEscape()) { @@ -24,7 +24,7 @@ this.selectedKey = null; this.lastKeySelection = Util.getMillis(); this.keyBindsList.resetMappingAndUpdateButtons(); -@@ -101,5 +_,18 @@ +@@ -105,5 +_,18 @@ } this.resetButton.active = canReset; diff --git a/patches/minecraft/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java.patch b/patches/minecraft/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java.patch index f34ed9e0f1..edbd9e4f58 100644 --- a/patches/minecraft/net/minecraft/client/gui/screens/worldselection/WorldOpenFlows.java.patch +++ b/patches/minecraft/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 -@@ -495,6 +_,8 @@ +@@ -504,6 +_,8 @@ this.minecraft.setScreenAndShow(new GenericMessageScreen(Component.translatable("selectWorld.resource_load"))); PackRepository packRepository = ServerPacksSource.createPackRepository(worldAccess); @@ -9,7 +9,7 @@ WorldStem worldStem; try { worldStem = this.loadWorldStem(worldAccess, levelDataTag, safeMode, packRepository); -@@ -537,6 +_,8 @@ +@@ -546,6 +_,8 @@ WorldData data = worldDataAndGenSettings.data(); boolean oldCustomized = worldDataAndGenSettings.genSettings().options().isOldCustomizedWorld(); boolean unstable = data.worldGenSettingsLifecycle() != Lifecycle.stable(); @@ -18,7 +18,7 @@ if (!oldCustomized && !unstable) { this.openWorldLoadBundledResourcePack(worldAccess, worldStem, packRepository, onCancel); } else { -@@ -553,6 +_,8 @@ +@@ -562,6 +_,8 @@ private void openWorldLoadBundledResourcePack( final LevelStorageSource.LevelStorageAccess worldAccess, final WorldStem worldStem, final PackRepository packRepository, final Runnable onCancel ) { diff --git a/patches/minecraft/net/minecraft/client/model/HumanoidModel.java.patch b/patches/minecraft/net/minecraft/client/model/HumanoidModel.java.patch index 8309858145..a19b9e7fd7 100644 --- a/patches/minecraft/net/minecraft/client/model/HumanoidModel.java.patch +++ b/patches/minecraft/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 -@@ -391,6 +_,8 @@ +@@ -380,6 +_,8 @@ break; case SPEAR: - SpearAnimations.thirdPersonHandUse(this.rightArm, this.head, true, state.getUseItemStackForArm(HumanoidArm.RIGHT), state); + SpearAnimations.thirdPersonHandUse(this.rightArm, this.head, HumanoidArm.RIGHT, state.getUseItemStackForArm(HumanoidArm.RIGHT), state); + default: -+ state.rightArmPose.applyTransform(this, state, net.minecraft.world.entity.HumanoidArm.RIGHT); ++ state.rightArmPose.applyTransform(this, state, HumanoidArm.RIGHT); } } -@@ -436,6 +_,8 @@ +@@ -425,6 +_,8 @@ break; case SPEAR: - SpearAnimations.thirdPersonHandUse(this.leftArm, this.head, false, state.getUseItemStackForArm(HumanoidArm.LEFT), state); + SpearAnimations.thirdPersonHandUse(this.leftArm, this.head, HumanoidArm.LEFT, state.getUseItemStackForArm(HumanoidArm.LEFT), state); + default: -+ state.leftArmPose.applyTransform(this, state, net.minecraft.world.entity.HumanoidArm.LEFT); ++ state.leftArmPose.applyTransform(this, state, HumanoidArm.LEFT); } } -@@ -497,7 +_,7 @@ +@@ -487,7 +_,7 @@ } @OnlyIn(Dist.CLIENT) @@ -27,7 +27,7 @@ EMPTY(false, false), ITEM(false, false), BLOCK(false, false), -@@ -523,10 +_,29 @@ +@@ -513,10 +_,29 @@ ArmPose(final boolean twoHanded, final boolean affectsOffhandPose) { this.twoHanded = twoHanded; this.affectsOffhandPose = affectsOffhandPose; diff --git a/patches/minecraft/net/minecraft/client/model/geom/LayerDefinitions.java.patch b/patches/minecraft/net/minecraft/client/model/geom/LayerDefinitions.java.patch index 2c26bba477..c32bb1281a 100644 --- a/patches/minecraft/net/minecraft/client/model/geom/LayerDefinitions.java.patch +++ b/patches/minecraft/net/minecraft/client/model/geom/LayerDefinitions.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/client/model/geom/LayerDefinitions.java +++ b/net/minecraft/client/model/geom/LayerDefinitions.java -@@ -557,6 +_,7 @@ - result.put(ModelLayers.PALE_OAK_CHEST_BOAT, chestBoatModel); - result.put(ModelLayers.MANGROVE_BOAT, boatModel); +@@ -561,6 +_,7 @@ result.put(ModelLayers.MANGROVE_CHEST_BOAT, chestBoatModel); + result.put(ModelLayers.POPLAR_BOAT, boatModel); + result.put(ModelLayers.POPLAR_CHEST_BOAT, chestBoatModel); + net.minecraftforge.client.ForgeHooksClient.loadLayerDefinitions(result); ImmutableMap definitions = result.build(); List missingDefinitions = ModelLayers.getKnownLocations().filter(l -> !definitions.containsKey(l)).toList(); diff --git a/patches/minecraft/net/minecraft/client/multiplayer/ClientChunkCache.java.patch b/patches/minecraft/net/minecraft/client/multiplayer/ClientChunkCache.java.patch index e20e0e1797..1575264969 100644 --- a/patches/minecraft/net/minecraft/client/multiplayer/ClientChunkCache.java.patch +++ b/patches/minecraft/net/minecraft/client/multiplayer/ClientChunkCache.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/multiplayer/ClientChunkCache.java +++ b/net/minecraft/client/multiplayer/ClientChunkCache.java -@@ -64,6 +_,7 @@ +@@ -61,6 +_,7 @@ int index = this.storage.getIndex(pos.x(), pos.z()); LevelChunk currentChunk = this.storage.getChunk(index); if (isValidChunk(currentChunk, pos.x(), pos.z())) { @@ -8,7 +8,7 @@ this.storage.drop(index, currentChunk); } } -@@ -124,6 +_,7 @@ +@@ -115,6 +_,7 @@ } this.level.onChunkLoaded(pos); diff --git a/patches/minecraft/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch b/patches/minecraft/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch index 7502d7fa93..4690579432 100644 --- a/patches/minecraft/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch +++ b/patches/minecraft/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 -@@ -157,6 +_,7 @@ +@@ -158,6 +_,7 @@ @Override public void handleCustomPayload(final ClientboundCustomPayloadPacket packet) { diff --git a/patches/minecraft/net/minecraft/client/multiplayer/ClientLevel.java.patch b/patches/minecraft/net/minecraft/client/multiplayer/ClientLevel.java.patch index e4aedd7cfb..5e2c1433f8 100644 --- a/patches/minecraft/net/minecraft/client/multiplayer/ClientLevel.java.patch +++ b/patches/minecraft/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 -@@ -165,6 +_,7 @@ +@@ -168,6 +_,7 @@ cache.put(BiomeColors.FOLIAGE_COLOR_RESOLVER, new BlockTintCache(pos -> this.calculateBlockTint(pos, BiomeColors.FOLIAGE_COLOR_RESOLVER))); cache.put(BiomeColors.DRY_FOLIAGE_COLOR_RESOLVER, new BlockTintCache(pos -> this.calculateBlockTint(pos, BiomeColors.DRY_FOLIAGE_COLOR_RESOLVER))); cache.put(BiomeColors.WATER_COLOR_RESOLVER, new BlockTintCache(pos -> this.calculateBlockTint(pos, BiomeColors.WATER_COLOR_RESOLVER))); @@ -8,7 +8,7 @@ }); private final ClientChunkCache chunkSource; private final Deque lightUpdateQueue = Queues.newArrayDeque(); -@@ -178,6 +_,8 @@ +@@ -181,6 +_,8 @@ private final Long2ObjectMap> destructionProgress = new Long2ObjectOpenHashMap<>(); private final int seaLevel; private static final Set MARKER_PARTICLE_ITEMS = Set.of(Items.BARRIER, Items.LIGHT); @@ -17,7 +17,7 @@ public void handleBlockChangedAck(final int sequence) { if (SharedConstants.DEBUG_BLOCK_BREAK) { -@@ -260,6 +_,8 @@ +@@ -263,6 +_,8 @@ this.serverSimulationDistance = serverSimulationDistance; this.environmentAttributes = this.addEnvironmentAttributeLayers(EnvironmentAttributeSystem.builder()).build(); this.updateSkyBrightness(); @@ -26,15 +26,15 @@ } private EnvironmentAttributeSystem.Builder addEnvironmentAttributeLayers(final EnvironmentAttributeSystem.Builder environmentAttributes) { -@@ -471,6 +_,7 @@ - entity.setOldPosAndRot(); - entity.tickCount++; +@@ -473,6 +_,7 @@ + public void tickNonPassenger(final Entity entity) { Profiler.get().push(entity.typeHolder()::getRegisteredName); + entity.commonTick(); + if (entity.canUpdate()) entity.tick(); Profiler.get().pop(); -@@ -527,8 +_,10 @@ +@@ -528,8 +_,10 @@ } public void addEntity(final Entity entity) { @@ -45,7 +45,7 @@ } public void removeEntity(final int id, final Entity.RemovalReason reason) { -@@ -692,8 +_,10 @@ +@@ -693,8 +_,10 @@ final float pitch, final long seed ) { @@ -57,7 +57,7 @@ } } -@@ -707,8 +_,10 @@ +@@ -708,8 +_,10 @@ final float pitch, final long seed ) { @@ -69,7 +69,7 @@ } } -@@ -1081,7 +_,7 @@ +@@ -1095,7 +_,7 @@ @Override public void addDestroyBlockEffect(final BlockPos pos, final BlockState blockState) { @@ -78,7 +78,7 @@ VoxelShape shape = blockState.getShape(this, pos); double density = 0.25; shape.forAllBoxes( -@@ -1108,6 +_,7 @@ +@@ -1122,6 +_,7 @@ new TerrainParticle( this, pos.getX() + x, pos.getY() + y, pos.getZ() + z, relX - 0.5, relY - 0.5, relZ - 0.5, blockState, pos ) @@ -86,30 +86,29 @@ ); } } -@@ -1117,6 +_,13 @@ - } - } - -+ public void addBreakingBlockEffect(BlockPos pos, net.minecraft.world.phys.BlockHitResult target) { -+ var state = this.getBlockState(pos); -+ if (!net.minecraftforge.client.extensions.common.IClientBlockExtensions.of(state).addHitEffects(state, this, target, this.minecraft.particleEngine)) -+ addBreakingBlockEffect(pos, target.getDirection()); -+ } -+ -+ /** @deprecated Forge - Use crack(BlockPos, BlockHitResult) as it has more context and gives more control to modders */ - public void addBreakingBlockEffect(final BlockPos pos, final Direction direction) { - BlockState blockState = this.getBlockState(pos); - if (blockState.getRenderShape() != RenderShape.INVISIBLE && blockState.shouldSpawnTerrainParticles()) { -@@ -1152,7 +_,7 @@ - xp = x + shape.maxX + 0.1F; +@@ -1138,6 +_,7 @@ + this.playBreakingSound(pos, blockState); } -- this.minecraft.particleEngine.add(new TerrainParticle(this, xp, yp, zp, 0.0, 0.0, 0.0, blockState, pos).setPower(0.2F).scale(0.6F)); -+ this.minecraft.particleEngine.add(new TerrainParticle(this, xp, yp, zp, 0.0, 0.0, 0.0, blockState, pos).updateSprite(blockState, pos).setPower(0.2F).scale(0.6F)); ++ if (!net.minecraftforge.client.extensions.common.IClientBlockExtensions.of(blockState).addHitEffects(blockState, this, direction, this.minecraft.particleEngine)) + if (blockState.getRenderShape() != RenderShape.INVISIBLE && blockState.shouldSpawnTerrainParticles()) { + this.addBreakingParticles(pos, direction, blockState); + } +@@ -1177,11 +_,11 @@ + xp = x + shape.maxX + 0.1F; } + +- this.minecraft.particleEngine.add(new TerrainParticle(this, xp, yp, zp, 0.0, 0.0, 0.0, blockState, pos).setPower(0.2F).scale(0.6F)); ++ this.minecraft.particleEngine.add(new TerrainParticle(this, xp, yp, zp, 0.0, 0.0, 0.0, blockState, pos).updateSprite(blockState, pos).setPower(0.2F).scale(0.6F)); } -@@ -1218,6 +_,16 @@ + private void playBreakingSound(final BlockPos pos, final BlockState blockState) { +- SoundType soundType = blockState.getSoundType(); ++ SoundType soundType = blockState.getSoundType(this, pos, this.minecraft.player); + this.minecraft + .getSoundManager() + .play( +@@ -1248,6 +_,16 @@ this.explosionTracker.track(center, radius, blockCount, blockParticles); } @@ -126,7 +125,7 @@ @OnlyIn(Dist.CLIENT) public static class ClientLevelData implements WritableLevelData { private final boolean hardcore; -@@ -1273,6 +_,7 @@ +@@ -1303,6 +_,7 @@ } public void setDifficulty(final Difficulty difficulty) { @@ -134,7 +133,7 @@ this.difficulty = difficulty; } -@@ -1315,6 +_,12 @@ +@@ -1345,6 +_,12 @@ break; default: } @@ -147,7 +146,7 @@ } public void onTrackingEnd(final Entity entity) { -@@ -1327,6 +_,15 @@ +@@ -1357,6 +_,15 @@ ClientLevel.this.dragonParts.removeAll(Arrays.asList(dragon.getSubEntities())); break; default: diff --git a/patches/minecraft/net/minecraft/client/multiplayer/ClientPacketListener.java.patch b/patches/minecraft/net/minecraft/client/multiplayer/ClientPacketListener.java.patch index 93ba01ef1f..21c91d97b0 100644 --- a/patches/minecraft/net/minecraft/client/multiplayer/ClientPacketListener.java.patch +++ b/patches/minecraft/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 -@@ -531,6 +_,7 @@ +@@ -534,6 +_,7 @@ this.debugSubscriber.clear(); this.minecraft.levelExtractor.debugRenderer.refreshRendererList(); this.minecraft.player.resetPos(); @@ -8,7 +8,7 @@ this.minecraft.player.setId(packet.playerId()); this.level.addEntity(this.minecraft.player); this.minecraft.player.input = new KeyboardInput(this.minecraft.options); -@@ -1323,6 +_,8 @@ +@@ -1334,6 +_,8 @@ newPlayer.getAttributes().assignBaseValues(oldPlayer.getAttributes()); } @@ -17,7 +17,7 @@ this.level.addEntity(newPlayer); newPlayer.input = new KeyboardInput(this.minecraft.options); this.minecraft.gameMode.adjustPlayer(newPlayer); -@@ -1478,7 +_,7 @@ +@@ -1492,7 +_,7 @@ ProblemReporter.ScopedCollector reporter = new ProblemReporter.ScopedCollector(blockEntity.problemPath(), LOGGER); try { @@ -26,7 +26,7 @@ } catch (Throwable t$) { try { reporter.close(); -@@ -1686,7 +_,9 @@ +@@ -1700,7 +_,9 @@ @Override public void handleCommands(final ClientboundCommandsPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.minecraft.packetProcessor()); @@ -37,7 +37,7 @@ } @Override -@@ -1787,6 +_,7 @@ +@@ -1801,6 +_,7 @@ if (this.minecraft.gui.screen() instanceof RecipeUpdateListener updateListener) { updateListener.recipesUpdated(); } @@ -45,8 +45,8 @@ } @Override -@@ -1830,6 +_,8 @@ - this.fuelValues = FuelValues.vanillaBurnTimes(this.registryAccess, this.enabledFeatures); +@@ -1843,6 +_,8 @@ + List searchItems = List.copyOf(CreativeModeTabs.searchTab().getDisplayItems()); this.searchTrees.updateCreativeTags(searchItems); + @@ -54,7 +54,7 @@ } @Override -@@ -2652,7 +_,9 @@ +@@ -2672,7 +_,9 @@ } } @@ -65,7 +65,7 @@ Instant timeStamp = Instant.now(); long salt = Crypt.SaltSupplier.getLong(); LastSeenMessagesTracker.Update lastSeenUpdate = this.lastSeenMessages.generateAndApplyUpdate(); -@@ -2661,6 +_,7 @@ +@@ -2681,6 +_,7 @@ } public void sendCommand(final String command) { @@ -73,7 +73,7 @@ SignableCommand signableCommand = SignableCommand.of(this.commands.parse(command, this.suggestionsProvider)); if (signableCommand.arguments().isEmpty()) { this.send(new ServerboundChatCommandPacket(command)); -@@ -2677,6 +_,7 @@ +@@ -2697,6 +_,7 @@ } public void sendUnattendedCommand(final String command, final @Nullable Screen screenAfterCommand) { diff --git a/patches/minecraft/net/minecraft/client/multiplayer/MultiPlayerGameMode.java.patch b/patches/minecraft/net/minecraft/client/multiplayer/MultiPlayerGameMode.java.patch index 3f564487bf..93c872ed95 100644 --- a/patches/minecraft/net/minecraft/client/multiplayer/MultiPlayerGameMode.java.patch +++ b/patches/minecraft/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 -@@ -115,6 +_,7 @@ +@@ -120,6 +_,7 @@ } public boolean destroyBlock(final BlockPos pos) { @@ -8,7 +8,7 @@ if (this.minecraft.player.blockActionRestricted(this.minecraft.level, pos, this.localPlayerMode)) { return false; } -@@ -134,9 +_,8 @@ +@@ -139,9 +_,8 @@ return false; } @@ -19,7 +19,7 @@ if (changed) { oldBlock.destroy(level, pos, oldState); } -@@ -165,6 +_,7 @@ +@@ -170,6 +_,7 @@ } this.startPrediction(this.minecraft.level, sequence -> { @@ -27,7 +27,7 @@ this.destroyBlock(pos); return new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, pos, direction, sequence); }); -@@ -178,6 +_,7 @@ +@@ -183,6 +_,7 @@ this.connection .send(new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, this.destroyBlockPos, direction)); } @@ -35,7 +35,7 @@ BlockState state = this.minecraft.level.getBlockState(pos); this.minecraft.getTutorial().onDestroyBlock(this.minecraft.level, pos, state, 0.0F); -@@ -188,9 +_,11 @@ +@@ -193,9 +_,11 @@ this.startPrediction(this.minecraft.level, sequence -> { boolean notAir = !state.isAir(); if (notAir && this.destroyProgress == 0.0F) { @@ -47,15 +47,15 @@ if (notAir && state.getDestroyProgress(this.minecraft.player, this.minecraft.player.level(), pos) >= 1.0F) { this.destroyBlock(pos); } else { -@@ -201,6 +_,7 @@ - this.destroyTicks = 0.0F; +@@ -208,6 +_,7 @@ this.minecraft.level.destroyBlockProgress(this.minecraft.player.getId(), this.destroyBlockPos, this.getDestroyStage()); + this.minecraft.level.addBreakingBlockEffects(this.destroyBlockPos, this.destroyDirection, true); } + } return new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, pos, direction, sequence); }); -@@ -242,6 +_,7 @@ +@@ -249,6 +_,7 @@ } this.startPrediction(this.minecraft.level, sequence -> { @@ -63,24 +63,15 @@ this.destroyBlock(pos); return new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, pos, direction, sequence); }); -@@ -255,7 +_,7 @@ - +@@ -263,6 +_,7 @@ this.destroyProgress = this.destroyProgress + state.getDestroyProgress(this.minecraft.player, this.minecraft.player.level(), pos); - if (this.destroyTicks % 4.0F == 0.0F) { -- SoundType soundType = state.getSoundType(); -+ SoundType soundType = state.getSoundType(this.minecraft.level, pos, this.minecraft.player); - this.minecraft - .getSoundManager() - .play( -@@ -272,6 +_,7 @@ - this.destroyTicks++; this.minecraft.getTutorial().onDestroyBlock(this.minecraft.level, pos, state, Mth.clamp(this.destroyProgress, 0.0F, 1.0F)); -+ if (net.minecraftforge.event.ForgeEventFactory.onLeftClickBlockHold(this.minecraft.player, pos, direction).getUseItem().isDenied()) return true; ++ if (net.minecraftforge.event.ForgeEventFactory.onLeftClickBlockHold(this.minecraft.player, pos, direction).getUseItem().isDenied()) return true; if (this.destroyProgress >= 1.0F) { this.isDestroying = false; if (SharedConstants.DEBUG_BLOCK_BREAK) { -@@ -279,6 +_,7 @@ +@@ -270,6 +_,7 @@ } this.startPrediction(this.minecraft.level, sequence -> { @@ -88,7 +79,7 @@ this.destroyBlock(pos); return new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.STOP_DESTROY_BLOCK, pos, direction, sequence); }); -@@ -313,7 +_,7 @@ +@@ -308,7 +_,7 @@ private boolean sameDestroyTarget(final BlockPos pos) { ItemStack selected = this.minecraft.player.getMainHandItem(); @@ -97,7 +88,7 @@ } private void ensureHasSentCarriedItem() { -@@ -341,13 +_,24 @@ +@@ -336,13 +_,24 @@ private InteractionResult performUseItemOn(final LocalPlayer player, final InteractionHand hand, final BlockHitResult blockHit) { BlockPos pos = blockHit.getBlockPos(); ItemStack itemStack = player.getItemInHand(hand); @@ -124,7 +115,7 @@ BlockState blockState = this.minecraft.level.getBlockState(pos); if (!this.connection.isFeatureEnabled(blockState.getBlock().requiredFeatures())) { return InteractionResult.FAIL; -@@ -366,8 +_,10 @@ +@@ -361,8 +_,10 @@ } } @@ -134,10 +125,10 @@ + return InteractionResult.PASS; + } + if (event.getUseItem().isAllowed() || (!itemStack.isEmpty() && !player.getCooldowns().isOnCooldown(itemStack))) { - InteractionResult success; + InteractionResult result; if (player.hasInfiniteMaterials()) { int count = itemStack.getCount(); -@@ -398,6 +_,12 @@ +@@ -399,6 +_,12 @@ return packet; } @@ -150,7 +141,7 @@ InteractionResult resultHolder = itemStack.use(this.minecraft.level, player, hand); ItemStack result; if (resultHolder instanceof InteractionResult.Success success) { -@@ -408,6 +_,9 @@ +@@ -409,6 +_,9 @@ if (result != itemStack) { player.setItemInHand(hand, result); @@ -160,7 +151,7 @@ } interactionResult.setValue(resultHolder); -@@ -445,6 +_,10 @@ +@@ -456,6 +_,10 @@ this.ensureHasSentCarriedItem(); Vec3 location = hitResult.getLocation().subtract(entity.getX(), entity.getY(), entity.getZ()); this.connection.send(new ServerboundInteractPacket(entity.getId(), hand, location, player.isShiftKeyDown())); diff --git a/patches/minecraft/net/minecraft/client/multiplayer/chat/ChatListener.java.patch b/patches/minecraft/net/minecraft/client/multiplayer/chat/ChatListener.java.patch index a44448243a..8bb06a4870 100644 --- a/patches/minecraft/net/minecraft/client/multiplayer/chat/ChatListener.java.patch +++ b/patches/minecraft/net/minecraft/client/multiplayer/chat/ChatListener.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/multiplayer/chat/ChatListener.java +++ b/net/minecraft/client/multiplayer/chat/ChatListener.java -@@ -142,6 +_,8 @@ +@@ -138,6 +_,8 @@ LocalPlayer receiver = this.minecraft.player; if (receiver != null && receiver.chatAbilities().canReceivePlayerMessages()) { Component decoratedMessage = boundChatType.decorate(message); @@ -9,7 +9,7 @@ this.minecraft.gui.hud.getChat().addPlayerMessage(decoratedMessage, null, GuiMessageTag.system()); this.narrateChatMessage(boundChatType, message); this.logSystemMessage(decoratedMessage, received); -@@ -177,12 +_,16 @@ +@@ -173,12 +_,16 @@ MessageSignature signature = message.signature(); FilterMask filterMask = message.filterMask(); if (filterMask.isEmpty()) { @@ -28,7 +28,7 @@ this.narrateChatMessage(boundChatType, filteredContent); } } -@@ -216,12 +_,14 @@ +@@ -212,12 +_,14 @@ chatLog.push(LoggedChatMessage.system(message, timeStamp)); } diff --git a/patches/minecraft/net/minecraft/client/particle/FireworkParticles.java.patch b/patches/minecraft/net/minecraft/client/particle/FireworkParticles.java.patch index e010a4a758..6de6171f93 100644 --- a/patches/minecraft/net/minecraft/client/particle/FireworkParticles.java.patch +++ b/patches/minecraft/net/minecraft/client/particle/FireworkParticles.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/particle/FireworkParticles.java +++ b/net/minecraft/client/particle/FireworkParticles.java -@@ -256,6 +_,10 @@ +@@ -259,6 +_,10 @@ colors = IntList.of(DyeColor.BLACK.getFireworkColor()); } diff --git a/patches/minecraft/net/minecraft/client/particle/ParticleResources.java.patch b/patches/minecraft/net/minecraft/client/particle/ParticleResources.java.patch index 405fb678b4..e402d0421b 100644 --- a/patches/minecraft/net/minecraft/client/particle/ParticleResources.java.patch +++ b/patches/minecraft/net/minecraft/client/particle/ParticleResources.java.patch @@ -8,7 +8,7 @@ private @Nullable Runnable onReload; public ParticleResources() { -@@ -183,14 +_,17 @@ +@@ -186,14 +_,17 @@ this.register(ParticleTypes.SULFUR_CUBE_GOO, BreakingItemParticle.SulfurCubeProvider::new); } @@ -27,7 +27,7 @@ } @Override -@@ -281,8 +_,13 @@ +@@ -284,8 +_,13 @@ } } diff --git a/patches/minecraft/net/minecraft/client/player/FirstPersonHandsAndItems.java.patch b/patches/minecraft/net/minecraft/client/player/FirstPersonHandsAndItems.java.patch new file mode 100644 index 0000000000..211eb57b27 --- /dev/null +++ b/patches/minecraft/net/minecraft/client/player/FirstPersonHandsAndItems.java.patch @@ -0,0 +1,23 @@ +--- a/net/minecraft/client/player/FirstPersonHandsAndItems.java ++++ b/net/minecraft/client/player/FirstPersonHandsAndItems.java +@@ -45,8 +_,18 @@ + this.offHandHeight = Mth.clamp(this.offHandHeight - 0.4F, 0.0F, 1.0F); + } else { + float attackAnim = player.getItemSwapScale(1.0F); +- float mainHandTargetHeight = this.mainHandItem != nextMainHand ? 0.0F : attackAnim * attackAnim * attackAnim; +- float offHandTargetHeight = this.offHandItem != nextOffHand ? 0.0F : 1.0F; ++ ++ boolean requipM = net.minecraftforge.client.ForgeHooksClient.shouldCauseReequipAnimation(this.mainHandItem, nextMainHand, player.getInventory().getSelectedSlot()); ++ boolean requipO = net.minecraftforge.client.ForgeHooksClient.shouldCauseReequipAnimation(this.offHandItem, nextOffHand, -1); ++ ++ if (!requipM && this.mainHandItem != nextMainHand) ++ this.mainHandItem = nextMainHand; ++ if (!requipO && this.offHandItem != nextOffHand) ++ this.offHandItem = nextOffHand; ++ ++ float mainHandTargetHeight = requipM ? 0.0F : attackAnim * attackAnim * attackAnim; ++ float offHandTargetHeight = requipO ? 0.0F : 1.0F; ++ + this.mainHandHeight = this.mainHandHeight + Mth.clamp(mainHandTargetHeight - this.mainHandHeight, -0.4F, 0.4F); + this.offHandHeight = this.offHandHeight + Mth.clamp(offHandTargetHeight - this.offHandHeight, -0.4F, 0.4F); + } diff --git a/patches/minecraft/net/minecraft/client/player/LocalPlayer.java.patch b/patches/minecraft/net/minecraft/client/player/LocalPlayer.java.patch index 6ccb204b23..2f117b41bc 100644 --- a/patches/minecraft/net/minecraft/client/player/LocalPlayer.java.patch +++ b/patches/minecraft/net/minecraft/client/player/LocalPlayer.java.patch @@ -1,14 +1,6 @@ --- a/net/minecraft/client/player/LocalPlayer.java +++ b/net/minecraft/client/player/LocalPlayer.java -@@ -318,6 +_,7 @@ - ServerboundPlayerActionPacket.Action action = all - ? ServerboundPlayerActionPacket.Action.DROP_ALL_ITEMS - : ServerboundPlayerActionPacket.Action.DROP_ITEM; -+ if (isUsingItem() && getUsedItemHand() == InteractionHand.MAIN_HAND && (all || getUseItem().getCount() == 1)) stopUsingItem(); // Forge: fix MC-231097 on the clientside - ItemStack prediction = this.getInventory().removeFromSelected(all); - this.connection.send(new ServerboundPlayerActionPacket(action, BlockPos.ZERO, Direction.DOWN)); - return !prediction.isEmpty(); -@@ -545,7 +_,10 @@ +@@ -560,7 +_,10 @@ @Override public void playSound(final SoundEvent sound, final float volume, final float pitch) { @@ -20,7 +12,7 @@ } @Override -@@ -787,6 +_,7 @@ +@@ -803,6 +_,7 @@ && this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.CROUCHING) && (this.isShiftKeyDown() || !this.isSleeping() && !this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.STANDING)); this.input.tick(); @@ -28,7 +20,7 @@ this.minecraft.getTutorial().onInput(this.input); boolean wasAutoJump = false; if (this.autoJumpTime > 0) { -@@ -859,8 +_,9 @@ +@@ -875,8 +_,9 @@ } this.wasFallFlying = this.isFallFlying(); @@ -40,7 +32,7 @@ } if (this.isEyeInFluid(FluidTags.WATER)) { -@@ -928,7 +_,7 @@ +@@ -944,7 +_,7 @@ } private boolean shouldStopSwimSprinting() { @@ -49,7 +41,7 @@ } public Portal.Transition getActivePortalLocalTransition() { -@@ -973,6 +_,8 @@ +@@ -1004,6 +_,8 @@ @Override public void rideTick() { super.rideTick(); @@ -58,7 +50,7 @@ this.handsBusy = false; if (this.getControlledVehicle() instanceof AbstractBoat boat) { boat.setInput(this.input.keyPresses.left(), this.input.keyPresses.right(), this.input.keyPresses.forward(), this.input.keyPresses.backward()); -@@ -1147,7 +_,7 @@ +@@ -1178,7 +_,7 @@ && this.isSprintingPossible(this.getAbilities().flying) && !this.isSlowDueToUsingItem() && (!this.isFallFlying() || this.isUnderWater()) @@ -67,7 +59,7 @@ } private boolean vehicleCanSprint(final Entity vehicle) { -@@ -1222,6 +_,17 @@ +@@ -1253,6 +_,17 @@ @Override public float getVisualRotationYInDegrees() { return this.getYRot(); diff --git a/patches/minecraft/net/minecraft/client/renderer/FirstPersonHandsAndItemsRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/FirstPersonHandsAndItemsRenderer.java.patch new file mode 100644 index 0000000000..ff8ef5a5db --- /dev/null +++ b/patches/minecraft/net/minecraft/client/renderer/FirstPersonHandsAndItemsRenderer.java.patch @@ -0,0 +1,35 @@ +--- a/net/minecraft/client/renderer/FirstPersonHandsAndItemsRenderer.java ++++ b/net/minecraft/client/renderer/FirstPersonHandsAndItemsRenderer.java +@@ -352,6 +_,7 @@ + if (state.handRenderSelection.renderMainHand) { + float mainHandAttack = attackHand == InteractionHand.MAIN_HAND ? attackValue : 0.0F; + float mainhandInverseArmHeight = state.mainHandSwapScale * (1.0F - Mth.lerp(partialTicks, state.oldMainHandHeight, state.mainHandHeight)); ++ if (!net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonHand(InteractionHand.MAIN_HAND, poseStack, submitNodeCollector, playerState.avatarRenderState.lightCoords, partialTicks, xRot, mainHandAttack, mainhandInverseArmHeight, state.mainHandItem)) + this.submitArmWithItem( + playerState, + state, +@@ -370,6 +_,7 @@ + if (state.handRenderSelection.renderOffHand) { + float offHandAttack = attackHand == InteractionHand.OFF_HAND ? attackValue : 0.0F; + float offhandInverseArmHeight = state.offHandSwapScale * (1.0F - Mth.lerp(partialTicks, state.oldOffHandHeight, state.offHandHeight)); ++ if (!net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonHand(InteractionHand.OFF_HAND, poseStack, submitNodeCollector, playerState.avatarRenderState.lightCoords, partialTicks, xRot, offHandAttack, offhandInverseArmHeight, state.offHandItem)) + this.submitArmWithItem( + playerState, + state, +@@ -418,7 +_,7 @@ + } else { + this.renderOneHandedMap(poseStack, submitNodeCollector, lightCoords, inverseArmHeight, arm, attack, itemStack, playerState, state); + } +- } else if (itemStack.is(Items.CROSSBOW)) { ++ } else if (itemStack.getItem() instanceof CrossbowItem) { + this.applyItemArmTransform(poseStack, arm, inverseArmHeight); + boolean charged = CrossbowItem.isCharged(itemStack); + boolean isRightArm = arm == HumanoidArm.RIGHT; +@@ -457,6 +_,7 @@ + } else { + boolean isRightArm = arm == HumanoidArm.RIGHT; + int invert = isRightArm ? 1 : -1; ++ if (!net.minecraftforge.client.extensions.common.IClientItemExtensions.of(itemStack).applyForgeHandTransform(poseStack, minecraft.player, arm, itemStack, partialTicks, inverseArmHeight, attack)) // FORGE: Allow items to define custom arm animation + if (avatarRenderState.isUsingItem && state.useItemRemainingTicks > 0 && avatarRenderState.useItemHand == hand) { + ItemUseAnimation useAnimation = itemStack.getUseAnimation(); + if (!useAnimation.hasCustomArmTransform()) { diff --git a/patches/minecraft/net/minecraft/client/renderer/GameRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/GameRenderer.java.patch index 6c126a4949..de6e48027a 100644 --- a/patches/minecraft/net/minecraft/client/renderer/GameRenderer.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/GameRenderer.java.patch @@ -1,33 +1,41 @@ --- a/net/minecraft/client/renderer/GameRenderer.java +++ b/net/minecraft/client/renderer/GameRenderer.java -@@ -220,6 +_,9 @@ +@@ -240,6 +_,9 @@ case null: default: - this.clearPostEffect(); + this.clearSpectatedEntityPostEffect(); + var rl = cameraEntity == null ? null : net.minecraftforge.client.EntitySpectatorShaderManager.get(cameraEntity.getType()); + if (rl != null) -+ this.setPostEffect(rl); ++ this.setSpectatedEntityPostEffect(rl); } } -@@ -515,6 +_,10 @@ - Registry blockRegistry = this.minecraft.level.registryAccess().lookupOrThrow(Registries.BLOCK); +@@ -430,6 +_,8 @@ + ProfilerFiller profiler = Profiler.get(); + profiler.push("camera"); + this.mainCamera.update(deltaTracker); ++ var cameraSetup = net.minecraftforge.client.event.ForgeEventFactoryClient.fireComputeCameraAngles(this, this.mainCamera, deltaTracker.getGameTimeDeltaPartialTick(true)); ++ this.mainCamera.setRotation(cameraSetup.getYaw(), cameraSetup.getPitch(), cameraSetup.getRoll()); + profiler.pop(); + this.requestedPostEffects.clear(); + this.requestedPostEffects.add(END_OF_FRAME_POST_EFFECT); +@@ -628,6 +_,10 @@ + BlockInWorld blockInWorld = new BlockInWorld(this.minecraft.level, pos, false); renderOutline = !itemStack.isEmpty() && (itemStack.canBreakBlockInAdventureMode(blockInWorld) || itemStack.canPlaceOnBlockInAdventureMode(blockInWorld)); -+ if (!renderOutline && blockState.hasBlockEntity()) { ++ if (!renderOutline && blockInWorld.getState().hasBlockEntity()) { + var blockEntity = this.minecraft.level.getBlockEntity(pos); + renderOutline = blockEntity != null && blockEntity.hasCustomOutlineRendering(); + } } } } -@@ -538,6 +_,9 @@ - if (optionsState.bobView) { - this.bobView(cameraState, bobStack); - } -+ +@@ -780,6 +_,8 @@ + + private void extractCamera(final DeltaTracker deltaTracker, final float worldPartialTicks) { + CameraRenderState cameraState = this.gameRenderState.levelRenderState.cameraRenderState; + var cameraSetup = net.minecraftforge.client.event.ForgeEventFactoryClient.fireComputeCameraAngles(this, this.mainCamera, worldPartialTicks); + this.mainCamera.setRotation(cameraSetup.getYaw(), cameraSetup.getPitch(), cameraSetup.getRoll()); - - projectionMatrix.mul(bobStack.last().pose()); - float screenEffectScale = optionsState.screenEffectScale; + this.mainCamera.extractRenderState(cameraState, deltaTracker); + cameraState.fogType = this.mainCamera.getFluidInCamera(); + cameraState.fogData = this.fogRenderer diff --git a/patches/minecraft/net/minecraft/client/renderer/ItemInHandRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/ItemInHandRenderer.java.patch deleted file mode 100644 index 4406fd83bb..0000000000 --- a/patches/minecraft/net/minecraft/client/renderer/ItemInHandRenderer.java.patch +++ /dev/null @@ -1,57 +0,0 @@ ---- a/net/minecraft/client/renderer/ItemInHandRenderer.java -+++ b/net/minecraft/client/renderer/ItemInHandRenderer.java -@@ -362,6 +_,7 @@ - float mainHandAttack = attackHand == InteractionHand.MAIN_HAND ? attackValue : 0.0F; - float mainhandInverseArmHeight = this.itemModelResolver.swapAnimationScale(this.mainHandItem) - * (1.0F - Mth.lerp(frameInterp, this.oMainHandHeight, this.mainHandHeight)); -+ if (!net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonHand(InteractionHand.MAIN_HAND, poseStack, submitNodeCollector, lightCoords, frameInterp, xRot, mainHandAttack, mainhandInverseArmHeight, this.mainHandItem)) - this.submitArmWithItem( - player, - frameInterp, -@@ -380,6 +_,8 @@ - float offHandAttack = attackHand == InteractionHand.OFF_HAND ? attackValue : 0.0F; - float offhandInverseArmHeight = this.itemModelResolver.swapAnimationScale(this.offHandItem) - * (1.0F - Mth.lerp(frameInterp, this.oOffHandHeight, this.offHandHeight)); -+ -+ if (!net.minecraftforge.client.ForgeHooksClient.renderSpecificFirstPersonHand(InteractionHand.OFF_HAND, poseStack, submitNodeCollector, lightCoords, frameInterp, xRot, offHandAttack, offhandInverseArmHeight, this.offHandItem)) - this.submitArmWithItem( - player, - frameInterp, -@@ -454,7 +_,7 @@ - } else { - this.renderOneHandedMap(poseStack, submitNodeCollector, lightCoords, inverseArmHeight, arm, attack, itemStack); - } -- } else if (itemStack.is(Items.CROSSBOW)) { -+ } else if (itemStack.getItem() instanceof CrossbowItem) { - this.applyItemArmTransform(poseStack, arm, inverseArmHeight); - boolean charged = CrossbowItem.isCharged(itemStack); - boolean isRightArm = arm == HumanoidArm.RIGHT; -@@ -499,6 +_,7 @@ - } else { - boolean isRightArm = arm == HumanoidArm.RIGHT; - int invert = isRightArm ? 1 : -1; -+ if (!net.minecraftforge.client.extensions.common.IClientItemExtensions.of(itemStack).applyForgeHandTransform(poseStack, minecraft.player, arm, itemStack, frameInterp, inverseArmHeight, attack)) // FORGE: Allow items to define custom arm animation - if (player.isUsingItem() && player.getUseItemRemainingTicks() > 0 && player.getUsedItemHand() == hand) { - ItemUseAnimation useAnimation = itemStack.getUseAnimation(); - if (!useAnimation.hasCustomArmTransform()) { -@@ -647,8 +_,18 @@ - this.offHandHeight = Mth.clamp(this.offHandHeight - 0.4F, 0.0F, 1.0F); - } else { - float attackAnim = player.getItemSwapScale(1.0F); -- float mainHandTargetHeight = this.mainHandItem != nextMainHand ? 0.0F : attackAnim * attackAnim * attackAnim; -- float offHandTargetHeight = this.offHandItem != nextOffHand ? 0.0F : 1.0F; -+ -+ boolean requipM = net.minecraftforge.client.ForgeHooksClient.shouldCauseReequipAnimation(this.mainHandItem, nextMainHand, player.getInventory().getSelectedSlot()); -+ boolean requipO = net.minecraftforge.client.ForgeHooksClient.shouldCauseReequipAnimation(this.offHandItem, nextOffHand, -1); -+ -+ if (!requipM && this.mainHandItem != nextMainHand) -+ this.mainHandItem = nextMainHand; -+ if (!requipO && this.offHandItem != nextOffHand) -+ this.offHandItem = nextOffHand; -+ -+ float mainHandTargetHeight = requipM ? 0.0F : attackAnim * attackAnim * attackAnim; -+ float offHandTargetHeight = requipO ? 0.0F : 1.0F; -+ - this.mainHandHeight = this.mainHandHeight + Mth.clamp(mainHandTargetHeight - this.mainHandHeight, -0.4F, 0.4F); - this.offHandHeight = this.offHandHeight + Mth.clamp(offHandTargetHeight - this.offHandHeight, -0.4F, 0.4F); - } diff --git a/patches/minecraft/net/minecraft/client/renderer/LevelEventHandler.java.patch b/patches/minecraft/net/minecraft/client/renderer/LevelEventHandler.java.patch index 72a8555d01..08c55d5585 100644 --- a/patches/minecraft/net/minecraft/client/renderer/LevelEventHandler.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/LevelEventHandler.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/LevelEventHandler.java +++ b/net/minecraft/client/renderer/LevelEventHandler.java -@@ -305,7 +_,7 @@ +@@ -312,7 +_,7 @@ case 2001: BlockState blockState = Block.stateById(data); if (!blockState.isAir()) { diff --git a/patches/minecraft/net/minecraft/client/renderer/LevelRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/LevelRenderer.java.patch index 905e188bac..aed19d6c25 100644 --- a/patches/minecraft/net/minecraft/client/renderer/LevelRenderer.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/LevelRenderer.java.patch @@ -1,16 +1,16 @@ --- a/net/minecraft/client/renderer/LevelRenderer.java +++ b/net/minecraft/client/renderer/LevelRenderer.java -@@ -235,6 +_,7 @@ +@@ -279,6 +_,7 @@ + } } - this.addAlwaysOnTopPass(frame, featureFrame, terrainFog); -+ net.minecraftforge.client.FramePassManager.insertForgePasses(frame, targets, this.levelRenderState, deltaTracker); // Forge: Modded passes are inserted here. ++ net.minecraftforge.client.FramePassManager.insertForgePasses(frame, targets, this.levelRenderState); // Forge: Modded passes are inserted here. profiler.popPush("executeFrameGraph"); frame.execute(resourceAllocator, new FrameGraphBuilder.Inspector() { @Override -@@ -285,7 +_,8 @@ - this.submitBlockDestroyAnimation(poseStack, submitNodeCollector, levelRenderState); +@@ -335,7 +_,8 @@ levelRenderState.blockBreakingRenderStates.clear(); + this.submitTransientBlocks(poseStack, submitNodeCollector, levelRenderState); levelRenderState.particlesRenderState.submit(submitNodeCollector, levelRenderState.cameraRenderState); - if (renderOutline) { + var hasCustomOutline = this.levelRenderState.blockOutlineRenderState != null && this.levelRenderState.blockOutlineRenderState.customRenderer() != null; @@ -18,7 +18,7 @@ this.submitBlockOutline(poseStack, this.submitNodeStorage, levelRenderState); } -@@ -705,6 +_,10 @@ +@@ -1075,6 +_,10 @@ private void submitBlockOutline(final PoseStack poseStack, final SubmitNodeCollector submitNodeCollector, final LevelRenderState levelRenderState) { BlockOutlineRenderState state = levelRenderState.blockOutlineRenderState; if (state != null) { @@ -29,7 +29,7 @@ Vec3 cameraPos = levelRenderState.cameraRenderState.pos; BlockPos pos = state.pos(); poseStack.pushPose(); -@@ -979,6 +_,14 @@ +@@ -1331,6 +_,14 @@ public SectionOcclusionGraph sectionOcclusionGraph() { return this.sectionOcclusionGraph; diff --git a/patches/minecraft/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch index 7250254598..13cbf72c20 100644 --- a/patches/minecraft/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/ScreenEffectRenderer.java.patch @@ -1,70 +1,43 @@ --- a/net/minecraft/client/renderer/ScreenEffectRenderer.java +++ b/net/minecraft/client/renderer/ScreenEffectRenderer.java -@@ -61,8 +_,9 @@ +@@ -40,6 +_,9 @@ PoseStack poseStack = new PoseStack(); - Player player = this.minecraft.player; - if (isFirstPerson && !isSleeping) { -- BlockState blockState = getViewBlockingState(player); -- if (blockState != null) { -+ var overlay = getOverlayBlock(player); -+ BlockState blockState = overlay == null ? null : overlay.getLeft(); -+ if (blockState != null && net.minecraftforge.client.ForgeHooksClient.renderBlockOverlay(player, poseStack, net.minecraftforge.client.event.RenderBlockScreenEffectEvent.OverlayType.BLOCK, overlay.getLeft(), overlay.getRight())) { - BlockStateModelSet blockStateModelSet = this.minecraft.getModelManager().getBlockStateModelSet(); - TextureAtlasSprite sprite = blockStateModelSet.getParticleMaterial(blockState).sprite(); - submitBlockSprite(sprite, poseStack, submitNodeCollector, -15132391); -@@ -70,11 +_,15 @@ + AvatarRenderState avatarRenderState = playerRenderState.avatarRenderState; + if (!cameraRenderState.entityRenderState.isSleeping && playerRenderState.hasPlayer && avatarRenderState != null) { ++ if (playerRenderState.customBlockOverlay != null) ++ playerRenderState.customBlockOverlay.render(poseStack, submitNodeCollector); ++ else + if (playerRenderState.blockOverlay != null) { + submitBlockSprite( + playerRenderState.blockOverlay.atlasLocation(), +@@ -54,10 +_,16 @@ + } - if (!this.minecraft.player.isSpectator()) { - if (this.minecraft.player.isEyeInFluid(FluidTags.WATER)) { -+ if (!net.minecraftforge.client.ForgeHooksClient.renderWaterOverlay(player, poseStack)) - submitWater(this.minecraft, poseStack, submitNodeCollector); -+ } else if (!player.getEyeInFluidType().isAir()) { -+ net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions.of(player.getEyeInFluidType()).renderOverlay(this.minecraft, poseStack, submitNodeCollector); + if (cameraRenderState.isFirstPerson && !avatarRenderState.isSpectator) { ++ if (playerRenderState.customFluidOverlay != null) ++ playerRenderState.customFluidOverlay.render(poseStack, submitNodeCollector); ++ else + if (playerRenderState.waterOverlay != null) { + submitWater(playerRenderState.waterOverlay, poseStack, submitNodeCollector); } - if (this.minecraft.player.isOnFire()) { ++ if (playerRenderState.customFireOverlay != null) ++ playerRenderState.customFireOverlay.render(poseStack, submitNodeCollector); ++ else + if (playerRenderState.isOnFire) { TextureAtlasSprite fireSprite = this.sprites.get(ModelBakery.FIRE_1); -+ if (!net.minecraftforge.client.ForgeHooksClient.renderFireOverlay(player, poseStack)) submitFire(poseStack, submitNodeCollector, fireSprite); - } - } -@@ -128,6 +_,11 @@ - return null; - } - -+ var ret = getOverlayBlock(player); -+ return ret == null ? null : ret.getLeft(); -+ } -+ -+ private static org.apache.commons.lang3.tuple.@Nullable Pair getOverlayBlock(Player player) { - BlockPos.MutableBlockPos testPos = new BlockPos.MutableBlockPos(); - - for (int i = 0; i < 8; i++) { -@@ -138,7 +_,7 @@ - ); - BlockState blockState = player.level().getBlockState(testPos); - if (blockState.getRenderShape() != RenderShape.INVISIBLE && blockState.isViewBlocking(player.level(), testPos)) { -- return blockState; -+ return org.apache.commons.lang3.tuple.Pair.of(blockState, testPos.immutable()); - } - } - -@@ -156,13 +_,17 @@ +@@ -116,9 +_,12 @@ } - private static void submitWater(final Minecraft minecraft, final PoseStack poseStack, final SubmitNodeCollector submitNodeCollector) { -+ renderFluid(minecraft, poseStack, submitNodeCollector, UNDERWATER_LOCATION); + private static void submitWater(final PlayerRenderState.WaterOverlay waterOverlay, final PoseStack poseStack, final SubmitNodeCollector submitNodeCollector) { ++ submitFluid(waterOverlay, poseStack, submitNodeCollector, UNDERWATER_LOCATION); + } -+ -+ public static void renderFluid(Minecraft minecraft, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, Identifier texture) { - LocalPlayer player = minecraft.player; - BlockPos pos = BlockPos.containing(player.getEyePosition()); - float brightness = Lightmap.getBrightness(player.level().dimensionType(), player.level().getMaxLocalRawBrightness(pos)); - int color = ARGB.colorFromFloat(0.1F, brightness, brightness, brightness); - float u0 = -player.getYRot() / 64.0F; - float v0 = player.getXRot() / 64.0F; -- submitNodeCollector.submitCustomGeometry(poseStack, RenderTypes.blockScreenEffect(UNDERWATER_LOCATION), (pose, builder) -> { -+ submitNodeCollector.submitCustomGeometry(poseStack, RenderTypes.blockScreenEffect(texture), (pose, builder) -> { - float uvSize = 4.0F; - buildQuad(builder, pose.pose(), -1.0F, -1.0F, 1.0F, 1.0F, -0.5F, u0 + 4.0F, v0 + 4.0F, u0, v0, color); - }); ++ public static void submitFluid(final PlayerRenderState.WaterOverlay waterOverlay, final PoseStack poseStack, final SubmitNodeCollector submitNodeCollector, Identifier texture) { + submitNodeCollector.submitCustomGeometry( + poseStack, +- RenderTypes.blockScreenEffect(UNDERWATER_LOCATION), ++ RenderTypes.blockScreenEffect(texture), + (pose, builder) -> { + float uvSize = 4.0F; + buildQuad( diff --git a/patches/minecraft/net/minecraft/client/renderer/Sheets.java.patch b/patches/minecraft/net/minecraft/client/renderer/Sheets.java.patch index 3486c46905..9fa542a723 100644 --- a/patches/minecraft/net/minecraft/client/renderer/Sheets.java.patch +++ b/patches/minecraft/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 -@@ -120,4 +_,13 @@ +@@ -153,4 +_,13 @@ case COPPER_OXIDIZED -> (SpriteId)CHEST_COPPER.oxidized().select(type); }; } diff --git a/patches/minecraft/net/minecraft/client/renderer/SpriteCoordinateExpander.java.patch b/patches/minecraft/net/minecraft/client/renderer/SpriteCoordinateExpander.java.patch deleted file mode 100644 index 0cbf08ef66..0000000000 --- a/patches/minecraft/net/minecraft/client/renderer/SpriteCoordinateExpander.java.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- a/net/minecraft/client/renderer/SpriteCoordinateExpander.java -+++ b/net/minecraft/client/renderer/SpriteCoordinateExpander.java -@@ -17,12 +_,14 @@ - - @Override - public VertexConsumer addVertex(final float x, final float y, final float z) { -- return this.delegate.addVertex(x, y, z); -+ this.delegate.addVertex(x, y, z); -+ return this; // Forge: Fix MC-263524 not working with chained methods - } - - @Override - public VertexConsumer setColor(final int r, final int g, final int b, final int a) { -- return this.delegate.setColor(r, g, b, a); -+ this.delegate.setColor(r, g, b, a); -+ return this; // Forge: Fix MC-263524 not working with chained methods - } - - @Override -@@ -32,22 +_,26 @@ - - @Override - public VertexConsumer setUv(final float u, final float v) { -- return this.delegate.setUv(this.sprite.getU(u), this.sprite.getV(v)); -+ this.delegate.setUv(this.sprite.getU(u), this.sprite.getV(v)); -+ return this; // Forge: Fix MC-263524 not working with chained methods - } - - @Override - public VertexConsumer setUv1(final int u, final int v) { -- return this.delegate.setUv1(u, v); -+ this.delegate.setUv1(u, v); -+ return this; // Forge: Fix MC-263524 not working with chained methods - } - - @Override - public VertexConsumer setUv2(final int u, final int v) { -- return this.delegate.setUv2(u, v); -+ this.delegate.setUv2(u, v); -+ return this; // Forge: Fix MC-263524 not working with chained methods - } - - @Override - public VertexConsumer setNormal(final float x, final float y, final float z) { -- return this.delegate.setNormal(x, y, z); -+ this.delegate.setNormal(x, y, z); -+ return this; // Forge: Fix MC-263524 not working with chained methods - } - - @Override diff --git a/patches/minecraft/net/minecraft/client/renderer/culling/Frustum.java.patch b/patches/minecraft/net/minecraft/client/renderer/culling/Frustum.java.patch index f84ccf0f15..fb032407d3 100644 --- a/patches/minecraft/net/minecraft/client/renderer/culling/Frustum.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/culling/Frustum.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/culling/Frustum.java +++ b/net/minecraft/client/renderer/culling/Frustum.java -@@ -83,6 +_,8 @@ +@@ -84,6 +_,8 @@ } public boolean isVisible(final AABB bb) { diff --git a/patches/minecraft/net/minecraft/client/renderer/debug/EntityHitboxDebugRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/debug/EntityHitboxDebugRenderer.java.patch index 7e02373768..acf5aa5133 100644 --- a/patches/minecraft/net/minecraft/client/renderer/debug/EntityHitboxDebugRenderer.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/debug/EntityHitboxDebugRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/debug/EntityHitboxDebugRenderer.java +++ b/net/minecraft/client/renderer/debug/EntityHitboxDebugRenderer.java -@@ -99,8 +_,8 @@ +@@ -102,8 +_,8 @@ ); } diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java.patch index a04ce8151e..d65f89210a 100644 --- a/patches/minecraft/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java +++ b/net/minecraft/client/renderer/entity/EntityRenderDispatcher.java -@@ -207,6 +_,14 @@ - return this.itemInHandRenderer; +@@ -201,6 +_,14 @@ + return this.camera.position().distanceToSqr(entity.position()); } + public Map> getPlayerRenderers() { @@ -15,7 +15,7 @@ @Override public void onResourceManagerReload(final ResourceManager resourceManager) { EntityRendererProvider.Context context = new EntityRendererProvider.Context( -@@ -224,5 +_,6 @@ +@@ -219,5 +_,6 @@ this.renderers = EntityRenderers.createEntityRenderers(context); this.playerRenderers = EntityRenderers.createAvatarRenderers(context); this.mannequinRenderers = EntityRenderers.createAvatarRenderers(context); diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java.patch index b44ff59f15..b732b08f38 100644 --- a/patches/minecraft/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java +++ b/net/minecraft/client/renderer/entity/HumanoidMobRenderer.java -@@ -69,7 +_,7 @@ +@@ -67,7 +_,7 @@ state.isCrouching = entity.isCrouching(); state.isFallFlying = entity.isFallFlying(); state.isVisuallySwimming = entity.isVisuallySwimming(); diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch index 3cc42ac3d9..1bea759d85 100644 --- a/patches/minecraft/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/entity/ItemFrameRenderer.java.patch @@ -3,9 +3,9 @@ @@ -82,6 +_,7 @@ if (state.mapId != null) { int rotation = state.rotation % 4 * 2; - poseStack.mulPose(Axis.ZP.rotationDegrees(rotation * 360.0F / 8.0F)); + poseStack.rotateDegrees(Axis.ZP, rotation * 360.0F / 8.0F); + if (!net.minecraftforge.client.event.ForgeEventFactoryClient.onRenderItemInFrame(state, this, poseStack, submitNodeCollector, state.lightCoords)) { - poseStack.mulPose(Axis.ZP.rotationDegrees(180.0F)); + poseStack.rotateDegrees(Axis.ZP, 180.0F); float s = 0.0078125F; poseStack.scale(0.0078125F, 0.0078125F, 0.0078125F); @@ -89,6 +_,7 @@ @@ -14,5 +14,5 @@ this.mapRenderer.render(state.mapRenderState, poseStack, submitNodeCollector, true, lightCoords); + } } else if (!state.item.isEmpty()) { - poseStack.mulPose(Axis.ZP.rotationDegrees(state.rotation * 360.0F / 8.0F)); + poseStack.rotateDegrees(Axis.ZP, state.rotation * 360.0F / 8.0F); int lightVal = this.getLightCoords(state.isGlowFrame, 15728880, state.lightCoords); diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/LivingEntityRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/LivingEntityRenderer.java.patch index 7ffa0ca238..bc6aef23e5 100644 --- a/patches/minecraft/net/minecraft/client/renderer/entity/LivingEntityRenderer.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/entity/LivingEntityRenderer.java.patch @@ -8,7 +8,7 @@ poseStack.pushPose(); if (state.hasPose(Pose.SLEEPING)) { Direction bedOrientation = state.bedOrientation; -@@ -110,6 +_,7 @@ +@@ -108,6 +_,7 @@ poseStack.popPose(); super.submit(state, poseStack, submitNodeCollector, camera); @@ -16,7 +16,7 @@ } protected boolean shouldRenderLayers(final S state) { -@@ -278,7 +_,7 @@ +@@ -276,7 +_,7 @@ state.isFullyFrozen = entity.isFullyFrozen(); state.isBaby = entity.isBaby(); diff --git a/patches/minecraft/net/minecraft/client/renderer/entity/player/AvatarRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/entity/player/AvatarRenderer.java.patch index 8dd36f4d24..6a5c2c667e 100644 --- a/patches/minecraft/net/minecraft/client/renderer/entity/player/AvatarRenderer.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/entity/player/AvatarRenderer.java.patch @@ -1,26 +1,24 @@ --- a/net/minecraft/client/renderer/entity/player/AvatarRenderer.java +++ b/net/minecraft/client/renderer/entity/player/AvatarRenderer.java -@@ -98,7 +_,7 @@ +@@ -94,7 +_,7 @@ return HumanoidModel.ArmPose.EMPTY; } -- if (!avatar.swinging && itemInHand.is(Items.CROSSBOW) && CrossbowItem.isCharged(itemInHand)) { -+ if (!avatar.swinging && itemInHand.getItem() instanceof CrossbowItem && CrossbowItem.isCharged(itemInHand)) { +- if (!avatar.isSwinging() && itemInHand.is(Items.CROSSBOW) && CrossbowItem.isCharged(itemInHand)) { ++ if (!avatar.isSwinging() && itemInHand.getItem() instanceof CrossbowItem && CrossbowItem.isCharged(itemInHand)) { return HumanoidModel.ArmPose.CROSSBOW_HOLD; } -@@ -141,7 +_,9 @@ - if (attack != null && attack.type() == SwingAnimationType.STAB && avatar.swinging) { - return HumanoidModel.ArmPose.SPEAR; - } else { -- return itemInHand.is(ItemTags.SPEARS) ? HumanoidModel.ArmPose.SPEAR : HumanoidModel.ArmPose.ITEM; -+ if (itemInHand.is(ItemTags.SPEARS)) return HumanoidModel.ArmPose.SPEAR; -+ var pose = net.minecraftforge.client.extensions.common.IClientItemExtensions.of(itemInHand).getArmPose(avatar, hand, itemInHand); -+ return pose == null ? HumanoidModel.ArmPose.ITEM : pose; - } +@@ -135,7 +_,7 @@ + + return HumanoidMobRenderer.usesSpearPose(itemInHand, hand.asArm(avatar.getMainArm()), avatar) + ? HumanoidModel.ArmPose.SPEAR +- : HumanoidModel.ArmPose.ITEM; ++ : net.minecraftforge.client.extensions.common.IClientItemExtensions.of(itemInHand).getArmPose(avatar, hand, itemInHand); } -@@ -241,12 +_,14 @@ + public Identifier getTextureLocation(final AvatarRenderState state) { +@@ -234,12 +_,14 @@ public void renderRightHand( final PoseStack poseStack, final SubmitNodeCollector submitNodeCollector, final int lightCoords, final Identifier skinTexture, final boolean hasSleeve ) { @@ -35,7 +33,7 @@ this.renderHand(poseStack, submitNodeCollector, lightCoords, skinTexture, this.model.leftArm, hasSleeve); } -@@ -304,5 +_,12 @@ +@@ -297,5 +_,12 @@ public static boolean isPlayerUpsideDown(final Player player) { return isUpsideDownName(player.getGameProfile().name()); diff --git a/patches/minecraft/net/minecraft/client/renderer/extract/LevelExtractor.java.patch b/patches/minecraft/net/minecraft/client/renderer/extract/LevelExtractor.java.patch index 1ed87d4486..0b885c6b39 100644 --- a/patches/minecraft/net/minecraft/client/renderer/extract/LevelExtractor.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/extract/LevelExtractor.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/client/renderer/extract/LevelExtractor.java +++ b/net/minecraft/client/renderer/extract/LevelExtractor.java -@@ -172,7 +_,7 @@ +@@ -188,7 +_,7 @@ profiler.popPush("entities"); this.extractVisibleEntities(camera, cullFrustum, deltaTracker, this.levelRenderState); profiler.popPush("blockEntities"); -- this.extractVisibleBlockEntities(camera, deltaPartialTick, this.levelRenderState); -+ this.extractVisibleBlockEntities(camera, deltaPartialTick, this.levelRenderState, cullFrustum); +- this.extractVisibleBlockEntities(camera, worldPartialTicks, this.levelRenderState); ++ this.extractVisibleBlockEntities(camera, worldPartialTicks, this.levelRenderState, cullFrustum); profiler.popPush("blockOutline"); this.extractBlockOutline(camera, this.levelRenderState); profiler.popPush("blockBreaking"); -@@ -264,7 +_,7 @@ +@@ -311,7 +_,7 @@ return this.levelRenderer.entityRenderDispatcher().extractEntity(entity, partialTickTime); } @@ -18,15 +18,15 @@ Vec3 cameraPos = camera.position(); double camX = cameraPos.x(); double camY = cameraPos.y(); -@@ -275,6 +_,7 @@ +@@ -323,6 +_,7 @@ List renderableBlockEntities = section.getSectionMesh().getRenderableBlockEntities(); - if (!renderableBlockEntities.isEmpty() && !(section.getVisibility(Util.getMillis()) < 0.3F)) { + if (!renderableBlockEntities.isEmpty() && !(section.getVisibility(Util.getMillis(), chunkFadeDuration) < 0.3F)) { for (BlockEntity blockEntity : renderableBlockEntities) { + if (!frustum.isVisible(blockEntity.getRenderBoundingBox())) continue; BlockPos blockPos = blockEntity.getBlockPos(); SortedSet progresses = this.level.destructionProgress().get(blockPos.asLong()); ModelFeatureRenderer.CrumblingOverlay breakProgress; -@@ -304,6 +_,7 @@ +@@ -352,6 +_,7 @@ if (blockEntity.isRemoved()) { iterator.remove(); } else { @@ -34,7 +34,7 @@ BlockEntityRenderState state = this.levelRenderer .blockEntityRenderDispatcher() .tryExtractRenderState(blockEntity, deltaPartialTick, null, true); -@@ -327,7 +_,7 @@ +@@ -375,7 +_,7 @@ SortedSet progresses = entry.getValue(); if (progresses != null && !progresses.isEmpty()) { int progress = progresses.last().getProgress(); @@ -43,7 +43,7 @@ } } } -@@ -335,6 +_,12 @@ +@@ -383,6 +_,12 @@ private void extractBlockOutline(final Camera camera, final LevelRenderState levelRenderState) { levelRenderState.blockOutlineRenderState = null; @@ -56,3 +56,60 @@ if (this.minecraft.hitResult instanceof BlockHitResult blockHitResult) { if (blockHitResult.getType() != HitResult.Type.MISS) { BlockPos pos = blockHitResult.getBlockPos(); +@@ -444,24 +_,32 @@ + } + + if (!(camera.entity() instanceof LivingEntity livingEntity && livingEntity.isSleeping())) { +- BlockState viewBlockingState = getViewBlockingState(player, camera.getCullFrustum()); ++ var overlay = getOverlayBlock(player, camera.getCullFrustum()); ++ BlockState viewBlockingState = overlay == null ? null : overlay.state(); + if (viewBlockingState != null) { + TextureAtlasSprite sprite = this.minecraft.getModelManager().getBlockStateModelSet().getParticleMaterial(viewBlockingState).sprite(); + state.blockOverlay = new PlayerRenderState.BlockOverlay( + sprite.atlasLocation(), sprite.getU0(), sprite.getV0(), sprite.getU1(), sprite.getV1() + ); ++ state.customBlockOverlay = net.minecraftforge.client.ForgeHooksClient.renderBlockOverlay(player, overlay.state(), overlay.pos()); + } + + if (this.minecraft.options.getCameraType().isFirstPerson()) { + state.isEyeInWater = player.isEyeInFluid(FluidTags.WATER); + state.isOnFire = player.isOnFire(); +- if (state.isEyeInWater) { ++ if (state.isEyeInWater || !player.getEyeInFluidType().isAir()) { + BlockPos eyePos = BlockPos.containing(player.getEyePosition()); + float brightness = Lightmap.getBrightness(player.level().dimensionType(), player.level().getMaxLocalRawBrightness(eyePos)); + state.waterOverlay = new PlayerRenderState.WaterOverlay( + ARGB.colorFromFloat(0.1F, brightness, brightness, brightness), -player.getYRot() / 64.0F, player.getXRot() / 64.0F + ); ++ if (state.isEyeInWater) ++ state.customFluidOverlay = net.minecraftforge.client.ForgeHooksClient.renderWaterOverlay(player, state); ++ else ++ state.customFluidOverlay = net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions.of(player.getEyeInFluidType()).renderOverlay(this.minecraft, state); + } ++ if (state.isOnFire) ++ state.customFireOverlay = net.minecraftforge.client.ForgeHooksClient.renderFireOverlay(player); + } + } + } else { +@@ -475,6 +_,12 @@ + return null; + } + ++ var ret = getOverlayBlock(player, frustum); ++ return ret == null ? null : ret.state(); ++ } ++ ++ private record OverlayInfo(BlockState state, BlockPos pos) {} ++ private static @Nullable OverlayInfo getOverlayBlock(final LocalPlayer player, final Frustum frustum) { + AABB nearPlaneBB = frustum.getNearPlaneBounds().move(player.getEyePosition()); + BlockPos.MutableBlockPos testPos = new BlockPos.MutableBlockPos(); + +@@ -486,7 +_,7 @@ + ); + BlockState blockState = player.level().getBlockState(testPos); + if (blockState.getRenderShape() != RenderShape.INVISIBLE && blockState.isViewBlocking(player.level(), testPos, nearPlaneBB)) { +- return blockState; ++ return new OverlayInfo(blockState, testPos.immutable()); + } + } + diff --git a/patches/minecraft/net/minecraft/client/renderer/fog/FogRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/fog/FogRenderer.java.patch index 386f3cf404..a4149fde48 100644 --- a/patches/minecraft/net/minecraft/client/renderer/fog/FogRenderer.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/fog/FogRenderer.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/client/renderer/fog/FogRenderer.java +++ b/net/minecraft/client/renderer/fog/FogRenderer.java -@@ -159,6 +_,12 @@ - fogBlue = Mth.lerp(brightenFactor, fogBlue, fogBlue * scale); +@@ -154,6 +_,12 @@ + fogBlue = Mth.lerp(brightenFactor, fogBlue, fogBlue * targetScale); } + var fogColor = net.minecraftforge.client.ForgeHooksClient.getFogColor(camera, partialTicks, level, renderDistance, darkenWorldAmount, fogRed, fogGreen, fogBlue); @@ -13,7 +13,7 @@ dest.set(fogRed, fogGreen, fogBlue, 1.0F); } -@@ -186,6 +_,7 @@ +@@ -181,6 +_,7 @@ float renderDistanceFogSpan = Mth.clamp(renderDistanceInBlocks / 10.0F, 4.0F, 64.0F); fog.renderDistanceStart = renderDistanceInBlocks - renderDistanceFogSpan; fog.renderDistanceEnd = renderDistanceInBlocks; diff --git a/patches/minecraft/net/minecraft/client/renderer/rendertype/RenderTypes.java.patch b/patches/minecraft/net/minecraft/client/renderer/rendertype/RenderTypes.java.patch index fcbfb34b31..3a6019f697 100644 --- a/patches/minecraft/net/minecraft/client/renderer/rendertype/RenderTypes.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/rendertype/RenderTypes.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/client/renderer/rendertype/RenderTypes.java +++ b/net/minecraft/client/renderer/rendertype/RenderTypes.java -@@ -574,7 +_,7 @@ +@@ -674,7 +_,7 @@ } - public static RenderType text(final Identifier texture) { -- return TEXT.apply(texture); + public static RenderType eyes(final Identifier texture) { +- return EYES.apply(texture); + return net.minecraftforge.client.ForgeRenderTypes.getText(texture); } - public static RenderType textBackground() { -@@ -582,19 +_,19 @@ + public static RenderType breezeEyes(final Identifier texture) { +@@ -737,23 +_,23 @@ } public static RenderType textGrayscale(final Identifier texture) { @@ -32,10 +32,6 @@ + return net.minecraftforge.client.ForgeRenderTypes.getTextSeeThrough(texture); } - public static RenderType textBackgroundSeeThrough() { -@@ -602,7 +_,7 @@ - } - public static RenderType textGrayscaleSeeThrough(final Identifier texture) { - return TEXT_GRAYSCALE_SEE_THROUGH.apply(texture); + return net.minecraftforge.client.ForgeRenderTypes.getTextGrayscaleSeeThrough(texture); diff --git a/patches/minecraft/net/minecraft/client/renderer/state/level/PlayerRenderState.java.patch b/patches/minecraft/net/minecraft/client/renderer/state/level/PlayerRenderState.java.patch new file mode 100644 index 0000000000..28323965c8 --- /dev/null +++ b/patches/minecraft/net/minecraft/client/renderer/state/level/PlayerRenderState.java.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/client/renderer/state/level/PlayerRenderState.java ++++ b/net/minecraft/client/renderer/state/level/PlayerRenderState.java +@@ -24,12 +_,19 @@ + public PlayerRenderState.@Nullable WaterOverlay waterOverlay; + public PlayerRenderState.@Nullable ItemActivationRenderState itemActivation; + ++ public net.minecraftforge.client.@Nullable IRenderCallback customBlockOverlay; ++ public net.minecraftforge.client.@Nullable IRenderCallback customFluidOverlay; ++ public net.minecraftforge.client.@Nullable IRenderCallback customFireOverlay; ++ + public void reset() { + this.hasPlayer = false; + this.avatarRenderState = null; + this.blockOverlay = null; + this.waterOverlay = null; + this.itemActivation = null; ++ this.customBlockOverlay = null; ++ this.customFluidOverlay = null; ++ this.customFireOverlay = null; + } + + @OnlyIn(Dist.CLIENT) diff --git a/patches/minecraft/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch b/patches/minecraft/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch index 1d4983188c..88cf56bde7 100644 --- a/patches/minecraft/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/texture/TextureAtlasSprite.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/renderer/texture/TextureAtlasSprite.java +++ b/net/minecraft/client/renderer/texture/TextureAtlasSprite.java -@@ -26,7 +_,7 @@ +@@ -24,7 +_,7 @@ private final float v1; private final int padding; @@ -9,7 +9,7 @@ final Identifier atlasLocation, final SpriteContents contents, final int atlasWidth, final int atlasHeight, final int x, final int y, final int padding ) { this.atlasLocation = atlasLocation; -@@ -127,5 +_,14 @@ +@@ -123,5 +_,14 @@ @Override public void close() { this.contents.close(); diff --git a/patches/minecraft/net/minecraft/client/resources/language/ClientLanguage.java.patch b/patches/minecraft/net/minecraft/client/resources/language/ClientLanguage.java.patch index 276fcda0e3..872e4b6ae5 100644 --- a/patches/minecraft/net/minecraft/client/resources/language/ClientLanguage.java.patch +++ b/patches/minecraft/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 -@@ -78,4 +_,9 @@ +@@ -83,4 +_,9 @@ public FormattedCharSequence getVisualOrder(final FormattedText logicalOrderText) { return FormattedBidiReorder.reorder(logicalOrderText, this.defaultRightToLeft); } diff --git a/patches/minecraft/net/minecraft/client/resources/language/LanguageManager.java.patch b/patches/minecraft/net/minecraft/client/resources/language/LanguageManager.java.patch index 03ba4a31c1..dd691a9bed 100644 --- a/patches/minecraft/net/minecraft/client/resources/language/LanguageManager.java.patch +++ b/patches/minecraft/net/minecraft/client/resources/language/LanguageManager.java.patch @@ -1,17 +1,17 @@ --- a/net/minecraft/client/resources/language/LanguageManager.java +++ b/net/minecraft/client/resources/language/LanguageManager.java -@@ -29,8 +_,8 @@ - private final Consumer reloadCallback; +@@ -34,8 +_,8 @@ - public LanguageManager(final String languageCode, final Consumer reloadCallback) { + public LanguageManager(final Minecraft minecraft, final String languageCode, final Consumer reloadCallback) { + this.minecraft = minecraft; - this.currentCode = languageCode; this.reloadCallback = reloadCallback; + setSelected(languageCode); } private static Map extractLanguages(final Stream resourcePacks) { -@@ -67,8 +_,12 @@ - this.reloadCallback.accept(locale); +@@ -86,8 +_,12 @@ + } } + private java.util.Locale javaLocale; // Forge: add locale information for modders diff --git a/patches/minecraft/net/minecraft/client/resources/model/ModelManager.java.patch b/patches/minecraft/net/minecraft/client/resources/model/ModelManager.java.patch index 0b9ae29949..a253aafa03 100644 --- a/patches/minecraft/net/minecraft/client/resources/model/ModelManager.java.patch +++ b/patches/minecraft/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 -@@ -61,6 +_,7 @@ +@@ -60,6 +_,7 @@ private static final Logger LOGGER = LogUtils.getLogger(); private static final FileToIdConverter MODEL_LISTER = FileToIdConverter.json("models"); private Map bakedItemStackModels = Map.of(); @@ -8,7 +8,7 @@ private Map itemProperties = Map.of(); private final AtlasManager atlasManager; private final PlayerSkinRenderCache playerSkinRenderCache; -@@ -71,6 +_,7 @@ +@@ -70,6 +_,7 @@ private @Nullable BlockModelSet blockModelSet; private @Nullable FluidStateModelSet fluidStateModelSet; private Object2IntMap modelGroups = Object2IntMaps.emptyMap(); @@ -16,7 +16,7 @@ public ModelManager(final BlockColors blockColors, final AtlasManager atlasManager, final PlayerSkinRenderCache playerSkinRenderCache) { this.blockColors = blockColors; -@@ -82,6 +_,18 @@ +@@ -81,6 +_,18 @@ return this.bakedItemStackModels.getOrDefault(id, this.missingModels.item()); } @@ -35,7 +35,7 @@ public ClientItem.Properties getItemProperties(final Identifier id) { return this.itemProperties.getOrDefault(id, ClientItem.Properties.DEFAULT); } -@@ -105,6 +_,7 @@ +@@ -104,6 +_,7 @@ final PreparableReloadListener.PreparationBarrier preparationBarrier, final Executor reloadExecutor ) { @@ -43,13 +43,13 @@ ResourceManager manager = currentReload.resourceManager(); CompletableFuture entityModelSet = CompletableFuture.supplyAsync(EntityModelSet::vanilla, taskExecutor); CompletableFuture> modelCache = loadBlockModels(manager, taskExecutor); -@@ -224,12 +_,14 @@ +@@ -221,12 +_,14 @@ + bakedModelsFuture, (bakingResult, bakedModels) -> { - blockItemMaterialBaker.logMissingTextures(); - Map fluidModels = FluidStateModelSet.bake(blockOnlyMaterialBaker); -+ fluidModels = net.minecraftforge.client.ForgeHooksClient.onFluidModelBake(bakery, blockOnlyMaterialBaker, fluidModels); + Map fluidModels = FluidStateModelSet.bake(materialBaker); ++ fluidModels = net.minecraftforge.client.ForgeHooksClient.onFluidModelBake(bakery, materialBaker, fluidModels); + net.minecraftforge.client.ForgeHooksClient.onModifyBakingResult(bakery, bakingResult); - blockOnlyMaterialBaker.logMissingTextures(); + materialBaker.logMissingTextures(); Map modelByStateCache = createBlockStateToModelDispatch( bakingResult.blockStateModels(), bakingResult.missingModels().block() ); @@ -59,7 +59,7 @@ ); } ); -@@ -261,10 +_,15 @@ +@@ -258,10 +_,15 @@ private void apply(final ModelManager.ReloadState preparations) { ModelBakery.BakingResult bakedModels = preparations.bakedModels; @@ -75,7 +75,7 @@ this.blockStateModelSet = new BlockStateModelSet(preparations.blockStateModels, this.missingModels.block()); this.blockModelSet = new BlockModelSet(this.blockStateModelSet, preparations.blockModels, this.blockColors); this.fluidStateModelSet = new FluidStateModelSet(preparations.fluidModels, this.missingModels.fluid()); -@@ -333,7 +_,8 @@ +@@ -297,7 +_,8 @@ Map blockStateModels, Map blockModels, Map fluidModels, diff --git a/patches/minecraft/net/minecraft/client/resources/model/cuboid/UnbakedCuboidGeometry.java.patch b/patches/minecraft/net/minecraft/client/resources/model/cuboid/UnbakedCuboidGeometry.java.patch index 5377339e00..9dae0883c5 100644 --- a/patches/minecraft/net/minecraft/client/resources/model/cuboid/UnbakedCuboidGeometry.java.patch +++ b/patches/minecraft/net/minecraft/client/resources/model/cuboid/UnbakedCuboidGeometry.java.patch @@ -29,9 +29,9 @@ - Material.Baked material = modelBaker.materials().resolveSlot(textures, face.texture(), name); + Material.Baked material = materialMapper.apply(face.texture()); BakedQuad quad = FaceBakery.bakeQuad( - modelBaker, from, to, face, material, facing, modelState, element.rotation(), element.shade(), element.lightEmission() - ); -@@ -76,7 +_,5 @@ + modelBaker, + from, +@@ -85,7 +_,5 @@ } } } diff --git a/patches/minecraft/net/minecraft/client/resources/sounds/SoundInstance.java.patch b/patches/minecraft/net/minecraft/client/resources/sounds/SoundInstance.java.patch index 4e5ef3db75..853cfc7857 100644 --- a/patches/minecraft/net/minecraft/client/resources/sounds/SoundInstance.java.patch +++ b/patches/minecraft/net/minecraft/client/resources/sounds/SoundInstance.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/resources/sounds/SoundInstance.java +++ b/net/minecraft/client/resources/sounds/SoundInstance.java -@@ -54,4 +_,8 @@ +@@ -56,4 +_,8 @@ NONE, LINEAR; } diff --git a/patches/minecraft/net/minecraft/client/server/IntegratedServer.java.patch b/patches/minecraft/net/minecraft/client/server/IntegratedServer.java.patch index 989eb4441f..cc7531b32e 100644 --- a/patches/minecraft/net/minecraft/client/server/IntegratedServer.java.patch +++ b/patches/minecraft/net/minecraft/client/server/IntegratedServer.java.patch @@ -15,7 +15,7 @@ } @Override -@@ -371,6 +_,7 @@ +@@ -397,6 +_,7 @@ @Override public void halt(final boolean wait) { diff --git a/patches/minecraft/net/minecraft/client/sounds/SoundEngine.java.patch b/patches/minecraft/net/minecraft/client/sounds/SoundEngine.java.patch index 0beb89e8a4..9fc6348a94 100644 --- a/patches/minecraft/net/minecraft/client/sounds/SoundEngine.java.patch +++ b/patches/minecraft/net/minecraft/client/sounds/SoundEngine.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/client/sounds/SoundEngine.java +++ b/net/minecraft/client/sounds/SoundEngine.java -@@ -82,6 +_,7 @@ +@@ -83,6 +_,7 @@ this.options = options; this.soundBuffers = new SoundBufferLibrary(resourceProvider); this.lastSeenDevices = this.deviceTracker.currentDevices(); @@ -8,7 +8,7 @@ } public void reload() { -@@ -99,6 +_,7 @@ +@@ -100,6 +_,7 @@ this.destroy(); this.loadLibrary(); @@ -16,28 +16,30 @@ } private synchronized void loadLibrary() { -@@ -340,7 +_,7 @@ +@@ -363,15 +_,18 @@ } } - public SoundEngine.PlayResult play(final SoundInstance instance) { -+ public SoundEngine.PlayResult play(SoundInstance instance) { ++ public SoundEngine.PlayResult play(final SoundInstance instanceArg) { if (!this.loaded) { return SoundEngine.PlayResult.NOT_STARTED; } -@@ -349,6 +_,9 @@ + +- if (!instance.canPlaySound()) { ++ if (!instanceArg.canPlaySound()) { return SoundEngine.PlayResult.NOT_STARTED; } -+ instance = net.minecraftforge.client.ForgeHooksClient.playSound(this, instance); ++ final var instance = net.minecraftforge.client.ForgeHooksClient.playSound(this, instanceArg); + if (instance == null || !instance.canPlaySound()) + return SoundEngine.PlayResult.NOT_STARTED; - WeighedSoundEvents soundEvent = instance.resolve(this.soundManager); + WeighedSoundEvents soundEvent = instance.getOrResolve(this.soundManager); Identifier eventLocation = instance.getIdentifier(); if (soundEvent == null) { -@@ -430,15 +_,18 @@ +@@ -447,15 +_,18 @@ channel.setSelfPosition(position); - channel.setRelative(isRelative); + channel.setRelative(instance.isRelative()); }); + SoundInstance soundinstance = instance; if (!isStreaming) { diff --git a/patches/minecraft/net/minecraft/commands/Commands.java.patch b/patches/minecraft/net/minecraft/commands/Commands.java.patch index 58a2296f83..83ae588e16 100644 --- a/patches/minecraft/net/minecraft/commands/Commands.java.patch +++ b/patches/minecraft/net/minecraft/commands/Commands.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/commands/Commands.java +++ b/net/minecraft/commands/Commands.java -@@ -265,7 +_,7 @@ +@@ -269,7 +_,7 @@ ChaseCommand.register(this.dispatcher); } @@ -9,7 +9,7 @@ RaidCommand.register(this.dispatcher, context); DebugPathCommand.register(this.dispatcher); DebugMobSpawningCommand.register(this.dispatcher); -@@ -299,6 +_,7 @@ +@@ -303,6 +_,7 @@ PublishCommand.register(this.dispatcher); UnpublishCommand.register(this.dispatcher); } @@ -17,7 +17,7 @@ this.dispatcher.setConsumer(ExecutionCommandSource.resultConsumer()); } -@@ -321,9 +_,18 @@ +@@ -325,9 +_,18 @@ public void performCommand(final ParseResults command, final String commandString) { CommandSourceStack sender = command.getContext().getSource(); Profiler.get().push(() -> "/" + commandString); @@ -37,7 +37,7 @@ if (commandChain != null) { executeCommandInContext( sender, -@@ -414,7 +_,10 @@ +@@ -418,7 +_,10 @@ Map, CommandNode> playerCommands = new HashMap<>(); RootCommandNode root = new RootCommandNode<>(); playerCommands.put(this.dispatcher.getRoot(), root); diff --git a/patches/minecraft/net/minecraft/commands/synchronization/ArgumentTypeInfos.java.patch b/patches/minecraft/net/minecraft/commands/synchronization/ArgumentTypeInfos.java.patch index 838237a4a8..0d1be1ff8c 100644 --- a/patches/minecraft/net/minecraft/commands/synchronization/ArgumentTypeInfos.java.patch +++ b/patches/minecraft/net/minecraft/commands/synchronization/ArgumentTypeInfos.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/commands/synchronization/ArgumentTypeInfos.java +++ b/net/minecraft/commands/synchronization/ArgumentTypeInfos.java -@@ -67,6 +_,20 @@ +@@ -69,6 +_,20 @@ public class ArgumentTypeInfos { private static final Map, ArgumentTypeInfo> BY_CLASS = Maps.newHashMap(); diff --git a/patches/minecraft/net/minecraft/core/BlockPos.java.patch b/patches/minecraft/net/minecraft/core/BlockPos.java.patch index 0755583bf8..7f74213ec5 100644 --- a/patches/minecraft/net/minecraft/core/BlockPos.java.patch +++ b/patches/minecraft/net/minecraft/core/BlockPos.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/core/BlockPos.java +++ b/net/minecraft/core/BlockPos.java -@@ -29,7 +_,7 @@ - import org.apache.commons.lang3.Validate; +@@ -28,7 +_,7 @@ + import org.jspecify.annotations.Nullable; @Immutable -public class BlockPos extends Vec3i { diff --git a/patches/minecraft/net/minecraft/core/Holder.java.patch b/patches/minecraft/net/minecraft/core/Holder.java.patch index 7fbde66e6f..0739fa2882 100644 --- a/patches/minecraft/net/minecraft/core/Holder.java.patch +++ b/patches/minecraft/net/minecraft/core/Holder.java.patch @@ -24,7 +24,7 @@ T value(); boolean isBound(); -@@ -258,6 +_,10 @@ +@@ -262,6 +_,10 @@ @Override public Stream> tags() { return this.boundTags().stream(); diff --git a/patches/minecraft/net/minecraft/core/HolderSet.java.patch b/patches/minecraft/net/minecraft/core/HolderSet.java.patch index 2ae19cd814..e70e22ec66 100644 --- a/patches/minecraft/net/minecraft/core/HolderSet.java.patch +++ b/patches/minecraft/net/minecraft/core/HolderSet.java.patch @@ -20,7 +20,7 @@ @@ -215,6 +_,12 @@ @Override public boolean canSerializeIn(final HolderOwner context) { - return this.owner.canSerializeIn(context); + return context.canSerialize(this.owner); + } + + // FORGE: Keep a list of invalidation callbacks so they can be run when tags rebind diff --git a/patches/minecraft/net/minecraft/core/MappedRegistry.java.patch b/patches/minecraft/net/minecraft/core/MappedRegistry.java.patch index 66de6fc518..a8fb6cd52e 100644 --- a/patches/minecraft/net/minecraft/core/MappedRegistry.java.patch +++ b/patches/minecraft/net/minecraft/core/MappedRegistry.java.patch @@ -68,7 +68,7 @@ @Override public Holder.Reference createIntrusiveHolder(final T value) { if (this.unregisteredIntrusiveHolders == null) { -@@ -393,6 +_,31 @@ +@@ -398,6 +_,31 @@ }; } @@ -100,7 +100,7 @@ @Override public Registry.PendingTags prepareTagReload(final TagLoader.LoadResult tags) { if (!this.frozen) { -@@ -441,6 +_,11 @@ +@@ -446,6 +_,11 @@ @Override public HolderLookup.RegistryLookup lookup() { return patchedHolder; diff --git a/patches/minecraft/net/minecraft/core/RegistrySetBuilder.java.patch b/patches/minecraft/net/minecraft/core/RegistrySetBuilder.java.patch index 27bba4809c..2e5466660f 100644 --- a/patches/minecraft/net/minecraft/core/RegistrySetBuilder.java.patch +++ b/patches/minecraft/net/minecraft/core/RegistrySetBuilder.java.patch @@ -1,98 +1,48 @@ --- a/net/minecraft/core/RegistrySetBuilder.java +++ b/net/minecraft/core/RegistrySetBuilder.java -@@ -22,7 +_,8 @@ - import org.apache.commons.lang3.mutable.MutableObject; - import org.jspecify.annotations.Nullable; +@@ -19,7 +_,7 @@ + import net.minecraft.data.worldgen.BootstrapContext; + import net.minecraft.resources.ResourceKey; -public class RegistrySetBuilder { +public class RegistrySetBuilder implements net.minecraftforge.common.extensions.IForgeRegistrySetBuilder { -+ private final it.unimi.dsi.fastutil.objects.Object2IntMap>> indexes = new it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap<>(); - private final List> entries = new ArrayList<>(); + private final List entries = new ArrayList<>(); - private static HolderGetter wrapContextLookup(final HolderLookup.RegistryLookup original) { -@@ -66,14 +_,43 @@ - public RegistrySetBuilder add( - final ResourceKey> key, final Lifecycle lifecycle, final RegistrySetBuilder.RegistryBootstrap bootstrap - ) { -- this.entries.add(new RegistrySetBuilder.RegistryStub<>(key, lifecycle, bootstrap)); -+ add(new RegistrySetBuilder.RegistryStub<>(key, lifecycle, bootstrap)); + private static RegistrySetBuilder.RegistryStub placeholderStub(final ResourceKey> key) { +@@ -65,6 +_,11 @@ return this; } -+ // Forge: This merges two entries in this builder together, so that we can reuse vanilla boostrap methods, or potentially other modder's methods. -+ private RegistrySetBuilder.RegistryStub add(RegistrySetBuilder.RegistryStub entry) { -+ int idx = indexes.getOrDefault(entry.key(), -1); -+ if (idx != -1) { -+ var _oldB = ((RegistrySetBuilder.RegistryStub)this.entries.get(idx)).bootstrap(); -+ var _newB = entry.bootstrap(); -+ var _new = new RegistrySetBuilder.RegistryStub<>(entry.key(), entry.lifecycle(), ctx -> { -+ _oldB.run(ctx); -+ _newB.run(ctx); -+ }); -+ this.entries.set(idx, _new); -+ return _new; -+ } else { -+ this.indexes.put(entry.key(), this.entries.size()); -+ this.entries.add(entry); -+ return entry; -+ } ++ public RegistrySetBuilder add(final RegistrySetBuilder other) { ++ this.entries.addAll(other.entries); ++ return this; + } + -+ public RegistrySetBuilder copy() { -+ var ret = new RegistrySetBuilder(); -+ this.entries.forEach(ret::add); -+ return ret; -+ } -+ - public RegistrySetBuilder add(final ResourceKey> key, final RegistrySetBuilder.RegistryBootstrap bootstrap) { - return this.add(key, Lifecycle.stable(), bootstrap); + private static HolderLookup.Provider buildProviderWithContext( + final HolderLookup.Provider context, final Stream> newRegistries + ) { +@@ -128,6 +_,10 @@ + return (ResourceKey>)registryKey; } + public List>> getEntryKeys() { -+ return this.entries.stream().map(RegistrySetBuilder.RegistryStub::key).toList(); ++ return newRegistryKeys(this.entries.stream()).toList(); + } + - private RegistrySetBuilder.BuildState createState(final RegistryAccess context) { - RegistrySetBuilder.BuildState state = RegistrySetBuilder.BuildState.create(context, this.entries.stream().map(RegistrySetBuilder.RegistryStub::key)); - this.entries.forEach(e -> e.apply(state)); -@@ -181,14 +_,16 @@ - } - - Map, Holder.Reference> entries = new HashMap<>(); -- HolderLookup.RegistryLookup patchContents = patchProvider.lookupOrThrow(registryKey); -+ HolderLookup.RegistryLookup patchContents = patchProvider.lookup(registryKey).orElse(null); - patchContents.listElements().forEach(elementHolder -> { - ResourceKey elementKey = elementHolder.key(); - RegistrySetBuilder.LazyHolder holder = new RegistrySetBuilder.LazyHolder<>(owner, elementKey); - holder.supplier = () -> cloner.clone((T)elementHolder.value(), patchProvider, targetProvider.get()); - entries.put(elementKey, holder); - }); -- HolderLookup.RegistryLookup fallbackContents = fallbackProvider.lookupOrThrow(registryKey); -+ HolderLookup.RegistryLookup fallbackContents = fallbackProvider.lookup(registryKey).orElse(null); -+ Lifecycle lifecycle = patchContents.registryLifecycle(); -+ if (fallbackContents != null) { - fallbackContents.listElements().forEach(elementHolder -> { - ResourceKey elementKey = elementHolder.key(); - entries.computeIfAbsent(elementKey, key -> { -@@ -197,7 +_,8 @@ - return holder; - }); - }); -- Lifecycle lifecycle = patchContents.registryLifecycle().add(fallbackContents.registryLifecycle()); -+ lifecycle = patchContents.registryLifecycle().add(fallbackContents.registryLifecycle()); -+ } - return lookupFromMap(registryKey, lifecycle, owner, entries); + private static Stream>> newRegistryKeys(final Stream entries) { + return entries.flatMap(RegistrySetBuilder.RegistryStub::requiredRegistries).distinct(); } - -@@ -266,6 +_,11 @@ +@@ -158,6 +_,13 @@ @Override - public HolderGetter lookup(final ResourceKey> key) { - return (HolderGetter)BuildState.this.registries.getOrDefault(key.identifier(), BuildState.this.lookup); + public Stream> listContextElements(final ResourceKey> key) { + return state.contextRegistries.lookupOrThrow(key).listElements(); + } + + @Override -+ public Optional> registryLookup(ResourceKey> registry) { -+ return Optional.ofNullable((HolderLookup.RegistryLookup) BuildState.this.registries.get(registry.identifier())); ++ public java.util.Optional> registryLookup(ResourceKey> registry) { ++ @SuppressWarnings("unchecked") ++ var ret = (java.util.Optional>)state.contextRegistries.lookup(registry); ++ return ret; } }; } diff --git a/patches/minecraft/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch b/patches/minecraft/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch index 35d8910ab2..6192b7c0e6 100644 --- a/patches/minecraft/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch +++ b/patches/minecraft/net/minecraft/core/dispenser/DispenseItemBehavior.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -141,7 +_,7 @@ +@@ -143,7 +_,7 @@ DispensibleContainerItem bucket = (DispensibleContainerItem)dispensed.getItem(); BlockPos target = source.pos().relative(source.state().getValue(DispenserBlock.FACING)); Level level = source.level(); diff --git a/patches/minecraft/net/minecraft/core/dispenser/FlintAndSteelDispenseItemBehavior.java.patch b/patches/minecraft/net/minecraft/core/dispenser/FlintAndSteelDispenseItemBehavior.java.patch index 67d867e46e..a2d5743846 100644 --- a/patches/minecraft/net/minecraft/core/dispenser/FlintAndSteelDispenseItemBehavior.java.patch +++ b/patches/minecraft/net/minecraft/core/dispenser/FlintAndSteelDispenseItemBehavior.java.patch @@ -5,7 +5,7 @@ level.setBlockAndUpdate(targetPos, target.setValue(BlockStateProperties.LIT, true)); level.gameEvent(null, GameEvent.BLOCK_CHANGE, targetPos); - } else if (target.getBlock() instanceof TntBlock) { -- if (TntBlock.prime(level, targetPos)) { +- if (TntBlock.prime(level, targetPos, null, dispensed)) { + } else if (target.isFlammable(level, targetPos, source.state().getValue(DispenserBlock.FACING).getOpposite())) { + if (target.onCaughtFire(level, targetPos, source.state().getValue(DispenserBlock.FACING).getOpposite(), null)) { + if (target.getBlock() instanceof TntBlock) diff --git a/patches/minecraft/net/minecraft/core/registries/BuiltInRegistries.java.patch b/patches/minecraft/net/minecraft/core/registries/BuiltInRegistries.java.patch index ebb3225c50..8b90806aab 100644 --- a/patches/minecraft/net/minecraft/core/registries/BuiltInRegistries.java.patch +++ b/patches/minecraft/net/minecraft/core/registries/BuiltInRegistries.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/registries/BuiltInRegistries.java +++ b/net/minecraft/core/registries/BuiltInRegistries.java -@@ -389,11 +_,13 @@ +@@ -391,11 +_,13 @@ } private static > R internalRegister( @@ -16,7 +16,7 @@ WRITABLE_REGISTRY.register((ResourceKey)name, registry, RegistrationInfo.BUILT_IN); return registry; } -@@ -429,7 +_,7 @@ +@@ -431,7 +_,7 @@ if (r instanceof DefaultedRegistry) { Identifier key = ((DefaultedRegistry)r).getDefaultKey(); diff --git a/patches/minecraft/net/minecraft/core/registries/PatchedRegistry.java.patch b/patches/minecraft/net/minecraft/core/registries/PatchedRegistry.java.patch new file mode 100644 index 0000000000..f618577c75 --- /dev/null +++ b/patches/minecraft/net/minecraft/core/registries/PatchedRegistry.java.patch @@ -0,0 +1,30 @@ +--- a/net/minecraft/core/registries/PatchedRegistry.java ++++ b/net/minecraft/core/registries/PatchedRegistry.java +@@ -73,8 +_,8 @@ + } + + HolderLookup.RegistryLookup patchContents = patchProvider.lookupOrThrow(registryKey); +- HolderLookup.RegistryLookup baseContents = baseProvider.lookupOrThrow(registryKey); +- Lifecycle lifecycle = patchContents.registryLifecycle().add(baseContents.registryLifecycle()); ++ HolderLookup.RegistryLookup baseContents = baseProvider.lookup(registryKey).orElse(null); ++ Lifecycle lifecycle = baseContents == null ? patchContents.registryLifecycle() : patchContents.registryLifecycle().add(baseContents.registryLifecycle()); + PatchedRegistry result = new PatchedRegistry<>(registryKey, lifecycle); + patchContents.listElements().forEach(elementHolder -> { + ResourceKey elementKey = elementHolder.key(); +@@ -82,6 +_,7 @@ + holder.supplier = () -> cloner.clone((T)elementHolder.value(), patchProvider, clonedRegistriesProvider.get()); + result.entries.put(elementKey, holder); + }); ++ if (baseContents != null) + baseContents.listElements().forEach(elementHolder -> { + ResourceKey elementKey = elementHolder.key(); + result.entries.computeIfAbsent(elementKey, key -> { +@@ -121,7 +_,7 @@ + } + + @Override +- protected void bindValue(final T value) { ++ public void bindValue(final T value) { + super.bindValue(value); + this.supplier = null; + } diff --git a/patches/minecraft/net/minecraft/core/registries/Registries.java.patch b/patches/minecraft/net/minecraft/core/registries/Registries.java.patch index 6069af07bf..156c2cc219 100644 --- a/patches/minecraft/net/minecraft/core/registries/Registries.java.patch +++ b/patches/minecraft/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 -@@ -326,6 +_,8 @@ +@@ -342,6 +_,8 @@ } private static String registryDirPath(final ResourceKey> registryKey) { diff --git a/patches/minecraft/net/minecraft/core/registries/codec/HolderSetCodec.java.patch b/patches/minecraft/net/minecraft/core/registries/codec/HolderSetCodec.java.patch new file mode 100644 index 0000000000..769b46ad42 --- /dev/null +++ b/patches/minecraft/net/minecraft/core/registries/codec/HolderSetCodec.java.patch @@ -0,0 +1,51 @@ +--- a/net/minecraft/core/registries/codec/HolderSetCodec.java ++++ b/net/minecraft/core/registries/codec/HolderSetCodec.java +@@ -7,6 +_,8 @@ + import com.mojang.serialization.DynamicOps; + import java.util.List; + import java.util.Optional; ++import java.util.function.Function; ++ + import net.minecraft.core.Holder; + import net.minecraft.core.HolderGetter; + import net.minecraft.core.HolderOwner; +@@ -20,6 +_,8 @@ + public class HolderSetCodec implements Codec> { + private final ResourceKey> registryKey; + private final Codec, List>>> tagKeyOrValuesCodec; ++ private final Codec> forgeDispatchCodec; ++ private final Codec, Either, List>>>> combinedCodec; + + private static Codec>> directCodec(final Codec> elementCodec, final boolean alwaysUseList) { + Codec>> listCodec = elementCodec.listOf(); +@@ -35,15 +_,21 @@ + private HolderSetCodec(final ResourceKey> registryKey, final Codec> elementCodec, final boolean alwaysUseList) { + this.registryKey = registryKey; + this.tagKeyOrValuesCodec = Codec.either(TagKey.hashedCodec(registryKey), directCodec(elementCodec, alwaysUseList)); ++ // FORGE: make registry-specific dispatch codec and make forge-or-vanilla either codec ++ this.forgeDispatchCodec = Codec.lazyInitialized(() -> net.minecraftforge.registries.ForgeRegistries.HOLDER_SET_TYPES.get().getCodec()) ++ .dispatch(net.minecraftforge.registries.holdersets.ICustomHolderSet::type, type -> type.makeCodec(registryKey, elementCodec, alwaysUseList)); ++ this.combinedCodec = Codec.either(this.forgeDispatchCodec, this.tagKeyOrValuesCodec); + } + + @Override + public DataResult, T>> decode(final DynamicOps ops, final T input) { +- return this.tagKeyOrValuesCodec ++ return this.combinedCodec + .decode(ops, input) + .flatMap( + tagKeyOrValues -> { + DataResult> result = tagKeyOrValues.getFirst() ++ .map(custom -> DataResult.success(custom), ++ tagOrList -> tagOrList + .map( + tagKey -> { + if (ops instanceof RegistryOps registryOps) { +@@ -56,6 +_,7 @@ + } + }, + values -> DataResult.success(HolderSet.direct((List>)values)) ++ ) + ); + return result.map(holders -> Pair.of((HolderSet)holders, (T)tagKeyOrValues.getSecond())); + } diff --git a/patches/minecraft/net/minecraft/data/Main.java.patch b/patches/minecraft/net/minecraft/data/Main.java.patch index 5bb968547a..1c1efa5b22 100644 --- a/patches/minecraft/net/minecraft/data/Main.java.patch +++ b/patches/minecraft/net/minecraft/data/Main.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/data/Main.java +++ b/net/minecraft/data/Main.java -@@ -78,14 +_,17 @@ +@@ -74,14 +_,17 @@ OptionSpec allOption = parser.accepts("all", "Include all generators"); OptionSpec outputOption = parser.accepts("output", "Output folder").withRequiredArg().defaultsTo("generated"); OptionSpec inputOption = parser.accepts("input", "Input folder").withRequiredArg(); diff --git a/patches/minecraft/net/minecraft/data/advancements/AdvancementProvider.java.patch b/patches/minecraft/net/minecraft/data/advancements/AdvancementProvider.java.patch deleted file mode 100644 index 8e389b6555..0000000000 --- a/patches/minecraft/net/minecraft/data/advancements/AdvancementProvider.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/net/minecraft/data/advancements/AdvancementProvider.java -+++ b/net/minecraft/data/advancements/AdvancementProvider.java -@@ -16,6 +_,11 @@ - import net.minecraft.data.PackOutput; - import net.minecraft.resources.Identifier; - -+/** -+ * @deprecated Forge: Use {@link net.minecraftforge.common.data.ForgeAdvancementProvider} instead, -+ * provides ease of access for the {@link net.minecraftforge.common.data.ExistingFileHelper} in the generator -+ */ -+@Deprecated - public class AdvancementProvider implements DataProvider { - private final PackOutput.PathProvider pathProvider; - private final List subProviders; diff --git a/patches/minecraft/net/minecraft/data/loot/BlockLootSubProvider.java.patch b/patches/minecraft/net/minecraft/data/loot/BlockLootSubProvider.java.patch index a26aec6715..b819f5a7f8 100644 --- a/patches/minecraft/net/minecraft/data/loot/BlockLootSubProvider.java.patch +++ b/patches/minecraft/net/minecraft/data/loot/BlockLootSubProvider.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/data/loot/BlockLootSubProvider.java +++ b/net/minecraft/data/loot/BlockLootSubProvider.java -@@ -721,12 +_,16 @@ +@@ -707,12 +_,16 @@ protected abstract void generate(); + protected Iterable getKnownBlocks() { -+ return BuiltInRegistries.BLOCK; ++ return BuiltInRegistries.BLOCK.stream().filter(b -> net.minecraft.resources.Identifier.DEFAULT_NAMESPACE.equals(BuiltInRegistries.BLOCK.getKey(b).getNamespace()))::iterator; + } + @Override - public void generate(final BiConsumer, LootTable.Builder> output) { + public void run() { this.generate(); Set> seen = new HashSet<>(); diff --git a/patches/minecraft/net/minecraft/data/loot/EntityLootSubProvider.java.patch b/patches/minecraft/net/minecraft/data/loot/EntityLootSubProvider.java.patch index 2cedc75886..2754537525 100644 --- a/patches/minecraft/net/minecraft/data/loot/EntityLootSubProvider.java.patch +++ b/patches/minecraft/net/minecraft/data/loot/EntityLootSubProvider.java.patch @@ -1,19 +1,19 @@ --- a/net/minecraft/data/loot/EntityLootSubProvider.java +++ b/net/minecraft/data/loot/EntityLootSubProvider.java -@@ -117,12 +_,16 @@ +@@ -134,12 +_,16 @@ public abstract void generate(); + protected java.util.stream.Stream> getKnownEntityTypes() { -+ return BuiltInRegistries.ENTITY_TYPE.stream(); ++ return this.output.listContextElements(Registries.ENTITY_TYPE).map(Holder::get); + } + @Override - public void generate(final BiConsumer, LootTable.Builder> output) { + public void run() { this.generate(); Set> seen = new HashSet<>(); -- BuiltInRegistries.ENTITY_TYPE -- .listElements() +- this.output +- .listContextElements(Registries.ENTITY_TYPE) + this.getKnownEntityTypes() + .map(EntityType::builtInRegistryHolder) .forEach( diff --git a/patches/minecraft/net/minecraft/data/loot/LootTableProvider.java.patch b/patches/minecraft/net/minecraft/data/loot/LootTableProvider.java.patch index ac401dd8aa..01185c3f2c 100644 --- a/patches/minecraft/net/minecraft/data/loot/LootTableProvider.java.patch +++ b/patches/minecraft/net/minecraft/data/loot/LootTableProvider.java.patch @@ -1,43 +1,25 @@ --- a/net/minecraft/data/loot/LootTableProvider.java +++ b/net/minecraft/data/loot/LootTableProvider.java -@@ -59,7 +_,7 @@ - private CompletableFuture run(final CachedOutput cache, final HolderLookup.Provider registries) { - WritableRegistry tables = new MappedRegistry<>(Registries.LOOT_TABLE, Lifecycle.experimental()); +@@ -33,7 +_,7 @@ Map randomSequenceSeeds = new Object2ObjectOpenHashMap<>(); -- this.subProviders.forEach(subProvider -> subProvider.provider().apply(registries).generate((id, lootTable) -> { -+ this.getTables().forEach(subProvider -> subProvider.provider().apply(registries).generate((id, lootTable) -> { - Identifier sequenceId = sequenceIdForLootTable(id); - Identifier previous = randomSequenceSeeds.put(RandomSequence.seedForKey(sequenceId), sequenceId); - if (previous != null) { -@@ -75,11 +_,8 @@ - HolderGetter.Provider validationProvider = new RegistryAccess.ImmutableRegistryAccess(List.of(tables)).freeze(); - ValidationContextSource validationContext = new ValidationContextSource(problems, validationProvider); + HolderGetter lootTables = context.lookup(Registries.LOOT_TABLE); + this.requiredTables.forEach(lootTables::get); +- this.subProviders.forEach(subProvider -> subProvider.bootstrap().create(new LootTableSubProvider.Context() { ++ this.getTables().forEach(subProvider -> subProvider.bootstrap().create(new LootTableSubProvider.Context() { + @Override + public Holder.Reference accept(final ResourceKey key, final LootTable.Builder lootTable) { + Identifier sequenceId = LootTableProvider.sequenceIdForLootTable(key); +@@ -61,6 +_,13 @@ -- for (ResourceKey missingTable : Sets.difference(this.requiredTables, tables.registryKeySet())) { -- problems.report(new LootTableProvider.MissingTableProblem(missingTable)); -- } -+ validate(tables, validationContext, problems); - -- LootDataType.TABLE.runValidation(validationContext, tables); - if (!problems.isEmpty()) { - problems.forEach((id, problem) -> LOGGER.warn("Found validation problem in {}: {}", id, problem.description())); - throw new IllegalStateException("Failed to validate loot tables, see logs"); -@@ -100,6 +_,18 @@ - @Override - public final String getName() { - return "Loot Tables"; + private static Identifier sequenceIdForLootTable(final ResourceKey id) { + return id.identifier(); + } + ++ public Set> getRequired() { ++ return this.requiredTables; ++ } + public List getTables() { + return this.subProviders; -+ } -+ -+ protected void validate(net.minecraft.core.Registry map, ValidationContextSource context, ProblemReporter report) { -+ for (ResourceKey resourcekey : Sets.difference(this.requiredTables, map.registryKeySet())) { -+ report.report(new LootTableProvider.MissingTableProblem(resourcekey)); -+ } -+ -+ LootDataType.TABLE.runValidation(context, map); } - public record MissingTableProblem(ResourceKey id) implements ProblemReporter.Problem { + public record SubProviderEntry(LootTableSubProvider.Factory bootstrap, ContextKeySet paramSet) { diff --git a/patches/minecraft/net/minecraft/data/recipes/RecipeOutput.java.patch b/patches/minecraft/net/minecraft/data/recipes/RecipeOutput.java.patch deleted file mode 100644 index 401351e3fa..0000000000 --- a/patches/minecraft/net/minecraft/data/recipes/RecipeOutput.java.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/net/minecraft/data/recipes/RecipeOutput.java -+++ b/net/minecraft/data/recipes/RecipeOutput.java -@@ -7,7 +_,19 @@ - import org.jspecify.annotations.Nullable; - - public interface RecipeOutput { -- void accept(ResourceKey> id, Recipe recipe, @Nullable AdvancementHolder advancement); -+ default void accept(ResourceKey> id, Recipe recipe, @Nullable AdvancementHolder advancement) { -+ if (advancement == null) { -+ accept(id, recipe, null, null); -+ } else { -+ var ops = registry().createSerializationContext(com.mojang.serialization.JsonOps.INSTANCE); -+ var json = Advancement.CODEC.encodeStart(ops, advancement.value()).getOrThrow(IllegalStateException::new); -+ accept(id, recipe, advancement.id(), json); -+ } -+ } -+ -+ void accept(ResourceKey> id, Recipe recipe, net.minecraft.resources.@Nullable Identifier advancementId, com.google.gson.@Nullable JsonElement advancement); -+ -+ net.minecraft.core.HolderLookup.Provider registry(); - - Advancement.Builder advancement(); - diff --git a/patches/minecraft/net/minecraft/data/recipes/RecipeProvider.java.patch b/patches/minecraft/net/minecraft/data/recipes/RecipeProvider.java.patch index 0dbbdf45d1..bff07e1188 100644 --- a/patches/minecraft/net/minecraft/data/recipes/RecipeProvider.java.patch +++ b/patches/minecraft/net/minecraft/data/recipes/RecipeProvider.java.patch @@ -1,50 +1,13 @@ --- a/net/minecraft/data/recipes/RecipeProvider.java +++ b/net/minecraft/data/recipes/RecipeProvider.java -@@ -908,14 +_,14 @@ - final List> tasks = new ArrayList<>(); - RecipeOutput recipeOutput = new RecipeOutput() { - @Override -- public void accept(final ResourceKey> id, final Recipe recipe, final @Nullable AdvancementHolder advancementHolder) { -+ public void accept(final ResourceKey> id, final Recipe recipe, net.minecraft.resources.@Nullable Identifier advancementId, com.google.gson.@Nullable JsonElement advancement) { - if (!allRecipes.add(id)) { - throw new IllegalStateException("Duplicate recipe " + id.identifier()); - } - - this.saveRecipe(id, recipe); -- if (advancementHolder != null) { -- this.saveAdvancement(advancementHolder); -+ if (advancement != null && advancementId != null) { -+ this.saveAdvancement(advancementId, advancement); - } - } - -@@ -929,19 +_,26 @@ - AdvancementHolder root = Advancement.Builder.recipeAdvancement() - .addCriterion("impossible", CriteriaTriggers.IMPOSSIBLE.createCriterion(new ImpossibleTrigger.TriggerInstance())) - .build(RecipeBuilder.ROOT_RECIPE_ADVANCEMENT); -- this.saveAdvancement(root); -+ var ops = registry().createSerializationContext(com.mojang.serialization.JsonOps.INSTANCE); -+ var json = Advancement.CODEC.encodeStart(ops, root.value()).getOrThrow(IllegalStateException::new); -+ this.saveAdvancement(root.id(), json); - } - - private void saveRecipe(final ResourceKey> id, final Recipe recipe) { - tasks.add(DataProvider.saveStable(cache, registries, Recipe.CODEC, recipe, recipePathProvider.json(id.identifier()))); - } - -- private void saveAdvancement(final AdvancementHolder advancementHolder) { -+ private void saveAdvancement(net.minecraft.resources.Identifier id, com.google.gson.JsonElement advancement) { - tasks.add( - DataProvider.saveStable( -- cache, registries, Advancement.CODEC, advancementHolder.value(), advancementPathProvider.json(advancementHolder.id()) -+ cache, advancement, advancementPathProvider.json(id) - ) - ); -+ } -+ -+ @Override -+ public HolderLookup.Provider registry() { -+ return registries; - } - }; - this.createRecipeProvider(registries, recipeOutput).buildRecipes(); +@@ -54,8 +_,8 @@ + public abstract class RecipeProvider { + private final HolderGetter items; + private final HolderGetter trimPatterns; +- protected final RecipeOutput output; +- protected final BootstrapContext advancementOutput; ++ protected RecipeOutput output; ++ protected BootstrapContext advancementOutput; + private static final Map SHAPE_BUILDERS = ImmutableMap.builder() + .put(BlockFamily.Variant.BUTTON, (context, result, base) -> context.buttonBuilder(result, Ingredient.of(base))) + .put(BlockFamily.Variant.CHISELED, (context, result, base) -> context.chiseledBuilder(RecipeCategory.BUILDING_BLOCKS, result, Ingredient.of(base))) diff --git a/patches/minecraft/net/minecraft/data/recipes/packs/VanillaBrewingProvider.java.patch b/patches/minecraft/net/minecraft/data/recipes/packs/VanillaBrewingProvider.java.patch new file mode 100644 index 0000000000..b86c93902a --- /dev/null +++ b/patches/minecraft/net/minecraft/data/recipes/packs/VanillaBrewingProvider.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/data/recipes/packs/VanillaBrewingProvider.java ++++ b/net/minecraft/data/recipes/packs/VanillaBrewingProvider.java +@@ -6,7 +_,7 @@ + import net.minecraft.world.item.alchemy.Potions; + + public class VanillaBrewingProvider extends BrewingProvider { +- protected VanillaBrewingProvider(final RecipeOutput recipeOutput) { ++ public VanillaBrewingProvider(final RecipeOutput recipeOutput) { + super(recipeOutput); + } + diff --git a/patches/minecraft/net/minecraft/data/recipes/packs/VanillaRecipeProvider.java.patch b/patches/minecraft/net/minecraft/data/recipes/packs/VanillaRecipeProvider.java.patch new file mode 100644 index 0000000000..3c8371979d --- /dev/null +++ b/patches/minecraft/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 +@@ -73,7 +_,7 @@ + public static final ImmutableList REDSTONE_SMELTABLES = ImmutableList.of(Items.REDSTONE_ORE, Items.DEEPSLATE_REDSTONE_ORE); + public static final ImmutableList EMERALD_SMELTABLES = ImmutableList.of(Items.EMERALD_ORE, Items.DEEPSLATE_EMERALD_ORE); + private static final int DEFAULT_COOKING_TIME = 200; +- private final BrewingProvider brewingProvider = new VanillaBrewingProvider(this.output); ++ protected BrewingProvider brewingProvider = new VanillaBrewingProvider(this.output); + + public VanillaRecipeProvider(final BootstrapContext> recipeOutput, final BootstrapContext advancementOutput) { + super(recipeOutput, advancementOutput); diff --git a/patches/minecraft/net/minecraft/data/registries/RegistriesDatapackGenerator.java.patch b/patches/minecraft/net/minecraft/data/registries/RegistriesDatapackGenerator.java.patch index a73e9cad16..4dbac9e4a2 100644 --- a/patches/minecraft/net/minecraft/data/registries/RegistriesDatapackGenerator.java.patch +++ b/patches/minecraft/net/minecraft/data/registries/RegistriesDatapackGenerator.java.patch @@ -1,38 +1,50 @@ --- a/net/minecraft/data/registries/RegistriesDatapackGenerator.java +++ b/net/minecraft/data/registries/RegistriesDatapackGenerator.java -@@ -18,10 +_,21 @@ - public class RegistriesDatapackGenerator implements DataProvider { - private final PackOutput output; +@@ -21,6 +_,11 @@ + private final String name; + private final Collection> registryData; private final CompletableFuture registries; -+ private final java.util.function.Predicate namespacePredicate; ++ private final java.util.function.Predicate> entryPredicate; ++ ++ public static net.minecraftforge.common.data.RegistryDataBuilder builder() { ++ return net.minecraftforge.common.data.RegistryDataBuilder.of(); ++ } - public RegistriesDatapackGenerator(final PackOutput output, final CompletableFuture registries) { -+ this(output, registries, null); + public RegistriesDatapackGenerator( + final PackOutput output, +@@ -28,14 +_,30 @@ + final Collection> registryData, + final CompletableFuture registryContents + ) { ++ this(output, name, registryData, registryContents, _ -> true); + } + -+ public RegistriesDatapackGenerator(final PackOutput output, final CompletableFuture registries, @org.jetbrains.annotations.Nullable java.util.Set modIds) { - this.registries = registries; ++ public RegistriesDatapackGenerator( ++ final PackOutput output, ++ final String name, ++ final Collection> registryData, ++ final CompletableFuture registryContents, ++ final java.util.function.Predicate> entryPredicate ++ ) { + this.name = name; + this.registryData = registryData; + this.registries = registryContents; this.output = output; -+ this.namespacePredicate = modIds == null ? namespace -> true : modIds::contains; ++ this.entryPredicate = entryPredicate; + } + -+ /** Forge: Call this to get the registry holder lookup provider that includes elements added via {@link net.minecraftforge.common.data.DatapackBuiltinEntriesProvider} */ ++ /** Forge: Call this to get the registry holder lookup provider that includes elements added via {@link net.minecraftforge.common.data.RegistryDataBuilder} */ + public CompletableFuture getRegistryProvider() { -+ return registries; ++ return this.registries; } - @Override -@@ -31,8 +_,7 @@ - access -> { - DynamicOps registryOps = access.createSerializationContext(JsonOps.INSTANCE); - return CompletableFuture.allOf( -- RegistryDataLoader.WORLDGEN_REGISTRIES -- .stream() -+ RegistryDataLoader.getWorldGenAndDimensionStream() - .flatMap(v -> this.dumpRegistryCap(cache, access, registryOps, (RegistryDataLoader.RegistryData)v).stream()) - .toArray(CompletableFuture[]::new) - ); -@@ -50,11 +_,16 @@ + public static RegistriesDatapackGenerator forWorldLayer(final PackOutput output, final CompletableFuture registryContents) { +- return new RegistriesDatapackGenerator(output, "world", RegistryDataLoader.WORLD_REGISTRIES, registryContents); ++ return new RegistriesDatapackGenerator(output, "world", RegistryDataLoader.getWorldAndDimensionRegistries(), registryContents); + } + + public static DataProvider forReloadableLayer(final PackOutput output, final CompletableFuture registryContents) { +@@ -68,11 +_,16 @@ PackOutput.PathProvider pathProvider = this.output.createRegistryElementsPathProvider(registryKey); return CompletableFuture.allOf( registry.listElements() @@ -45,7 +57,7 @@ + } + + protected boolean shouldDump(ResourceKey key) { -+ return this.namespacePredicate.test(key.identifier().getNamespace()); ++ return this.entryPredicate.test(key); } private static CompletableFuture dumpValue( diff --git a/patches/minecraft/net/minecraft/data/registries/RegistryPatchGenerator.java.patch b/patches/minecraft/net/minecraft/data/registries/RegistryPatchGenerator.java.patch index 091d98a9ab..a7cd8f07b0 100644 --- a/patches/minecraft/net/minecraft/data/registries/RegistryPatchGenerator.java.patch +++ b/patches/minecraft/net/minecraft/data/registries/RegistryPatchGenerator.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/data/registries/RegistryPatchGenerator.java +++ b/net/minecraft/data/registries/RegistryPatchGenerator.java -@@ -21,7 +_,7 @@ - parent -> { - RegistryAccess.Frozen staticRegistries = RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY); - Cloner.Factory cloner = new Cloner.Factory(); -- RegistryDataLoader.WORLDGEN_REGISTRIES.forEach(registryData -> registryData.runWithArguments(cloner::addCodec)); -+ RegistryDataLoader.getWorldGenAndDimensionStream().forEach(registryData -> registryData.runWithArguments(cloner::addCodec)); - RegistrySetBuilder.PatchedRegistries newRegistries = packBuilder.buildPatch(staticRegistries, parent, cloner); - HolderLookup.Provider fullPatchedRegistry = newRegistries.full(); - Optional> biomes = fullPatchedRegistry.lookup(Registries.BIOME); +@@ -23,7 +_,7 @@ + return vanilla.thenApply(parent -> { + RegistryAccess.Frozen staticRegistries = RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY); + Cloner.Factory cloner = new Cloner.Factory(); +- RegistryDataLoader.WORLD_REGISTRIES.forEach(registryData -> registryData.runWithArguments(cloner::addCodec)); ++ RegistryDataLoader.getWorldAndDimensionRegistries().forEach(registryData -> registryData.runWithArguments(cloner::addCodec)); + RegistrySetBuilder.PatchedRegistries newRegistries = packBuilder.buildPatch(staticRegistries, parent, cloner); + boolean hasAnyPatchedBiomes = hasAnyPatchedElement(newRegistries, Registries.BIOME); + boolean hasAnyPatchedFeatures = hasAnyPatchedElement(newRegistries, Registries.PLACED_FEATURE); diff --git a/patches/minecraft/net/minecraft/data/registries/VanillaRegistries.java.patch b/patches/minecraft/net/minecraft/data/registries/VanillaRegistries.java.patch index adf14ed7fa..0741ff6625 100644 --- a/patches/minecraft/net/minecraft/data/registries/VanillaRegistries.java.patch +++ b/patches/minecraft/net/minecraft/data/registries/VanillaRegistries.java.patch @@ -1,20 +1,19 @@ --- a/net/minecraft/data/registries/VanillaRegistries.java +++ b/net/minecraft/data/registries/VanillaRegistries.java -@@ -110,6 +_,7 @@ - .add(Registries.TIMELINE, Timelines::bootstrap) - .add(Registries.VILLAGER_TRADE, VillagerTrades::bootstrap) - .add(Registries.TRADE_SET, TradeSets::bootstrap); -+ public static final List>> DATAPACK_REGISTRY_KEYS = BUILDER.getEntryKeys(); - - private static void validateThatAllBiomeFeaturesHaveBiomeFilter(final HolderLookup.Provider provider) { - validateThatAllBiomeFeaturesHaveBiomeFilter(provider.lookupOrThrow(Registries.PLACED_FEATURE), provider.lookupOrThrow(Registries.BIOME)); -@@ -141,5 +_,9 @@ - HolderLookup.Provider newRegistries = BUILDER.build(staticRegistries); - validateThatAllBiomeFeaturesHaveBiomeFilter(newRegistries); +@@ -184,4 +_,16 @@ + validateLootData(newRegistries); return newRegistries; -+ } + } + + public static RegistrySetBuilder builder() { -+ return BUILDER.copy(); - } ++ return worldBuilder().add(RELOADABLE_BUILDER); ++ } ++ ++ public static RegistrySetBuilder worldBuilder() { ++ return WORLD_BUILDER.copy(); ++ } ++ ++ public static RegistrySetBuilder reloadableBuilder() { ++ return RELOADABLE_BUILDER.copy(); ++ } } diff --git a/patches/minecraft/net/minecraft/data/tags/BlockItemTagsProvider.java.patch b/patches/minecraft/net/minecraft/data/tags/BlockItemTagsProvider.java.patch index 3f4b6a64db..8477ce3904 100644 --- a/patches/minecraft/net/minecraft/data/tags/BlockItemTagsProvider.java.patch +++ b/patches/minecraft/net/minecraft/data/tags/BlockItemTagsProvider.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/data/tags/BlockItemTagsProvider.java +++ b/net/minecraft/data/tags/BlockItemTagsProvider.java -@@ -64,6 +_,12 @@ +@@ -72,6 +_,12 @@ return this; } diff --git a/patches/minecraft/net/minecraft/data/tags/VanillaBlockTagsProvider.java.patch b/patches/minecraft/net/minecraft/data/tags/VanillaBlockTagsProvider.java.patch index 4e69799faf..7dcd20f228 100644 --- a/patches/minecraft/net/minecraft/data/tags/VanillaBlockTagsProvider.java.patch +++ b/patches/minecraft/net/minecraft/data/tags/VanillaBlockTagsProvider.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/data/tags/VanillaBlockTagsProvider.java +++ b/net/minecraft/data/tags/VanillaBlockTagsProvider.java -@@ -29,6 +_,10 @@ +@@ -30,6 +_,10 @@ }; } diff --git a/patches/minecraft/net/minecraft/data/worldgen/BootstrapContext.java.patch b/patches/minecraft/net/minecraft/data/worldgen/BootstrapContext.java.patch deleted file mode 100644 index cb40e626e5..0000000000 --- a/patches/minecraft/net/minecraft/data/worldgen/BootstrapContext.java.patch +++ /dev/null @@ -1,9 +0,0 @@ ---- a/net/minecraft/data/worldgen/BootstrapContext.java -+++ b/net/minecraft/data/worldgen/BootstrapContext.java -@@ -14,4 +_,6 @@ - } - - HolderGetter lookup(ResourceKey> key); -+ -+ default java.util.Optional> registryLookup(ResourceKey> registry) { return java.util.Optional.empty(); } - } diff --git a/patches/minecraft/net/minecraft/data/worldgen/BootstrapContextAccess.java.patch b/patches/minecraft/net/minecraft/data/worldgen/BootstrapContextAccess.java.patch new file mode 100644 index 0000000000..e8d97a1b23 --- /dev/null +++ b/patches/minecraft/net/minecraft/data/worldgen/BootstrapContextAccess.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/data/worldgen/BootstrapContextAccess.java ++++ b/net/minecraft/data/worldgen/BootstrapContextAccess.java +@@ -9,6 +_,8 @@ + public interface BootstrapContextAccess { + HolderGetter lookup(ResourceKey> key); + ++ default java.util.Optional> registryLookup(ResourceKey> registry) { return java.util.Optional.empty(); } ++ + @Deprecated + Stream> listContextElements(ResourceKey> key); + } diff --git a/patches/minecraft/net/minecraft/gametest/framework/GameTestHelper.java.patch b/patches/minecraft/net/minecraft/gametest/framework/GameTestHelper.java.patch index a77a2f311d..896a1de58a 100644 --- a/patches/minecraft/net/minecraft/gametest/framework/GameTestHelper.java.patch +++ b/patches/minecraft/net/minecraft/gametest/framework/GameTestHelper.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/gametest/framework/GameTestHelper.java +++ b/net/minecraft/gametest/framework/GameTestHelper.java -@@ -77,7 +_,7 @@ +@@ -78,7 +_,7 @@ import net.minecraft.world.phys.Vec3; import org.jspecify.annotations.Nullable; @@ -9,7 +9,7 @@ private final GameTestInfo testInfo; private boolean finalCheckAdded; -@@ -1109,6 +_,12 @@ +@@ -1130,6 +_,12 @@ return this.testInfo.getTick(); } @@ -22,8 +22,8 @@ public AABB getBounds() { return this.testInfo.getStructureBounds(); } -@@ -1153,6 +_,26 @@ - if (result.right().isPresent()) { +@@ -1167,6 +_,26 @@ + if (result.right().isPresent() && result.right().get().getType() != FillBiomeCommand.ERROR_NO_BIOMES_SET) { throw this.assertionException("test.error.set_biome"); } + } diff --git a/patches/minecraft/net/minecraft/gametest/framework/TestCommand.java.patch b/patches/minecraft/net/minecraft/gametest/framework/TestCommand.java.patch index 5dae5ebe99..5bfad546b7 100644 --- a/patches/minecraft/net/minecraft/gametest/framework/TestCommand.java.patch +++ b/patches/minecraft/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 -@@ -481,7 +_,12 @@ +@@ -557,7 +_,12 @@ return Optional.empty(); } else { Holder.Reference test = maybeTest.get(); @@ -11,6 +11,6 @@ + var steps = StructureUtils.getRotationStepsForRotation(blockEntity.getRotation()) - StructureUtils.getRotationStepsForRotation(rotation); + if (steps < 0) steps += 4; + GameTestInfo testInfo = new GameTestInfo(test, StructureUtils.getRotationForRotationSteps(steps), level, retryOptions); - testInfo.setTestBlockPos(testBlockPos); + testInfo.setTestBlockPos(testBlockPos.pos()); return !verifyStructureExists(source, testInfo.getStructure()) ? Optional.empty() : Optional.of(testInfo); } diff --git a/patches/minecraft/net/minecraft/network/Connection.java.patch b/patches/minecraft/net/minecraft/network/Connection.java.patch index 2567ce0d12..b64f8b0818 100644 --- a/patches/minecraft/net/minecraft/network/Connection.java.patch +++ b/patches/minecraft/net/minecraft/network/Connection.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/network/Connection.java +++ b/net/minecraft/network/Connection.java -@@ -81,9 +_,17 @@ +@@ -79,9 +_,17 @@ + private boolean handlingFault; private volatile @Nullable DisconnectionDetails delayedDisconnect; private @Nullable BandwidthDebugMonitor bandwidthDebugMonitor; - private @Nullable UUID intendedProfileId; + private java.util.function.Consumer activationHandler; + private final net.minecraftforge.common.util.PacketLogger packetLogger = new net.minecraftforge.common.util.PacketLogger(this); + private ProtocolInfo outboundProtocol = null; @@ -18,7 +18,7 @@ } @Override -@@ -91,6 +_,7 @@ +@@ -89,6 +_,7 @@ super.channelActive(ctx); this.channel = ctx.channel(); this.address = this.channel.remoteAddress(); @@ -26,7 +26,7 @@ if (this.delayedDisconnect != null) { this.disconnect(this.delayedDisconnect); } -@@ -152,6 +_,7 @@ +@@ -150,6 +_,7 @@ if (packetListener.shouldHandleMessage(packet)) { try { @@ -34,7 +34,7 @@ genericsFtw(packet, packetListener); } catch (RunningOnDifferentThreadException var5) { } catch (RejectedExecutionException ignored) { -@@ -201,6 +_,7 @@ +@@ -199,6 +_,7 @@ throw new IllegalStateException("Invalid inbound protocol: " + protocol.id()); } @@ -42,7 +42,7 @@ this.packetListener = packetListener; this.disconnectListener = null; UnconfiguredPipelineHandler.InboundConfigurationTask configMessage = UnconfiguredPipelineHandler.setupInboundProtocol(protocol); -@@ -218,7 +_,7 @@ +@@ -216,7 +_,7 @@ throw new IllegalStateException("Invalid outbound protocol: " + protocol.id()); } @@ -51,7 +51,7 @@ BundlerInfo bundlerInfo = protocol.bundlerInfo(); if (bundlerInfo != null) { PacketBundleUnpacker newUnbundler = new PacketBundleUnpacker(bundlerInfo); -@@ -265,7 +_,8 @@ +@@ -263,7 +_,8 @@ this.disconnectListener = listener; this.runOnceConnected(connection -> { this.setupInboundProtocol(inbound, listener); @@ -61,7 +61,7 @@ this.setupOutboundProtocol(outbound); }); } -@@ -309,10 +_,13 @@ +@@ -307,10 +_,13 @@ if (listener != null) { ChannelFuture future = flush ? this.channel.writeAndFlush(packet) : this.channel.write(packet); future.addListener(listener); @@ -75,7 +75,7 @@ } } -@@ -381,7 +_,7 @@ +@@ -379,7 +_,7 @@ if (this.address == null) { return "local"; } else { @@ -84,7 +84,7 @@ } } -@@ -426,7 +_,9 @@ +@@ -424,7 +_,9 @@ } public static ChannelFuture connect(final InetSocketAddress address, final EventLoopGroupHolder eventLoopGroupHolder, final Connection connection) { @@ -95,7 +95,7 @@ @Override protected void initChannel(final Channel channel) { try { -@@ -491,7 +_,8 @@ +@@ -489,7 +_,8 @@ public static Connection connectToLocalServer(final SocketAddress address) { final Connection connection = new Connection(PacketFlow.CLIENTBOUND); @@ -105,7 +105,7 @@ @Override protected void initChannel(final Channel channel) { ChannelPipeline pipeline = channel.pipeline(); -@@ -590,6 +_,22 @@ +@@ -588,6 +_,22 @@ public float getAverageSentPackets() { return this.averageSentPackets; diff --git a/patches/minecraft/net/minecraft/network/FriendlyByteBuf.java.patch b/patches/minecraft/net/minecraft/network/FriendlyByteBuf.java.patch index 726ecc919e..fc7a432c1a 100644 --- a/patches/minecraft/net/minecraft/network/FriendlyByteBuf.java.patch +++ b/patches/minecraft/net/minecraft/network/FriendlyByteBuf.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/network/FriendlyByteBuf.java +++ b/net/minecraft/network/FriendlyByteBuf.java -@@ -1615,4 +_,8 @@ +@@ -1484,4 +_,8 @@ public boolean release(final int decrement) { return this.source.release(decrement); } diff --git a/patches/minecraft/net/minecraft/network/syncher/EntityDataSerializers.java.patch b/patches/minecraft/net/minecraft/network/syncher/EntityDataSerializers.java.patch index 67b68b8513..0f992d6941 100644 --- a/patches/minecraft/net/minecraft/network/syncher/EntityDataSerializers.java.patch +++ b/patches/minecraft/net/minecraft/network/syncher/EntityDataSerializers.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/network/syncher/EntityDataSerializers.java +++ b/net/minecraft/network/syncher/EntityDataSerializers.java -@@ -146,15 +_,17 @@ - public static final EntityDataSerializer HUMANOID_ARM = EntityDataSerializer.forValueType(HumanoidArm.STREAM_CODEC); +@@ -148,15 +_,17 @@ + public static final EntityDataSerializer DYE_COLOR = EntityDataSerializer.forValueType(DyeColor.STREAM_CODEC); public static void registerSerializer(final EntityDataSerializer serializer) { + int id = diff --git a/patches/minecraft/net/minecraft/resources/HolderSetCodec.java.patch b/patches/minecraft/net/minecraft/resources/HolderSetCodec.java.patch deleted file mode 100644 index 6ddfba8610..0000000000 --- a/patches/minecraft/net/minecraft/resources/HolderSetCodec.java.patch +++ /dev/null @@ -1,60 +0,0 @@ ---- a/net/minecraft/resources/HolderSetCodec.java -+++ b/net/minecraft/resources/HolderSetCodec.java -@@ -21,6 +_,8 @@ - private final Codec> elementCodec; - private final Codec>> homogenousListCodec; - private final Codec, List>>> registryAwareCodec; -+ private final Codec> forgeDispatchCodec; -+ private final Codec, Either, List>>>> combinedCodec; - - private static Codec>> homogenousList(final Codec> elementCodec, final boolean alwaysUseList) { - Codec>> listCodec = elementCodec.listOf().validate(ExtraCodecs.ensureHomogenous(Holder::kind)); -@@ -38,6 +_,10 @@ - this.elementCodec = elementCodec; - this.homogenousListCodec = homogenousList(elementCodec, alwaysUseList); - this.registryAwareCodec = Codec.either(TagKey.hashedCodec(registryKey), this.homogenousListCodec); -+ // FORGE: make registry-specific dispatch codec and make forge-or-vanilla either codec -+ this.forgeDispatchCodec = Codec.lazyInitialized(() -> net.minecraftforge.registries.ForgeRegistries.HOLDER_SET_TYPES.get().getCodec()) -+ .dispatch(net.minecraftforge.registries.holdersets.ICustomHolderSet::type, type -> type.makeCodec(registryKey, elementCodec, alwaysUseList)); -+ this.combinedCodec = Codec.either(this.forgeDispatchCodec, this.registryAwareCodec); - } - - @Override -@@ -46,14 +_,17 @@ - Optional> registryOptional = registryOps.getter(this.registryKey); - if (registryOptional.isPresent()) { - HolderGetter registry = registryOptional.get(); -- return this.registryAwareCodec -+ return this.combinedCodec - .decode(ops, input) - .flatMap( - p -> { - DataResult> result = p.getFirst() -+ .map(custom -> DataResult.success(custom), -+ tagOrList -> tagOrList - .map( - tag -> lookupTag(registry, (TagKey)tag), - values -> DataResult.success(HolderSet.direct((List>)values)) -+ ) - ); - return result.map(holders -> Pair.of((HolderSet)holders, (T)p.getSecond())); - } -@@ -86,7 +_,7 @@ - } - - private DataResult, T>> decodeWithoutRegistry(final DynamicOps ops, final T input) { -- return this.elementCodec.listOf().decode(ops, input).flatMap(p -> { -+ return this.homogenousListCodec.decode(ops, input).flatMap(p -> { // Forge: Match encodeWithoutRegistry's use of the homogenousListCodec - List> directHolders = new ArrayList<>(); - - for (Holder holder : p.getFirst()) { -@@ -102,6 +_,9 @@ - } - - private DataResult encodeWithoutRegistry(final HolderSet input, final DynamicOps ops, final T prefix) { -+ // FORGE: use the dispatch codec to encode custom holdersets, otherwise fall back to vanilla tag/list -+ if (input instanceof net.minecraftforge.registries.holdersets.ICustomHolderSet customHolderSet) -+ return this.forgeDispatchCodec.encode(customHolderSet, ops, prefix); - return this.homogenousListCodec.encode(input.stream().toList(), ops, prefix); - } - } diff --git a/patches/minecraft/net/minecraft/resources/RegistryDataLoader.java.patch b/patches/minecraft/net/minecraft/resources/RegistryDataLoader.java.patch index d76a89a96c..00d275656f 100644 --- a/patches/minecraft/net/minecraft/resources/RegistryDataLoader.java.patch +++ b/patches/minecraft/net/minecraft/resources/RegistryDataLoader.java.patch @@ -1,30 +1,39 @@ --- a/net/minecraft/resources/RegistryDataLoader.java +++ b/net/minecraft/resources/RegistryDataLoader.java -@@ -81,7 +_,7 @@ +@@ -95,7 +_,7 @@ public class RegistryDataLoader { private static final Logger LOGGER = LogUtils.getLogger(); private static final Comparator> ERROR_KEY_COMPARATOR = Comparator., Identifier>comparing(ResourceKey::registry).thenComparing(ResourceKey::identifier); -- public static final List> WORLDGEN_REGISTRIES = List.of( -+ public static final List> WORLDGEN_REGISTRIES = net.minecraftforge.registries.DataPackRegistriesHooks.grabWorldgenRegistries( +- public static final List> WORLD_REGISTRIES = List.of( ++ public static final List> WORLD_REGISTRIES = net.minecraftforge.registries.DataPackRegistriesHooks.grabWorldRegistries( new RegistryDataLoader.RegistryData<>(Registries.DIMENSION_TYPE, DimensionType.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.BIOME, Biome.DIRECT_CODEC), new RegistryDataLoader.RegistryData<>(Registries.CHAT_TYPE, ChatType.DIRECT_CODEC), -@@ -132,7 +_,7 @@ +@@ -151,7 +_,7 @@ public static final List> DIMENSION_REGISTRIES = List.of( new RegistryDataLoader.RegistryData<>(Registries.LEVEL_STEM, LevelStem.CODEC) ); +- public static final List> RELOADABLE_REGISTRIES = List.of( ++ public static final List> RELOADABLE_REGISTRIES = net.minecraftforge.registries.DataPackRegistriesHooks.grabReloadableRegistries( + new RegistryDataLoader.RegistryData<>(Registries.LOOT_TABLE, LootTable.DIRECT_CODEC), + new RegistryDataLoader.RegistryData<>(Registries.PREDICATE, LootItemCondition.DIRECT_CODEC), + new RegistryDataLoader.RegistryData<>(Registries.CONTEXT_FLOAT_PROVIDER, ContextFloatProviders.DIRECT_CODEC), +@@ -161,7 +_,7 @@ + new RegistryDataLoader.RegistryData<>(Registries.ADVANCEMENT, Advancement.CODEC), + new RegistryDataLoader.RegistryData<>(Registries.RECIPE, Recipe.DIRECT_CODEC) + ); - public static final List> SYNCHRONIZED_REGISTRIES = List.of( + public static final List> SYNCHRONIZED_REGISTRIES = net.minecraftforge.registries.DataPackRegistriesHooks.grabSynchronizedRegistries( 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), -@@ -163,6 +_,10 @@ - new RegistryDataLoader.RegistryData<>(Registries.WORLD_CLOCK, WorldClock.DIRECT_CODEC), - new RegistryDataLoader.RegistryData<>(Registries.TIMELINE, Timeline.NETWORK_CODEC) +@@ -195,6 +_,10 @@ + new RegistryDataLoader.RegistryData<>(Registries.BLOCK_TRANSFORMER, BlockTransformer.DIRECT_CODEC), + new RegistryDataLoader.RegistryData<>(Registries.BLOCK_STATE_PROVIDER, BlockStateProvider.DIRECT_CODEC) ); + -+ public static java.util.stream.Stream> getWorldGenAndDimensionStream() { -+ return java.util.stream.Stream.concat(RegistryDataLoader.WORLDGEN_REGISTRIES.stream(), RegistryDataLoader.DIMENSION_REGISTRIES.stream()); ++ public static List> getWorldAndDimensionRegistries() { ++ return java.util.stream.Stream.concat(RegistryDataLoader.WORLD_REGISTRIES.stream(), RegistryDataLoader.DIMENSION_REGISTRIES.stream()).toList(); + } public static CompletableFuture load( diff --git a/patches/minecraft/net/minecraft/resources/RegistryOps.java.patch b/patches/minecraft/net/minecraft/resources/RegistryOps.java.patch index 9ba97434c8..34274d4184 100644 --- a/patches/minecraft/net/minecraft/resources/RegistryOps.java.patch +++ b/patches/minecraft/net/minecraft/resources/RegistryOps.java.patch @@ -1,22 +1,22 @@ --- a/net/minecraft/resources/RegistryOps.java +++ b/net/minecraft/resources/RegistryOps.java -@@ -76,6 +_,22 @@ - .forGetter(e -> null); +@@ -71,6 +_,22 @@ + .forGetter(var0 -> null); } -+ public static com.mojang.serialization.MapCodec> retrieveRegistryLookup(final ResourceKey> resourceKey) { ++ public static com.mojang.serialization.MapCodec> retrieveRegistryLookup(final ResourceKey> registryKey) { + return ExtraCodecs.retrieveContext(ops -> { -+ if (!(ops instanceof RegistryOps registryOps)) { ++ if (!(ops instanceof RegistryOps registryOps)) + return DataResult.error(() -> "Not a registry ops"); -+ } + -+ return registryOps.lookupProvider.lookup(resourceKey).map(registryInfo -> { -+ if (!(registryInfo.owner() instanceof HolderLookup.RegistryLookup registryLookup)) { -+ return DataResult.>error(() -> "Found holder getter but was not a registry lookup for " + resourceKey); -+ } ++ var lookup = registryOps.lookupProvider.lookup(registryKey); ++ if (lookup.isEmpty()) ++ return DataResult.error(() -> "Unknown Registry: " + registryKey); + -+ return DataResult.success(registryLookup, registryInfo.elementsLifecycle()); -+ }).orElseGet(() -> DataResult.error(() -> "Unknown registry: " + resourceKey)); ++ if (!(lookup.get() instanceof HolderLookup.RegistryLookup registryLookup)) ++ return DataResult.>error(() -> "Found holder getter but was not a registry lookup for " + registryKey); ++ ++ return DataResult.success(registryLookup, registryLookup.registryLifecycle()); + }); + } + diff --git a/patches/minecraft/net/minecraft/resources/ResourceKey.java.patch b/patches/minecraft/net/minecraft/resources/ResourceKey.java.patch index 5b3820256f..04668abf21 100644 --- a/patches/minecraft/net/minecraft/resources/ResourceKey.java.patch +++ b/patches/minecraft/net/minecraft/resources/ResourceKey.java.patch @@ -6,10 +6,10 @@ -public class ResourceKey { +public class ResourceKey implements Comparable>, net.minecraftforge.common.extensions.IForgeResourceKey { + public static final StreamCodec>> REGISTRY_STREAM_CODEC = Identifier.STREAM_CODEC + .map(ResourceKey::createRegistryKey, ResourceKey::identifier); private static final ConcurrentMap> VALUES = new MapMaker().weakValues().makeMap(); - private final Identifier registryName; - private final Identifier identifier; -@@ -74,5 +_,18 @@ +@@ -76,5 +_,18 @@ } private record InternKey(Identifier registry, Identifier identifier) { diff --git a/patches/minecraft/net/minecraft/resources/ResourceManagerRegistryLoadTask.java.patch b/patches/minecraft/net/minecraft/resources/ResourceManagerRegistryLoadTask.java.patch index 9db7969690..335c644be9 100644 --- a/patches/minecraft/net/minecraft/resources/ResourceManagerRegistryLoadTask.java.patch +++ b/patches/minecraft/net/minecraft/resources/ResourceManagerRegistryLoadTask.java.patch @@ -16,7 +16,7 @@ return CompletableFuture.>supplyAsync(() -> lister.listMatchingResources(this.resourceManager), executor) .thenCompose( registryResources -> { -@@ -49,9 +_,18 @@ +@@ -49,9 +_,19 @@ (resourceId, thunk) -> { ResourceKey elementKey = ResourceKey.create(this.registryKey(), lister.fileToId(resourceId)); RegistrationInfo registrationInfo = REGISTRATION_INFO_CACHE.apply(thunk.knownPackInfo()); @@ -28,6 +28,7 @@ + LOGGER.debug("Skipping {} conditions not met", elementKey); + return null; + } ++ net.minecraftforge.common.ForgeHooks.onJsonDataParsed(this.data.elementCodec(), elementKey.identifier(), value.get()); + } return new RegistryLoadTask.PendingRegistration<>( elementKey, diff --git a/patches/minecraft/net/minecraft/server/Bootstrap.java.patch b/patches/minecraft/net/minecraft/server/Bootstrap.java.patch index 8392dba490..5341c8dc2c 100644 --- a/patches/minecraft/net/minecraft/server/Bootstrap.java.patch +++ b/patches/minecraft/net/minecraft/server/Bootstrap.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/server/Bootstrap.java +++ b/net/minecraft/server/Bootstrap.java @@ -59,6 +_,8 @@ - CauldronInteractions.bootStrap(); BuiltInRegistries.bootStrap(); CreativeModeTabs.validate(); + LootContextParamSets.validate(); + net.minecraftforge.registries.GameData.vanillaSnapshot(); + if (false) // skip redirectOutputToLog, Forge already redirects stdout and stderr output to log so that they print with more context wrapStreams(); diff --git a/patches/minecraft/net/minecraft/server/Main.java.patch b/patches/minecraft/net/minecraft/server/Main.java.patch index 6bb69fb7f5..f76d09348f 100644 --- a/patches/minecraft/net/minecraft/server/Main.java.patch +++ b/patches/minecraft/net/minecraft/server/Main.java.patch @@ -57,7 +57,7 @@ - } - File universePath = new File(options.valueOf(universe)); - Services services = Services.create(new YggdrasilAuthenticationService(Proxy.NO_PROXY), universePath); + Services services = Services.create(MinecraftServicesDiscoveryService.create(Proxy.NO_PROXY), universePath); NotificationManager notificationManager = new NotificationManager(); ManagementServer jsonRpcServer = JsonRpc.create(settings, notificationManager); String levelName = Optional.ofNullable(options.valueOf(worldName)).orElse(settings.getProperties().levelName); @@ -92,11 +92,11 @@ shutdownThread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER)); @@ -268,6 +_,16 @@ worldOptions = bonusChest ? properties.worldOptions.withBonusChest(true) : properties.worldOptions; - dimensions = properties.createDimensions(context.datapackWorldgen()); + dimensions = properties.createDimensions(context.datapackWorldRegistries()); } + + //Forge: Do a write-read-cycle to inject modded dimensions on first start of a dedicated server into its generated world dimensions list. -+ var dynamicops = net.minecraft.resources.RegistryOps.create(net.minecraft.nbt.NbtOps.INSTANCE, context.datapackWorldgen()); ++ var dynamicops = net.minecraft.resources.RegistryOps.create(net.minecraft.nbt.NbtOps.INSTANCE, context.datapackWorldRegistries()); + dimensions = WorldDimensions.CODEC.encoder() + .encodeStart(dynamicops, dimensions) + .flatMap((writtenPayloadWithModdedDimensions) -> @@ -106,4 +106,4 @@ + .orElse(dimensions); WorldDimensions.Complete finalDimensions = dimensions.bake(datapackDimensions); - Lifecycle lifecycle = finalDimensions.lifecycle().add(context.datapackWorldgen().allRegistriesLifecycle()); + Lifecycle lifecycle = finalDimensions.lifecycle().add(context.datapackWorldRegistries().allRegistriesLifecycle()); diff --git a/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch b/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch index f8e85ecfb6..b39eff0395 100644 --- a/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch +++ b/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -296,7 +_,7 @@ +@@ -291,7 +_,7 @@ public static S spin(final Function factory) { AtomicReference serverReference = new AtomicReference<>(); @@ -9,7 +9,7 @@ thread.setUncaughtExceptionHandler((t, e) -> LOGGER.error("Uncaught exception in server thread", e)); if (Runtime.getRuntime().availableProcessors() > 4) { thread.setPriority(8); -@@ -436,6 +_,7 @@ +@@ -429,6 +_,7 @@ this.scoreboard.load(this.savedDataStorage.computeIfAbsent(ScoreboardSaveData.TYPE).getData()); this.commandStorage = new CommandStorage(this.savedDataStorage); this.stopwatches = this.savedDataStorage.computeIfAbsent(Stopwatches.TYPE); @@ -17,7 +17,7 @@ if (!levelData.isInitialized()) { try { setInitialSpawn(overworld, levelData, worldOptions.generateBonusChest(), isDebug, this.levelLoadListener); -@@ -470,6 +_,7 @@ +@@ -463,6 +_,7 @@ this, this.executor, this.storageSource, derivedLevelData, dimension, entry.getValue(), isDebug, biomeZoomSeed, ImmutableList.of(), false ); this.levels.put(dimension, level); @@ -25,15 +25,15 @@ } else { level = overworld; } -@@ -492,6 +_,7 @@ +@@ -485,6 +_,7 @@ levelData.setSpawn(LevelData.RespawnData.of(level.dimension(), BlockPos.ZERO.above(80), 0.0F, 0.0F)); } else { ServerChunkCache chunkSource = level.getChunkSource(); + if (net.minecraftforge.event.ForgeEventFactory.onCreateWorldSpawn(level, levelData)) return; - ChunkPos spawnChunk = ChunkPos.containing(chunkSource.randomState().sampler().findSpawnPosition()); + ChunkPos spawnChunk = chunkSource.getGenerator().getOrigin(chunkSource.randomState()); levelLoadListener.start(LevelLoadListener.Stage.PREPARE_GLOBAL_SPAWN, 0); levelLoadListener.updateFocus(level.dimension(), spawnChunk); -@@ -678,6 +_,7 @@ +@@ -662,6 +_,7 @@ for (ServerLevel level : this.getAllLevels()) { if (level != null) { try { @@ -41,7 +41,7 @@ level.close(); } catch (IOException e) { LOGGER.error("Exception closing the level", e); -@@ -725,9 +_,11 @@ +@@ -709,9 +_,11 @@ throw new IllegalStateException("Failed to initialize server"); } @@ -53,7 +53,7 @@ while (this.running) { long thisTickNanos; -@@ -781,6 +_,8 @@ +@@ -765,6 +_,8 @@ this.isReady = true; JvmProfiler.INSTANCE.onServerTick(this.smoothedTickTimeMillis); } @@ -62,7 +62,7 @@ } catch (Throwable t) { LOGGER.error("Encountered an unexpected exception", t); CrashReport report = constructOrExtractCrashReport(t); -@@ -792,6 +_,7 @@ +@@ -776,6 +_,7 @@ LOGGER.error("We were unable to save this crash report to disk."); } @@ -70,7 +70,7 @@ this.onServerCrash(report); } finally { try { -@@ -800,6 +_,7 @@ +@@ -784,6 +_,7 @@ } catch (Throwable t) { LOGGER.error("Exception stopping the server", t); } finally { @@ -78,7 +78,7 @@ this.onServerExit(); } } -@@ -980,12 +_,14 @@ +@@ -964,12 +_,14 @@ } } @@ -93,7 +93,7 @@ } this.ticksUntilAutosave--; -@@ -1003,6 +_,7 @@ +@@ -987,6 +_,7 @@ this.smoothedTickTimeMillis = this.smoothedTickTimeMillis * 0.8F + (float)tickTime / (float)TimeUtil.NANOSECONDS_PER_MILLISECOND * 0.19999999F; this.logTickMethodTime(nano); profiler.pop(); @@ -101,7 +101,7 @@ } protected void processPacketsAndTick(final boolean sprinting) { -@@ -1064,7 +_,8 @@ +@@ -1048,7 +_,8 @@ Optional.of(players), Optional.of(ServerStatus.Version.current()), Optional.ofNullable(this.statusIcon), @@ -111,7 +111,7 @@ ); } -@@ -1109,9 +_,11 @@ +@@ -1093,9 +_,11 @@ profiler.push("levels"); this.updateEffectiveRespawnData(); @@ -124,7 +124,7 @@ try { level.tick(haveTime); -@@ -1120,9 +_,11 @@ +@@ -1104,9 +_,11 @@ level.fillReportDetails(report); throw new ReportedException(report); } @@ -136,7 +136,7 @@ } profiler.popPush("connection"); -@@ -1131,7 +_,7 @@ +@@ -1115,7 +_,7 @@ this.playerList.tick(); profiler.popPush("debugSubscribers"); this.debugSubscribers.tick(); @@ -145,7 +145,7 @@ profiler.popPush("gameTests"); GameTestTicker.SINGLETON.tick(); } -@@ -1217,7 +_,7 @@ +@@ -1201,7 +_,7 @@ } public String getServerModName() { @@ -154,15 +154,15 @@ } public ServerClockManager clockManager() { -@@ -1561,6 +_,7 @@ +@@ -1544,6 +_,7 @@ + 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.getPlayerList().getPlayers().forEach(this.getPlayerList()::sendPlayerPermissionLevel); //Forge: Fix newly added/modified commands not being sent to the client when commands reload. }, this); if (this.isSameThread()) { this.managedBlock(result::isDone); -@@ -1572,12 +_,15 @@ +@@ -1555,12 +_,15 @@ public static WorldDataConfiguration configurePackRepository( final PackRepository packRepository, final WorldDataConfiguration initialDataConfig, final boolean initMode, final boolean safeMode ) { @@ -179,7 +179,7 @@ } Set selected = Sets.newLinkedHashSet(); -@@ -2226,6 +_,48 @@ +@@ -2192,6 +_,48 @@ public ServerLinks serverLinks() { return ServerLinks.EMPTY; diff --git a/patches/minecraft/net/minecraft/server/PlayerAdvancements.java.patch b/patches/minecraft/net/minecraft/server/PlayerAdvancements.java.patch index bd42a95708..844fd75437 100644 --- a/patches/minecraft/net/minecraft/server/PlayerAdvancements.java.patch +++ b/patches/minecraft/net/minecraft/server/PlayerAdvancements.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/PlayerAdvancements.java +++ b/net/minecraft/server/PlayerAdvancements.java -@@ -171,6 +_,7 @@ +@@ -172,6 +_,7 @@ this.unregisterListeners(holder); this.progressChanged.add(holder); result = true; @@ -8,15 +8,15 @@ if (!wasDone && progress.isDone()) { holder.value().rewards().grant(this.player); holder.value().display().ifPresent(display -> { -@@ -178,6 +_,7 @@ - this.playerList.broadcastSystemMessage(display.getType().createAnnouncement(holder, this.player), false); +@@ -179,6 +_,7 @@ + this.playerList.broadcastSystemMessage(display.type().createAnnouncement(holder, this.player), false); } }); + net.minecraftforge.event.ForgeEventFactory.onAdvancementEarned(this.player, holder); } } -@@ -196,6 +_,7 @@ +@@ -197,6 +_,7 @@ this.registerListeners(advancement); this.progressChanged.add(advancement); result = true; diff --git a/patches/minecraft/net/minecraft/server/ReloadableServerResources.java.patch b/patches/minecraft/net/minecraft/server/ReloadableServerResources.java.patch index 5715cce8ce..bf1ecb5949 100644 --- a/patches/minecraft/net/minecraft/server/ReloadableServerResources.java.patch +++ b/patches/minecraft/net/minecraft/server/ReloadableServerResources.java.patch @@ -1,28 +1,28 @@ --- a/net/minecraft/server/ReloadableServerResources.java +++ b/net/minecraft/server/ReloadableServerResources.java -@@ -30,6 +_,7 @@ +@@ -29,6 +_,7 @@ private final ServerFunctionLibrary functionLibrary; private final List> postponedTags; private final List> newComponents; + private final net.minecraftforge.common.crafting.conditions.ICondition.IContext context; private ReloadableServerResources( - final LayeredRegistryAccess fullLayers, -@@ -43,9 +_,11 @@ - this.fullRegistryHolder = new ReloadableServerRegistries.Holder(fullLayers.compositeAccess()); + final ReloadableServerRegistries.LoadResult loadingContext, +@@ -41,9 +_,11 @@ + this.fullRegistryHolder = new ReloadableServerRegistries.Holder(loadingContext.layers().compositeAccess()); this.postponedTags = postponedTags; this.newComponents = newComponents; -- this.recipes = new RecipeManager(loadingContext); - this.commands = new Commands(commandSelection, CommandBuildContext.simple(loadingContext, enabledFeatures)); -- this.advancements = new ServerAdvancementManager(loadingContext); +- this.recipes = new RecipeManager(loadingContext.lookupWithUpdatedTags()); + this.commands = new Commands(commandSelection, CommandBuildContext.simple(loadingContext.lookupWithUpdatedTags(), enabledFeatures)); +- this.advancements = new ServerAdvancementManager(loadingContext.lookupWithUpdatedTags()); + // Forge: Create context object and pass it to the recipe manager. + this.context = new net.minecraftforge.common.crafting.conditions.ConditionContext(this.postponedTags); -+ this.recipes = new RecipeManager(loadingContext, this.context); -+ this.advancements = new ServerAdvancementManager(loadingContext, this.context); ++ this.recipes = new RecipeManager(loadingContext.lookupWithUpdatedTags()); ++ this.advancements = new ServerAdvancementManager(loadingContext.lookupWithUpdatedTags(), this.context); this.functionLibrary = new ServerFunctionLibrary(functionCompilationPermissions, this.commands.getDispatcher()); } -@@ -101,7 +_,7 @@ +@@ -98,7 +_,7 @@ ); return SimpleReloadInstance.create( resourceManager, @@ -31,7 +31,7 @@ backgroundExecutor, mainThreadExecutor, DATA_RELOAD_INITIAL_TASK, -@@ -117,5 +_,14 @@ +@@ -114,5 +_,14 @@ public void updateComponentsAndStaticRegistryTags() { this.postponedTags.forEach(Registry.PendingTags::apply); this.newComponents.forEach(DataComponentInitializers.PendingComponents::apply); diff --git a/patches/minecraft/net/minecraft/server/ServerAdvancementManager.java.patch b/patches/minecraft/net/minecraft/server/ServerAdvancementManager.java.patch index 91b0ce308c..d1bccef0fb 100644 --- a/patches/minecraft/net/minecraft/server/ServerAdvancementManager.java.patch +++ b/patches/minecraft/net/minecraft/server/ServerAdvancementManager.java.patch @@ -1,13 +1,13 @@ --- a/net/minecraft/server/ServerAdvancementManager.java +++ b/net/minecraft/server/ServerAdvancementManager.java -@@ -27,6 +_,10 @@ - private final HolderLookup.Provider registries; +@@ -22,6 +_,10 @@ + private final AdvancementTree tree; public ServerAdvancementManager(final HolderLookup.Provider registries) { + this(registries, net.minecraftforge.common.crafting.conditions.ICondition.IContext.EMPTY); + } + + public ServerAdvancementManager(final HolderLookup.Provider registries, net.minecraftforge.common.crafting.conditions.ICondition.IContext context) { - super(registries, Advancement.CODEC, Registries.ADVANCEMENT); - this.registries = registries; - } + HolderLookup.RegistryLookup advancements = registries.lookupOrThrow(Registries.ADVANCEMENT); + Builder builder = ImmutableMap.builder(); + advancements.listElements().forEach(advancement -> { diff --git a/patches/minecraft/net/minecraft/server/commands/TeleportCommand.java.patch b/patches/minecraft/net/minecraft/server/commands/TeleportCommand.java.patch index 11f9610d5d..769ae1f0e2 100644 --- a/patches/minecraft/net/minecraft/server/commands/TeleportCommand.java.patch +++ b/patches/minecraft/net/minecraft/server/commands/TeleportCommand.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/commands/TeleportCommand.java +++ b/net/minecraft/server/commands/TeleportCommand.java -@@ -236,14 +_,17 @@ +@@ -223,14 +_,17 @@ final CommandSourceStack source, final Entity victim, final ServerLevel level, diff --git a/patches/minecraft/net/minecraft/server/level/ChunkMap.java.patch b/patches/minecraft/net/minecraft/server/level/ChunkMap.java.patch index a4cd417234..8bdd028522 100644 --- a/patches/minecraft/net/minecraft/server/level/ChunkMap.java.patch +++ b/patches/minecraft/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 -@@ -392,6 +_,7 @@ +@@ -391,6 +_,7 @@ this.modified = true; } @@ -8,7 +8,7 @@ return chunk; } -@@ -522,6 +_,7 @@ +@@ -521,6 +_,7 @@ if (this.pendingUnloads.remove(pos, chunkHolder) && chunk != null) { if (chunk instanceof LevelChunk levelChunk) { levelChunk.setLoaded(false); @@ -16,7 +16,7 @@ } this.save(chunk); -@@ -767,6 +_,7 @@ +@@ -766,6 +_,7 @@ this.activeChunkWrites.incrementAndGet(); SerializableChunkData data = SerializableChunkData.copyOf(this.level, chunk); CompletableFuture encodedData = CompletableFuture.supplyAsync(data::write, Util.backgroundExecutor()); @@ -24,7 +24,7 @@ this.write(pos, encodedData::join).handle((ignored, throwable) -> { if (throwable != null) { this.level.getServer().reportChunkSaveFailure(throwable, this.storageInfo(), pos); -@@ -1142,7 +_,7 @@ +@@ -1141,7 +_,7 @@ } protected void addEntity(final Entity entity) { diff --git a/patches/minecraft/net/minecraft/server/level/ServerChunkCache.java.patch b/patches/minecraft/net/minecraft/server/level/ServerChunkCache.java.patch index c76f6f6747..f4bd4ad165 100644 --- a/patches/minecraft/net/minecraft/server/level/ServerChunkCache.java.patch +++ b/patches/minecraft/net/minecraft/server/level/ServerChunkCache.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java -@@ -194,6 +_,11 @@ +@@ -191,6 +_,11 @@ return null; } diff --git a/patches/minecraft/net/minecraft/server/level/ServerEntity.java.patch b/patches/minecraft/net/minecraft/server/level/ServerEntity.java.patch index 30b21a502a..e1287d47ab 100644 --- a/patches/minecraft/net/minecraft/server/level/ServerEntity.java.patch +++ b/patches/minecraft/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 -@@ -262,6 +_,7 @@ +@@ -297,6 +_,7 @@ public void removePairing(final ServerPlayer player) { this.entity.stopSeenByPlayer(player); player.connection.send(new ClientboundRemoveEntitiesPacket(this.entity.getId())); @@ -8,7 +8,7 @@ } public void addPairing(final ServerPlayer player) { -@@ -269,6 +_,7 @@ +@@ -304,6 +_,7 @@ this.sendPairingData(player, packets::add); player.connection.send(new ClientboundBundlePacket(packets)); this.entity.startSeenByPlayer(player); diff --git a/patches/minecraft/net/minecraft/server/level/ServerLevel.java.patch b/patches/minecraft/net/minecraft/server/level/ServerLevel.java.patch index d5e687789e..1a2189bd19 100644 --- a/patches/minecraft/net/minecraft/server/level/ServerLevel.java.patch +++ b/patches/minecraft/net/minecraft/server/level/ServerLevel.java.patch @@ -1,10 +1,11 @@ --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -217,10 +_,12 @@ +@@ -218,11 +_,13 @@ private final List customSpawners; private @Nullable EnderDragonFight dragonFight; private final Int2ObjectMap dragonParts = new Int2ObjectOpenHashMap<>(); + final Int2ObjectMap> partEntities = new Int2ObjectOpenHashMap<>(); + private final BiomeResolver uncachedBiomeResolver; private final StructureManager structureManager; private final StructureCheck structureCheck; private final boolean tickTime; @@ -13,9 +14,9 @@ public ServerLevel( final MinecraftServer server, -@@ -304,6 +_,18 @@ - this.waypointManager = new ServerWaypointManager(); +@@ -306,6 +_,18 @@ this.environmentAttributes = EnvironmentAttributeSystem.builder().addDefaultLayers(this).build(); + this.uncachedBiomeResolver = this.getChunkSource().getGenerator().getBiomeSource().createUncachedResolver(this.getChunkSource().randomState()); this.updateSkyBrightness(); + this.initCapabilities(); + } @@ -32,18 +33,18 @@ } @Override -@@ -367,7 +_,9 @@ +@@ -373,7 +_,9 @@ if (this.sleepStatus.areEnoughSleeping(percentage) && this.sleepStatus.areEnoughDeepSleeping(percentage, this.players)) { Optional> defaultClock = this.dimensionType().defaultClock(); if (this.getGameRules().get(GameRules.ADVANCE_TIME) && defaultClock.isPresent()) { - this.server.clockManager().moveToTimeMarker(defaultClock.get(), ClockTimeMarkers.WAKE_UP_FROM_SLEEP); -+ long minTime = this.server.clockManager().getTotalTicks(defaultClock.get()); ++ long minTime = this.server.clockManager().getInstance(defaultClock.get()).totalTicks(); + long newTime = this.server.clockManager().getTimeMarker(defaultClock.get(), ClockTimeMarkers.WAKE_UP_FROM_SLEEP); + this.server.clockManager().setTotalTicks(defaultClock.get(), net.minecraftforge.event.ForgeEventFactory.onSleepFinished(this, newTime, minTime)); } this.wakeUpAllPlayers(); -@@ -441,6 +_,7 @@ +@@ -447,6 +_,7 @@ entity.stopRiding(); } @@ -51,7 +52,7 @@ profiler.push("tick"); this.guardEntityTick(this::tickNonPassenger, entity); profiler.pop(); -@@ -581,6 +_,7 @@ +@@ -588,6 +_,7 @@ BlockPos topPos = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos); BlockPos belowPos = topPos.below(); Biome biome = this.getBiome(topPos).value(); @@ -59,7 +60,7 @@ if (biome.shouldFreeze(this, belowPos)) { this.setBlockAndUpdate(belowPos, Blocks.ICE.defaultBlockState()); } -@@ -790,8 +_,8 @@ +@@ -797,8 +_,8 @@ this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(ClientboundGameEventPacket.START_RAINING, 0.0F)); } @@ -70,23 +71,29 @@ } } -@@ -829,6 +_,7 @@ - entity.tickCount++; +@@ -834,8 +_,10 @@ + ProfilerFiller profiler = Profiler.get(); profiler.push(entity.typeHolder()::getRegisteredName); profiler.incrementCounter("tickNonPassenger"); -+ if (entity.canUpdate()) ++ if (entity.canUpdate()) { + entity.commonTick(); entity.tick(); ++ } profiler.pop(); -@@ -846,6 +_,7 @@ + for (Entity passenger : entity.getPassengers()) { +@@ -850,8 +_,10 @@ ProfilerFiller profiler = Profiler.get(); profiler.push(entity.typeHolder()::getRegisteredName); profiler.incrementCounter("tickPassenger"); -+ if (entity.canUpdate()) ++ if (entity.canUpdate()) { + entity.commonTick(); entity.rideTick(); ++ } profiler.pop(); -@@ -892,6 +_,7 @@ + for (Entity passenger : entity.getPassengers()) { +@@ -897,6 +_,7 @@ } else { this.entityManager.autoSave(); } @@ -94,7 +101,7 @@ } } -@@ -983,6 +_,7 @@ +@@ -988,6 +_,7 @@ } private void addPlayer(final ServerPlayer player) { @@ -102,7 +109,7 @@ Entity existing = this.getEntity(player.getUUID()); if (existing != null) { LOGGER.warn("Force-added player with duplicate UUID {}", player.getUUID()); -@@ -990,7 +_,8 @@ +@@ -995,7 +_,8 @@ this.removePlayerImmediately((ServerPlayer)existing, Entity.RemovalReason.DISCARDED); } @@ -112,7 +119,7 @@ } private boolean addEntity(final Entity entity) { -@@ -998,7 +_,12 @@ +@@ -1003,7 +_,12 @@ LOGGER.warn("Tried to add entity {} but it was marked as removed already", entity.typeHolder().getRegisteredName()); return false; } else { @@ -126,7 +133,7 @@ } } -@@ -1047,6 +_,8 @@ +@@ -1052,6 +_,8 @@ final float pitch, final long seed ) { @@ -135,7 +142,7 @@ this.server .getPlayerList() .broadcast( -@@ -1054,9 +_,9 @@ +@@ -1059,9 +_,9 @@ x, y, z, @@ -147,7 +154,7 @@ ); } -@@ -1070,6 +_,8 @@ +@@ -1075,6 +_,8 @@ final float pitch, final long seed ) { @@ -156,7 +163,7 @@ this.server .getPlayerList() .broadcast( -@@ -1079,7 +_,7 @@ +@@ -1084,7 +_,7 @@ sourceEntity.getZ(), sound.value().getRange(volume), this.dimension(), @@ -165,7 +172,7 @@ ); } -@@ -1128,6 +_,7 @@ +@@ -1133,6 +_,7 @@ @Override public void gameEvent(final Holder gameEvent, final Vec3 position, final GameEvent.Context context) { @@ -173,7 +180,7 @@ this.gameEventDispatcher.post(gameEvent, position, context); } -@@ -1166,11 +_,15 @@ +@@ -1171,11 +_,15 @@ @Override public void updateNeighborsAt(final BlockPos pos, final Block sourceBlock) { @@ -189,7 +196,7 @@ this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, null, orientation); } -@@ -1178,6 +_,10 @@ +@@ -1183,6 +_,10 @@ public void updateNeighborsAtExceptFromFacing( final BlockPos pos, final Block blockObject, final Direction skipDirection, final @Nullable Orientation orientation ) { @@ -200,7 +207,7 @@ this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, blockObject, skipDirection, orientation); } -@@ -1226,7 +_,7 @@ +@@ -1231,7 +_,7 @@ Explosion.BlockInteraction blockInteraction = switch (interactionType) { case NONE -> Explosion.BlockInteraction.KEEP; case BLOCK -> this.getDestroyType(GameRules.BLOCK_EXPLOSION_DROP_DECAY); @@ -209,7 +216,7 @@ ? this.getDestroyType(GameRules.MOB_EXPLOSION_DROP_DECAY) : Explosion.BlockInteraction.KEEP; case TNT -> this.getDestroyType(GameRules.TNT_EXPLOSION_DROP_DECAY); -@@ -1234,6 +_,8 @@ +@@ -1239,6 +_,8 @@ }; Vec3 center = new Vec3(x, y, z); ServerExplosion explosion = new ServerExplosion(this, source, damageSource, damageCalculator, center, r, fire, blockInteraction); @@ -218,7 +225,7 @@ int blockCount = explosion.explode(); ParticleOptions explosionParticle = explosion.isSmall() ? smallExplosionParticles : largeExplosionParticles; -@@ -1894,6 +_,11 @@ +@@ -2010,6 +_,11 @@ return this.getGameRules().get(GameRules.SPAWNER_BLOCKS_WORK); } @@ -230,7 +237,7 @@ private final class EntityCallbacks implements LevelCallback { public void onCreated(final Entity entity) { if (entity instanceof WaypointTransmitter waypoint && waypoint.isTransmittingWaypoint()) { -@@ -1949,6 +_,12 @@ +@@ -2065,6 +_,12 @@ } } @@ -243,7 +250,7 @@ entity.updateDynamicGameEventListener(DynamicGameEventListener::add); } -@@ -1977,8 +_,17 @@ +@@ -2093,8 +_,17 @@ } } diff --git a/patches/minecraft/net/minecraft/server/level/ServerPlayer.java.patch b/patches/minecraft/net/minecraft/server/level/ServerPlayer.java.patch index f9691666ec..ad6872bd09 100644 --- a/patches/minecraft/net/minecraft/server/level/ServerPlayer.java.patch +++ b/patches/minecraft/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 -@@ -205,7 +_,8 @@ +@@ -209,7 +_,8 @@ import org.jspecify.annotations.Nullable; import org.slf4j.Logger; @@ -10,7 +10,7 @@ private static final Logger LOGGER = LogUtils.getLogger(); private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32; private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10; -@@ -881,6 +_,7 @@ +@@ -891,6 +_,7 @@ @Override public void die(final DamageSource source) { @@ -18,7 +18,7 @@ this.gameEvent(GameEvent.ENTITY_DIE); boolean showDeathMessage = this.level().getGameRules().get(GameRules.SHOW_DEATH_MESSAGES); if (showDeathMessage) { -@@ -1093,6 +_,7 @@ +@@ -1139,6 +_,7 @@ } public @Nullable ServerPlayer teleport(final TeleportTransition transition) { @@ -26,7 +26,7 @@ if (this.isRemoved()) { return null; } -@@ -1122,7 +_,7 @@ +@@ -1168,7 +_,7 @@ PlayerList playerList = this.server.getPlayerList(); playerList.sendPlayerPermissionLevel(this); oldLevel.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION); @@ -35,7 +35,7 @@ ProfilerFiller profiler = Profiler.get(); profiler.push("moving"); if (lastDimension == Level.OVERWORLD && newLevel.dimension() == Level.NETHER) { -@@ -1147,6 +_,7 @@ +@@ -1194,6 +_,7 @@ this.lastSentHealth = -1.0F; this.lastSentFood = -1; this.teleportSpectators(transition, oldLevel); @@ -43,22 +43,21 @@ return this; } -@@ -1186,10 +_,13 @@ - - @Override - public Either startSleepInBed(final BlockPos pos) { +@@ -1235,9 +_,12 @@ + public Either startSleepInBed( + final AbstractBedBlock bedBlock, final BlockState bedBlockState, final BedRule rule, final BlockPos pos + ) { + var optAt = java.util.Optional.of(pos); + var ret = net.minecraftforge.event.ForgeEventFactory.onPlayerSleepInBed(this, optAt); + if (ret != null) return Either.left(ret); - Direction direction = this.level().getBlockState(pos).getValue(HorizontalDirectionalBlock.FACING); + Direction direction = bedBlockState.getValue(HorizontalDirectionalBlock.FACING); if (!this.isSleeping() && this.isAlive()) { - BedRule rule = this.level().environmentAttributes().getValue(EnvironmentAttributes.BED_RULE, pos); - boolean canSleep = rule.canSleep(this.level()); + boolean canSleep = net.minecraftforge.event.ForgeEventFactory.onSleepingTimeCheck(this, optAt, rule); boolean canSetSpawn = rule.canSetSpawn(this.level()); - if (!canSetSpawn && !canSleep) { - return Either.left(rule.asProblem()); -@@ -1250,6 +_,7 @@ + if (!this.bedInRange(pos, direction)) { + return Either.left(Player.BedSleepingProblem.TOO_FAR_AWAY); +@@ -1304,6 +_,7 @@ } private boolean bedInRange(final BlockPos pos, final Direction direction) { @@ -66,7 +65,7 @@ return this.isReachableBedBlock(pos) || this.isReachableBedBlock(pos.relative(direction.getOpposite())); } -@@ -1354,6 +_,7 @@ +@@ -1408,6 +_,7 @@ this.connection.send(new ClientboundOpenScreenPacket(menu.containerId, menu.getType(), provider.getDisplayName())); this.initMenu(menu); this.containerMenu = menu; @@ -74,7 +73,7 @@ return OptionalInt.of(this.containerCounter); } } -@@ -1422,6 +_,7 @@ +@@ -1476,6 +_,7 @@ public void doCloseContainer() { this.containerMenu.removed(this); this.inventoryMenu.transferState(this.containerMenu); @@ -82,7 +81,7 @@ this.containerMenu = this.inventoryMenu; } -@@ -1641,6 +_,15 @@ +@@ -1693,6 +_,15 @@ this.setShoulderEntityRight(oldPlayer.getShoulderEntityRight()); this.setLastDeathLocation(oldPlayer.getLastDeathLocation()); this.waypointIcon().copyFrom(oldPlayer.waypointIcon()); @@ -98,7 +97,7 @@ } private void transferInventoryXpAndScore(final Player oldPlayer) { -@@ -1750,8 +_,9 @@ +@@ -1802,8 +_,9 @@ return (ServerLevel)super.level(); } @@ -109,7 +108,7 @@ if (!this.gameMode.changeGameModeForPlayer(mode)) { return false; } -@@ -1935,6 +_,9 @@ +@@ -1977,6 +_,9 @@ public void setCamera(final @Nullable Entity newCamera) { Entity oldCamera = this.getCamera(); this.camera = newCamera == null ? this : newCamera; @@ -119,7 +118,7 @@ if (oldCamera != this.camera) { if (this.camera.level() instanceof ServerLevel level) { this.teleportTo(level, this.camera.getX(), this.camera.getY(), this.camera.getZ(), Set.of(), this.getYRot(), this.getXRot(), false); -@@ -1961,7 +_,11 @@ +@@ -2003,7 +_,11 @@ } public @Nullable Component getTabListDisplayName() { @@ -132,7 +131,7 @@ } public int getTabListOrder() { -@@ -1995,6 +_,7 @@ +@@ -2031,6 +_,7 @@ } public void setRespawnPosition(final ServerPlayer.@Nullable RespawnConfig respawnConfig, final boolean showMessage) { @@ -140,7 +139,7 @@ if (showMessage && respawnConfig != null && !respawnConfig.isSamePosition(this.respawnConfig)) { this.sendSystemMessage(SPAWN_SET_MESSAGE); } -@@ -2082,6 +_,9 @@ +@@ -2119,6 +_,9 @@ public void drop(final boolean all) { Inventory inventory = this.getInventory(); @@ -150,16 +149,16 @@ ItemStack removed = inventory.removeFromSelected(all); this.containerMenu .findSlot(inventory, inventory.getSelectedSlot()) -@@ -2090,7 +_,7 @@ +@@ -2127,7 +_,7 @@ this.stopUsingItem(); } -- this.drop(removed, false, true); -+ net.minecraftforge.common.ForgeHooks.onPlayerTossEvent(this, removed, true); +- this.drop(removed, true, Prediction.PREDICTED); ++ net.minecraftforge.common.ForgeHooks.onPlayerTossEvent(this, removed, true, Prediction.PREDICTED); + this.resetAttackStrengthTicker(); } - @Override -@@ -2192,6 +_,75 @@ +@@ -2229,6 +_,75 @@ public @Nullable BlockPos getRaidOmenPosition() { return this.raidOmenPosition; diff --git a/patches/minecraft/net/minecraft/server/level/ServerPlayerGameMode.java.patch b/patches/minecraft/net/minecraft/server/level/ServerPlayerGameMode.java.patch index 0f23261e57..8fa0fc0283 100644 --- a/patches/minecraft/net/minecraft/server/level/ServerPlayerGameMode.java.patch +++ b/patches/minecraft/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 -@@ -150,6 +_,10 @@ +@@ -163,6 +_,10 @@ public void handleBlockBreakAction( final BlockPos pos, final ServerboundPlayerActionPacket.Action action, final Direction direction, final int maxY, final int sequence ) { @@ -9,9 +9,9 @@ + return; + } if (!this.player.isWithinBlockInteractionRange(pos, 1.0)) { - this.debugLogging(pos, false, sequence, "too far"); - } else if (pos.getY() > maxY) { -@@ -184,6 +_,7 @@ + if (this.isDestroyingBlock && action == ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK) { + this.abortDestroyBlock(pos, sequence); +@@ -201,6 +_,7 @@ float progress = 1.0F; BlockState blockState = this.level.getBlockState(pos); if (!blockState.isAir()) { @@ -19,7 +19,7 @@ EnchantmentHelper.onHitBlock( this.level, this.player.getMainHandItem(), -@@ -195,6 +_,7 @@ +@@ -212,6 +_,7 @@ item -> this.player.onEquippedItemBroken(item, EquipmentSlot.MAINHAND) ); blockState.attack(this.level, pos, this.player); @@ -27,7 +27,7 @@ progress = blockState.getDestroyProgress(this.player, this.player.level(), pos); } -@@ -261,7 +_,8 @@ +@@ -285,7 +_,8 @@ public boolean destroyBlock(final BlockPos pos) { BlockState state = this.level.getBlockState(pos); @@ -37,7 +37,7 @@ return false; } -@@ -272,35 +_,53 @@ +@@ -296,35 +_,53 @@ return false; } @@ -102,7 +102,7 @@ public InteractionResult useItem(final ServerPlayer player, final Level level, final ItemStack itemStack, final InteractionHand hand) { if (this.gameModeForPlayer == GameType.SPECTATOR) { return InteractionResult.PASS; -@@ -310,6 +_,8 @@ +@@ -334,6 +_,8 @@ return InteractionResult.PASS; } @@ -111,7 +111,7 @@ int oldCount = itemStack.getCount(); int oldDamage = itemStack.getDamageValue(); InteractionResult result = itemStack.use(level, player, hand); -@@ -355,6 +_,8 @@ +@@ -379,6 +_,8 @@ return InteractionResult.FAIL; } @@ -120,7 +120,7 @@ if (this.gameModeForPlayer == GameType.SPECTATOR) { MenuProvider menuProvider = state.getMenuProvider(level, pos); if (menuProvider != null) { -@@ -364,10 +_,16 @@ +@@ -404,10 +_,16 @@ return InteractionResult.PASS; } } else { @@ -138,7 +138,7 @@ InteractionResult itemUse = state.useItemOn(player.getItemInHand(hand), level, player, hand, hitResult); if (itemUse.consumesAction()) { CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(player, pos, usedItemStack); -@@ -383,8 +_,8 @@ +@@ -423,8 +_,8 @@ } } @@ -146,6 +146,6 @@ - UseOnContext context = new UseOnContext(player, hand, hitResult); + if (event.getUseItem().isAllowed() || (!itemStack.isEmpty() && !player.getCooldowns().isOnCooldown(itemStack))) { + if (event.getUseItem().isDenied()) return InteractionResult.PASS; - InteractionResult success; + InteractionResult result; if (player.hasInfiniteMaterials()) { int count = itemStack.getCount(); diff --git a/patches/minecraft/net/minecraft/server/level/WorldGenRegion.java.patch b/patches/minecraft/net/minecraft/server/level/WorldGenRegion.java.patch index 267dd699cc..763be37cb1 100644 --- a/patches/minecraft/net/minecraft/server/level/WorldGenRegion.java.patch +++ b/patches/minecraft/net/minecraft/server/level/WorldGenRegion.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/level/WorldGenRegion.java +++ b/net/minecraft/server/level/WorldGenRegion.java -@@ -341,6 +_,7 @@ +@@ -368,6 +_,7 @@ @Override public boolean addFreshEntity(final Entity entity) { diff --git a/patches/minecraft/net/minecraft/server/network/ServerConnectionListener.java.patch b/patches/minecraft/net/minecraft/server/network/ServerConnectionListener.java.patch index 3e7eab4ee0..c3fb4c4f16 100644 --- a/patches/minecraft/net/minecraft/server/network/ServerConnectionListener.java.patch +++ b/patches/minecraft/net/minecraft/server/network/ServerConnectionListener.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/network/ServerConnectionListener.java +++ b/net/minecraft/server/network/ServerConnectionListener.java -@@ -40,6 +_,7 @@ +@@ -42,6 +_,7 @@ import org.slf4j.Logger; public class ServerConnectionListener { @@ -8,7 +8,7 @@ private static final Logger LOGGER = LogUtils.getLogger(); private final MinecraftServer server; public volatile boolean running; -@@ -53,6 +_,8 @@ +@@ -56,6 +_,8 @@ } public void startTcpServerListener(final @Nullable InetAddress address, final int port) throws IOException { @@ -17,7 +17,7 @@ synchronized (this.channels) { EventLoopGroupHolder eventLoopGroupHolder = EventLoopGroupHolder.remote(this.server.useNativeTransport()); this.channels -@@ -68,7 +_,7 @@ +@@ -71,7 +_,7 @@ } catch (ChannelException var5) { } @@ -26,7 +26,7 @@ if (ServerConnectionListener.this.server.repliesToStatus()) { pipeline.addLast("legacy_query", new LegacyQueryHandler(ServerConnectionListener.this.getServer())); } -@@ -87,7 +_,7 @@ +@@ -90,7 +_,7 @@ } ) .group(eventLoopGroupHolder.eventLoopGroup()) diff --git a/patches/minecraft/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/patches/minecraft/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index 41650457d9..6070578922 100644 --- a/patches/minecraft/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/patches/minecraft/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1297,9 +_,10 @@ +@@ -1363,9 +_,10 @@ } case SWAP_ITEM_WITH_OFFHAND: if (!this.player.isSpectator()) { @@ -14,7 +14,7 @@ this.player.stopUsingItem(); } -@@ -1515,8 +_,9 @@ +@@ -1583,8 +_,9 @@ } CompletableFuture filteredFuture = this.filterTextPacket(signedMessage.signedContent()); @@ -25,7 +25,7 @@ PlayerChatMessage filteredMessage = signedMessage.withUnsignedContent(decorated).filter(filtered.mask()); this.broadcastChatMessage(filteredMessage); }); -@@ -2195,6 +_,7 @@ +@@ -2266,6 +_,7 @@ @Override public void handleCustomPayload(final ServerboundCustomPayloadPacket packet) { diff --git a/patches/minecraft/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch b/patches/minecraft/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch index 7d3d662689..b0e159442d 100644 --- a/patches/minecraft/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch +++ b/patches/minecraft/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -@@ -188,7 +_,7 @@ +@@ -185,7 +_,7 @@ throw new IllegalStateException("Protocol error", e); } @@ -9,7 +9,7 @@ @Override public void run() { String name = Objects.requireNonNull(ServerLoginPacketListenerImpl.this.requestedUsername, "Player name not initialized"); -@@ -234,6 +_,7 @@ +@@ -231,6 +_,7 @@ @Override public void handleCustomQueryPacket(final ServerboundCustomQueryAnswerPacket packet) { @@ -17,7 +17,7 @@ this.disconnect(ServerCommonPacketListenerImpl.DISCONNECT_UNEXPECTED_QUERY); } -@@ -256,6 +_,11 @@ +@@ -253,6 +_,11 @@ @Override public void handleCookieResponse(final ServerboundCookieResponsePacket packet) { this.disconnect(ServerCommonPacketListenerImpl.DISCONNECT_UNEXPECTED_QUERY); diff --git a/patches/minecraft/net/minecraft/server/packs/AbstractPackResources.java.patch b/patches/minecraft/net/minecraft/server/packs/AbstractPackMetadataResources.java.patch similarity index 65% rename from patches/minecraft/net/minecraft/server/packs/AbstractPackResources.java.patch rename to patches/minecraft/net/minecraft/server/packs/AbstractPackMetadataResources.java.patch index 2a159a9ae9..871e1eb615 100644 --- a/patches/minecraft/net/minecraft/server/packs/AbstractPackResources.java.patch +++ b/patches/minecraft/net/minecraft/server/packs/AbstractPackMetadataResources.java.patch @@ -1,5 +1,5 @@ ---- a/net/minecraft/server/packs/AbstractPackResources.java -+++ b/net/minecraft/server/packs/AbstractPackResources.java +--- a/net/minecraft/server/packs/AbstractPackMetadataResources.java ++++ b/net/minecraft/server/packs/AbstractPackMetadataResources.java @@ -39,4 +_,9 @@ public PackLocationInfo location() { return this.location; diff --git a/patches/minecraft/net/minecraft/server/packs/PackResources.java.patch b/patches/minecraft/net/minecraft/server/packs/PackResources.java.patch index 8b829869d3..e66a1c23d1 100644 --- a/patches/minecraft/net/minecraft/server/packs/PackResources.java.patch +++ b/patches/minecraft/net/minecraft/server/packs/PackResources.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/server/packs/PackResources.java +++ b/net/minecraft/server/packs/PackResources.java -@@ -11,7 +_,7 @@ +@@ -9,7 +_,7 @@ import net.minecraft.server.packs.resources.IoSupplier; import org.jspecify.annotations.Nullable; --public interface PackResources extends AutoCloseable { -+public interface PackResources extends AutoCloseable, net.minecraftforge.common.extensions.IForgePackResources { +-public interface PackResources extends PackMetadataResources { ++public interface PackResources extends PackMetadataResources, net.minecraftforge.common.extensions.IForgePackResources { String METADATA_EXTENSION = ".mcmeta"; String PACK_META = "pack.mcmeta"; diff --git a/patches/minecraft/net/minecraft/server/packs/repository/Pack.java.patch b/patches/minecraft/net/minecraft/server/packs/repository/Pack.java.patch index b30611ce73..86a4fd7eef 100644 --- a/patches/minecraft/net/minecraft/server/packs/repository/Pack.java.patch +++ b/patches/minecraft/net/minecraft/server/packs/repository/Pack.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/packs/repository/Pack.java +++ b/net/minecraft/server/packs/repository/Pack.java -@@ -24,6 +_,7 @@ +@@ -26,6 +_,7 @@ private final Pack.ResourcesSupplier resources; private final Pack.Metadata metadata; private final PackSelectionConfig selectionConfig; @@ -8,7 +8,7 @@ public static @Nullable Pack readMetaAndCreate( final PackLocationInfo location, final Pack.ResourcesSupplier resources, final PackType packType, final PackSelectionConfig selectionConfig -@@ -40,6 +_,7 @@ +@@ -42,6 +_,7 @@ this.resources = resources; this.metadata = metadata; this.selectionConfig = selectionConfig; @@ -16,16 +16,7 @@ } public static Pack.@Nullable Metadata readPackMetadata( -@@ -63,7 +_,7 @@ - PackCompatibility packCompatibility = PackCompatibility.forVersion(meta.supportedFormats(), currentPackVersion); - OverlayMetadataSection overlays = pack.getMetadataSection(OverlayMetadataSection.forPackType(type)); - List overlaySet = overlays != null ? overlays.overlaysForVersion(currentPackVersion) : List.of(); -- return new Pack.Metadata(meta.description(), packCompatibility, requiredFlags, overlaySet); -+ return new Pack.Metadata(meta.description(), packCompatibility, requiredFlags, overlaySet, pack.isHidden()); - } - } catch (Exception e) { - LOGGER.warn("Failed to read pack {} metadata", location.id(), e); -@@ -123,6 +_,10 @@ +@@ -129,6 +_,10 @@ return this.location.source(); } @@ -36,7 +27,7 @@ @Override public boolean equals(final Object o) { if (this == o) { -@@ -137,7 +_,10 @@ +@@ -143,7 +_,10 @@ return this.location.hashCode(); } diff --git a/patches/minecraft/net/minecraft/server/packs/repository/ServerPacksSource.java.patch b/patches/minecraft/net/minecraft/server/packs/repository/ServerPacksSource.java.patch index 0c0f43f683..027bd5daf0 100644 --- a/patches/minecraft/net/minecraft/server/packs/repository/ServerPacksSource.java.patch +++ b/patches/minecraft/net/minecraft/server/packs/repository/ServerPacksSource.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/packs/repository/ServerPacksSource.java +++ b/net/minecraft/server/packs/repository/ServerPacksSource.java -@@ -70,7 +_,9 @@ +@@ -69,7 +_,9 @@ } public static PackRepository createPackRepository(final Path datapackDir, final DirectoryValidator validator) { diff --git a/patches/minecraft/net/minecraft/server/packs/resources/FallbackResourceManager.java.patch b/patches/minecraft/net/minecraft/server/packs/resources/FallbackResourceManager.java.patch index a807929241..91f4861b3b 100644 --- a/patches/minecraft/net/minecraft/server/packs/resources/FallbackResourceManager.java.patch +++ b/patches/minecraft/net/minecraft/server/packs/resources/FallbackResourceManager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/packs/resources/FallbackResourceManager.java +++ b/net/minecraft/server/packs/resources/FallbackResourceManager.java -@@ -103,8 +_,11 @@ +@@ -102,8 +_,11 @@ for (int i = this.fallbacks.size() - 1; i >= 0; i--) { FallbackResourceManager.PackEntry entry = this.fallbacks.get(i); @@ -14,7 +14,7 @@ IoSupplier resource = fileSource.getResource(this.type, location); if (resource != null) { IoSupplier metadataGetter; -@@ -118,6 +_,7 @@ +@@ -117,6 +_,7 @@ } result.add(new Resource(fileSource, resource, metadataGetter)); diff --git a/patches/minecraft/net/minecraft/server/packs/resources/ReloadableResourceManager.java.patch b/patches/minecraft/net/minecraft/server/packs/resources/ReloadableResourceManager.java.patch index 105d3b9dd5..421c642bf5 100644 --- a/patches/minecraft/net/minecraft/server/packs/resources/ReloadableResourceManager.java.patch +++ b/patches/minecraft/net/minecraft/server/packs/resources/ReloadableResourceManager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/packs/resources/ReloadableResourceManager.java +++ b/net/minecraft/server/packs/resources/ReloadableResourceManager.java -@@ -78,4 +_,10 @@ +@@ -77,4 +_,10 @@ public Stream listPacks() { return this.resources.listPacks(); } diff --git a/patches/minecraft/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java.patch b/patches/minecraft/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java.patch index 83fe9b302e..3cb7bfc23e 100644 --- a/patches/minecraft/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java.patch +++ b/patches/minecraft/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java.patch @@ -1,29 +1,29 @@ --- a/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java +++ b/net/minecraft/server/packs/resources/SimpleJsonResourceReloadListener.java -@@ -32,6 +_,10 @@ - this(registries.createSerializationContext(JsonOps.INSTANCE), codec, FileToIdConverter.registry(registryKey)); - } - -+ protected SimpleJsonResourceReloadListener(final HolderLookup.Provider registries, final Codec codec, final ResourceKey> registryKey, net.minecraftforge.common.crafting.conditions.ICondition.IContext context) { -+ this(context.wrap(registries.createSerializationContext(JsonOps.INSTANCE)), codec, FileToIdConverter.registry(registryKey)); -+ } -+ - protected SimpleJsonResourceReloadListener(final Codec codec, final FileToIdConverter lister) { +@@ -27,6 +_,10 @@ this(JsonOps.INSTANCE, codec, lister); } -@@ -66,7 +_,15 @@ - Identifier id = lister.fileToId(location); + ++ protected SimpleJsonResourceReloadListener(final Codec codec, final FileToIdConverter lister, net.minecraftforge.common.crafting.conditions.ICondition.IContext context) { ++ this(context.wrap(JsonOps.INSTANCE), codec, lister); ++ } ++ + protected SimpleJsonResourceReloadListener(final DynamicOps ops, final Codec codec, final FileToIdConverter lister) { + this.ops = ops; + this.codec = codec; +@@ -41,7 +_,15 @@ + Identifier id = this.lister.fileToId(location); try (Reader reader = entry.getValue().openAsReader()) { -- codec.parse(ops, StrictJsonParser.parse(reader)).ifSuccess(parsed -> { +- this.codec.parse(this.ops, StrictJsonParser.parse(reader)).ifSuccess(parsed -> { + var json = StrictJsonParser.parse(reader); -+ json = net.minecraftforge.common.ForgeHooks.readConditional(ops, json); ++ json = net.minecraftforge.common.ForgeHooks.readConditional(this.ops, json); + if (json == null) { + LOGGER.debug("Skipping loading {} as its conditions were not met", location); + continue; + } -+ codec.parse(ops, json).ifSuccess(parsed -> { -+ parsed = net.minecraftforge.common.ForgeHooks.onJsonDataParsed(codec, id, parsed); ++ this.codec.parse(this.ops, json).ifSuccess(parsed -> { ++ parsed = net.minecraftforge.common.ForgeHooks.onJsonDataParsed(this.codec, id, parsed); + if (parsed == null) return; if (result.putIfAbsent(id, (T)parsed) != null) { throw new IllegalStateException("Duplicate data file ignored with ID " + id); diff --git a/patches/minecraft/net/minecraft/server/players/PlayerList.java.patch b/patches/minecraft/net/minecraft/server/players/PlayerList.java.patch index b5c17dc1d1..817a55bf42 100644 --- a/patches/minecraft/net/minecraft/server/players/PlayerList.java.patch +++ b/patches/minecraft/net/minecraft/server/players/PlayerList.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -126,6 +_,8 @@ +@@ -128,6 +_,8 @@ + private int viewDistance; private int simulationDistance; - private boolean allowCommandsForAllPlayers; private int sendAllPlayerInfoIn; + private final List playersView = java.util.Collections.unmodifiableList(players); + private final Map playersByUUIDView = java.util.Collections.unmodifiableMap(this.playersByUUID); public PlayerList( final MinecraftServer server, -@@ -189,6 +_,7 @@ +@@ -191,6 +_,7 @@ playerConnection.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities())); playerConnection.send(new ClientboundSetHeldSlotPacket(player.getInventory().getSelectedSlot())); RecipeManager recipeManager = this.server.getRecipeManager(); @@ -17,7 +17,7 @@ playerConnection.send( new ClientboundUpdateRecipesPacket(recipeManager.getSynchronizedItemProperties(), recipeManager.getSynchronizedStonecutterRecipes()) ); -@@ -222,6 +_,7 @@ +@@ -225,6 +_,7 @@ player.initInventoryMenu(); this.server.notificationManager().playerJoined(player); playerConnection.resumeFlushing(); @@ -25,7 +25,7 @@ } protected void updateEntireScoreboard(final ServerScoreboard scoreboard, final ServerPlayer player) { -@@ -291,6 +_,7 @@ +@@ -294,6 +_,7 @@ } protected void save(final ServerPlayer player) { @@ -33,7 +33,7 @@ this.playerIo.save(player); ServerStatsCounter stats = this.stats.get(player.getUUID()); if (stats != null) { -@@ -304,6 +_,7 @@ +@@ -307,6 +_,7 @@ } public void remove(final ServerPlayer player) { @@ -41,7 +41,7 @@ ServerLevel level = player.level(); player.awardStat(Stats.LEAVE_GAME); this.save(player); -@@ -429,6 +_,7 @@ +@@ -437,6 +_,7 @@ this.playersByUUID.put(player.getUUID(), player); player.initInventoryMenu(); player.setHealth(player.getHealth()); @@ -49,7 +49,7 @@ ServerPlayer.RespawnConfig respawnConfig = player.getRespawnConfig(); if (!keepAllPlayerData && respawnConfig != null) { LevelData.RespawnData respawnData = respawnConfig.respawnData(); -@@ -542,6 +_,7 @@ +@@ -550,6 +_,7 @@ } public void op(final NameAndId nameAndId, final Optional permissions, final Optional canBypassPlayerLimit) { @@ -57,7 +57,7 @@ this.ops .add( new ServerOpListEntry( -@@ -555,6 +_,7 @@ +@@ -563,6 +_,7 @@ } public void deop(final NameAndId nameAndId) { @@ -65,7 +65,7 @@ if (this.ops.remove(nameAndId)) { ServerPlayer player = this.getPlayer(nameAndId.id()); if (player != null) { -@@ -826,11 +_,11 @@ +@@ -830,11 +_,11 @@ } public List getPlayers() { @@ -79,7 +79,7 @@ } public @Nullable ServerPlayer getPlayer(final UUID uuid) { -@@ -856,6 +_,7 @@ +@@ -860,6 +_,7 @@ advancements.reload(this.server.getAdvancements()); } @@ -88,9 +88,9 @@ RecipeManager recipeManager = this.server.getRecipeManager(); ClientboundUpdateRecipesPacket recipes = new ClientboundUpdateRecipesPacket( @@ -870,5 +_,9 @@ - - public boolean isAllowCommandsForAllPlayers() { - return this.allowCommandsForAllPlayers; + player.connection.send(recipes); + player.getRecipeBook().sendInitialRecipeBook(player); + } + } + + public PlayerDataStorage getPlayerIo() { diff --git a/patches/minecraft/net/minecraft/server/rcon/RconConsoleSource.java.patch b/patches/minecraft/net/minecraft/server/rcon/RconConsoleSource.java.patch index 02501c8b05..f0d78607ac 100644 --- a/patches/minecraft/net/minecraft/server/rcon/RconConsoleSource.java.patch +++ b/patches/minecraft/net/minecraft/server/rcon/RconConsoleSource.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/rcon/RconConsoleSource.java +++ b/net/minecraft/server/rcon/RconConsoleSource.java -@@ -44,7 +_,7 @@ +@@ -35,7 +_,7 @@ @Override public void sendSystemMessage(final Component message) { diff --git a/patches/minecraft/net/minecraft/tags/BiomeTags.java.patch b/patches/minecraft/net/minecraft/tags/BiomeTags.java.patch index 77b1e4196c..d13ba04675 100644 --- a/patches/minecraft/net/minecraft/tags/BiomeTags.java.patch +++ b/patches/minecraft/net/minecraft/tags/BiomeTags.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/tags/BiomeTags.java +++ b/net/minecraft/tags/BiomeTags.java -@@ -80,4 +_,12 @@ +@@ -98,4 +_,12 @@ private static TagKey create(final String name) { return TagKey.create(Registries.BIOME, Identifier.withDefaultNamespace(name)); } diff --git a/patches/minecraft/net/minecraft/tags/BlockTags.java.patch b/patches/minecraft/net/minecraft/tags/BlockTags.java.patch index 328c87ba12..431ff83c19 100644 --- a/patches/minecraft/net/minecraft/tags/BlockTags.java.patch +++ b/patches/minecraft/net/minecraft/tags/BlockTags.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/tags/BlockTags.java +++ b/net/minecraft/tags/BlockTags.java -@@ -260,4 +_,12 @@ +@@ -296,4 +_,12 @@ private static TagKey create(final String name) { return TagKey.create(Registries.BLOCK, Identifier.withDefaultNamespace(name)); } diff --git a/patches/minecraft/net/minecraft/tags/DamageTypeTags.java.patch b/patches/minecraft/net/minecraft/tags/DamageTypeTags.java.patch index de766c6d43..9dab614000 100644 --- a/patches/minecraft/net/minecraft/tags/DamageTypeTags.java.patch +++ b/patches/minecraft/net/minecraft/tags/DamageTypeTags.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/tags/DamageTypeTags.java +++ b/net/minecraft/tags/DamageTypeTags.java -@@ -44,4 +_,12 @@ +@@ -45,4 +_,12 @@ private static TagKey create(final String name) { return TagKey.create(Registries.DAMAGE_TYPE, Identifier.withDefaultNamespace(name)); } diff --git a/patches/minecraft/net/minecraft/tags/EntityTypeTags.java.patch b/patches/minecraft/net/minecraft/tags/EntityTypeTags.java.patch index deef29fb0b..4bf9221be0 100644 --- a/patches/minecraft/net/minecraft/tags/EntityTypeTags.java.patch +++ b/patches/minecraft/net/minecraft/tags/EntityTypeTags.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/tags/EntityTypeTags.java +++ b/net/minecraft/tags/EntityTypeTags.java -@@ -57,4 +_,12 @@ +@@ -58,4 +_,12 @@ private static TagKey> create(final String name) { return TagKey.create(Registries.ENTITY_TYPE, Identifier.withDefaultNamespace(name)); } diff --git a/patches/minecraft/net/minecraft/tags/FluidTags.java.patch b/patches/minecraft/net/minecraft/tags/FluidTags.java.patch index f6b87402d3..8bff12ab16 100644 --- a/patches/minecraft/net/minecraft/tags/FluidTags.java.patch +++ b/patches/minecraft/net/minecraft/tags/FluidTags.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/tags/FluidTags.java +++ b/net/minecraft/tags/FluidTags.java -@@ -18,4 +_,12 @@ +@@ -22,4 +_,12 @@ private static TagKey create(final String name) { return TagKey.create(Registries.FLUID, Identifier.withDefaultNamespace(name)); } diff --git a/patches/minecraft/net/minecraft/tags/ItemTags.java.patch b/patches/minecraft/net/minecraft/tags/ItemTags.java.patch index 508c67264a..562b455f3b 100644 --- a/patches/minecraft/net/minecraft/tags/ItemTags.java.patch +++ b/patches/minecraft/net/minecraft/tags/ItemTags.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/tags/ItemTags.java +++ b/net/minecraft/tags/ItemTags.java -@@ -220,4 +_,12 @@ +@@ -231,4 +_,12 @@ private static TagKey bind(final String name) { return TagKey.create(Registries.ITEM, Identifier.withDefaultNamespace(name)); } diff --git a/patches/minecraft/net/minecraft/tags/StructureTags.java.patch b/patches/minecraft/net/minecraft/tags/StructureTags.java.patch index 6461e1f5ad..6d6a3bf9bf 100644 --- a/patches/minecraft/net/minecraft/tags/StructureTags.java.patch +++ b/patches/minecraft/net/minecraft/tags/StructureTags.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/tags/StructureTags.java +++ b/net/minecraft/tags/StructureTags.java -@@ -29,4 +_,12 @@ +@@ -42,4 +_,12 @@ private static TagKey create(final String name) { return TagKey.create(Registries.STRUCTURE, Identifier.withDefaultNamespace(name)); } diff --git a/patches/minecraft/net/minecraft/util/Util.java.patch b/patches/minecraft/net/minecraft/util/Util.java.patch index 51be679f5f..56ddfe3201 100644 --- a/patches/minecraft/net/minecraft/util/Util.java.patch +++ b/patches/minecraft/net/minecraft/util/Util.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/util/Util.java +++ b/net/minecraft/util/Util.java -@@ -313,7 +_,7 @@ +@@ -318,7 +_,7 @@ .getSchema(DataFixUtils.makeKey(SharedConstants.getCurrentVersion().dataVersion().version())) .getChoiceType(reference, name); } catch (IllegalArgumentException e) { diff --git a/patches/minecraft/net/minecraft/util/context/ContextMap.java.patch b/patches/minecraft/net/minecraft/util/context/ContextMap.java.patch index 72e02cadf8..4cd2473ec6 100644 --- a/patches/minecraft/net/minecraft/util/context/ContextMap.java.patch +++ b/patches/minecraft/net/minecraft/util/context/ContextMap.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/util/context/ContextMap.java +++ b/net/minecraft/util/context/ContextMap.java -@@ -37,6 +_,10 @@ +@@ -42,6 +_,10 @@ return (T)this.params.getOrDefault(param, _default); } @@ -9,10 +9,10 @@ + } + public static class Builder { - private final Map, Object> params = new IdentityHashMap<>(); + private final Map, Object> params = new Reference2ObjectOpenHashMap<>(); -@@ -80,6 +_,10 @@ - return new ContextMap(this.params); +@@ -78,6 +_,10 @@ + return this.build(); } } + } diff --git a/patches/minecraft/net/minecraft/world/attribute/EnvironmentAttributeMap.java.patch b/patches/minecraft/net/minecraft/world/attribute/EnvironmentAttributeMap.java.patch new file mode 100644 index 0000000000..aa34f68f2f --- /dev/null +++ b/patches/minecraft/net/minecraft/world/attribute/EnvironmentAttributeMap.java.patch @@ -0,0 +1,27 @@ +--- a/net/minecraft/world/attribute/EnvironmentAttributeMap.java ++++ b/net/minecraft/world/attribute/EnvironmentAttributeMap.java +@@ -100,6 +_,12 @@ + return this.modify(attribute, AttributeModifier.override(), value); + } + ++ public @Nullable Entry get(final EnvironmentAttribute attribute) { ++ @SuppressWarnings("unchecked") ++ var entry = (Entry)this.entries.get(attribute); ++ return entry == null ? null : entry; ++ } ++ + public EnvironmentAttributeMap build() { + return this.entries.isEmpty() ? EnvironmentAttributeMap.EMPTY : new EnvironmentAttributeMap(Map.copyOf(this.entries)); + } +@@ -134,6 +_,11 @@ + + public Value applyModifier(final Value subject) { + return this.modifier.apply(subject, this.argument); ++ } ++ ++ @SuppressWarnings("unchecked") ++ public A cast(AttributeModifier modifier) { ++ return (A)argument; + } + } + } diff --git a/patches/minecraft/net/minecraft/world/clock/ServerClockManager.java.patch b/patches/minecraft/net/minecraft/world/clock/ServerClockManager.java.patch index 1295489d46..ae0d543cab 100644 --- a/patches/minecraft/net/minecraft/world/clock/ServerClockManager.java.patch +++ b/patches/minecraft/net/minecraft/world/clock/ServerClockManager.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/clock/ServerClockManager.java +++ b/net/minecraft/world/clock/ServerClockManager.java -@@ -97,6 +_,12 @@ - return set.booleanValue(); +@@ -101,6 +_,12 @@ + return result.get(); } + public long getTimeMarker(final Holder clock, final ResourceKey timeMarkerId) { diff --git a/patches/minecraft/net/minecraft/world/entity/ConversionTracker.java.patch b/patches/minecraft/net/minecraft/world/entity/ConversionTracker.java.patch new file mode 100644 index 0000000000..43c6b6a6a5 --- /dev/null +++ b/patches/minecraft/net/minecraft/world/entity/ConversionTracker.java.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/world/entity/ConversionTracker.java ++++ b/net/minecraft/world/entity/ConversionTracker.java +@@ -95,10 +_,12 @@ + } + + private void doConversion(final ServerLevel serverLevel) { ++ if (!net.minecraftforge.event.ForgeEventFactory.canLivingConvert(this.mob, this.convertsTo.get(), (timer) -> this.conversionTime = timer)) return; + this.mob.convertTo(this.convertsTo.get(), ConversionParams.single(this.mob, true, true), converted -> { + if (this.postConversionStep != null) { + this.postConversionStep.accept((M)converted, serverLevel); + } ++ net.minecraftforge.event.ForgeEventFactory.onLivingConvert(this.mob, converted); + + if (!converted.isSilent()) { + serverLevel.levelEvent(null, this.conversionSound.get(), converted.blockPosition(), 0); diff --git a/patches/minecraft/net/minecraft/world/entity/Entity.java.patch b/patches/minecraft/net/minecraft/world/entity/Entity.java.patch index 902b817cac..95c43a9a94 100644 --- a/patches/minecraft/net/minecraft/world/entity/Entity.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/Entity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -156,7 +_,9 @@ +@@ -158,7 +_,9 @@ import org.slf4j.Logger; public abstract class Entity @@ -10,16 +10,16 @@ EntityAccess, ScoreHolder, SyncedDataHolder, -@@ -205,6 +_,7 @@ - private static final int MAX_BLOCK_ITERATIONS_ALONG_TRAVEL_PER_TICK = 16; +@@ -209,6 +_,7 @@ private static final double MAX_MOVEMENT_RESETTING_TRACE_DISTANCE = 8.0; + private static final Set> FLUIDS_WITH_CURRENT = Set.of(FluidTags.WATER, FluidTags.LAVA); private static double viewScale = 1.0; + @Deprecated // Forge: Use the getter to allow overriding in mods private final EntityType type; private boolean requiresPrecisePosition; private int id = 0; -@@ -322,6 +_,8 @@ - this.entityData = entityDataBuilder.build(); +@@ -328,6 +_,8 @@ + this.interpolationHandler = this.createInterpolationHandler(); this.setPos(0.0, 0.0, 0.0); this.eyeHeight = this.dimensions.eyeHeight(); + net.minecraftforge.event.ForgeEventFactory.onEntityConstructing(this); @@ -27,7 +27,7 @@ } public boolean isColliding(final BlockPos pos, final BlockState state) { -@@ -429,6 +_,7 @@ +@@ -435,6 +_,7 @@ public void remove(final Entity.RemovalReason reason) { this.setRemoved(reason); @@ -35,7 +35,7 @@ } public void onClientRemoval() { -@@ -548,7 +_,7 @@ +@@ -567,7 +_,7 @@ } if (this.isInLava()) { @@ -44,7 +44,7 @@ } this.checkBelowWorld(); -@@ -1064,9 +_,7 @@ +@@ -1100,9 +_,7 @@ } BlockState belowState = this.level().getBlockState(getOnPos); @@ -55,7 +55,7 @@ ? getOnPos.atY(Mth.floor(this.position.y - offset)) : getOnPos; } else { -@@ -1447,19 +_,19 @@ +@@ -1483,19 +_,19 @@ return !aboveState.is(BlockTags.INSIDE_STEP_SOUND_BLOCKS) && !aboveState.is(BlockTags.COMBINATION_STEP_SOUND_BLOCKS) ? affectingPos : abovePos; } @@ -81,7 +81,7 @@ this.playSound(soundType.getStepSound(), soundType.getVolume() * 0.15F, soundType.getPitch()); } -@@ -1598,6 +_,10 @@ +@@ -1634,6 +_,10 @@ return this.wasTouchingWater; } @@ -92,7 +92,7 @@ private boolean isInRain() { BlockPos pos = this.blockPosition(); return this.level().isRainingAt(pos) || this.level().isRainingAt(BlockPos.containing(pos.getX(), this.getBoundingBox().maxY, pos.getZ())); -@@ -1635,10 +_,10 @@ +@@ -1675,10 +_,10 @@ public void updateSwimming() { if (this.isSwimming()) { @@ -105,7 +105,7 @@ ); } } -@@ -1655,16 +_,7 @@ +@@ -1695,16 +_,7 @@ } this.wasTouchingWater = inWater; @@ -121,9 +121,9 @@ - } + this.fluidInteraction.applyCurrentTo(this); - return inWater || inLava; + return inAnyFluid; } -@@ -1712,12 +_,13 @@ +@@ -1752,12 +_,13 @@ } public boolean canSpawnSprintParticle() { @@ -138,7 +138,7 @@ if (blockState.getRenderShape() != RenderShape.INVISIBLE) { Vec3 movement = this.getDeltaMovement(); BlockPos entityPosition = this.blockPosition(); -@@ -1732,7 +_,7 @@ +@@ -1772,7 +_,7 @@ } this.level() @@ -147,7 +147,7 @@ } } -@@ -2113,6 +_,10 @@ +@@ -2165,6 +_,10 @@ output.putBoolean("HasVisualFire", this.hasVisualFire); } @@ -158,7 +158,7 @@ if (!this.tags.isEmpty()) { output.store("Tags", TAG_LIST_CODEC, List.copyOf(this.tags)); } -@@ -2184,6 +_,9 @@ +@@ -2237,6 +_,9 @@ this.setGlowingTag(input.getBooleanOr("Glowing", false)); this.setTicksFrozen(input.getIntOr("TicksFrozen", 0)); this.hasVisualFire = input.getBooleanOr("HasVisualFire", false); @@ -168,7 +168,7 @@ this.customData = input.read("data", CustomData.CODEC).orElse(CustomData.EMPTY); this.tags.clear(); input.read("Tags", TAG_LIST_CODEC).ifPresent(this.tags::addAll); -@@ -2234,6 +_,8 @@ +@@ -2298,6 +_,8 @@ ItemEntity entity = new ItemEntity(level, this.getX() + offset.x, this.getY() + offset.y, this.getZ() + offset.z, itemStack); entity.setDefaultPickUpDelay(); @@ -177,7 +177,7 @@ level.addFreshEntity(entity); return entity; } -@@ -2291,11 +_,11 @@ +@@ -2355,11 +_,11 @@ } ItemStack heldItem = player.getItemInHand(hand); @@ -191,7 +191,7 @@ && target.canShearEquipment(player) && !player.isSecondaryUseActive() && target.attemptToShearEquipment(player, hand, heldItem)) { -@@ -2379,6 +_,7 @@ +@@ -2443,6 +_,7 @@ public void rideTick() { this.setDeltaMovement(Vec3.ZERO); @@ -199,7 +199,7 @@ this.tick(); if (this.isPassenger()) { this.getVehicle().positionRider(this); -@@ -2444,6 +_,7 @@ +@@ -2508,6 +_,7 @@ } } @@ -207,7 +207,7 @@ if (force || this.canRide(entityToRide) && entityToRide.canAddPassenger(this)) { if (this.isPassenger()) { this.stopRiding(); -@@ -2478,6 +_,7 @@ +@@ -2552,6 +_,7 @@ public void removeVehicle() { if (this.vehicle != null) { Entity oldVehicle = this.vehicle; @@ -215,7 +215,7 @@ this.vehicle = null; oldVehicle.removePassenger(this); Entity.RemovalReason removalReason = this.getRemovalReason(); -@@ -2528,6 +_,8 @@ +@@ -2602,6 +_,8 @@ return this.passengers.isEmpty(); } @@ -224,7 +224,7 @@ protected boolean couldAcceptPassenger() { return true; } -@@ -2724,7 +_,7 @@ +@@ -2816,7 +_,7 @@ } public boolean isVisuallyCrawling() { @@ -233,7 +233,7 @@ } public void setSwimming(final boolean swimming) { -@@ -2840,7 +_,7 @@ +@@ -2932,7 +_,7 @@ this.igniteForSeconds(8.0F); } @@ -242,7 +242,7 @@ } public void onAboveBubbleColumn(final boolean dragDown, final BlockPos pos) { -@@ -2959,7 +_,7 @@ +@@ -3061,7 +_,7 @@ } protected Component getTypeName() { @@ -251,7 +251,7 @@ } public boolean is(final Entity other) { -@@ -3272,6 +_,7 @@ +@@ -3392,6 +_,7 @@ return this.stringUUID; } @@ -259,7 +259,7 @@ public boolean isPushedByFluid() { return true; } -@@ -3682,6 +_,10 @@ +@@ -3813,6 +_,10 @@ return this.fluidInteraction.getFluidHeight(type); } @@ -270,7 +270,7 @@ public double getFluidJumpThreshold() { return this.getEyeHeight() < 0.4 ? 0.0 : 0.4; } -@@ -3694,7 +_,9 @@ +@@ -3825,7 +_,9 @@ return this.dimensions.height(); } @@ -280,7 +280,7 @@ return new ClientboundAddEntityPacket(this, serverEntity); } -@@ -3833,6 +_,11 @@ +@@ -3964,6 +_,11 @@ } } } @@ -292,7 +292,7 @@ } public void checkDespawn() { -@@ -4007,6 +_,83 @@ +@@ -4151,6 +_,83 @@ float xRot = (float)Mth.lerp(alpha, this.getXRot(), targetXRot); this.setPos(x, y, z); this.setRot(yRot, xRot); @@ -334,7 +334,7 @@ + public boolean canTrample(ServerLevel level, BlockState state, BlockPos pos, double fallDistance) { + return level.getRandom().nextFloat() < fallDistance - 0.5F + && this instanceof LivingEntity -+ && (this instanceof Player || net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(level, this)) ++ && (this instanceof Player player ? !level.getServer().isUnderSpawnProtection(level, pos, player) : net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(level, this)) + && this.getBbWidth() * this.getBbWidth() * this.getBbHeight() > 0.512F; + } + diff --git a/patches/minecraft/net/minecraft/world/entity/EntityEquipment.java.patch b/patches/minecraft/net/minecraft/world/entity/EntityEquipment.java.patch index 98afa9846c..48d01e105a 100644 --- a/patches/minecraft/net/minecraft/world/entity/EntityEquipment.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/EntityEquipment.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/EntityEquipment.java +++ b/net/minecraft/world/entity/EntityEquipment.java -@@ -49,7 +_,7 @@ +@@ -50,7 +_,7 @@ for (Entry entry : this.items.entrySet()) { ItemStack item = entry.getValue(); if (!item.isEmpty()) { @@ -9,7 +9,7 @@ } } } -@@ -69,5 +_,9 @@ +@@ -73,5 +_,9 @@ public void clear() { this.items.replaceAll((s, v) -> ItemStack.EMPTY); diff --git a/patches/minecraft/net/minecraft/world/entity/EntityFluidInteraction.java.patch b/patches/minecraft/net/minecraft/world/entity/EntityFluidInteraction.java.patch index 54d1aa113e..c04a4846e0 100644 --- a/patches/minecraft/net/minecraft/world/entity/EntityFluidInteraction.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/EntityFluidInteraction.java.patch @@ -1,118 +1,137 @@ --- a/net/minecraft/world/entity/EntityFluidInteraction.java +++ b/net/minecraft/world/entity/EntityFluidInteraction.java -@@ -21,16 +_,39 @@ +@@ -25,8 +_,20 @@ import org.jspecify.annotations.Nullable; public class EntityFluidInteraction { -+ private static final Map, java.util.function.Supplier> MODDED_TYPES = new java.util.HashMap<>(); -+ public static void register(final TagKey fluid) { -+ register(fluid, EntityFluidInteraction.Tracker::new); ++ private static final Reference2ObjectMap> MODDED_TYPES = new Reference2ObjectArrayMap<>(); ++ public static void register(final net.minecraftforge.fluids.FluidType fluid) { ++ register(fluid, CurrentAccumulator::new); + } -+ public static void register(final TagKey fluid, final java.util.function.Supplier factory) { -+ register(fluid, factory); ++ public static void register(final net.minecraftforge.fluids.FluidType fluid, final java.util.function.Supplier factory) { ++ MODDED_TYPES.put(fluid, factory); + } + - private final Map, EntityFluidInteraction.Tracker> trackerByFluid = new Reference2ObjectArrayMap<>(); -+ private final Map trackerByFluidType = new Reference2ObjectArrayMap(); + private final List fluidTrackers = new ArrayList<>(); ++ private final Reference2ObjectMap fluidTrackersByType = new Reference2ObjectArrayMap<>(); + private final Reference2ObjectMap, EntityFluidInteraction.CurrentAccumulator> currentAccumulators = new Reference2ObjectArrayMap<>(); ++ private final Reference2ObjectMap currentAccumulatorsByType = new Reference2ObjectArrayMap<>(); + private boolean isInFluid = false; + private net.minecraftforge.fluids.FluidType eyeFluid = net.minecraftforge.common.ForgeMod.EMPTY_TYPE.get(); - public EntityFluidInteraction(final Set> fluids) { - for (TagKey fluid : fluids) { - this.trackerByFluid.put(fluid, new EntityFluidInteraction.Tracker()); + public EntityFluidInteraction(final Set> fluidsWithCurrent) { + for (TagKey fluid : fluidsWithCurrent) { +@@ -34,9 +_,19 @@ } -+ for (var entry : MODDED_TYPES.entrySet()) { -+ if (!fluids.contains(entry.getKey())) -+ this.trackerByFluid.put(entry.getKey(), entry.getValue().get()); -+ } -+ } -+ -+ public EntityFluidInteraction.@Nullable Tracker getTracker(final TagKey fluid) { -+ return this.trackerByFluid.get(fluid); } - public void update(final Entity entity, final boolean ignoreCurrent) { - this.trackerByFluid.values().forEach(EntityFluidInteraction.Tracker::reset); -+ this.trackerByFluidType.values().forEach(EntityFluidInteraction.Tracker::reset); ++ public EntityFluidInteraction.@Nullable CurrentAccumulator getAccumulator(final TagKey fluid) { ++ return this.currentAccumulators.get(fluid); ++ } ++ + public boolean update(final Entity entity, final boolean ignoreCurrent) { + this.fluidTrackers.removeIf(EntityFluidInteraction.Tracker::reset); ++ this.fluidTrackersByType.values().removeIf(tracker -> tracker.reset()); + this.currentAccumulators.values().forEach(EntityFluidInteraction.CurrentAccumulator::reset); ++ this.currentAccumulatorsByType.values().removeIf(current -> current.currentCount == 0); ++ this.currentAccumulatorsByType.values().forEach(EntityFluidInteraction.CurrentAccumulator::reset); + this.isInFluid = false; + this.eyeFluid = net.minecraftforge.common.ForgeMod.EMPTY_TYPE.get(); + AABB box = entity.getFluidInteractionBox(); - if (box != null) { - int x0 = Mth.floor(box.minX); -@@ -45,7 +_,7 @@ - double eyeY = entity.getEyeY(); - int eyeBlockZ = entity.getBlockZ(); - Fluid lastFluidType = null; -- EntityFluidInteraction.Tracker tracker = null; -+ EntityFluidInteraction.Tracker[] trackers = null; - BlockGetter level = entity.level(); - BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); + if (box == null) { + return false; +@@ -57,8 +_,8 @@ + double eyeY = entity.getEyeY(); + int eyeBlockZ = entity.getBlockZ(); + Holder lastFluidType = null; +- EntityFluidInteraction.Tracker tracker = null; +- EntityFluidInteraction.CurrentAccumulator current = null; ++ EntityFluidInteraction.Tracker[] trackers = null; ++ EntityFluidInteraction.CurrentAccumulator[] currents = null; + BlockGetter level = entity.level(); + BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); -@@ -55,23 +_,26 @@ - mutablePos.set(x, y, z); - FluidState fluidState = level.getFluidState(mutablePos); - if (!fluidState.isEmpty()) { -+ isInFluid = true; - double fluidBottom = mutablePos.getY(); - double fluidTop = fluidBottom + fluidState.getHeight(level, mutablePos); - if (!(fluidTop < box.minY)) { - Fluid fluidType = fluidState.getType(); - if (fluidType != lastFluidType) { - lastFluidType = fluidType; -- tracker = this.getTrackerFor(fluidType); -+ trackers = this.getTrackersFor(fluidType); - } - -- if (tracker != null) { -+ for (var tracker : trackers) { - if (x == eyeBlockX && z == eyeBlockZ && eyeY >= fluidBottom && eyeY <= fluidTop) { - tracker.eyesInside = true; -+ this.eyeFluid = lastFluidType.getFluidType(); - } - - tracker.height = Math.max(fluidTop - entityY, tracker.height); -- if (!ignoreCurrent) { -- Vec3 flow = fluidState.getFlow(level, mutablePos); -+ if (!ignoreCurrent || !fluidState.getType().getFluidType().canPushEntity(entity)) { -+ Vec3 flow = fluidState.getFlow(level, mutablePos, entity); +@@ -68,17 +_,22 @@ + mutablePos.set(x, y, z); + FluidState fluidState = level.getFluidState(mutablePos); + if (!fluidState.isEmpty()) { ++ isInFluid = true; + double fluidBottom = mutablePos.getY(); + double fluidTop = fluidBottom + fluidState.getHeight(level, mutablePos); + if (!(fluidTop < box.minY)) { + Holder fluidType = fluidState.typeHolder(); + if (fluidType != lastFluidType) { + lastFluidType = fluidType; +- tracker = this.getOrCreateTrackerFor(fluidType); ++ trackers = this.getOrCreateTrackersFor(fluidState); + if (!ignoreCurrent) { +- current = this.getCurrentAccumulatorFor(fluidType); ++ currents = this.getCurrentAccumulatorsFor(fluidState, entity); + } + } + - if (tracker.height < 0.4) { - flow = flow.scale(tracker.height); - } -@@ -118,15 +_,27 @@ - return hasFluid; ++ for (int group = 0; group < trackers.length; group++) { ++ var tracker = trackers[group]; ++ var current = currents == null ? null : currents[group]; + + if (x == eyeBlockX && z == eyeBlockZ && eyeY >= fluidBottom) { + double fluidTopForCamera = fluidBottom + fluidState.getHeightForCamera(level, mutablePos); +@@ -97,6 +_,7 @@ + + current.accumulate(flow); + } ++ } + } + } + } +@@ -148,6 +_,13 @@ + return tracker; } -- private EntityFluidInteraction.@Nullable Tracker getTrackerFor(final Fluid fluid) { -+ private final EntityFluidInteraction.Tracker[] NONE = new EntityFluidInteraction.Tracker[0]; ++ private Tracker[] getOrCreateTrackersFor(final FluidState state) { ++ return new Tracker[] { ++ getOrCreateTrackerFor(state.typeHolder()), ++ this.fluidTrackersByType.computeIfAbsent(state.getFluidType(), _ -> new EntityFluidInteraction.Tracker()) ++ }; ++ } + -+ private EntityFluidInteraction.@Nullable Tracker[] getTrackersFor(final Fluid fluid) { -+ var ret = new java.util.ArrayList(1); - for (Entry, EntityFluidInteraction.Tracker> entry : this.trackerByFluid.entrySet()) { - TagKey tag = entry.getKey(); - if (fluid.is(tag)) { -- return entry.getValue(); -+ ret.add(entry.getValue()); - } - } + private EntityFluidInteraction.@Nullable CurrentAccumulator getCurrentAccumulatorFor(final Holder fluid) { + for (Entry, EntityFluidInteraction.CurrentAccumulator> entry : Reference2ObjectMaps.fastIterable(this.currentAccumulators)) { + if (fluid.is(entry.getKey())) { +@@ -158,6 +_,30 @@ + return null; + } -- return null; -+ ret.add(this.trackerByFluidType.computeIfAbsent(fluid.getFluidType(), k -> new EntityFluidInteraction.Tracker())); -+ return ret.isEmpty() ? NONE : ret.toArray(EntityFluidInteraction.Tracker[]::new); ++ private @Nullable CurrentAccumulator getCurrentAccumulatorFor(final net.minecraftforge.fluids.FluidType fluid) { ++ var ret = this.currentAccumulatorsByType.get(fluid); ++ if (ret == null) { ++ var factory = MODDED_TYPES.get(fluid); ++ if (factory == null) ++ return null; ++ ret = factory.get(); ++ this.currentAccumulatorsByType.put(fluid, ret); ++ } ++ return ret; ++ } ++ ++ private @Nullable CurrentAccumulator[] getCurrentAccumulatorsFor(final FluidState state, final Entity entity) { ++ return new CurrentAccumulator[] { ++ getCurrentAccumulatorFor(state.typeHolder()), ++ entity.isPushedByFluid(state.getFluidType()) ? getCurrentAccumulatorFor(state.getFluidType()) : null ++ }; + } + + public void applyCurrentTo(final Entity entity) { -+ for (var entry : this.trackerByFluidType.entrySet()) { -+ if (!entity.isPushedByFluid(entry.getKey())) -+ continue; -+ entry.getValue().applyCurrentTo(entity, entity.getFluidMotionScale(entry.getKey())); -+ } - } - ++ for (var entry : this.currentAccumulatorsByType.entrySet()) ++ entry.getValue().applyTo(entity, entity.getFluidMotionScale(entry.getKey())); ++ } ++ public void applyCurrentTo(final TagKey fluid, final Entity entity, final double scale) { -@@ -141,6 +_,19 @@ - return tracker != null ? tracker.height : 0.0; + EntityFluidInteraction.CurrentAccumulator current = this.currentAccumulators.get(fluid); + if (current != null) { +@@ -177,6 +_,19 @@ + return height; } + public double getFluidHeight(final Fluid fluid) { @@ -120,7 +139,7 @@ + } + + public double getFluidHeight(final net.minecraftforge.fluids.FluidType fluid) { -+ var tracker = this.trackerByFluidType.get(fluid); ++ var tracker = this.fluidTrackersByType.get(fluid); + return tracker == null ? 0 : tracker.height; + } + @@ -131,18 +150,17 @@ public boolean isInFluid(final TagKey fluid) { return this.getFluidHeight(fluid) > 0.0; } -@@ -148,6 +_,45 @@ - public boolean isEyeInFluid(final TagKey fluid) { - EntityFluidInteraction.Tracker tracker = this.trackerByFluid.get(fluid); - return tracker != null && tracker.eyesInside; -+ } -+ +@@ -191,7 +_,45 @@ + return false; + } + +- private static class CurrentAccumulator { + public boolean isEyeInFluid(final Fluid fluid) { + return isEyeInFluid(fluid.getFluidType()); + } + + public boolean isEyeInFluid(final net.minecraftforge.fluids.FluidType fluid) { -+ var tracker = this.trackerByFluidType.get(fluid); ++ var tracker = this.fluidTrackersByType.get(fluid); + return tracker != null && tracker.eyesInside; + } + @@ -153,8 +171,7 @@ + public net.minecraftforge.fluids.FluidType getMaxHeightFluid() { + var ret = net.minecraftforge.common.ForgeMod.EMPTY_TYPE.get(); + double height = 0; -+ EntityFluidInteraction.Tracker max = null; -+ for (var entry : this.trackerByFluidType.entrySet()) { ++ for (var entry : this.fluidTrackersByType.entrySet()) { + if (entry.getValue().height > height) { + height = entry.getValue().height; + ret = entry.getKey(); @@ -165,7 +182,7 @@ + + public final boolean isInFluid(java.util.function.BiPredicate predicate, boolean forAllTypes) { + boolean match = false; -+ for (var entry : this.trackerByFluidType.entrySet()) { ++ for (var entry : this.fluidTrackersByType.entrySet()) { + if (entry.getValue().height > 0 && predicate.test(entry.getKey(), entry.getValue().height)) { + match = true; + if (!forAllTypes) @@ -174,6 +191,24 @@ + return false; + } + return match; ++ } ++ ++ public static class CurrentAccumulator { + private double height; + private Vec3 accumulatedCurrent = Vec3.ZERO; + private int currentCount; +@@ -229,9 +_,13 @@ } private static class Tracker { +- private final Holder fluidType; ++ private final @Nullable Holder fluidType; + private double height; + private boolean eyesInside; ++ ++ private Tracker() { ++ this.fluidType = null; ++ } + + public Tracker(final Holder fluidType) { + this.fluidType = fluidType; diff --git a/patches/minecraft/net/minecraft/world/entity/EntityType.java.patch b/patches/minecraft/net/minecraft/world/entity/EntityType.java.patch index 1289ce6c6c..7c69990cac 100644 --- a/patches/minecraft/net/minecraft/world/entity/EntityType.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/EntityType.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/world/entity/EntityType.java +++ b/net/minecraft/world/entity/EntityType.java -@@ -73,6 +_,11 @@ - private final FeatureFlagSet requiredFeatures; +@@ -75,6 +_,11 @@ private final boolean allowedInPeaceful; + private final boolean trackDeltas; + private final java.util.function.Predicate> velocityUpdateSupplier; + private final java.util.function.ToIntFunction> trackingRangeSupplier; @@ -12,20 +12,20 @@ public static Identifier getKey(final EntityType type) { return BuiltInRegistries.ENTITY_TYPE.getKey(type); } -@@ -92,7 +_,8 @@ - final String descriptionId, +@@ -95,7 +_,8 @@ final Optional> lootTable, final FeatureFlagSet requiredFeatures, -- final boolean allowedInPeaceful -+ final boolean allowedInPeaceful, + final boolean allowedInPeaceful, +- final boolean trackDeltas ++ final boolean trackDeltas, + final Builder builder ) { this.factory = factory; this.category = category; -@@ -109,6 +_,10 @@ - this.lootTable = lootTable; +@@ -113,6 +_,10 @@ this.requiredFeatures = requiredFeatures; this.allowedInPeaceful = allowedInPeaceful; + this.trackDeltas = trackDeltas; + this.velocityUpdateSupplier = builder == null || builder.velocityUpdateSupplier == null ? EntityType::defaultVelocitySupplier : builder.velocityUpdateSupplier; + this.trackingRangeSupplier = builder == null || builder.trackingRangeSupplier == null ? EntityType::defaultTrackingRangeSupplier : builder.trackingRangeSupplier; + this.updateIntervalSupplier = builder == null || builder.updateIntervalSupplier == null ? EntityType::defaultUpdateIntervalSupplier : builder.updateIntervalSupplier; @@ -33,7 +33,7 @@ } public @Nullable T spawn( -@@ -424,14 +_,26 @@ +@@ -432,14 +_,26 @@ } public int clientTrackingRange() { @@ -52,15 +52,15 @@ return this.updateInterval; } - public boolean trackDeltas() { + public boolean hasUpdateInterval() { + return velocityUpdateSupplier.test(this); + } + + private boolean defaultVelocitySupplier() { - return this != EntityTypes.PLAYER - && this != EntityTypes.LLAMA_SPIT - && this != EntityTypes.WITHER -@@ -466,6 +_,15 @@ + return this.updateInterval != Integer.MAX_VALUE; + } + +@@ -469,6 +_,15 @@ return EntityTypes.OP_ONLY_CUSTOM_DATA.contains(this); } @@ -76,10 +76,10 @@ public static class Builder { private final EntityType.EntityFactory factory; private final MobCategory category; -@@ -485,6 +_,10 @@ - ); +@@ -489,6 +_,10 @@ private final DependantName, String> descriptionId = id -> Util.makeDescriptionId("entity", id.identifier()); private boolean allowedInPeaceful = true; + private boolean trackDeltas = true; + private java.util.function.Predicate> velocityUpdateSupplier = EntityType::defaultVelocitySupplier; + private java.util.function.ToIntFunction> trackingRangeSupplier = EntityType::defaultTrackingRangeSupplier; + private java.util.function.ToIntFunction> updateIntervalSupplier = EntityType::defaultUpdateIntervalSupplier; @@ -87,7 +87,7 @@ private Builder(final EntityType.EntityFactory factory, final MobCategory category) { this.factory = factory; -@@ -603,6 +_,30 @@ +@@ -616,6 +_,30 @@ return this; } @@ -118,12 +118,12 @@ public EntityType build(final ResourceKey> name) { if (this.serialize) { Util.fetchChoiceType(References.ENTITY_TREE, name.identifier().toString()); -@@ -623,7 +_,8 @@ - this.descriptionId.get(name), +@@ -637,7 +_,8 @@ this.lootTable.get(name), this.requiredFeatures, -- this.allowedInPeaceful -+ this.allowedInPeaceful, + this.allowedInPeaceful, +- this.trackDeltas ++ this.trackDeltas, + this ); } diff --git a/patches/minecraft/net/minecraft/world/entity/ExperienceOrb.java.patch b/patches/minecraft/net/minecraft/world/entity/ExperienceOrb.java.patch index 8ae1b260d8..045094baec 100644 --- a/patches/minecraft/net/minecraft/world/entity/ExperienceOrb.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/ExperienceOrb.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ExperienceOrb.java +++ b/net/minecraft/world/entity/ExperienceOrb.java -@@ -136,7 +_,8 @@ +@@ -134,7 +_,8 @@ this.applyEffectsFromBlocks(); float friction = this.getAirDrag(); if (this.onGround()) { @@ -10,7 +10,7 @@ } this.setDeltaMovement(this.getDeltaMovement().scale(friction)); -@@ -282,6 +_,7 @@ +@@ -280,6 +_,7 @@ public void playerTouch(final Player player) { if (player instanceof ServerPlayer serverPlayer) { if (player.takeXpDelay == 0) { diff --git a/patches/minecraft/net/minecraft/world/entity/LightningBolt.java.patch b/patches/minecraft/net/minecraft/world/entity/LightningBolt.java.patch index 2312813865..272c168b58 100644 --- a/patches/minecraft/net/minecraft/world/entity/LightningBolt.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/LightningBolt.java.patch @@ -23,7 +23,7 @@ private void powerLightningRod() { BlockPos strikePosition = this.getStrikePosition(); BlockState stateBelow = this.level().getBlockState(strikePosition); -@@ -150,6 +_,7 @@ +@@ -152,6 +_,7 @@ ); for (Entity entity : entities) { diff --git a/patches/minecraft/net/minecraft/world/entity/LivingEntity.java.patch b/patches/minecraft/net/minecraft/world/entity/LivingEntity.java.patch index 903f63c21f..0b3f161335 100644 --- a/patches/minecraft/net/minecraft/world/entity/LivingEntity.java.patch +++ b/patches/minecraft/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 -@@ -138,7 +_,7 @@ +@@ -143,7 +_,7 @@ import org.jspecify.annotations.Nullable; import org.slf4j.Logger; @@ -9,7 +9,7 @@ private static final Logger LOGGER = LogUtils.getLogger(); private static final String TAG_ACTIVE_EFFECTS = "active_effects"; public static final String TAG_ATTRIBUTES = "attributes"; -@@ -209,6 +_,8 @@ +@@ -214,6 +_,8 @@ public static final float ELYTRA_VERTICAL_AIR_DRAG = 0.98F; public static final float BASE_SWIM_SPEED = 0.02F; private int currentImpulseContextResetGraceTime = 0; @@ -18,7 +18,7 @@ public static final Predicate PLAYER_NOT_WEARING_DISGUISE_ITEM = livingEntity -> { if (livingEntity instanceof Player player) { ItemStack helmet = player.getItemBySlot(EquipmentSlot.HEAD); -@@ -292,7 +_,7 @@ +@@ -293,7 +_,7 @@ this.reapplyPosition(); this.setYRot(this.random.nextFloat() * (float) (Math.PI * 2)); this.yHeadRot = this.getYRot(); @@ -27,7 +27,7 @@ } @Override -@@ -356,7 +_,8 @@ +@@ -357,7 +_,8 @@ .add(Attributes.AIR_DRAG_MODIFIER) .add(Attributes.FRICTION_MODIFIER) .add(Attributes.NAME_TAG_DISTANCE) @@ -37,7 +37,7 @@ } @Override -@@ -383,7 +_,8 @@ +@@ -384,7 +_,8 @@ double scale = Math.min(0.2F + power / 15.0, 2.5); int particles = (int)(150.0 * scale); @@ -47,7 +47,7 @@ } } -@@ -393,6 +_,7 @@ +@@ -394,6 +_,7 @@ } } @@ -55,7 +55,7 @@ public boolean canBreatheUnderwater() { return this.is(EntityTypeTags.CAN_BREATHE_UNDER_WATER); } -@@ -433,6 +_,9 @@ +@@ -438,6 +_,9 @@ } } @@ -65,18 +65,18 @@ if (this.isEyeInFluid(FluidTags.WATER) && !level.getBlockState(BlockPos.containing(this.getX(), this.getEyeY(), this.getZ())).is(Blocks.BUBBLE_COLUMN)) { boolean canDrownInWater = !this.canBreatheUnderwater() -@@ -788,6 +_,9 @@ +@@ -792,6 +_,9 @@ - ItemEntity entity = this.createItemStackToDrop(itemStack, randomly, thrownFromHand); + ItemEntity entity = this.createItemStackToDrop(itemStack, false, thrownFromHand); if (entity != null) { -+ if (captureDrops() != null) -+ captureDrops().add(entity); -+ else ++ if (captureDrops() != null) ++ captureDrops().add(entity); ++ else this.level().addFreshEntity(entity); } -@@ -828,7 +_,7 @@ - this.setPosToBed(sleepingPos); +@@ -824,7 +_,7 @@ + this.stopSleeping(); } }, this::clearSleepingPos); - input.read("Brain", Brain.Packed.CODEC).ifPresent(packedBrain -> this.brain = this.makeBrain(packedBrain)); @@ -84,7 +84,7 @@ this.lastHurtByPlayer = EntityReference.read(input, "last_hurt_by_player"); this.lastHurtByPlayerMemoryTime = input.getIntOr("last_hurt_by_player_memory_time", 0); this.lastHurtByMob = EntityReference.read(input, "last_hurt_by_mob"); -@@ -854,8 +_,10 @@ +@@ -850,8 +_,10 @@ Holder mobEffect = iterator.next(); MobEffectInstance effect = this.activeEffects.get(mobEffect); if (!effect.tickServer(serverLevel, this, () -> this.onEffectUpdated(effect, true, null))) { @@ -95,15 +95,23 @@ } else if (effect.getDuration() % 600 == 0) { this.onEffectUpdated(effect, false, null); } -@@ -942,6 +_,7 @@ +@@ -940,6 +_,7 @@ } } + visibilityPercent = net.minecraftforge.common.ForgeHooks.getEntityVisibilityMultiplier(this, targetingEntity, visibilityPercent); - return visibilityPercent; + return Mth.clamp(visibilityPercent, 0.0, 10.0); } -@@ -1018,6 +_,7 @@ +@@ -961,7 +_,6 @@ + return false; + } + } +- + return true; + } + +@@ -1016,6 +_,7 @@ MobEffectInstance effect = this.activeEffects.get(newEffect.getEffect()); boolean changed = false; @@ -111,7 +119,7 @@ if (effect == null) { this.activeEffects.put(newEffect.getEffect(), newEffect); this.onEffectAdded(newEffect, source); -@@ -1033,6 +_,10 @@ +@@ -1031,6 +_,10 @@ } public boolean canBeAffected(final MobEffectInstance newEffect) { @@ -122,7 +130,7 @@ if (this.is(EntityTypeTags.IMMUNE_TO_INFESTED)) { return !newEffect.is(MobEffects.INFESTED); } else if (this.is(EntityTypeTags.IMMUNE_TO_OOZING)) { -@@ -1063,6 +_,9 @@ +@@ -1061,6 +_,9 @@ } public boolean removeEffect(final Holder effect) { @@ -132,7 +140,7 @@ MobEffectInstance effectInstance = this.removeEffectNoUpdate(effect); if (effectInstance != null) { this.onEffectsRemoved(List.of(effectInstance)); -@@ -1107,6 +_,9 @@ +@@ -1105,6 +_,9 @@ this.effectsDirty = true; for (MobEffectInstance effect : effects) { @@ -142,7 +150,7 @@ effect.getEffect().value().removeAttributeModifiers(this.getAttributes()); for (Entity passenger : this.getPassengers()) { -@@ -1154,9 +_,13 @@ +@@ -1152,9 +_,13 @@ } public void heal(final float heal) { @@ -157,7 +165,7 @@ } } -@@ -1174,6 +_,9 @@ +@@ -1176,6 +_,9 @@ @Override public boolean hurtServer(final ServerLevel level, final DamageSource source, float damage) { @@ -167,7 +175,7 @@ if (this.isInvulnerableTo(level, source)) { return false; } -@@ -1332,6 +_,10 @@ +@@ -1335,6 +_,10 @@ } float damageBlocked = blocksAttacks.resolveBlockedDamage(source, damage, angle); @@ -177,8 +185,8 @@ + if (ev.shieldTakesDamage()) blocksAttacks.hurtBlockingItem(this.level(), blockingWith, this, this.getUsedItemHand(), damageBlocked); if (damageBlocked > 0.0F && !source.is(DamageTypeTags.IS_PROJECTILE) && source.getDirectEntity() instanceof LivingEntity livingEntity) { - this.blockUsingItem(level, livingEntity, source, damage); -@@ -1363,7 +_,7 @@ + this.blockUsingItem(level, livingEntity, source, damage, damageBlocked >= damage); +@@ -1366,7 +_,7 @@ Entity sourceEntity = source.getEntity(); if (sourceEntity instanceof Player playerSource) { this.setLastHurtByPlayer(playerSource, 100); @@ -187,7 +195,7 @@ if (wolf.getOwnerReference() != null) { this.setLastHurtByPlayer(wolf.getOwnerReference().getUUID(), 100); } else { -@@ -1394,7 +_,7 @@ +@@ -1401,7 +_,7 @@ for (InteractionHand hand : InteractionHand.values()) { ItemStack itemStack = this.getItemInHand(hand); protection = itemStack.get(DataComponents.DEATH_PROTECTION); @@ -196,7 +204,7 @@ protectionItem = itemStack.copy(); itemStack.shrink(1); break; -@@ -1449,6 +_,7 @@ +@@ -1456,6 +_,7 @@ } public void die(final DamageSource source) { @@ -204,7 +212,7 @@ if (!this.isRemoved() && !this.dead) { Entity sourceEntity = source.getEntity(); LivingEntity killer = this.getKillCredit(); -@@ -1489,10 +_,10 @@ +@@ -1495,10 +_,10 @@ if (this.level() instanceof ServerLevel serverLevel) { boolean var6 = false; if (killer instanceof WitherBoss) { @@ -214,10 +222,10 @@ BlockState state = Blocks.WITHER_ROSE.defaultBlockState(); - if (this.level().getBlockState(pos).isAir() && state.canSurvive(this.level(), pos)) { + if (this.level().isEmptyBlock(pos) && state.canSurvive(this.level(), pos)) { - this.level().setBlock(pos, state, 3); + this.level().setBlockAndUpdate(pos, state); var6 = true; } -@@ -1507,6 +_,7 @@ +@@ -1513,6 +_,7 @@ } protected void dropAllDeathLoot(final ServerLevel level, final DamageSource source) { @@ -225,7 +233,7 @@ boolean playerKilled = this.lastHurtByPlayerMemoryTime > 0; if (this.shouldDropLoot(level)) { this.dropFromLootTable(level, source, playerKilled); -@@ -1515,6 +_,11 @@ +@@ -1521,6 +_,11 @@ this.dropEquipment(level); this.dropExperience(level, source.getEntity()); @@ -237,7 +245,7 @@ } protected void dropEquipment(final ServerLevel level) { -@@ -1526,7 +_,8 @@ +@@ -1532,7 +_,8 @@ this.isAlwaysExperienceDropper() || this.lastHurtByPlayerMemoryTime > 0 && this.shouldDropExperience() && level.getGameRules().get(GameRules.MOB_DROPS) )) { @@ -247,7 +255,7 @@ } } -@@ -1639,6 +_,11 @@ +@@ -1645,6 +_,11 @@ } public void knockback(double power, double xd, double zd, final DamageSource source, final float damage, final boolean comesFromEffect) { @@ -259,7 +267,7 @@ power *= 1.0 - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE); if (!(power <= 0.0)) { this.needsSync = true; -@@ -1724,6 +_,13 @@ +@@ -1730,6 +_,13 @@ } else { BlockPos ladderCheckPos = this.blockPosition(); BlockState state = this.getInBlockState(); @@ -273,7 +281,7 @@ if (this.isFallFlying() && state.is(BlockTags.CAN_GLIDE_THROUGH)) { return false; } else if (state.is(BlockTags.CLIMBABLE)) { -@@ -1788,9 +_,11 @@ +@@ -1794,9 +_,11 @@ @Override public boolean causeFallDamage(final double fallDistance, final float damageModifier, final DamageSource damageSource) { @@ -286,7 +294,7 @@ boolean hasLandedAboveCurrentImpulseImpactPosY = effectiveFallDistance <= 0.0; if (hasLandedAboveCurrentImpulseImpactPosY) { this.resetCurrentImpulseContext(); -@@ -1798,11 +_,11 @@ +@@ -1804,11 +_,11 @@ this.tryResetCurrentImpulseContext(); } } else { @@ -301,7 +309,7 @@ if (dmg > 0) { this.resetCurrentImpulseContext(); this.playSound(this.getFallDamageSound(dmg), 1.0F, 1.0F); -@@ -1864,9 +_,10 @@ +@@ -1870,9 +_,10 @@ int xx = Mth.floor(this.getX()); int yy = Mth.floor(this.getY() - 0.2F); int zz = Mth.floor(this.getZ()); @@ -314,7 +322,7 @@ this.playSound(soundType.getFallSound(), soundType.getVolume() * 0.5F, soundType.getPitch() * 0.75F); } } -@@ -1927,9 +_,9 @@ +@@ -1933,9 +_,9 @@ float damageResisted = oldDamage - damage; if (damageResisted > 0.0F && damageResisted < 3.4028235E37F) { if (this instanceof ServerPlayer serverPlayer) { @@ -326,7 +334,7 @@ } } } -@@ -1958,6 +_,8 @@ +@@ -1964,6 +_,8 @@ protected void actuallyHurt(final ServerLevel level, final DamageSource source, float dmg) { if (!this.isInvulnerableTo(level, source)) { @@ -335,7 +343,7 @@ dmg = this.getDamageAfterArmorAbsorb(source, dmg); dmg = this.getDamageAfterMagicAbsorb(source, dmg); float originalDamage = dmg; -@@ -1968,6 +_,7 @@ +@@ -1974,6 +_,7 @@ serverPlayer.awardStat(Stats.DAMAGE_DEALT_ABSORBED, Math.round(absorbedDamage * 10.0F)); } @@ -343,16 +351,16 @@ if (dmg != 0.0F) { this.getCombatTracker().recordDamage(source, dmg); this.setHealth(this.getHealth() - dmg); -@@ -2031,6 +_,8 @@ +@@ -2036,6 +_,8 @@ } - public void swing(final InteractionHand hand, final boolean sendToSwingingEntity) { + public boolean swing(final InteractionHand hand, final SwingAnimation animation, final boolean sendToSwingingEntity) { + ItemStack stack = this.getItemInHand(hand); -+ if (!stack.isEmpty() && stack.onEntitySwing(this)) return; - if (!this.swinging || this.swingTime >= this.getCurrentSwingDuration() / 2 || this.swingTime < 0) { - this.swingTime = -1; - this.swinging = true; -@@ -2172,9 +_,10 @@ ++ if (!stack.isEmpty() && stack.onEntitySwing(this)) return false; + if (this.swingState.startIfAble(hand, animation, this.getModifiedSwingDuration(animation))) { + if (this.level() instanceof ServerLevel serverLevel) { + ClientboundSwingAnimationPacket packet = new ClientboundSwingAnimationPacket(this, hand, animation); +@@ -2178,9 +_,10 @@ } private void swapHandItems() { @@ -366,7 +374,7 @@ } @Override -@@ -2396,15 +_,18 @@ +@@ -2387,15 +_,18 @@ } this.needsSync = true; @@ -387,7 +395,7 @@ } protected float getWaterSlowDown() { -@@ -2427,8 +_,9 @@ +@@ -2418,8 +_,9 @@ } public void travel(final Vec3 input) { @@ -399,16 +407,16 @@ } else if (this.isFallFlying()) { this.travelFallFlying(input); } else { -@@ -2441,7 +_,7 @@ +@@ -2432,7 +_,7 @@ } protected boolean shouldTravelInFluid(final FluidState fluidState) { -- return (this.isInWater() || this.isInLava()) && this.isAffectedByFluids() && !this.canStandOnFluid(fluidState); +- return this.isInLiquid() && this.isAffectedByFluids() && !this.canStandOnFluid(fluidState); + return (this.isInWater() || this.isInLava() || this.isInFluidType(fluidState)) && this.isAffectedByFluids() && !this.canStandOnFluid(fluidState); } protected void travelFlying(final Vec3 input, final float speed) { -@@ -2468,7 +_,7 @@ +@@ -2459,7 +_,7 @@ BlockPos posBelow = this.getBlockPosBelowThatAffectsMyMovement(); float blockFriction = this.onGround() ? computeModifiedFriction( @@ -417,7 +425,7 @@ ) : 1.0F; Vec3 movement = this.handleRelativeFrictionAndCalculateMovement(input, blockFriction); -@@ -2500,10 +_,18 @@ +@@ -2491,10 +_,18 @@ return computeModifiedFriction(this.omnidirectionalAirMover() ? 0.91F : 0.98F, (float)this.getAttributeValue(Attributes.AIR_DRAG_MODIFIER)); } @@ -436,8 +444,8 @@ + } else if (this.isInWater()) { this.travelInWater(input, baseGravity, isFalling, oldY); - this.floatInWaterWhileRidden(); -@@ -2529,6 +_,7 @@ + } else { +@@ -2521,6 +_,7 @@ slowDown = 0.96F; } @@ -445,7 +453,7 @@ this.moveRelative(speed, input); this.move(MoverType.SELF, this.getDeltaMovement()); Vec3 movement = this.getDeltaMovement(); -@@ -2706,7 +_,7 @@ +@@ -2701,7 +_,7 @@ double xd = Mth.clamp(delta.x, -0.15F, 0.15F); double zd = Mth.clamp(delta.z, -0.15F, 0.15F); double yd = Math.max(delta.y, -0.15F); @@ -454,7 +462,7 @@ yd = 0.0; } -@@ -2762,6 +_,7 @@ +@@ -2757,6 +_,7 @@ @Override public void tick() { @@ -462,7 +470,7 @@ super.tick(); this.updatingUsingItem(); this.updateSwimAmount(); -@@ -2962,6 +_,7 @@ +@@ -2957,6 +_,7 @@ ItemStack previous = lastEquipmentItems.get(slot); ItemStack current = this.getItemBySlot(slot); if (this.equipmentHasChanged(previous, current)) { @@ -470,7 +478,7 @@ if (changedItems == null) { changedItems = Maps.newEnumMap(EquipmentSlot.class); } -@@ -3097,6 +_,10 @@ +@@ -3094,6 +_,10 @@ profiler.push("jump"); if (this.jumping && this.isAffectedByFluids()) { double fluidHeight; @@ -481,7 +489,7 @@ if (this.isInLava()) { fluidHeight = this.getFluidHeight(FluidTags.LAVA); } else { -@@ -3107,15 +_,19 @@ +@@ -3104,15 +_,19 @@ double fluidJumpThreshold = this.getFluidJumpThreshold(); if (!inWaterAndHasFluidHeight || this.onGround() && !(fluidHeight > fluidJumpThreshold)) { if (!this.isInLava() || this.onGround() && this.isInShallowFluid(FluidTags.LAVA)) { @@ -503,7 +511,7 @@ } } else { this.noJumpDelay = 0; -@@ -3434,8 +_,11 @@ +@@ -3436,8 +_,11 @@ private void updatingUsingItem() { if (this.isUsingItem()) { @@ -516,7 +524,7 @@ this.updateUsingItem(this.useItem); } else { this.stopUsingItem(); -@@ -3478,8 +_,12 @@ +@@ -3480,8 +_,12 @@ } protected void updateUsingItem(final ItemStack useItem) { @@ -530,7 +538,7 @@ this.completeUsingItem(); } } -@@ -3507,8 +_,10 @@ +@@ -3509,8 +_,10 @@ public void startUsingItem(final InteractionHand hand) { ItemStack itemStack = this.getItemInHand(hand); if (!itemStack.isEmpty() && !this.isUsingItem()) { @@ -540,9 +548,9 @@ - this.useItemRemaining = itemStack.getUseDuration(this); + this.useItemRemaining = duration; if (!this.level().isClientSide()) { + this.updatePlayersWithNewEquipment((ServerLevel)this.level(), List.of(Pair.of(hand.asEquipmentSlot(), this.useItem))); this.setLivingEntityFlag(1, true); - this.setLivingEntityFlag(2, hand == InteractionHand.OFF_HAND); -@@ -3566,6 +_,9 @@ +@@ -3569,6 +_,9 @@ p = p.xRot(-this.getXRot() * (float) (Math.PI / 180.0)); p = p.yRot(-this.getYRot() * (float) (Math.PI / 180.0)); p = p.add(this.getX(), this.getEyeY(), this.getZ()); @@ -552,7 +560,7 @@ this.level().addParticle(breakParticle, p.x, p.y, p.z, d.x, d.y + 0.05, d.z); } } -@@ -3578,7 +_,9 @@ +@@ -3581,7 +_,9 @@ this.releaseUsingItem(); } else { if (!this.useItem.isEmpty() && this.isUsingItem()) { @@ -562,7 +570,7 @@ if (result != this.useItem) { this.setItemInHand(hand, result); } -@@ -3612,7 +_,13 @@ +@@ -3615,7 +_,13 @@ ItemStack itemInUsedHand = this.getItemInHand(this.getUsedItemHand()); if (!this.useItem.isEmpty() && ItemStack.isSameItem(itemInUsedHand, this.useItem)) { this.useItem = itemInUsedHand; @@ -576,7 +584,7 @@ if (this.useItem.useOnRelease()) { this.updatingUsingItem(); } -@@ -3622,6 +_,7 @@ +@@ -3625,6 +_,7 @@ } public void stopUsingItem() { @@ -584,37 +592,84 @@ if (!this.level().isClientSide()) { boolean wasUsingItem = this.isUsingItem(); this.recentKineticEnemies = null; -@@ -3783,8 +_,8 @@ - } +@@ -3721,7 +_,9 @@ + } + if (this.canRandomlyTeleportTo(xx, y, zz)) { +- this.teleportTo(xx, y, zz); ++ var event = net.minecraftforge.event.ForgeEventFactory.onEntityRandomTeleport(this, xx, y, zz); ++ if (event == null) return false; ++ this.teleportTo(event.getTargetX(), event.getTargetY(), event.getTargetZ()); + if (showParticles) { + level.broadcastEntityEvent(this, (byte)46); + } +@@ -3804,8 +_,7 @@ + + public boolean startSleeping(final BlockPos bedPosition) { BlockState blockState = this.level().getBlockState(bedPosition); -- if (blockState.getBlock() instanceof BedBlock) { -- this.level().setBlock(bedPosition, blockState.setValue(BedBlock.OCCUPIED, true), 3); -+ if (blockState.isBed(level(), bedPosition, this)) { -+ blockState.setBedOccupied(level(), bedPosition, this, true); - } +- if (blockState.getBlock() instanceof AbstractBedBlock bedBlock) { +- OptionalDouble sleepHeight = bedBlock.getSleepHeight(blockState, this.level(), bedPosition); ++ OptionalDouble sleepHeight = blockState.getBedHeight(this.level(), bedPosition); + if (sleepHeight.isEmpty()) { + return false; + } +@@ -3815,30 +_,23 @@ + } - this.setPose(Pose.SLEEPING); -@@ -3799,15 +_,15 @@ + this.setPosToBed(sleepHeight.getAsDouble(), bedPosition); +- this.level().setBlockAndUpdate(bedPosition, blockState.setValue(BedBlock.OCCUPIED, true)); ++ blockState.setBedOccupied(this.level(), bedPosition, this, true); + this.setPose(Pose.SLEEPING); + this.setSleepingPos(bedPosition); + this.setDeltaMovement(Vec3.ZERO); + this.needsSync = true; + return true; +- } else { +- return false; +- } + } + + private boolean setPosToBed(final BlockPos bedPosition) { + BlockState state = this.level().getBlockState(bedPosition); +- if (state.getBlock() instanceof AbstractBedBlock bedBlock) { +- OptionalDouble sleepHeight = bedBlock.getSleepHeight(state, this.level(), bedPosition); ++ OptionalDouble sleepHeight = state.getBedHeight(this.level(), bedPosition); + if (sleepHeight.isEmpty()) { + return false; + } + + this.setPosToBed(sleepHeight.getAsDouble(), bedPosition); + return true; +- } else { +- return false; +- } + } + + private void setPosToBed(final double sleepHeight, final BlockPos bedPosition) { +@@ -3847,19 +_,15 @@ } private boolean checkBedExists() { -- return this.getSleepingPos().map(bedPosition -> this.level().getBlockState(bedPosition).getBlock() instanceof BedBlock).orElse(false); +- return this.getSleepingPos().map(bedPosition -> { +- BlockState state = this.level().getBlockState(bedPosition); +- return state.getBlock() instanceof AbstractBedBlock bedBlock && bedBlock.getSleepHeight(state, this.level(), bedPosition).isPresent(); +- }).orElse(false); + return this.getSleepingPos().map(bedPosition -> net.minecraftforge.event.ForgeEventFactory.fireSleepingLocationCheck(this, bedPosition)).orElse(false); } public void stopSleeping() { this.getSleepingPos().filter(this.level()::hasChunkAt).ifPresent(bedPosition -> { BlockState state = this.level().getBlockState(bedPosition); -- if (state.getBlock() instanceof BedBlock) { +- if (state.getBlock() instanceof AbstractBedBlock bedBlock) { + if (state.isBed(level(), bedPosition, this)) { Direction facing = state.getValue(BedBlock.FACING); -- this.level().setBlock(bedPosition, state.setValue(BedBlock.OCCUPIED, false), 3); +- this.level().setBlockAndUpdate(bedPosition, state.setValue(BedBlock.OCCUPIED, false)); +- bedBlock.onStopSleeping(this.level(), bedPosition); + state.setBedOccupied(level(), bedPosition, this, false); - Vec3 standUp = BedBlock.findStandUpPosition(this.getType(), this.level(), bedPosition, facing, this.getYRot()).orElseGet(() -> { + Vec3 standUp = AbstractBedBlock.findStandUpPosition(this.getType(), this.level(), bedPosition, facing, this.getYRot()).orElseGet(() -> { BlockPos above = bedPosition.above(); return new Vec3(above.getX() + 0.5, above.getY() + 0.1, above.getZ() + 0.5); -@@ -3827,7 +_,9 @@ +@@ -3879,7 +_,9 @@ public @Nullable Direction getBedOrientation() { BlockPos bedPos = this.getSleepingPos().orElse(null); @@ -625,7 +680,7 @@ } @Override -@@ -3836,7 +_,7 @@ +@@ -3888,7 +_,7 @@ } public ItemStack getProjectile(final ItemStack heldWeapon) { @@ -633,8 +688,8 @@ + return net.minecraftforge.common.ForgeHooks.getProjectile(this, heldWeapon, ItemStack.EMPTY); } - private static byte entityEventForEquipmentBreak(final EquipmentSlot equipmentSlot) { -@@ -3888,6 +_,8 @@ + private static @EntityEvent.Value byte entityEventForEquipmentBreak(final EquipmentSlot equipmentSlot) { +@@ -3940,6 +_,8 @@ } public EquipmentSlot getEquipmentSlotForItem(final ItemStack itemStack) { @@ -643,7 +698,7 @@ Equippable equippable = itemStack.get(DataComponents.EQUIPPABLE); return equippable != null && this.canUseSlot(equippable.slot()) ? equippable.slot() : EquipmentSlot.MAINHAND; } -@@ -4055,5 +_,42 @@ +@@ -4107,6 +_,43 @@ } public record Fallsounds(SoundEvent small, SoundEvent big) { @@ -685,4 +740,5 @@ + super.reviveCaps(); + handlers = net.minecraftforge.items.wrapper.EntityEquipmentInvWrapper.create(this); } - } + + public record SwingDescription(InteractionHand hand, SwingAnimation animation, int durationTicks) { diff --git a/patches/minecraft/net/minecraft/world/entity/Mob.java.patch b/patches/minecraft/net/minecraft/world/entity/Mob.java.patch index 0c49a6994b..df3f7c88c4 100644 --- a/patches/minecraft/net/minecraft/world/entity/Mob.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/Mob.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java -@@ -144,6 +_,9 @@ +@@ -145,6 +_,9 @@ private Leashable.@Nullable LeashData leashData; private BlockPos homePosition = BlockPos.ZERO; private int homeRadius = -1; @@ -10,7 +10,7 @@ protected Mob(final EntityType type, final Level level) { super(type, level); -@@ -249,7 +_,10 @@ +@@ -250,7 +_,10 @@ } public void setTarget(final @Nullable LivingEntity target) { @@ -22,7 +22,7 @@ } @Override -@@ -388,6 +_,10 @@ +@@ -389,6 +_,10 @@ if (this.isNoAi()) { output.putBoolean("NoAI", this.isNoAi()); } @@ -33,7 +33,7 @@ } @Override -@@ -406,6 +_,13 @@ +@@ -407,6 +_,13 @@ this.lootTable = input.read("DeathLootTable", LootTable.KEY_CODEC); this.lootTableSeed = input.getLongOr("DeathLootTableSeed", 0L); this.setNoAi(input.getBooleanOr("NoAI", false)); @@ -47,7 +47,7 @@ } @Override -@@ -464,7 +_,7 @@ +@@ -465,7 +_,7 @@ && this.canPickUpLoot() && this.isAlive() && !this.dead @@ -56,9 +56,9 @@ Vec3i pickupReach = this.getPickupReach(); for (ItemEntity entity : this.level() -@@ -691,6 +_,14 @@ - this.discard(); - } else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) { +@@ -688,6 +_,14 @@ + } else { + boolean isPersistent = this.isPersistenceRequired() || this.requiresCustomPersistence(); Entity player = this.level().getNearestPlayer(this, -1.0); + var result = net.minecraftforge.event.ForgeEventFactory.canEntityDespawn(this, (ServerLevel)this.level()); + if (result.isDenied()) { @@ -71,7 +71,7 @@ if (player != null) { double distSqr = player.distanceToSqr(this); int instantDespawnDistance = this.getType().getCategory().getDespawnDistance(); -@@ -1084,6 +_,16 @@ +@@ -1083,6 +_,16 @@ } } @@ -88,7 +88,7 @@ public @Nullable SpawnGroupData finalizeSpawn( final ServerLevelAccessor level, final DifficultyInstance difficulty, final EntitySpawnReason spawnReason, final @Nullable SpawnGroupData groupData ) { -@@ -1096,6 +_,7 @@ +@@ -1095,6 +_,7 @@ } this.setLeftHanded(random.nextFloat() < 0.05F); @@ -96,7 +96,7 @@ return groupData; } -@@ -1409,15 +_,25 @@ +@@ -1408,15 +_,25 @@ return wasHurt; } @@ -123,7 +123,7 @@ @VisibleForTesting public void removeFreeWill() { this.removeAllGoals(goal -> true); -@@ -1449,6 +_,41 @@ +@@ -1448,6 +_,41 @@ @Override public @Nullable ItemStack getPickResult() { return SpawnEggItem.byId(this.getType()).map(ItemStack::new).orElse(null); diff --git a/patches/minecraft/net/minecraft/world/entity/ai/behavior/Swim.java.patch b/patches/minecraft/net/minecraft/world/entity/ai/behavior/Swim.java.patch index 62c54642c5..a1f68770fc 100644 --- a/patches/minecraft/net/minecraft/world/entity/ai/behavior/Swim.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/ai/behavior/Swim.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/entity/ai/behavior/Swim.java +++ b/net/minecraft/world/entity/ai/behavior/Swim.java -@@ -14,7 +_,7 @@ - } - - public static boolean shouldSwim(final T mob) { -- return mob.isInWater() && mob.getFluidHeight(FluidTags.WATER) > mob.getFluidJumpThreshold() || mob.isInLava(); -+ return mob.isInWater() && mob.getFluidHeight(FluidTags.WATER) > mob.getFluidJumpThreshold() || mob.isInLava() || mob.isInFluidType((fluidType, height) -> mob.canSwimInFluidType(fluidType) && height > mob.getFluidJumpThreshold()); +@@ -22,7 +_,7 @@ } protected boolean checkExtraStartConditions(final ServerLevel level, final Mob body) { +- return body.isInFluidDeeperThan(body.getFluidJumpThreshold(), this.fluid) || body.isInLava(); ++ return body.isInFluidDeeperThan(body.getFluidJumpThreshold(), this.fluid) || body.isInLava() || body.isInFluidType((fluidType, height) -> body.canSwimInFluidType(fluidType) && height > body.getFluidJumpThreshold()); + } + + protected boolean canStillUse(final ServerLevel level, final Mob body, final long timestamp) { diff --git a/patches/minecraft/net/minecraft/world/entity/ai/goal/FloatGoal.java.patch b/patches/minecraft/net/minecraft/world/entity/ai/goal/FloatGoal.java.patch index 89c81c80e2..e0d746b20c 100644 --- a/patches/minecraft/net/minecraft/world/entity/ai/goal/FloatGoal.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/ai/goal/FloatGoal.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/entity/ai/goal/FloatGoal.java +++ b/net/minecraft/world/entity/ai/goal/FloatGoal.java -@@ -15,7 +_,7 @@ +@@ -23,7 +_,7 @@ @Override public boolean canUse() { -- return this.mob.isInWater() && this.mob.getFluidHeight(FluidTags.WATER) > this.mob.getFluidJumpThreshold() || this.mob.isInLava(); -+ return this.mob.isInWater() && this.mob.getFluidHeight(FluidTags.WATER) > this.mob.getFluidJumpThreshold() || this.mob.isInLava() || this.mob.isInFluidType((fluidType, height) -> this.mob.canSwimInFluidType(fluidType) && height > this.mob.getFluidJumpThreshold()); +- return this.mob.isInFluidDeeperThan(this.mob.getFluidJumpThreshold(), this.fluid) || this.mob.isInLava(); ++ return this.mob.isInFluidDeeperThan(this.mob.getFluidJumpThreshold(), this.fluid) || this.mob.isInLava() || this.mob.isInFluidType((fluidType, height) -> this.mob.canSwimInFluidType(fluidType) && height > this.mob.getFluidJumpThreshold()); } @Override diff --git a/patches/minecraft/net/minecraft/world/entity/ai/navigation/PathNavigation.java.patch b/patches/minecraft/net/minecraft/world/entity/ai/navigation/PathNavigation.java.patch index 2864829c1b..6eeccc8170 100644 --- a/patches/minecraft/net/minecraft/world/entity/ai/navigation/PathNavigation.java.patch +++ b/patches/minecraft/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 -@@ -248,12 +_,13 @@ +@@ -252,12 +_,13 @@ Vec3 mobPos = this.getTempMobPos(); this.maxDistanceToWaypoint = this.mob.getBbWidth() > 0.75F ? this.mob.getBbWidth() / 2.0F : 0.75F - this.mob.getBbWidth() / 2.0F; Vec3i currentNodePos = this.path.getNextNodePos(); diff --git a/patches/minecraft/net/minecraft/world/entity/animal/Animal.java.patch b/patches/minecraft/net/minecraft/world/entity/animal/Animal.java.patch index 62dbc2071d..54f75c10a0 100644 --- a/patches/minecraft/net/minecraft/world/entity/animal/Animal.java.patch +++ b/patches/minecraft/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 -@@ -208,6 +_,17 @@ +@@ -209,6 +_,17 @@ public void spawnChildFromBreeding(final ServerLevel level, final Animal partner) { AgeableMob offspring = this.getBreedOffspring(level, partner); diff --git a/patches/minecraft/net/minecraft/world/entity/animal/allay/Allay.java.patch b/patches/minecraft/net/minecraft/world/entity/animal/allay/Allay.java.patch index 1b8ffb5728..0a9092a63d 100644 --- a/patches/minecraft/net/minecraft/world/entity/animal/allay/Allay.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/animal/allay/Allay.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/allay/Allay.java +++ b/net/minecraft/world/entity/animal/allay/Allay.java -@@ -341,7 +_,7 @@ +@@ -342,7 +_,7 @@ public boolean wantsToPickUp(final ServerLevel level, final ItemStack itemStack) { ItemStack itemInHand = this.getItemInHand(InteractionHand.MAIN_HAND); return !itemInHand.isEmpty() diff --git a/patches/minecraft/net/minecraft/world/entity/animal/bee/Bee.java.patch b/patches/minecraft/net/minecraft/world/entity/animal/bee/Bee.java.patch index c9f7edb036..69632ebd8f 100644 --- a/patches/minecraft/net/minecraft/world/entity/animal/bee/Bee.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/animal/bee/Bee.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/bee/Bee.java +++ b/net/minecraft/world/entity/animal/bee/Bee.java -@@ -473,7 +_,9 @@ +@@ -474,7 +_,9 @@ if (this.hivePos == null) { return null; } else { @@ -11,7 +11,7 @@ } } -@@ -639,13 +_,22 @@ +@@ -640,13 +_,22 @@ } @Override diff --git a/patches/minecraft/net/minecraft/world/entity/animal/cow/MushroomCow.java.patch b/patches/minecraft/net/minecraft/world/entity/animal/cow/MushroomCow.java.patch index 9bb7975d6a..7e2f239e8d 100644 --- a/patches/minecraft/net/minecraft/world/entity/animal/cow/MushroomCow.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/animal/cow/MushroomCow.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/cow/MushroomCow.java +++ b/net/minecraft/world/entity/animal/cow/MushroomCow.java -@@ -122,7 +_,7 @@ +@@ -123,7 +_,7 @@ this.playSound(milkSound, 1.0F, 1.0F); return InteractionResult.SUCCESS; @@ -9,7 +9,7 @@ if (this.level() instanceof ServerLevel level) { this.shear(level, SoundSource.PLAYERS, itemStack); this.gameEvent(GameEvent.SHEAR, player); -@@ -178,6 +_,8 @@ +@@ -186,6 +_,8 @@ @Override public void shear(final ServerLevel level, final SoundSource soundSource, final ItemStack tool) { @@ -18,7 +18,7 @@ level.playSound(null, this, SoundEvents.MOOSHROOM_SHEAR, soundSource, 1.0F, 1.0F); this.convertTo(EntityTypes.COW, ConversionParams.single(this, false, false), cow -> { level.sendParticles(ParticleTypes.EXPLOSION, this.getX(), this.getY(0.5), this.getZ(), 1, 0.0, 0.0, 0.0, 0.0); -@@ -186,6 +_,7 @@ +@@ -194,6 +_,7 @@ l.addFreshEntity(new ItemEntity(this.level(), this.getX(), this.getY(1.0), this.getZ(), drop.copyWithCount(1))); } }); diff --git a/patches/minecraft/net/minecraft/world/entity/animal/equine/AbstractHorse.java.patch b/patches/minecraft/net/minecraft/world/entity/animal/equine/AbstractHorse.java.patch index de0805d2b9..60c14ed233 100644 --- a/patches/minecraft/net/minecraft/world/entity/animal/equine/AbstractHorse.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/animal/equine/AbstractHorse.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/equine/AbstractHorse.java +++ b/net/minecraft/world/entity/animal/equine/AbstractHorse.java -@@ -142,6 +_,7 @@ +@@ -143,6 +_,7 @@ } this.addBehaviourGoals(); @@ -8,7 +8,7 @@ } protected void addBehaviourGoals() { -@@ -277,17 +_,20 @@ +@@ -278,17 +_,20 @@ @Override public boolean causeFallDamage(final double fallDistance, final float damageModifier, final DamageSource damageSource) { @@ -32,7 +32,7 @@ this.playBlockFallSound(); return true; } -@@ -342,9 +_,9 @@ +@@ -343,9 +_,9 @@ protected void playStepSound(final BlockPos pos, final BlockState blockState) { if (!blockState.liquid()) { BlockState aboveState = this.level().getBlockState(pos.above()); @@ -44,7 +44,7 @@ } if (this.isVehicle() && this.canGallop) { -@@ -778,6 +_,7 @@ +@@ -779,6 +_,7 @@ float cos = Mth.cos(this.getYRot() * (float) (Math.PI / 180.0)); this.setDeltaMovement(this.getDeltaMovement().add(-0.4F * sin * amount, 0.0, 0.4F * cos * amount)); } @@ -52,7 +52,7 @@ } protected void playJumpSound() { -@@ -1028,6 +_,26 @@ +@@ -1029,6 +_,26 @@ public boolean hasInventoryChanged(final Container oldInventory) { return this.inventory != oldInventory; diff --git a/patches/minecraft/net/minecraft/world/entity/animal/equine/SkeletonTrapGoal.java.patch b/patches/minecraft/net/minecraft/world/entity/animal/equine/SkeletonTrapGoal.java.patch index 8fed45b75d..5ad7099cfd 100644 --- a/patches/minecraft/net/minecraft/world/entity/animal/equine/SkeletonTrapGoal.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/animal/equine/SkeletonTrapGoal.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/equine/SkeletonTrapGoal.java +++ b/net/minecraft/world/entity/animal/equine/SkeletonTrapGoal.java -@@ -31,6 +_,13 @@ +@@ -32,6 +_,13 @@ @Override public void tick() { ServerLevel level = (ServerLevel)this.horse.level(); diff --git a/patches/minecraft/net/minecraft/world/entity/animal/feline/Ocelot.java.patch b/patches/minecraft/net/minecraft/world/entity/animal/feline/Ocelot.java.patch index a7507eaadc..36869cf565 100644 --- a/patches/minecraft/net/minecraft/world/entity/animal/feline/Ocelot.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/animal/feline/Ocelot.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/feline/Ocelot.java +++ b/net/minecraft/world/entity/animal/feline/Ocelot.java -@@ -168,7 +_,7 @@ +@@ -169,7 +_,7 @@ if ((this.temptGoal == null || this.temptGoal.isRunning()) && !this.isTrusting() && this.isFood(itemStack) && player.distanceToSqr(this) < 9.0) { this.usePlayerItem(player, hand, itemStack); if (!this.level().isClientSide()) { diff --git a/patches/minecraft/net/minecraft/world/entity/animal/fox/Fox.java.patch b/patches/minecraft/net/minecraft/world/entity/animal/fox/Fox.java.patch index fd188324e4..f7f2721fcc 100644 --- a/patches/minecraft/net/minecraft/world/entity/animal/fox/Fox.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/animal/fox/Fox.java.patch @@ -31,8 +31,8 @@ @Override public boolean canUse() { -- return Fox.this.isInWater() && Fox.this.getFluidHeight(FluidTags.WATER) > 0.25 || Fox.this.isInLava(); -+ return Fox.this.isInWater() && Fox.this.getFluidHeight(FluidTags.WATER) > 0.25 || Fox.this.isInLava() || Fox.this.isInFluidType((fluidType, height) -> Fox.this.canSwimInFluidType(fluidType) && height > 0.25D); +- return Fox.this.isInFluidDeeperThan(0.25, this.fluid) || Fox.this.isInLava(); ++ return Fox.this.isInFluidDeeperThan(0.25, this.fluid) || Fox.this.isInLava() || Fox.this.isInFluidType((fluidType, height) -> Fox.this.canSwimInFluidType(fluidType) && height > 0.25D); } } diff --git a/patches/minecraft/net/minecraft/world/entity/animal/golem/SnowGolem.java.patch b/patches/minecraft/net/minecraft/world/entity/animal/golem/SnowGolem.java.patch index cf1375a26d..3b4177e3f1 100644 --- a/patches/minecraft/net/minecraft/world/entity/animal/golem/SnowGolem.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/animal/golem/SnowGolem.java.patch @@ -18,7 +18,7 @@ this.level().setBlockAndUpdate(snowPos, snow); this.level().gameEvent(GameEvent.BLOCK_PLACE, snowPos, GameEvent.Context.of(this, snow)); } -@@ -136,7 +_,7 @@ +@@ -141,7 +_,7 @@ @Override protected InteractionResult mobInteract(final Player player, final InteractionHand hand) { ItemStack itemStack = player.getItemInHand(hand); diff --git a/patches/minecraft/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch b/patches/minecraft/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch index a855468db0..112bce3741 100644 --- a/patches/minecraft/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/animal/rabbit/Rabbit.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/rabbit/Rabbit.java +++ b/net/minecraft/world/entity/animal/rabbit/Rabbit.java -@@ -603,7 +_,7 @@ +@@ -604,7 +_,7 @@ @Override public boolean canUse() { if (this.nextStartTick <= 0) { @@ -9,7 +9,7 @@ return false; } -@@ -652,7 +_,7 @@ +@@ -653,7 +_,7 @@ @Override protected boolean isValidTarget(final LevelReader level, final BlockPos pos) { BlockState state = level.getBlockState(pos); diff --git a/patches/minecraft/net/minecraft/world/entity/animal/sheep/Sheep.java.patch b/patches/minecraft/net/minecraft/world/entity/animal/sheep/Sheep.java.patch index 7d90cbab8d..6a1892afc5 100644 --- a/patches/minecraft/net/minecraft/world/entity/animal/sheep/Sheep.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/animal/sheep/Sheep.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/sheep/Sheep.java +++ b/net/minecraft/world/entity/animal/sheep/Sheep.java -@@ -145,7 +_,7 @@ +@@ -146,7 +_,7 @@ @Override public InteractionResult mobInteract(final Player player, final InteractionHand hand) { ItemStack itemStack = player.getItemInHand(hand); diff --git a/patches/minecraft/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch b/patches/minecraft/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch index 588a18f224..bfc786fde0 100644 --- a/patches/minecraft/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/entity/animal/sniffer/Sniffer.java +++ b/net/minecraft/world/entity/animal/sniffer/Sniffer.java -@@ -308,7 +_,7 @@ +@@ -306,7 +_,7 @@ + } + if (this.tickCount % 10 == 0) { - this.level() - .playLocalSound( -- this.getX(), this.getY(), this.getZ(), stateBelow.getSoundType().getHitSound(), this.getSoundSource(), 0.5F, 0.5F, false -+ this.getX(), this.getY(), this.getZ(), stateBelow.getSoundType(level(), head.below(), this).getHitSound(), this.getSoundSource(), 0.5F, 0.5F, false - ); +- this.level().playLocalSound(this, stateBelow.getSoundType().getHitSound(), this.getSoundSource(), 0.5F, 0.5F); ++ this.level().playLocalSound(this, stateBelow.getSoundType(this.level(), head.below(), this).getHitSound(), this.getSoundSource(), 0.5F, 0.5F); } } + } diff --git a/patches/minecraft/net/minecraft/world/entity/animal/wolf/Wolf.java.patch b/patches/minecraft/net/minecraft/world/entity/animal/wolf/Wolf.java.patch index 735cb4dd6e..050d4f4d7a 100644 --- a/patches/minecraft/net/minecraft/world/entity/animal/wolf/Wolf.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/animal/wolf/Wolf.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/wolf/Wolf.java +++ b/net/minecraft/world/entity/animal/wolf/Wolf.java -@@ -506,7 +_,7 @@ +@@ -507,7 +_,7 @@ } private void tryToTame(final Player player) { diff --git a/patches/minecraft/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch b/patches/minecraft/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch index 3d2e4e1e57..a9fc8f5ae3 100644 --- a/patches/minecraft/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch @@ -27,7 +27,7 @@ this.processFlappingMovement(); if (this.level().isClientSide()) { this.setHealth(this.getHealth()); -@@ -436,7 +_,7 @@ +@@ -437,7 +_,7 @@ BlockPos blockPos = new BlockPos(x, y, z); BlockState state = level.getBlockState(blockPos); if (!state.isAir() && !state.is(BlockTags.DRAGON_TRANSPARENT)) { @@ -36,7 +36,7 @@ destroyedBlock = level.removeBlock(blockPos, false) || destroyedBlock; } else { hitWall = true; -@@ -540,7 +_,8 @@ +@@ -541,7 +_,8 @@ if (this.level() instanceof ServerLevel level) { if (this.dragonDeathTime > 150 && this.dragonDeathTime % 5 == 0 && level.getGameRules().get(GameRules.MOB_DROPS)) { @@ -46,7 +46,7 @@ } if (this.dragonDeathTime == 1 && !this.isSilent()) { -@@ -558,7 +_,8 @@ +@@ -559,7 +_,8 @@ if (this.dragonDeathTime >= 200 && this.level() instanceof ServerLevel level) { if (level.getGameRules().get(GameRules.MOB_DROPS)) { @@ -56,7 +56,7 @@ } if (this.dragonFight != null) { -@@ -884,5 +_,15 @@ +@@ -885,6 +_,16 @@ @Override protected float sanitizeScale(final float scale) { return 1.0F; @@ -71,4 +71,5 @@ + public net.minecraftforge.entity.PartEntity[] getParts() { + return this.subEntities; } - } + + @Override diff --git a/patches/minecraft/net/minecraft/world/entity/decoration/HangingEntity.java.patch b/patches/minecraft/net/minecraft/world/entity/decoration/HangingEntity.java.patch index 50e6838a1e..3ed9340ce1 100644 --- a/patches/minecraft/net/minecraft/world/entity/decoration/HangingEntity.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/decoration/HangingEntity.java.patch @@ -1,11 +1,13 @@ --- a/net/minecraft/world/entity/decoration/HangingEntity.java +++ b/net/minecraft/world/entity/decoration/HangingEntity.java -@@ -86,6 +_,8 @@ +@@ -84,7 +_,9 @@ + return false; + } - boolean isSupported = BlockPos.betweenClosedStream(this.calculateSupportBox()).allMatch(pos -> { - BlockState state = this.level().getBlockState(pos); -+ if (net.minecraft.world.level.block.Block.canSupportCenter(this.level(), pos, this.getDirection())) -+ return true; - return state.isSolid() || DiodeBlock.isDiode(state); - }); +- boolean isSupported = this.level().findBlocksIn(this.calculateSupportBox()).filterState(HangingEntity::isSupportingBlock).allMatched(); ++ boolean isSupported = !this.level().findBlocksIn(this.calculateSupportBox()).forEachUntil((pos, state) -> ++ net.minecraft.util.Continuation.continueIf(isSupportingBlock(state) || net.minecraft.world.level.block.Block.canSupportCenter(this.level(), pos, this.getDirection())) ++ ); return isSupported && this.canCoexist(false); + } + diff --git a/patches/minecraft/net/minecraft/world/entity/item/FallingBlockEntity.java.patch b/patches/minecraft/net/minecraft/world/entity/item/FallingBlockEntity.java.patch index 9db3602906..7cb7861135 100644 --- a/patches/minecraft/net/minecraft/world/entity/item/FallingBlockEntity.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/item/FallingBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/net/minecraft/world/entity/item/FallingBlockEntity.java -@@ -158,7 +_,7 @@ +@@ -160,7 +_,7 @@ if (this.level() instanceof ServerLevel serverLevel && (this.isAlive() || this.forceTickAfterTeleportToDuplicate)) { BlockPos pos = this.blockPosition(); boolean isConcrete = this.blockState.getBlock() instanceof ConcretePowderBlock; @@ -9,7 +9,7 @@ double moveVec = this.getDeltaMovement().lengthSqr(); if (isConcrete && moveVec > 1.0) { BlockHitResult clip = this.level() -@@ -167,7 +_,7 @@ +@@ -169,7 +_,7 @@ new Vec3(this.xo, this.yo, this.zo), this.position(), ClipContext.Block.COLLIDER, ClipContext.Fluid.SOURCE_ONLY, this ) ); diff --git a/patches/minecraft/net/minecraft/world/entity/item/ItemEntity.java.patch b/patches/minecraft/net/minecraft/world/entity/item/ItemEntity.java.patch index 8098c345f0..ef65994883 100644 --- a/patches/minecraft/net/minecraft/world/entity/item/ItemEntity.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/item/ItemEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/item/ItemEntity.java +++ b/net/minecraft/world/entity/item/ItemEntity.java -@@ -52,6 +_,10 @@ +@@ -53,6 +_,10 @@ private @Nullable EntityReference thrower; private @Nullable UUID target; public final float bobOffs = this.random.nextFloat() * (float) Math.PI * 2.0F; @@ -11,7 +11,7 @@ public ItemEntity(final EntityType type, final Level level) { super(type, level); -@@ -79,6 +_,7 @@ +@@ -80,6 +_,7 @@ this.setPos(x, y, z); this.setItem(itemStack); this.setDeltaMovement(deltaX, deltaY, deltaZ); @@ -19,7 +19,7 @@ } @Override -@@ -116,6 +_,7 @@ +@@ -117,6 +_,7 @@ @Override public void tick() { @@ -27,7 +27,7 @@ if (this.getItem().isEmpty()) { this.discard(); } else { -@@ -128,6 +_,10 @@ +@@ -129,6 +_,10 @@ this.yo = this.getY(); this.zo = this.getZ(); Vec3 oldMovement = this.getDeltaMovement(); @@ -38,7 +38,7 @@ if (this.isInWater() && this.getFluidHeight(FluidTags.WATER) > 0.1F) { this.setUnderwaterMovement(); } else if (this.isInLava() && this.getFluidHeight(FluidTags.LAVA) > 0.1F) { -@@ -153,7 +_,8 @@ +@@ -154,7 +_,8 @@ float airDrag = this.getAirDrag(); float groundFriction = airDrag; if (this.onGround()) { @@ -48,7 +48,7 @@ } this.setDeltaMovement(this.getDeltaMovement().multiply(groundFriction, airDrag, groundFriction)); -@@ -185,7 +_,16 @@ +@@ -186,7 +_,16 @@ } } @@ -66,7 +66,7 @@ this.discard(); } } -@@ -300,7 +_,7 @@ +@@ -301,7 +_,7 @@ this.health = (int)(this.health - damage); this.gameEvent(GameEvent.ENTITY_DAMAGE, source.getEntity()); if (this.health <= 0) { @@ -75,7 +75,7 @@ this.discard(); } -@@ -317,6 +_,7 @@ +@@ -318,6 +_,7 @@ output.putShort("Health", (short)this.health); output.putShort("Age", (short)this.age); output.putShort("PickupDelay", (short)this.pickupDelay); @@ -83,7 +83,7 @@ EntityReference.store(this.thrower, output, "Thrower"); output.storeNullable("Owner", UUIDUtil.CODEC, this.target); if (!this.getItem().isEmpty()) { -@@ -329,6 +_,7 @@ +@@ -330,6 +_,7 @@ this.health = input.getShortOr("Health", (short)5); this.age = input.getShortOr("Age", (short)0); this.pickupDelay = input.getShortOr("PickupDelay", (short)0); @@ -91,7 +91,7 @@ this.target = input.read("Owner", UUIDUtil.CODEC).orElse(null); this.thrower = EntityReference.read(input, "Thrower"); this.setItem(input.read("Item", ItemStack.CODEC).orElse(ItemStack.EMPTY)); -@@ -340,10 +_,17 @@ +@@ -341,10 +_,17 @@ @Override public void playerTouch(final Player player) { if (!this.level().isClientSide()) { @@ -110,7 +110,7 @@ player.take(this, orgCount); if (itemStack.isEmpty()) { this.discard(); -@@ -427,7 +_,7 @@ +@@ -428,7 +_,7 @@ public void makeFakeItem() { this.setNeverPickUp(); diff --git a/patches/minecraft/net/minecraft/world/entity/monster/CrossbowAttackMob.java.patch b/patches/minecraft/net/minecraft/world/entity/monster/CrossbowAttackMob.java.patch index dd11a4d067..1b3bcd09fd 100644 --- a/patches/minecraft/net/minecraft/world/entity/monster/CrossbowAttackMob.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/monster/CrossbowAttackMob.java.patch @@ -10,6 +10,6 @@ - if (usedItem.getItem() instanceof CrossbowItem crossbow) { + if (body.isHolding(is -> is.getItem() instanceof CrossbowItem)) { + var crossbow = (CrossbowItem) usedItem.getItem(); - crossbow.performShooting(body.level(), body, hand, usedItem, crossbowPower, 14 - body.level().getDifficulty().getId() * 4, this.getTarget()); + crossbow.performShooting(body.level(), body, hand, usedItem, crossbowPower, this.rangedAttackUncertainty(body.level()), this.getTarget()); } diff --git a/patches/minecraft/net/minecraft/world/entity/monster/EnderMan.java.patch b/patches/minecraft/net/minecraft/world/entity/monster/EnderMan.java.patch index f905ee625d..1dd5ab5e30 100644 --- a/patches/minecraft/net/minecraft/world/entity/monster/EnderMan.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/monster/EnderMan.java.patch @@ -1,6 +1,6 @@ ---- a/net/minecraft/world/entity/monster/EnderMan.java -+++ b/net/minecraft/world/entity/monster/EnderMan.java -@@ -121,7 +_,6 @@ +--- a/net/minecraft/world/entity/monster/Enderman.java ++++ b/net/minecraft/world/entity/monster/Enderman.java +@@ -124,7 +_,6 @@ @Override public void setTarget(final @Nullable LivingEntity target) { @@ -8,7 +8,7 @@ AttributeInstance movementSpeed = this.getAttribute(Attributes.MOVEMENT_SPEED); if (target == null) { this.targetChangeTime = 0; -@@ -135,6 +_,7 @@ +@@ -138,6 +_,7 @@ movementSpeed.addTransientModifier(SPEED_MODIFIER_ATTACKING); } } @@ -16,7 +16,7 @@ } @Override -@@ -207,7 +_,7 @@ +@@ -210,7 +_,7 @@ } private boolean isBeingStaredBy(final Player player) { @@ -25,19 +25,7 @@ } @Override -@@ -285,8 +_,10 @@ - boolean couldStandOn = blockState.blocksMotion(); - boolean isWet = blockState.getFluidState().is(FluidTags.WATER); - if (couldStandOn && !isWet) { -+ var event = net.minecraftforge.event.ForgeEventFactory.onEnderManTeleport(this, x, y, z); -+ if (event == null) return false; - Vec3 oldPos = this.position(); -- boolean result = this.randomTeleport(x, y, z, true); -+ boolean result = this.randomTeleport(event.getTargetX(), event.getTargetY(), event.getTargetZ(), true); - if (result) { - this.level().gameEvent(GameEvent.TELEPORT, oldPos, GameEvent.Context.of(this)); - if (!this.isSilent()) { -@@ -441,7 +_,7 @@ +@@ -461,7 +_,7 @@ if (this.enderman.getCarriedBlock() == null) { return false; } else { @@ -46,16 +34,16 @@ ? false : this.enderman.getRandom().nextInt(reducedTickDelay(2000)) == 0; } -@@ -461,7 +_,7 @@ +@@ -481,7 +_,7 @@ BlockState carried = this.enderman.getCarriedBlock(); if (carried != null) { carried = Block.updateFromNeighbourShapes(carried, this.enderman.level(), pos); - if (this.canPlaceBlock(level, pos, carried, targetState, belowState, below)) { + if (this.canPlaceBlock(level, pos, carried, targetState, belowState, below) && !net.minecraftforge.event.ForgeEventFactory.onBlockPlace(enderman, net.minecraftforge.common.util.BlockSnapshot.create(level.dimension(), level, below), net.minecraft.core.Direction.UP)) { - level.setBlock(pos, carried, 3); + level.setBlockAndUpdate(pos, carried); level.gameEvent(GameEvent.BLOCK_PLACE, pos, GameEvent.Context.of(this.enderman, carried)); this.enderman.setCarriedBlock(null); -@@ -475,6 +_,7 @@ +@@ -495,6 +_,7 @@ return targetState.isAir() && !belowState.isAir() && !belowState.is(Blocks.BEDROCK) @@ -63,7 +51,7 @@ && belowState.isCollisionShapeFullBlock(level, below) && carried.canSurvive(level, pos) && level.getEntities(this.enderman, AABB.unitCubeFromLowerCorner(Vec3.atLowerCornerOf(pos))).isEmpty(); -@@ -585,7 +_,7 @@ +@@ -605,7 +_,7 @@ if (this.enderman.getCarriedBlock() != null) { return false; } else { diff --git a/patches/minecraft/net/minecraft/world/entity/monster/Monster.java.patch b/patches/minecraft/net/minecraft/world/entity/monster/Monster.java.patch index 80686f0291..6175f583cb 100644 --- a/patches/minecraft/net/minecraft/world/entity/monster/Monster.java.patch +++ b/patches/minecraft/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 -@@ -147,9 +_,9 @@ +@@ -146,9 +_,9 @@ if (heldWeapon.getItem() instanceof ProjectileWeaponItem) { Predicate supportedProjectiles = ((ProjectileWeaponItem)heldWeapon.getItem()).getSupportedHeldProjectiles(); ItemStack heldProjectile = ProjectileWeaponItem.getHeldProjectile(this, supportedProjectiles); diff --git a/patches/minecraft/net/minecraft/world/entity/monster/Ravager.java.patch b/patches/minecraft/net/minecraft/world/entity/monster/Ravager.java.patch index 1e737394b4..116dc08c71 100644 --- a/patches/minecraft/net/minecraft/world/entity/monster/Ravager.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/monster/Ravager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Ravager.java +++ b/net/minecraft/world/entity/monster/Ravager.java -@@ -143,7 +_,7 @@ +@@ -144,7 +_,7 @@ this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(Mth.lerp(0.1, baseValue, maxSpeed)); } diff --git a/patches/minecraft/net/minecraft/world/entity/monster/Shulker.java.patch b/patches/minecraft/net/minecraft/world/entity/monster/Shulker.java.patch index 512ab3dd79..b01f7bf62d 100644 --- a/patches/minecraft/net/minecraft/world/entity/monster/Shulker.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/monster/Shulker.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/entity/monster/Shulker.java +++ b/net/minecraft/world/entity/monster/Shulker.java -@@ -401,6 +_,12 @@ - && this.level().noCollision(this, new AABB(target).deflate(1.0E-6))) { +@@ -405,6 +_,12 @@ Direction attachmentDirection = this.findAttachableSurface(target); - if (attachmentDirection != null) { -+ var event = new net.minecraftforge.event.entity.EntityTeleportEvent.EnderEntity(this, target.getX(), target.getY(), target.getZ()); -+ if (net.minecraftforge.event.entity.EntityTeleportEvent.EnderEntity.BUS.post(event)) attachmentDirection = null; + if (attachmentDirection != null + && !this.level().getBlockState(target.relative(attachmentDirection)).is(BlockTags.SHULKER_DOES_NOT_TELEPORT_TO)) { ++ var event = new net.minecraftforge.event.entity.EntityTeleportEvent.EntityRandom(this, target.getX(), target.getY(), target.getZ()); ++ if (net.minecraftforge.event.entity.EntityTeleportEvent.EntityRandom.BUS.post(event)) attachmentDirection = null; + target = BlockPos.containing(event.getTargetX(), event.getTargetY(), event.getTargetZ()); + } + diff --git a/patches/minecraft/net/minecraft/world/entity/monster/Silverfish.java.patch b/patches/minecraft/net/minecraft/world/entity/monster/Silverfish.java.patch index 589b3c0372..a38fb9fdf6 100644 --- a/patches/minecraft/net/minecraft/world/entity/monster/Silverfish.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/monster/Silverfish.java.patch @@ -17,4 +17,4 @@ + if (net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(getServerLevel(level), this.silverfish)) { level.destroyBlock(testPos, true, this.silverfish); } else { - level.setBlock(testPos, infestedBlock.hostStateByInfested(level.getBlockState(testPos)), 3); + level.setBlockAndUpdate(testPos, infestedBlock.hostStateByInfested(level.getBlockState(testPos))); diff --git a/patches/minecraft/net/minecraft/world/entity/monster/creaking/Creaking.java.patch b/patches/minecraft/net/minecraft/world/entity/monster/creaking/Creaking.java.patch index 8568a1f469..66b2105a43 100644 --- a/patches/minecraft/net/minecraft/world/entity/monster/creaking/Creaking.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/monster/creaking/Creaking.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/creaking/Creaking.java +++ b/net/minecraft/world/entity/monster/creaking/Creaking.java -@@ -468,7 +_,7 @@ +@@ -469,7 +_,7 @@ for (Player player : players) { if (this.canAttack(player) && !this.isAlliedTo(player)) { hasPotentialTarget = true; diff --git a/patches/minecraft/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch b/patches/minecraft/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch index a2444bba97..dcb95bdd27 100644 --- a/patches/minecraft/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/hoglin/Hoglin.java +++ b/net/minecraft/world/entity/monster/hoglin/Hoglin.java -@@ -148,7 +_,7 @@ +@@ -149,7 +_,7 @@ HoglinAi.updateActivity(this); if (this.isConverting()) { this.timeInOverworld++; @@ -9,7 +9,7 @@ this.makeSound(SoundEvents.HOGLIN_CONVERTED_TO_ZOMBIFIED); this.finishConversion(); } -@@ -249,9 +_,7 @@ +@@ -250,9 +_,7 @@ } private void finishConversion() { diff --git a/patches/minecraft/net/minecraft/world/entity/monster/piglin/Piglin.java.patch b/patches/minecraft/net/minecraft/world/entity/monster/piglin/Piglin.java.patch index 0b63ebe319..b446b169e1 100644 --- a/patches/minecraft/net/minecraft/world/entity/monster/piglin/Piglin.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/monster/piglin/Piglin.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/piglin/Piglin.java +++ b/net/minecraft/world/entity/monster/piglin/Piglin.java -@@ -323,7 +_,7 @@ +@@ -318,7 +_,7 @@ } else if (this.isChargingCrossbow()) { return PiglinArmPose.CROSSBOW_CHARGE; } else { @@ -9,7 +9,7 @@ } } -@@ -362,14 +_,14 @@ +@@ -357,14 +_,14 @@ protected void holdInOffHand(final ItemStack itemStack) { this.setItemSlotAndDropWhenKilled(EquipmentSlot.OFFHAND, itemStack); diff --git a/patches/minecraft/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch b/patches/minecraft/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch index 6e2e9bdc2b..daeac8cff5 100644 --- a/patches/minecraft/net/minecraft/world/entity/monster/piglin/PiglinAi.java.patch +++ b/patches/minecraft/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 -@@ -647,7 +_,7 @@ +@@ -648,7 +_,7 @@ public static boolean isWearingSafeArmor(final LivingEntity livingEntity) { for (EquipmentSlot slot : EquipmentSlotGroup.ARMOR) { @@ -9,7 +9,7 @@ return true; } } -@@ -799,7 +_,7 @@ +@@ -800,7 +_,7 @@ } private static boolean hasCrossbow(final LivingEntity body) { @@ -18,7 +18,7 @@ } private static void admireGoldItem(final LivingEntity body) { -@@ -811,7 +_,7 @@ +@@ -812,7 +_,7 @@ } private static boolean isBarterCurrency(final ItemStack itemStack) { diff --git a/patches/minecraft/net/minecraft/world/entity/monster/skeleton/Skeleton.java.patch b/patches/minecraft/net/minecraft/world/entity/monster/skeleton/Skeleton.java.patch deleted file mode 100644 index 62ab199b69..0000000000 --- a/patches/minecraft/net/minecraft/world/entity/monster/skeleton/Skeleton.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net/minecraft/world/entity/monster/skeleton/Skeleton.java -+++ b/net/minecraft/world/entity/monster/skeleton/Skeleton.java -@@ -93,6 +_,7 @@ - } - - protected void doFreezeConversion() { -+ if (!net.minecraftforge.event.ForgeEventFactory.canLivingConvert(this, EntityTypes.STRAY, (timer) -> this.conversionTime = timer)) return; - this.convertTo(EntityTypes.STRAY, ConversionParams.single(this, true, true), stray -> { - if (!this.isSilent()) { - this.level().levelEvent(null, 1048, this.blockPosition(), 0); diff --git a/patches/minecraft/net/minecraft/world/entity/monster/zombie/Husk.java.patch b/patches/minecraft/net/minecraft/world/entity/monster/zombie/Husk.java.patch deleted file mode 100644 index 77619ab765..0000000000 --- a/patches/minecraft/net/minecraft/world/entity/monster/zombie/Husk.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net/minecraft/world/entity/monster/zombie/Husk.java -+++ b/net/minecraft/world/entity/monster/zombie/Husk.java -@@ -80,6 +_,7 @@ - - @Override - protected void doUnderWaterConversion(final ServerLevel level) { -+ if (!net.minecraftforge.event.ForgeEventFactory.canLivingConvert(this, EntityTypes.ZOMBIE, (timer) -> this.conversionTime = timer)) return; - this.convertToZombieType(level, EntityTypes.ZOMBIE); - if (!this.isSilent()) { - level.levelEvent(null, 1041, this.blockPosition(), 0); diff --git a/patches/minecraft/net/minecraft/world/entity/monster/zombie/Zombie.java.patch b/patches/minecraft/net/minecraft/world/entity/monster/zombie/Zombie.java.patch index d1a4f8ed66..03dd7d3e7d 100644 --- a/patches/minecraft/net/minecraft/world/entity/monster/zombie/Zombie.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/monster/zombie/Zombie.java.patch @@ -1,31 +1,15 @@ --- a/net/minecraft/world/entity/monster/zombie/Zombie.java +++ b/net/minecraft/world/entity/monster/zombie/Zombie.java -@@ -245,17 +_,21 @@ - } - - protected void convertToZombieType(final ServerLevel level, final EntityType zombieType) { -+ if (!net.minecraftforge.event.ForgeEventFactory.canLivingConvert(this, zombieType, timer -> this.conversionTime = timer)) return; - this.convertTo( - zombieType, - ConversionParams.single(this, true, true), -- newZombie -> newZombie.handleAttributes( -- level.getCurrentDifficultyAt(newZombie.blockPosition()).getSpecialMultiplier(), EntitySpawnReason.CONVERSION -- ) -+ newZombie -> { -+ newZombie.handleAttributes(level.getCurrentDifficultyAt(newZombie.blockPosition()).getSpecialMultiplier(), EntitySpawnReason.CONVERSION); -+ net.minecraftforge.event.ForgeEventFactory.onLivingConvert(this, newZombie); -+ } - ); - } +@@ -231,6 +_,8 @@ @VisibleForTesting public boolean convertVillagerToZombieVillager(final ServerLevel level, final Villager villager) { -+ if (!net.minecraftforge.event.ForgeEventFactory.canLivingConvert(villager, EntityTypes.ZOMBIE_VILLAGER, (timer) -> {})) ++ if (!net.minecraftforge.event.ForgeEventFactory.canLivingConvert(villager, EntityTypes.ZOMBIE_VILLAGER, _ -> {})) + return false; ZombieVillager zombieVillager = villager.convertTo( EntityTypes.ZOMBIE_VILLAGER, ConversionParams.single(villager, true, true), -@@ -268,6 +_,7 @@ +@@ -243,6 +_,7 @@ zombie.setGossips(villager.getGossips().copy()); zombie.setTradeOffers(villager.getOffers().copy()); zombie.setVillagerXp(villager.getVillagerXp()); @@ -33,7 +17,7 @@ if (!this.isSilent()) { level.levelEvent(null, 1026, this.blockPosition(), 0); } -@@ -291,15 +_,26 @@ +@@ -266,15 +_,26 @@ target = (LivingEntity)source.getEntity(); } diff --git a/patches/minecraft/net/minecraft/world/entity/npc/villager/Villager.java.patch b/patches/minecraft/net/minecraft/world/entity/npc/villager/Villager.java.patch index cd35c7a612..07914b1404 100644 --- a/patches/minecraft/net/minecraft/world/entity/npc/villager/Villager.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/npc/villager/Villager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/npc/villager/Villager.java +++ b/net/minecraft/world/entity/npc/villager/Villager.java -@@ -289,7 +_,7 @@ +@@ -267,7 +_,7 @@ @Override public InteractionResult mobInteract(final Player player, final InteractionHand hand) { ItemStack itemStack = player.getItemInHand(hand); @@ -9,7 +9,7 @@ return super.mobInteract(player, hand); } -@@ -761,7 +_,7 @@ +@@ -744,7 +_,7 @@ @Override public void thunderHit(final ServerLevel level, final LightningBolt lightningBolt) { diff --git a/patches/minecraft/net/minecraft/world/entity/player/Inventory.java.patch b/patches/minecraft/net/minecraft/world/entity/player/Inventory.java.patch index fcc33cde89..7c9a6b0a9f 100644 --- a/patches/minecraft/net/minecraft/world/entity/player/Inventory.java.patch +++ b/patches/minecraft/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 -@@ -91,6 +_,10 @@ +@@ -93,6 +_,10 @@ return this.items; } @@ -11,7 +11,7 @@ private boolean hasRemainingSpaceForItem(final ItemStack slotItemStack, final ItemStack newItemStack) { return !slotItemStack.isEmpty() && ItemStack.isSameItemSameComponents(slotItemStack, newItemStack) -@@ -169,7 +_,7 @@ +@@ -171,7 +_,7 @@ for (int slot = 0; slot < 9; slot++) { int index = (this.selected + slot) % 9; @@ -20,7 +20,7 @@ return index; } } -@@ -242,7 +_,7 @@ +@@ -243,7 +_,7 @@ for (int i = 0; i < this.items.size(); i++) { ItemStack itemStack = this.getItem(i); if (!itemStack.isEmpty()) { @@ -29,7 +29,7 @@ } } } -@@ -293,6 +_,8 @@ +@@ -294,6 +_,8 @@ } catch (Throwable t) { CrashReport report = CrashReport.forThrowable(t, "Adding item to inventory"); CrashReportCategory category = report.addCategory("Item being added"); diff --git a/patches/minecraft/net/minecraft/world/entity/player/Player.java.patch b/patches/minecraft/net/minecraft/world/entity/player/Player.java.patch index a9f5e2cff1..1e6f250054 100644 --- a/patches/minecraft/net/minecraft/world/entity/player/Player.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/player/Player.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/entity/player/Player.java +++ b/net/minecraft/world/entity/player/Player.java @@ -123,7 +_,7 @@ - import net.minecraft.world.scores.Team; + import net.minecraft.world.scores.PlayerTeam; import org.jspecify.annotations.Nullable; -public abstract class Player extends Avatar implements ContainerUser { @@ -9,8 +9,8 @@ public static final int MAX_HEALTH = 20; public static final int SLEEP_DURATION = 100; public static final int WAKE_UP_DURATION = 10; -@@ -171,6 +_,9 @@ - private Optional lastDeathLocation = Optional.empty(); +@@ -172,6 +_,9 @@ + protected final List postEffects = new ArrayList<>(); public @Nullable FishingHook fishing; protected float hurtDir; + private final java.util.Collection prefixes = new java.util.LinkedList<>(); @@ -19,7 +19,7 @@ public Player(final Level level, final GameProfile gameProfile) { super(EntityTypes.PLAYER, level); -@@ -179,6 +_,17 @@ +@@ -180,6 +_,17 @@ this.inventory = new Inventory(this, this.equipment); this.inventoryMenu = new InventoryMenu(this.inventory, !level.isClientSide(), this); this.containerMenu = this.inventoryMenu; @@ -37,7 +37,7 @@ } @Override -@@ -216,7 +_,8 @@ +@@ -217,7 +_,8 @@ .add(Attributes.MINING_EFFICIENCY) .add(Attributes.SWEEPING_DAMAGE_RATIO) .add(Attributes.WAYPOINT_TRANSMIT_RANGE, 6.0E7) @@ -47,7 +47,7 @@ } @Override -@@ -230,6 +_,7 @@ +@@ -231,6 +_,7 @@ @Override public void tick() { @@ -55,16 +55,17 @@ this.noPhysics = this.isSpectator(); if (this.isSpectator() || this.isPassenger()) { this.setOnGround(false); -@@ -246,7 +_,7 @@ +@@ -247,8 +_,7 @@ } if (!this.level().isClientSide() -- && !this.level().environmentAttributes().getValue(EnvironmentAttributes.BED_RULE, this.position()).canSleep(this.level())) { -+ && !net.minecraftforge.event.ForgeEventFactory.onSleepingTimeCheck(this, getSleepingPos(), this.level().environmentAttributes().getValue(EnvironmentAttributes.BED_RULE, this.position()))) { +- && this.getInBlockState().getBlock() instanceof AbstractBedBlock abstractBedBlock +- && !abstractBedBlock.getBedRule(this.level(), this.blockPosition()).canSleep(this.level())) { ++ && !net.minecraftforge.event.ForgeEventFactory.onSleepingTimeCheck(this, getSleepingPos())) { this.stopSleepInBed(false, true); } } else if (this.sleepCounter > 0) { -@@ -282,6 +_,7 @@ +@@ -284,6 +_,7 @@ this.cooldowns.tick(); this.updatePlayerPose(); @@ -72,7 +73,7 @@ } @Override -@@ -341,6 +_,10 @@ +@@ -343,6 +_,10 @@ } protected void updatePlayerPose() { @@ -83,7 +84,7 @@ if (this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.SWIMMING)) { Pose desiredPose = this.getDesiredPose(); Pose actualPose; -@@ -524,6 +_,7 @@ +@@ -525,6 +_,7 @@ @Override public void die(final DamageSource source) { @@ -91,14 +92,15 @@ super.die(source); this.reapplyPosition(); if (!this.isSpectator() && this.level() instanceof ServerLevel level) { -@@ -580,10 +_,15 @@ - } - - public @Nullable ItemEntity drop(final ItemStack itemStack, final boolean thrownFromHand) { -- return this.drop(itemStack, false, thrownFromHand); -+ return net.minecraftforge.common.ForgeHooks.onPlayerTossEvent(this, itemStack, thrownFromHand); +@@ -580,7 +_,17 @@ + public void handleCreativeModeItemDrop(final ItemStack stack) { } ++ @Override ++ public net.minecraft.world.entity.item.@Nullable ItemEntity drop(final ItemStack itemStack, final boolean thrownFromHand, final net.minecraft.util.Prediction prediction) { ++ return net.minecraftforge.common.ForgeHooks.onPlayerTossEvent(this, itemStack, thrownFromHand, prediction); ++ } ++ + /** @deprecated Use {@link #getDestroySpeed(BlockState,BlockPos) */ public float getDestroySpeed(final BlockState state) { + return getDestroySpeed(state, null); @@ -108,7 +110,7 @@ float speed = this.inventory.getSelectedItem().getDestroySpeed(state); if (speed > 1.0F) { speed += (float)this.getAttributeValue(Attributes.MINING_EFFICIENCY); -@@ -612,11 +_,14 @@ +@@ -605,11 +_,14 @@ speed /= 5.0F; } @@ -124,7 +126,7 @@ } @Override -@@ -677,6 +_,7 @@ +@@ -670,6 +_,7 @@ @Override public boolean hurtServer(final ServerLevel level, final DamageSource source, float damage) { @@ -132,7 +134,7 @@ if (this.isInvulnerableTo(level, source)) { return false; } -@@ -747,11 +_,14 @@ +@@ -736,11 +_,14 @@ @Override protected void actuallyHurt(final ServerLevel level, final DamageSource source, float dmg) { if (!this.isInvulnerableTo(level, source)) { @@ -147,7 +149,7 @@ float absorbedDamage = originalDamage - dmg; if (absorbedDamage > 0.0F && absorbedDamage < 3.4028235E37F) { this.awardStat(Stats.DAMAGE_ABSORBED, Math.round(absorbedDamage * 10.0F)); -@@ -829,6 +_,10 @@ +@@ -818,6 +_,10 @@ return InteractionResult.PASS; } else { @@ -158,7 +160,7 @@ ItemStack itemStack = this.getItemInHand(hand); ItemStack itemStackClone = itemStack.copy(); InteractionResult interact = entity.interact(this, hand, location); -@@ -837,6 +_,10 @@ +@@ -826,6 +_,10 @@ itemStack.setCount(itemStackClone.getCount()); } @@ -169,7 +171,7 @@ return interact; } else { if (!itemStack.isEmpty() && entity instanceof LivingEntity livingEntity) { -@@ -848,6 +_,7 @@ +@@ -837,6 +_,7 @@ if (interactionResult.consumesAction()) { this.level().gameEvent(GameEvent.ENTITY_INTERACT, entity.position(), GameEvent.Context.of(this)); if (itemStack.isEmpty() && !this.hasInfiniteMaterials()) { @@ -177,7 +179,7 @@ this.setItemInHand(hand, ItemStack.EMPTY); } -@@ -949,6 +_,7 @@ +@@ -938,6 +_,7 @@ } public void attack(final Entity entity) { @@ -185,7 +187,7 @@ if (!this.cannotAttack(entity)) { float baseDamage = this.isAutoSpinAttack() ? this.autoSpinAttackDmg : (float)this.getAttributeValue(Attributes.ATTACK_DAMAGE); ItemStack attackingItemStack = this.getWeaponItem(); -@@ -970,8 +_,10 @@ +@@ -959,8 +_,10 @@ baseDamage += attackingItemStack.getItem().getAttackDamageBonus(entity, baseDamage, damageSource); boolean criticalAttack = fullStrengthAttack && this.canCriticalAttack(entity); @@ -197,7 +199,7 @@ } float totalDamage = baseDamage + magicBoost; -@@ -1045,7 +_,7 @@ +@@ -1034,7 +_,7 @@ double approximateSpeedSq = this.getKnownMovement().horizontalDistanceSqr(); double maxSpeedForSweepAttack = this.getSpeed() * 2.5; if (approximateSpeedSq < Mth.square(maxSpeedForSweepAttack)) { @@ -206,7 +208,7 @@ } } -@@ -1088,8 +_,8 @@ +@@ -1077,8 +_,8 @@ private void itemAttackInteraction(final Entity entity, final ItemStack attackingItemStack, final DamageSource damageSource, final boolean applyToTarget) { Entity hurtTarget = entity; @@ -217,7 +219,7 @@ } boolean itemHurtEnemy = false; -@@ -1114,6 +_,7 @@ +@@ -1103,6 +_,7 @@ } else { this.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY); } @@ -225,7 +227,7 @@ } } } -@@ -1166,7 +_,7 @@ +@@ -1155,7 +_,7 @@ if (this.level() instanceof ServerLevel serverLevel) { float var12 = 1.0F + (float)this.getAttributeValue(Attributes.SWEEPING_DAMAGE_RATIO) * baseDamage; @@ -234,7 +236,7 @@ if (nearby != this && nearby != entity && !this.isAlliedTo(nearby) -@@ -1339,6 +_,7 @@ +@@ -1333,6 +_,7 @@ } public void stopSleepInBed(final boolean forcefulWakeUp, final boolean updateLevelList) { @@ -242,7 +244,7 @@ super.stopSleeping(); if (this.level() instanceof ServerLevel && updateLevelList) { ((ServerLevel)this.level()).updateSleepingPlayerList(); -@@ -1450,6 +_,7 @@ +@@ -1437,6 +_,7 @@ @Override public boolean causeFallDamage(final double fallDistance, final float damageModifier, final DamageSource damageSource) { if (this.abilities.mayfly) { @@ -250,7 +252,7 @@ return false; } -@@ -1484,13 +_,13 @@ +@@ -1471,13 +_,13 @@ protected void playStepSound(final BlockPos onPos, final BlockState onState) { if (this.isInWater()) { this.waterSwimSound(); @@ -266,7 +268,7 @@ } else { super.playStepSound(primaryStepSoundPos, primaryStepState); } -@@ -1520,7 +_,13 @@ +@@ -1507,7 +_,13 @@ this.tryResetCurrentImpulseContext(); } @@ -281,7 +283,7 @@ this.increaseScore(i); this.experienceProgress = this.experienceProgress + (float)i / this.getXpNeededForNextLevel(); this.totalExperience = Mth.clamp(this.totalExperience + i, 0, Integer.MAX_VALUE); -@@ -1548,7 +_,7 @@ +@@ -1535,7 +_,7 @@ } public void onEnchantmentPerformed(final ItemStack itemStack, final int enchantmentCost) { @@ -290,7 +292,7 @@ if (this.experienceLevel < 0) { this.experienceLevel = 0; this.experienceProgress = 0.0F; -@@ -1558,7 +_,13 @@ +@@ -1545,7 +_,13 @@ this.enchantmentSeed = this.random.nextInt(); } @@ -305,7 +307,7 @@ this.experienceLevel = IntMath.saturatedAdd(this.experienceLevel, amount); if (this.experienceLevel < 0) { this.experienceLevel = 0; -@@ -1697,7 +_,13 @@ +@@ -1680,7 +_,13 @@ @Override public Component getDisplayName() { @@ -320,7 +322,7 @@ return this.decorateDisplayNameComponent(result); } -@@ -1882,7 +_,7 @@ +@@ -1865,7 +_,7 @@ Predicate supportedProjectiles = ((ProjectileWeaponItem)heldWeapon.getItem()).getSupportedHeldProjectiles(); ItemStack heldProjectile = ProjectileWeaponItem.getHeldProjectile(this, supportedProjectiles); if (!heldProjectile.isEmpty()) { @@ -329,7 +331,7 @@ } supportedProjectiles = ((ProjectileWeaponItem)heldWeapon.getItem()).getAllSupportedProjectiles(); -@@ -1890,11 +_,12 @@ +@@ -1873,11 +_,12 @@ for (int i = 0; i < this.inventory.getContainerSize(); i++) { ItemStack itemStack = this.inventory.getItem(i); if (supportedProjectiles.test(itemStack)) { @@ -344,7 +346,7 @@ } @Override -@@ -2015,6 +_,54 @@ +@@ -1998,6 +_,54 @@ double maxRange = this.blockInteractionRange() + buffer; return new AABB(pos).distanceToSqr(this.getEyePosition()) < maxRange * maxRange; } diff --git a/patches/minecraft/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch b/patches/minecraft/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch index c484ae4a55..53248a0aa6 100644 --- a/patches/minecraft/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch +++ b/patches/minecraft/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 -@@ -314,6 +_,13 @@ +@@ -315,6 +_,13 @@ } @Override diff --git a/patches/minecraft/net/minecraft/world/entity/projectile/FishingHook.java.patch b/patches/minecraft/net/minecraft/world/entity/projectile/FishingHook.java.patch index d78b9f93df..6eb0882af3 100644 --- a/patches/minecraft/net/minecraft/world/entity/projectile/FishingHook.java.patch +++ b/patches/minecraft/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 -@@ -254,8 +_,8 @@ +@@ -255,8 +_,8 @@ if (owner.canInteractWithLevel()) { ItemStack selectedItem = owner.getMainHandItem(); ItemStack selectedItemOffHand = owner.getOffhandItem(); @@ -11,7 +11,7 @@ if ((mainHandIsFishing || offHandIsFishing) && this.distanceToSqr(owner) <= 1024.0) { return false; } -@@ -267,6 +_,7 @@ +@@ -268,6 +_,7 @@ private void checkCollision() { HitResult hitResult = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); @@ -19,7 +19,7 @@ this.hitTargetOrDeflectSelf(hitResult); } -@@ -448,6 +_,7 @@ +@@ -449,6 +_,7 @@ Player owner = this.getPlayerOwner(); if (!this.level().isClientSide() && owner != null && !this.shouldStopFishing(owner)) { int dmg = 0; @@ -27,7 +27,7 @@ if (this.hookedIn != null) { this.pullEntity(this.hookedIn); CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer)owner, rod, this, Collections.emptyList()); -@@ -458,10 +_,16 @@ +@@ -459,10 +_,16 @@ .withParameter(LootContextParams.ORIGIN, this.position()) .withParameter(LootContextParams.TOOL, rod) .withParameter(LootContextParams.THIS_ENTITY, this) @@ -44,7 +44,7 @@ CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer)owner, rod, this, items); for (ItemStack itemStack : items) { -@@ -487,7 +_,7 @@ +@@ -488,7 +_,7 @@ } this.discard(); diff --git a/patches/minecraft/net/minecraft/world/entity/projectile/Projectile.java.patch b/patches/minecraft/net/minecraft/world/entity/projectile/Projectile.java.patch index 7702952934..b90b1ac85d 100644 --- a/patches/minecraft/net/minecraft/world/entity/projectile/Projectile.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/projectile/Projectile.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/Projectile.java +++ b/net/minecraft/world/entity/projectile/Projectile.java -@@ -363,7 +_,7 @@ +@@ -422,7 +_,7 @@ @Override public boolean mayInteract(final ServerLevel level, final BlockPos pos) { Entity owner = this.getOwner(); @@ -8,4 +8,4 @@ + return owner instanceof Player ? owner.mayInteract(level, pos) : owner == null || net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(level, owner); } - public boolean mayBreak(final ServerLevel level) { + public boolean mayBreak(final ServerLevel level, final BlockPos pos) { diff --git a/patches/minecraft/net/minecraft/world/entity/projectile/ProjectileUtil.java.patch b/patches/minecraft/net/minecraft/world/entity/projectile/ProjectileUtil.java.patch index d7381e8823..fb7281800f 100644 --- a/patches/minecraft/net/minecraft/world/entity/projectile/ProjectileUtil.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/projectile/ProjectileUtil.java.patch @@ -9,7 +9,7 @@ if (nearest == 0.0) { hovered = entity; hoveredPos = location; -@@ -268,8 +_,13 @@ +@@ -281,8 +_,13 @@ } } diff --git a/patches/minecraft/net/minecraft/world/entity/projectile/ThrowableProjectile.java.patch b/patches/minecraft/net/minecraft/world/entity/projectile/ThrowableProjectile.java.patch index 39f52acee7..814fded723 100644 --- a/patches/minecraft/net/minecraft/world/entity/projectile/ThrowableProjectile.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/projectile/ThrowableProjectile.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/ThrowableProjectile.java +++ b/net/minecraft/world/entity/projectile/ThrowableProjectile.java -@@ -59,7 +_,7 @@ +@@ -57,7 +_,7 @@ this.updateRotation(); this.applyEffectsFromBlocks(); super.tick(); diff --git a/patches/minecraft/net/minecraft/world/entity/projectile/arrow/AbstractArrow.java.patch b/patches/minecraft/net/minecraft/world/entity/projectile/arrow/AbstractArrow.java.patch index bfe8e60770..696093620c 100644 --- a/patches/minecraft/net/minecraft/world/entity/projectile/arrow/AbstractArrow.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/projectile/arrow/AbstractArrow.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/arrow/AbstractArrow.java +++ b/net/minecraft/world/entity/projectile/arrow/AbstractArrow.java -@@ -79,6 +_,7 @@ +@@ -77,6 +_,7 @@ private @Nullable List piercedAndKilledEntities; private ItemStack pickupItemStack = this.getDefaultPickupItem(); private @Nullable ItemStack firedFromWeapon = null; @@ -8,7 +8,7 @@ protected AbstractArrow(final EntityType type, final Level level) { super(type, level); -@@ -196,7 +_,7 @@ +@@ -194,7 +_,7 @@ this.shakeTime--; } @@ -17,7 +17,7 @@ this.clearFire(); } -@@ -601,7 +_,7 @@ +@@ -593,7 +_,7 @@ protected boolean canHitEntity(final Entity entity) { return entity instanceof Player playerEntity && this.getOwner() instanceof Player player && !player.canHarmPlayer(playerEntity) ? false diff --git a/patches/minecraft/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java.patch b/patches/minecraft/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java.patch index 7cc436e850..8c3e663dc6 100644 --- a/patches/minecraft/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/projectile/throwableitemprojectile/ThrownEnderpearl.java.patch @@ -14,7 +14,7 @@ if (this.random.nextFloat() < 0.05F && level.isSpawningMonsters() && level.getLevelData().getDifficulty() != Difficulty.PEACEFUL) { Endermite endermite = EntityTypes.ENDERMITE.create(level, EntitySpawnReason.TRIGGERED); if (endermite != null) { -@@ -124,7 +_,7 @@ +@@ -122,7 +_,7 @@ if (newOwner != null) { newOwner.resetFallDistance(); newOwner.resetCurrentImpulseContext(); diff --git a/patches/minecraft/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java.patch b/patches/minecraft/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java.patch index b0daa4861e..cf7f2ac37e 100644 --- a/patches/minecraft/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java +++ b/net/minecraft/world/entity/vehicle/boat/AbstractBoat.java -@@ -48,7 +_,7 @@ +@@ -51,7 +_,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; import org.jspecify.annotations.Nullable; @@ -9,7 +9,7 @@ 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); -@@ -416,7 +_,7 @@ +@@ -440,7 +_,7 @@ for (int z = minZ; z < maxZ; z++) { pos.set(x, y, z); FluidState fluidState = this.level().getFluidState(pos); @@ -18,7 +18,7 @@ blockHeight = Math.max(blockHeight, fluidState.getHeight(this.level(), pos)); } -@@ -458,7 +_,7 @@ +@@ -482,7 +_,7 @@ BlockState blockState = this.level().getBlockState(blockPos); if (!(blockState.getBlock() instanceof LilyPadBlock) && Shapes.joinIsNotEmpty(blockState.getCollisionShape(this.level(), blockPos).move(blockPos), boatShape, BooleanOp.AND)) { @@ -27,7 +27,7 @@ count++; } } -@@ -487,7 +_,7 @@ +@@ -511,7 +_,7 @@ for (int z = minZ; z < maxZ; z++) { pos.set(x, y, z); FluidState fluidState = this.level().getFluidState(pos); @@ -36,7 +36,7 @@ float height = y + fluidState.getHeight(this.level(), pos); this.waterLevel = Math.max(height, this.waterLevel); inWater |= bb.minY < height; -@@ -516,7 +_,7 @@ +@@ -540,7 +_,7 @@ for (int z = z0; z < z1; z++) { pos.set(x, y, z); FluidState fluidState = this.level().getFluidState(pos); @@ -45,7 +45,7 @@ if (!fluidState.isSource()) { return AbstractBoat.Status.UNDER_FLOWING_WATER; } -@@ -725,7 +_,7 @@ +@@ -761,7 +_,7 @@ if (!this.isPassenger()) { if (onGround) { this.resetFallDistance(); @@ -54,7 +54,7 @@ this.fallDistance -= (float)ya; } } -@@ -749,7 +_,7 @@ +@@ -785,7 +_,7 @@ @Override protected boolean canAddPassenger(final Entity passenger) { diff --git a/patches/minecraft/net/minecraft/world/entity/vehicle/minecart/AbstractMinecart.java.patch b/patches/minecraft/net/minecraft/world/entity/vehicle/minecart/AbstractMinecart.java.patch index a6ea0ec349..f8c4b1fda1 100644 --- a/patches/minecraft/net/minecraft/world/entity/vehicle/minecart/AbstractMinecart.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/vehicle/minecart/AbstractMinecart.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/minecart/AbstractMinecart.java +++ b/net/minecraft/world/entity/vehicle/minecart/AbstractMinecart.java -@@ -46,7 +_,7 @@ +@@ -47,7 +_,7 @@ import net.minecraft.world.phys.Vec3; import org.jspecify.annotations.Nullable; @@ -9,7 +9,7 @@ private static final Vec3 LOWERED_PASSENGER_ATTACHMENT = new Vec3(0.0, 0.0, 0.0); private static final EntityDataAccessor> DATA_ID_CUSTOM_DISPLAY_BLOCK = SynchedEntityData.defineId( AbstractMinecart.class, EntityDataSerializers.OPTIONAL_BLOCK_STATE -@@ -96,15 +_,12 @@ +@@ -97,15 +_,12 @@ } ) ); @@ -27,7 +27,7 @@ } protected AbstractMinecart(final EntityType type, final Level level, final double x, final double y, final double z) { -@@ -166,7 +_,7 @@ +@@ -167,7 +_,7 @@ @Override public boolean isPushable() { @@ -36,7 +36,7 @@ } @Override -@@ -367,22 +_,31 @@ +@@ -373,22 +_,31 @@ } protected void comeOffTrack(final ServerLevel level) { @@ -70,7 +70,7 @@ } protected double makeStepAlongTrack(final BlockPos pos, final RailShape shape, final double movementLeft) { -@@ -438,7 +_,7 @@ +@@ -444,7 +_,7 @@ public Vec3 getRedstoneDirection(final BlockPos pos) { BlockState state = this.level().getBlockState(pos); if (state.is(Blocks.POWERED_RAIL) && state.getValue(PoweredRailBlock.POWERED)) { @@ -79,7 +79,7 @@ if (shape == RailShape.EAST_WEST) { if (this.isRedstoneConductor(pos.west())) { return new Vec3(1.0, 0.0, 0.0); -@@ -609,5 +_,40 @@ +@@ -615,5 +_,40 @@ public boolean isFurnace() { return false; diff --git a/patches/minecraft/net/minecraft/world/entity/vehicle/minecart/MinecartSpawner.java.patch b/patches/minecraft/net/minecraft/world/entity/vehicle/minecart/MinecartSpawner.java.patch index ecdf77384e..9fcb6b6770 100644 --- a/patches/minecraft/net/minecraft/world/entity/vehicle/minecart/MinecartSpawner.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/vehicle/minecart/MinecartSpawner.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/minecart/MinecartSpawner.java +++ b/net/minecraft/world/entity/vehicle/minecart/MinecartSpawner.java -@@ -19,6 +_,11 @@ +@@ -20,6 +_,11 @@ public void broadcastEvent(final Level level, final BlockPos pos, final int id) { level.broadcastEntityEvent(MinecartSpawner.this, (byte)id); } diff --git a/patches/minecraft/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java.patch b/patches/minecraft/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java.patch index 53f4548353..51458ca9fb 100644 --- a/patches/minecraft/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java.patch +++ b/patches/minecraft/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java +++ b/net/minecraft/world/entity/vehicle/minecart/OldMinecartBehavior.java -@@ -60,9 +_,9 @@ +@@ -54,9 +_,9 @@ BlockState state = this.level().getBlockState(var11); boolean onRails = BaseRailBlock.isRail(state); this.minecart.setOnRails(onRails); @@ -12,7 +12,7 @@ this.minecart.activateMinecart(level, var11.getX(), var11.getY(), var11.getZ(), state.getValue(PoweredRailBlock.POWERED)); } } else { -@@ -112,18 +_,19 @@ +@@ -104,18 +_,19 @@ y = pos.getY(); boolean powerTrack = false; boolean haltTrack = false; @@ -35,7 +35,7 @@ switch (shape) { case ASCENDING_EAST: this.setDeltaMovement(movement.add(-slideSpeed, 0.0, 0.0)); -@@ -175,7 +_,7 @@ +@@ -167,7 +_,7 @@ } } @@ -44,7 +44,7 @@ double speedLength = this.getDeltaMovement().horizontalDistance(); if (speedLength < 0.03) { this.setDeltaMovement(Vec3.ZERO); -@@ -204,11 +_,7 @@ +@@ -196,11 +_,7 @@ x = x0 + xD * progress; z = z0 + zD * progress; this.setPos(x, y, z); @@ -57,7 +57,7 @@ if (exit0.getY() != 0 && Mth.floor(this.minecart.getX()) - pos.getX() == exit0.getX() && Mth.floor(this.minecart.getZ()) - pos.getZ() == exit0.getZ()) { this.setPos(this.minecart.getX(), this.minecart.getY() + exit0.getY(), this.minecart.getZ()); } else if (exit1.getY() != 0 -@@ -238,7 +_,11 @@ +@@ -230,7 +_,11 @@ this.setDeltaMovement(otherPow * (xn - pos.getX()), vec3.y, otherPow * (zn - pos.getZ())); } @@ -70,7 +70,7 @@ Vec3 vec3 = this.getDeltaMovement(); double speedLength = vec3.horizontalDistance(); if (speedLength > 0.01) { -@@ -281,7 +_,7 @@ +@@ -273,7 +_,7 @@ BlockState state = this.level().getBlockState(new BlockPos(xt, yt, zt)); if (BaseRailBlock.isRail(state)) { @@ -79,7 +79,7 @@ y = yt; if (shape.isSlope()) { y = yt + 1; -@@ -319,7 +_,7 @@ +@@ -311,7 +_,7 @@ BlockState state = this.level().getBlockState(new BlockPos(xt, yt, zt)); if (BaseRailBlock.isRail(state)) { @@ -88,7 +88,7 @@ Pair exits = AbstractMinecart.exits(shape); Vec3i exit0 = exits.getFirst(); Vec3i exit1 = exits.getSecond(); -@@ -412,5 +_,20 @@ +@@ -404,5 +_,20 @@ @Override public double getSlowdownFactor() { return this.minecart.isVehicle() ? 0.997 : 0.96; diff --git a/patches/minecraft/net/minecraft/world/inventory/AbstractContainerMenu.java.patch b/patches/minecraft/net/minecraft/world/inventory/AbstractContainerMenu.java.patch index b7e2243a9e..0ddbf2cd87 100644 --- a/patches/minecraft/net/minecraft/world/inventory/AbstractContainerMenu.java.patch +++ b/patches/minecraft/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 -@@ -435,6 +_,7 @@ +@@ -438,6 +_,7 @@ ItemStack carried = this.getCarried(); player.updateTutorialInventoryAction(carried, slot.getItem(), clickAction); if (!this.tryItemClickBehaviourOverride(player, clickAction, slot, clicked, carried)) { @@ -8,7 +8,7 @@ if (clicked.isEmpty()) { if (!carried.isEmpty()) { int amount = clickAction == ClickAction.PRIMARY ? carried.getCount() : 1; -@@ -648,7 +_,7 @@ +@@ -664,7 +_,7 @@ ItemStack target = slot.getItem(); if (!target.isEmpty() && ItemStack.isSameItemSameComponents(itemStack, target)) { int totalStack = target.getCount() + itemStack.getCount(); diff --git a/patches/minecraft/net/minecraft/world/inventory/BeaconMenu.java.patch b/patches/minecraft/net/minecraft/world/inventory/BeaconMenu.java.patch index ea2a685a9a..a3e9307f53 100644 --- a/patches/minecraft/net/minecraft/world/inventory/BeaconMenu.java.patch +++ b/patches/minecraft/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 -@@ -88,10 +_,8 @@ +@@ -89,10 +_,8 @@ } slot.onQuickCraft(stack, clicked); diff --git a/patches/minecraft/net/minecraft/world/inventory/BrewingStandMenu.java.patch b/patches/minecraft/net/minecraft/world/inventory/BrewingStandMenu.java.patch index 701b3abb7b..8736815ee8 100644 --- a/patches/minecraft/net/minecraft/world/inventory/BrewingStandMenu.java.patch +++ b/patches/minecraft/net/minecraft/world/inventory/BrewingStandMenu.java.patch @@ -1,56 +1,10 @@ --- a/net/minecraft/world/inventory/BrewingStandMenu.java +++ b/net/minecraft/world/inventory/BrewingStandMenu.java -@@ -45,9 +_,9 @@ - this.brewingStand = brewingStand; - this.brewingStandData = brewingStandData; - PotionBrewing potionBrewing = inventory.player.level().potionBrewing(); -- this.addSlot(new BrewingStandMenu.PotionSlot(brewingStand, 0, 56, 51)); -- this.addSlot(new BrewingStandMenu.PotionSlot(brewingStand, 1, 79, 58)); -- this.addSlot(new BrewingStandMenu.PotionSlot(brewingStand, 2, 102, 51)); -+ this.addSlot(new BrewingStandMenu.PotionSlot(brewingStand, 0, 56, 51, potionBrewing)); -+ this.addSlot(new BrewingStandMenu.PotionSlot(brewingStand, 1, 79, 58, potionBrewing)); -+ this.addSlot(new BrewingStandMenu.PotionSlot(brewingStand, 2, 102, 51, potionBrewing)); - this.ingredientSlot = this.addSlot(new BrewingStandMenu.IngredientsSlot(potionBrewing, brewingStand, 3, 79, 17)); - this.addSlot(new BrewingStandMenu.FuelSlot(brewingStand, 4, 17, 17)); - this.addDataSlots(brewingStandData); -@@ -75,7 +_,7 @@ - if (!this.moveItemStackTo(stack, 3, 4, false)) { - return ItemStack.EMPTY; - } -- } else if (BrewingStandMenu.PotionSlot.mayPlaceItem(clicked)) { -+ } else if (this.slots.get(0).mayPlace(clicked)) { // Forge: Use the slot's place which goes through custom recipes. - if (!this.moveItemStackTo(stack, 0, 3, false)) { - return ItemStack.EMPTY; - } -@@ -157,12 +_,23 @@ - } - - public static class PotionSlot extends Slot { -+ private final PotionBrewing potionBrewing; -+ -+ /** @deprecated Use the one that specifes a PotionBrewing */ - public PotionSlot(final Container container, final int slot, final int x, final int y) { -+ this(container, slot, x, y, null); -+ } -+ -+ public PotionSlot(final Container container, final int slot, final int x, final int y, PotionBrewing potionBrewing) { - super(container, slot, x, y); -+ this.potionBrewing = potionBrewing; - } - - @Override - public boolean mayPlace(final ItemStack itemStack) { -+ if (this.potionBrewing != null) { -+ return this.potionBrewing.isValidInput(itemStack); -+ } - return mayPlaceItem(itemStack); - } - -@@ -175,6 +_,7 @@ +@@ -186,6 +_,7 @@ public void onTake(final Player player, final ItemStack carried) { - Optional> potion = carried.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY).potion(); - if (potion.isPresent() && player instanceof ServerPlayer serverPlayer) { + PotionContents potionContents = carried.get(DataComponents.POTION_CONTENTS); + if (potionContents != null && player instanceof ServerPlayer serverPlayer) { + net.minecraftforge.event.ForgeEventFactory.onPlayerBrewedPotion(player, carried); - CriteriaTriggers.BREWED_POTION.trigger(serverPlayer, potion.get()); + CriteriaTriggers.BREWED_POTION.trigger(serverPlayer, potionContents); } diff --git a/patches/minecraft/net/minecraft/world/inventory/ResultSlot.java.patch b/patches/minecraft/net/minecraft/world/inventory/ResultSlot.java.patch index 05358614f9..3c52752a8c 100644 --- a/patches/minecraft/net/minecraft/world/inventory/ResultSlot.java.patch +++ b/patches/minecraft/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 -@@ -57,6 +_,7 @@ +@@ -58,6 +_,7 @@ protected void checkTakeAchievements(final ItemStack carried) { if (this.removeCount > 0) { carried.onCraftedBy(this.player, this.removeCount); @@ -8,7 +8,7 @@ } if (this.container instanceof RecipeCraftingHolder recipeCraftingHolder) { -@@ -92,7 +_,9 @@ +@@ -93,7 +_,9 @@ CraftingInput input = positionedRecipe.input(); int recipeLeft = positionedRecipe.left(); int recipeTop = positionedRecipe.top(); diff --git a/patches/minecraft/net/minecraft/world/item/AxeItem.java.patch b/patches/minecraft/net/minecraft/world/item/AxeItem.java.patch deleted file mode 100644 index 64ef0e2db7..0000000000 --- a/patches/minecraft/net/minecraft/world/item/AxeItem.java.patch +++ /dev/null @@ -1,56 +0,0 @@ ---- a/net/minecraft/world/item/AxeItem.java -+++ b/net/minecraft/world/item/AxeItem.java -@@ -65,7 +_,7 @@ - return InteractionResult.PASS; - } - -- Optional newBlock = this.evaluateNewBlockState(level, pos, player, level.getBlockState(pos)); -+ Optional newBlock = this.evaluateNewBlockState(level, pos, player, level.getBlockState(pos), context); - if (newBlock.isEmpty()) { - return InteractionResult.PASS; - } -@@ -92,17 +_,24 @@ - } - - private Optional evaluateNewBlockState(final Level level, final BlockPos pos, final @Nullable Player player, final BlockState oldState) { -- Optional strippedBlock = this.getStripped(oldState); -+ return this.evaluateNewBlockState(level, pos, player, oldState, null); -+ } -+ -+ private Optional evaluateNewBlockState(final Level level, final BlockPos pos, final @Nullable Player player, final BlockState oldState, final @Nullable UseOnContext ctx) { -+ var strip = ctx == null ? null : oldState.getToolModifiedState(ctx, net.minecraftforge.common.ToolActions.AXE_STRIP, false); -+ Optional strippedBlock = strip != null ? Optional.of(strip) : this.getStripped(oldState); - if (strippedBlock.isPresent()) { - level.playSound(player, pos, SoundEvents.AXE_STRIP, SoundSource.BLOCKS, 1.0F, 1.0F); - return strippedBlock; - } else { -- Optional scrapedBlock = WeatheringCopper.getPrevious(oldState); -+ var scrape = ctx == null ? null : oldState.getToolModifiedState(ctx, net.minecraftforge.common.ToolActions.AXE_SCRAPE, false); -+ Optional scrapedBlock = scrape != null ? Optional.of(scrape) : WeatheringCopper.getPrevious(oldState); - if (scrapedBlock.isPresent()) { - spawnSoundAndParticle(level, pos, player, oldState, SoundEvents.AXE_SCRAPE, 3005); - return scrapedBlock; - } else { -- Optional waxoffBlock = Optional.ofNullable(HoneycombItem.WAX_OFF_BY_BLOCK.get().get(oldState.getBlock())) -+ var waxOff = ctx == null ? null : oldState.getToolModifiedState(ctx, net.minecraftforge.common.ToolActions.AXE_WAX_OFF, false); -+ Optional waxoffBlock = waxOff != null ? Optional.of(waxOff) : Optional.ofNullable(HoneycombItem.WAX_OFF_BY_BLOCK.get().get(oldState.getBlock())) - .map(b -> b.withPropertiesOf(oldState)); - if (waxoffBlock.isPresent()) { - spawnSoundAndParticle(level, pos, player, oldState, SoundEvents.AXE_WAX_OFF, 3004); -@@ -129,5 +_,16 @@ - private Optional getStripped(final BlockState state) { - return Optional.ofNullable(STRIPPABLES.get(state.getBlock())) - .map(block -> block.defaultBlockState().setValue(RotatedPillarBlock.AXIS, state.getValue(RotatedPillarBlock.AXIS))); -+ } -+ -+ @Override -+ public boolean canPerformAction(ItemStack stack, net.minecraftforge.common.ToolAction toolAction) { -+ return net.minecraftforge.common.ToolActions.DEFAULT_AXE_ACTIONS.contains(toolAction); -+ } -+ -+ @Nullable -+ public static BlockState getAxeStrippingState(BlockState originalState) { -+ Block block = STRIPPABLES.get(originalState.getBlock()); -+ return block != null ? block.defaultBlockState().setValue(RotatedPillarBlock.AXIS, originalState.getValue(RotatedPillarBlock.AXIS)) : null; - } - } diff --git a/patches/minecraft/net/minecraft/world/item/BlockItem.java.patch b/patches/minecraft/net/minecraft/world/item/BlockItem.java.patch index 8a01695623..0bb2e283ac 100644 --- a/patches/minecraft/net/minecraft/world/item/BlockItem.java.patch +++ b/patches/minecraft/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 -@@ -83,17 +_,23 @@ +@@ -92,17 +_,23 @@ } } @@ -26,7 +26,7 @@ public @Nullable BlockPlaceContext updatePlacementContext(final BlockPlaceContext context) { return context; } -@@ -188,6 +_,10 @@ +@@ -191,6 +_,10 @@ public void registerBlocks(final Map map, final Item item) { map.put(this.getBlock(), item); diff --git a/patches/minecraft/net/minecraft/world/item/BoneMealItem.java.patch b/patches/minecraft/net/minecraft/world/item/BoneMealItem.java.patch index f6bccac981..ce0cc43fb8 100644 --- a/patches/minecraft/net/minecraft/world/item/BoneMealItem.java.patch +++ b/patches/minecraft/net/minecraft/world/item/BoneMealItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/BoneMealItem.java +++ b/net/minecraft/world/item/BoneMealItem.java -@@ -37,7 +_,7 @@ +@@ -38,7 +_,7 @@ BlockPos pos = context.getClickedPos(); BlockPos relative = pos.relative(context.getClickedFace()); ItemStack boneMealStack = context.getItemInHand(); @@ -9,7 +9,7 @@ if (!level.isClientSide()) { boneMealStack.causeUseVibration(context.getPlayer(), GameEvent.ITEM_INTERACT_FINISH); level.levelEvent(1505, pos, 15); -@@ -61,8 +_,18 @@ +@@ -62,8 +_,18 @@ } } @@ -25,6 +25,6 @@ BlockState state = level.getBlockState(pos); + int hook = net.minecraftforge.event.ForgeEventFactory.onApplyBonemeal(player, level, pos, state, itemStack); + if (hook != 0) return hook > 0; - if (state.getBlock() instanceof BonemealableBlock block && block.isValidBonemealTarget(level, pos, state)) { + if (state.getBlock() instanceof BonemealableBlock block && block.isValidBonemealTarget(level, pos, state, BonemealSource.INTERACTION)) { if (level instanceof ServerLevel serverLevel) { - if (block.isBonemealSuccess(level, level.getRandom(), pos, state)) { + if (block.isBonemealSuccess(level, level.getRandom(), pos, state, BonemealSource.INTERACTION)) { diff --git a/patches/minecraft/net/minecraft/world/item/BucketItem.java.patch b/patches/minecraft/net/minecraft/world/item/BucketItem.java.patch index b90ffe3574..55cdedc6de 100644 --- a/patches/minecraft/net/minecraft/world/item/BucketItem.java.patch +++ b/patches/minecraft/net/minecraft/world/item/BucketItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/BucketItem.java +++ b/net/minecraft/world/item/BucketItem.java -@@ -32,17 +_,31 @@ +@@ -34,17 +_,31 @@ import org.jspecify.annotations.Nullable; public class BucketItem extends Item implements DispensibleContainerItem { @@ -33,7 +33,7 @@ if (hitResult.getType() == HitResult.Type.MISS) { return InteractionResult.PASS; } -@@ -56,8 +_,8 @@ +@@ -58,8 +_,8 @@ BlockPos directionOffsetPos = pos.relative(direction); if (level.mayInteract(player, pos) && player.mayUseItemAt(directionOffsetPos, direction, itemStack)) { BlockState clicked = level.getBlockState(pos); @@ -44,7 +44,7 @@ this.checkExtraContent(player, level, itemStack, placePos); if (player instanceof ServerPlayer serverPlayer && this.content != Fluids.EMPTY) { CriteriaTriggers.PLACED_BLOCK.trigger(serverPlayer, placePos, itemStack); -@@ -73,7 +_,7 @@ +@@ -75,7 +_,7 @@ ItemStack taken = bucketPickupBlock.pickupBlock(player, level, pos, blockState); if (!taken.isEmpty()) { player.awardStat(Stats.ITEM_USED.get(this)); @@ -53,7 +53,7 @@ level.gameEvent(player, GameEvent.FLUID_PICKUP, pos); ItemStack result = ItemUtils.createFilledResult(itemStack, player, taken); if (!level.isClientSide()) { -@@ -104,8 +_,13 @@ +@@ -106,8 +_,13 @@ public void checkExtraContent(final @Nullable LivingEntity user, final Level level, final ItemStack itemStack, final BlockPos pos) { } @@ -67,32 +67,37 @@ if (!(this.content instanceof FlowingFluid flowingFluid)) { return false; } else { -@@ -116,8 +_,14 @@ - boolean placeLiquid = mayReplace +@@ -119,6 +_,12 @@ || block instanceof LiquidBlockContainer container && container.canPlaceLiquid(user, level, pos, blockState, this.content); boolean canPlaceFluidInsideBlock = blockState.isAir() || placeLiquid && (!shiftKeyDown || hitResult == null); -+ var containedFluidStack = java.util.Optional.ofNullable(containerItem).flatMap(net.minecraftforge.fluids.FluidUtil::getFluidContained); - if (!canPlaceFluidInsideBlock) { + if (canPlaceFluidInsideBlock) { ++ var containedFluidStack = java.util.Optional.ofNullable(containerItem).flatMap(net.minecraftforge.fluids.FluidUtil::getFluidContained); ++ if (containedFluidStack.isPresent() && this.content.getFluidType().isVaporizedOnPlacement(level, pos, containedFluidStack.get())) { ++ this.content.getFluidType().onVaporize(user, level, pos, containedFluidStack.get()); ++ return true; ++ } ++ + if (level.environmentAttributes().getValue(EnvironmentAttributes.WATER_EVAPORATES, pos) && this.content.is(FluidTags.WATER)) { + int x = pos.getX(); + int y = pos.getY(); +@@ -132,7 +_,7 @@ + } + + return true; +- } else if (block instanceof LiquidBlockContainer container && this.content == Fluids.WATER) { ++ } else if (block instanceof LiquidBlockContainer container && this.content == Fluids.WATER && container.canPlaceLiquid(user, level, pos, blockState, content)) { + container.placeLiquid(level, pos, blockState, flowingFluid.getSource(false)); + this.playEmptySound(user, level, pos); + return true; +@@ -149,15 +_,40 @@ + return true; + } + } else { - return hitResult != null && this.emptyContents(user, level, hitResult.getBlockPos().relative(hitResult.getDirection()), null); + return hitResult != null && this.emptyContents(user, level, hitResult.getBlockPos().relative(hitResult.getDirection()), null, containerItem); -+ } -+ -+ if (containedFluidStack.isPresent() && this.content.getFluidType().isVaporizedOnPlacement(level, pos, containedFluidStack.get())) { -+ this.content.getFluidType().onVaporize(user, level, pos, containedFluidStack.get()); -+ return true; } - - if (level.environmentAttributes().getValue(EnvironmentAttributes.WATER_EVAPORATES, pos) && this.content.is(FluidTags.WATER)) { -@@ -132,7 +_,7 @@ - } - - return true; -- } else if (block instanceof LiquidBlockContainer container && this.content == Fluids.WATER) { -+ } else if (block instanceof LiquidBlockContainer container && container.canPlaceLiquid(user, level, pos, blockState, content) && this.content == Fluids.WATER) { - container.placeLiquid(level, pos, blockState, flowingFluid.getSource(false)); - this.playEmptySound(user, level, pos); - return true; -@@ -153,8 +_,33 @@ + } + } protected void playEmptySound(final @Nullable LivingEntity user, final LevelAccessor level, final BlockPos pos) { SoundEvent soundEvent = this.content.is(FluidTags.LAVA) ? SoundEvents.BUCKET_EMPTY_LAVA : SoundEvents.BUCKET_EMPTY; diff --git a/patches/minecraft/net/minecraft/world/item/BundleItem.java.patch b/patches/minecraft/net/minecraft/world/item/BundleItem.java.patch index 9b1a179268..b9b3690e00 100644 --- a/patches/minecraft/net/minecraft/world/item/BundleItem.java.patch +++ b/patches/minecraft/net/minecraft/world/item/BundleItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/BundleItem.java +++ b/net/minecraft/world/item/BundleItem.java -@@ -97,6 +_,7 @@ +@@ -98,6 +_,7 @@ public boolean overrideOtherStackedOnMe( final ItemStack self, final ItemStack other, final Slot slot, final ClickAction clickAction, final Player player, final SlotAccess carriedItem ) { diff --git a/patches/minecraft/net/minecraft/world/item/CrossbowItem.java.patch b/patches/minecraft/net/minecraft/world/item/CrossbowItem.java.patch index 1874ab130d..32385c09c8 100644 --- a/patches/minecraft/net/minecraft/world/item/CrossbowItem.java.patch +++ b/patches/minecraft/net/minecraft/world/item/CrossbowItem.java.patch @@ -7,4 +7,4 @@ + if (shooter instanceof Player player && net.minecraftforge.event.ForgeEventFactory.onArrowLoose(weapon, shooter.level(), player, 1, true) < 0) return; ChargedProjectiles charged = weapon.set(DataComponents.CHARGED_PROJECTILES, ChargedProjectiles.EMPTY); if (charged != null && !charged.isEmpty()) { - this.shoot(serverLevel, shooter, hand, weapon, charged.itemCopies(), power, uncertainty, shooter instanceof Player, targetOverride); + List projectiles = charged.itemCopies().toList(); diff --git a/patches/minecraft/net/minecraft/world/item/HoeItem.java.patch b/patches/minecraft/net/minecraft/world/item/HoeItem.java.patch deleted file mode 100644 index 590f71809b..0000000000 --- a/patches/minecraft/net/minecraft/world/item/HoeItem.java.patch +++ /dev/null @@ -1,36 +0,0 @@ ---- a/net/minecraft/world/item/HoeItem.java -+++ b/net/minecraft/world/item/HoeItem.java -@@ -21,6 +_,12 @@ - import net.minecraft.world.level.gameevent.GameEvent; - - public class HoeItem extends Item { -+ /** -+ * @deprecated Forge: This map is patched out of vanilla code. -+ * Listen to {@link net.minecraftforge.event.world.BlockEvent.BlockToolModificationEvent} -+ * or override {@link net.minecraftforge.common.extensions.IForgeBlock#getToolModifiedState(BlockState, UseOnContext, net.minecraftforge.common.ToolAction, boolean)}. -+ */ -+ @Deprecated - protected static final Map, Consumer>> TILLABLES = Maps.newHashMap( - ImmutableMap.of( - Blocks.GRASS_BLOCK, -@@ -44,7 +_,8 @@ - public InteractionResult useOn(final UseOnContext context) { - Level level = context.getLevel(); - BlockPos pos = context.getClickedPos(); -- Pair, Consumer> logicPair = TILLABLES.get(level.getBlockState(pos).getBlock()); -+ BlockState toolModifiedState = level.getBlockState(pos).getToolModifiedState(context, net.minecraftforge.common.ToolActions.HOE_TILL, false); -+ Pair, Consumer> logicPair = toolModifiedState == null ? null : Pair.of(ctx -> true, changeIntoState(toolModifiedState)); - if (logicPair == null) { - return InteractionResult.PASS; - } -@@ -84,5 +_,10 @@ - - public static boolean onlyIfAirAbove(final UseOnContext context) { - return context.getClickedFace() != Direction.DOWN && context.getLevel().getBlockState(context.getClickedPos().above()).isAir(); -+ } -+ -+ @Override -+ public boolean canPerformAction(ItemStack stack, net.minecraftforge.common.ToolAction toolAction) { -+ return net.minecraftforge.common.ToolActions.DEFAULT_HOE_ACTIONS.contains(toolAction); - } - } diff --git a/patches/minecraft/net/minecraft/world/item/Item.java.patch b/patches/minecraft/net/minecraft/world/item/Item.java.patch index 6643c1cfdd..fb5211d863 100644 --- a/patches/minecraft/net/minecraft/world/item/Item.java.patch +++ b/patches/minecraft/net/minecraft/world/item/Item.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/Item.java +++ b/net/minecraft/world/item/Item.java -@@ -96,7 +_,7 @@ +@@ -109,7 +_,7 @@ import org.jspecify.annotations.Nullable; import org.slf4j.Logger; @@ -9,7 +9,7 @@ public static final Codec> CODEC = BuiltInRegistries.ITEM .holderByNameCodec() .validate(item -> item.is(Items.AIR.builtInRegistryHolder()) ? DataResult.error(() -> "Item must not be minecraft:air") : DataResult.success(item)); -@@ -107,7 +_,7 @@ +@@ -120,7 +_,7 @@ : DataResult.success(item) ); private static final Logger LOGGER = LogUtils.getLogger(); @@ -18,7 +18,7 @@ public static final Identifier BASE_ATTACK_DAMAGE_ID = Identifier.withDefaultNamespace("base_attack_damage"); public static final Identifier BASE_ATTACK_SPEED_ID = Identifier.withDefaultNamespace("base_attack_speed"); public static final int DEFAULT_MAX_STACK_SIZE = 64; -@@ -146,6 +_,7 @@ +@@ -159,6 +_,7 @@ LOGGER.error("Item classes should end with Item and {} doesn't.", className); } } @@ -26,7 +26,7 @@ } @Deprecated -@@ -153,8 +_,15 @@ +@@ -166,8 +_,15 @@ return this.builtInRegistryHolder; } @@ -43,7 +43,7 @@ } public int getDefaultMaxStackSize() { -@@ -164,6 +_,7 @@ +@@ -177,6 +_,7 @@ public void onUseTick(final Level level, final LivingEntity livingEntity, final ItemStack itemStack, final int ticksRemaining) { } @@ -51,7 +51,7 @@ public void onDestroyed(final ItemEntity itemEntity) { } -@@ -282,6 +_,8 @@ +@@ -297,6 +_,8 @@ return BuiltInRegistries.ITEM.wrapAsHolder(this).getRegisteredName(); } @@ -60,7 +60,7 @@ public final @Nullable ItemStackTemplate getCraftingRemainder() { return this.craftingRemainingItem; } -@@ -374,6 +_,30 @@ +@@ -389,6 +_,30 @@ return false; } @@ -91,7 +91,7 @@ public static class Properties { private static final DependantName BLOCK_DESCRIPTION_ID = id -> Util.makeDescriptionId("block", id.identifier()); private static final DependantName ITEM_DESCRIPTION_ID = id -> Util.makeDescriptionId("item", id.identifier()); -@@ -722,6 +_,11 @@ +@@ -773,6 +_,11 @@ boolean isPeaceful(); @@ -103,7 +103,7 @@ static Item.TooltipContext of(final @Nullable Level level) { return level == null ? EMPTY : new Item.TooltipContext() { @Override -@@ -742,6 +_,11 @@ +@@ -793,6 +_,11 @@ @Override public boolean isPeaceful() { return level.getDifficulty() == Difficulty.PEACEFUL; diff --git a/patches/minecraft/net/minecraft/world/item/ItemStack.java.patch b/patches/minecraft/net/minecraft/world/item/ItemStack.java.patch index 559de64dbb..33a8e0be49 100644 --- a/patches/minecraft/net/minecraft/world/item/ItemStack.java.patch +++ b/patches/minecraft/net/minecraft/world/item/ItemStack.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/ItemStack.java +++ b/net/minecraft/world/item/ItemStack.java -@@ -99,7 +_,7 @@ +@@ -100,7 +_,7 @@ import org.jspecify.annotations.Nullable; import org.slf4j.Logger; @@ -9,7 +9,7 @@ private static final List OP_NBT_WARNING = List.of( Component.translatable("item.op_warning.line1").withStyle(ChatFormatting.RED, ChatFormatting.BOLD), Component.translatable("item.op_warning.line2").withStyle(ChatFormatting.RED), -@@ -257,12 +_,15 @@ +@@ -258,12 +_,15 @@ } private ItemStack(final Holder item, final int count, final PatchedDataComponentMap components) { @@ -25,7 +25,7 @@ this.item = null; this.components = new PatchedDataComponentMap(DataComponentMap.EMPTY); } -@@ -355,6 +_,15 @@ +@@ -356,6 +_,15 @@ } public InteractionResult useOn(final UseOnContext context) { @@ -41,19 +41,19 @@ Player player = context.getPlayer(); BlockPos pos = context.getClickedPos(); if (player != null && !player.getAbilities().mayBuild && !this.canPlaceOnBlockInAdventureMode(new BlockInWorld(context.getLevel(), pos, false))) { -@@ -362,7 +_,7 @@ - } - - Item usedItem = this.getItem(); -- InteractionResult result = usedItem.useOn(context); -+ InteractionResult result = callback.apply(context); - if (player != null && result instanceof InteractionResult.Success success && success.wasItemInteraction()) { - player.awardStat(Stats.ITEM_USED.get(usedItem)); - } -@@ -442,18 +_,26 @@ +@@ -363,7 +_,7 @@ + } else { + ItemStack stackBeforeUse = this.copy(); + Item usedItem = this.getItem(); +- InteractionResult result = usedItem.useOn(context); ++ InteractionResult result = callback.apply(context); + if (player != null && result instanceof InteractionResult.Success success && success.wasItemInteraction()) { + player.awardStat(Stats.ITEM_USED.get(usedItem)); + ItemStack transformTo = success.heldItemTransformedTo() == null ? this : success.heldItemTransformedTo(); +@@ -447,18 +_,26 @@ } - public void hurtAndBreak(final int amount, final ServerLevel level, final @Nullable ServerPlayer player, final Consumer onBreak) { + public void hurtAndBreak(final int amount, final ServerLevel level, final @Nullable ServerPlayer player, final Consumer onBreak) { - int newAmount = this.processDurabilityChange(amount, level, player); + // FORGE: use context-sensitive sister of processDurabilityChange that calls IForgeItem.damageItem + int newAmount = this.processDurabilityChange(amount, level, player, true, onBreak); @@ -63,11 +63,11 @@ } private int processDurabilityChange(final int amount, final ServerLevel level, final @Nullable ServerPlayer player) { -+ return this.processDurabilityChange(amount, level, player, false, item -> { }); ++ return this.processDurabilityChange(amount, level, player, false, _ -> { }); + } + + /** FORGE: context-sensitive sister of processDurabilityChange that calls IForgeItem.damageItem */ -+ private int processDurabilityChange(int amount, final ServerLevel level, final @Nullable ServerPlayer player, final boolean canBreak, final Consumer onBreak) { ++ private int processDurabilityChange(int amount, final ServerLevel level, final @Nullable ServerPlayer player, final boolean canBreak, final Consumer onBreak) { if (!this.isDamageableItem()) { return 0; } else if (player != null && player.hasInfiniteMaterials()) { @@ -78,7 +78,7 @@ return amount > 0 ? EnchantmentHelper.processDurabilityChange(level, this, amount) : amount; } } -@@ -490,7 +_,13 @@ +@@ -495,7 +_,13 @@ public void hurtAndBreak(final int amount, final LivingEntity owner, final EquipmentSlot slot) { if (owner.level() instanceof ServerLevel serverLevel) { this.hurtAndBreak( @@ -93,7 +93,7 @@ ); } } -@@ -857,6 +_,7 @@ +@@ -873,6 +_,7 @@ List lines = Lists.newArrayList(); lines.add(this.getStyledHoverName()); this.addDetailsToTooltip(context, display, player, tooltipFlag, lines::add); @@ -101,7 +101,7 @@ return lines; } } -@@ -1105,6 +_,7 @@ +@@ -1127,6 +_,7 @@ } } diff --git a/patches/minecraft/net/minecraft/world/item/Items.java.patch b/patches/minecraft/net/minecraft/world/item/Items.java.patch index 3e3e617bf7..63bac5323b 100644 --- a/patches/minecraft/net/minecraft/world/item/Items.java.patch +++ b/patches/minecraft/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 -@@ -2099,7 +_,25 @@ +@@ -2972,7 +_,25 @@ } private static Item registerBlock(final BlockItemId id, final Block block, final Block... alternatives) { @@ -27,7 +27,7 @@ for (Block alternative : alternatives) { Item.BY_BLOCK.put(alternative, item); -@@ -2140,10 +_,6 @@ +@@ -3027,10 +_,6 @@ private static Item registerItem(final ResourceKey id, final Function itemFactory, final Item.Properties properties) { Item item = itemFactory.apply(properties.setId(id)); diff --git a/patches/minecraft/net/minecraft/world/item/ShovelItem.java.patch b/patches/minecraft/net/minecraft/world/item/ShovelItem.java.patch deleted file mode 100644 index 8d0bc05084..0000000000 --- a/patches/minecraft/net/minecraft/world/item/ShovelItem.java.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/net/minecraft/world/item/ShovelItem.java -+++ b/net/minecraft/world/item/ShovelItem.java -@@ -43,9 +_,9 @@ - } - - Player player = context.getPlayer(); -- BlockState newState = FLATTENABLES.get(blockState.getBlock()); -+ BlockState newState = blockState.getToolModifiedState(context, net.minecraftforge.common.ToolActions.SHOVEL_FLATTEN, false); - BlockState updatedState = null; -- if (newState != null && level.getBlockState(pos.above()).isAir()) { -+ if (newState != null && level.isEmptyBlock(pos.above())) { - level.playSound(player, pos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F); - updatedState = newState; - } else if (blockState.getBlock() instanceof CampfireBlock && blockState.getValue(CampfireBlock.LIT)) { -@@ -70,5 +_,15 @@ - } else { - return InteractionResult.PASS; - } -+ } -+ -+ @org.jetbrains.annotations.Nullable -+ public static BlockState getShovelPathingState(BlockState originalState) { -+ return FLATTENABLES.get(originalState.getBlock()); -+ } -+ -+ @Override -+ public boolean canPerformAction(ItemStack stack, net.minecraftforge.common.ToolAction toolAction) { -+ return net.minecraftforge.common.ToolActions.DEFAULT_SHOVEL_ACTIONS.contains(toolAction); - } - } diff --git a/patches/minecraft/net/minecraft/world/item/alchemy/PotionBrewing.java.patch b/patches/minecraft/net/minecraft/world/item/alchemy/PotionBrewing.java.patch deleted file mode 100644 index b6321fc02b..0000000000 --- a/patches/minecraft/net/minecraft/world/item/alchemy/PotionBrewing.java.patch +++ /dev/null @@ -1,134 +0,0 @@ ---- a/net/minecraft/world/item/alchemy/PotionBrewing.java -+++ b/net/minecraft/world/item/alchemy/PotionBrewing.java -@@ -19,17 +_,37 @@ - private final List containers; - private final List> potionMixes; - private final List> containerMixes; -+ private final List recipes; - - private PotionBrewing( - final List containers, final List> potionMixes, final List> containerMixes - ) { -+ this(containers, potionMixes, containerMixes, null); -+ } -+ -+ PotionBrewing(final List containers, final List> potionMixes, final List> containerMixes, Builder builder) { - this.containers = containers; - this.potionMixes = potionMixes; - this.containerMixes = containerMixes; -+ var tmp = new ArrayList(); -+ tmp.add(new net.minecraftforge.common.brewing.VanillaBrewingRecipe(this, this::mixVanilla)); -+ if (builder != null) { -+ tmp.addAll(builder.recipes); -+ } -+ this.recipes = java.util.Collections.unmodifiableList(tmp); - } - - public boolean isIngredient(final ItemStack ingredient) { -- return this.isContainerIngredient(ingredient) || this.isPotionIngredient(ingredient); -+ if (ingredient.isEmpty()) { -+ return false; -+ } -+ -+ for (var recipe : recipes) { -+ if (recipe.isIngredient(ingredient)) { -+ return true; -+ } -+ } -+ return false; - } - - private boolean isContainer(final ItemStack input) { -@@ -73,9 +_,10 @@ - } - - public boolean hasMix(final ItemStack source, final ItemStack ingredient) { -- return !this.isContainer(source) ? false : this.hasContainerMix(source, ingredient) || this.hasPotionMix(source, ingredient); -+ return !mix(ingredient, source).isEmpty(); - } - -+ /** @deprecated Forge: use hasMix(ItemStack, ItemStack)*/ - public boolean hasContainerMix(final ItemStack source, final ItemStack ingredient) { - for (PotionBrewing.Mix mix : this.containerMixes) { - if (source.is(mix.from) && mix.ingredient.test(ingredient)) { -@@ -86,6 +_,7 @@ - return false; - } - -+ /** @deprecated Forge: use hasMix(ItemStack, ItemStack)*/ - public boolean hasPotionMix(final ItemStack source, final ItemStack ingredient) { - Optional> potion = source.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY).potion(); - if (potion.isEmpty()) { -@@ -102,6 +_,19 @@ - } - - public ItemStack mix(final ItemStack ingredient, final ItemStack source) { -+ if (source.isEmpty() || source.getCount() != 1) return ItemStack.EMPTY; -+ if (ingredient.isEmpty()) return ItemStack.EMPTY; -+ -+ for (var recipe : recipes) { -+ ItemStack output = recipe.getOutput(source, ingredient); -+ if (!output.isEmpty()) { -+ return output; -+ } -+ } -+ return ItemStack.EMPTY; -+ } -+ -+ private ItemStack mixVanilla(final ItemStack ingredient, final ItemStack source) { - if (source.isEmpty()) { - return source; - } -@@ -126,9 +_,29 @@ - return source; - } - -+ /** -+ * Returns true if the passed ItemStack is a valid input for the start of a recipe -+ */ -+ public boolean isValidInput(ItemStack stack) { -+ for (var recipe : recipes) { -+ if (recipe.isInput(stack)) { -+ return true; -+ } -+ } -+ return false; -+ } -+ -+ /** -+ * Returns an unmodifiable list containing all the recipes in the registry -+ */ -+ public List getRecipes() { -+ return this.recipes; -+ } -+ - public static PotionBrewing bootstrap(final FeatureFlagSet enabledFeatures) { - PotionBrewing.Builder builder = new PotionBrewing.Builder(enabledFeatures); - addVanillaMixes(builder); -+ net.minecraftforge.event.ForgeEventFactory.onBrewingRecipeRegister(builder, enabledFeatures); - return builder.build(); - } - -@@ -197,6 +_,7 @@ - private final List> potionMixes = new ArrayList<>(); - private final List> containerMixes = new ArrayList<>(); - private final FeatureFlagSet enabledFeatures; -+ private final List recipes = new ArrayList<>(); - - public Builder(final FeatureFlagSet enabledFeatures) { - this.enabledFeatures = enabledFeatures; -@@ -236,8 +_,13 @@ - } - } - -+ public Builder add(net.minecraftforge.common.brewing.IBrewingRecipe recipe) { -+ this.recipes.add(recipe); -+ return this; -+ } -+ - public PotionBrewing build() { -- return new PotionBrewing(List.copyOf(this.containers), List.copyOf(this.potionMixes), List.copyOf(this.containerMixes)); -+ return new PotionBrewing(List.copyOf(this.containers), List.copyOf(this.potionMixes), List.copyOf(this.containerMixes), this); - } - } - diff --git a/patches/minecraft/net/minecraft/world/item/crafting/Ingredient.java.patch b/patches/minecraft/net/minecraft/world/item/crafting/Ingredient.java.patch index 3defabf390..f886fb140d 100644 --- a/patches/minecraft/net/minecraft/world/item/crafting/Ingredient.java.patch +++ b/patches/minecraft/net/minecraft/world/item/crafting/Ingredient.java.patch @@ -33,7 +33,7 @@ values.unwrap().ifRight(directValues -> { if (directValues.isEmpty()) { throw new UnsupportedOperationException("Ingredients can't be empty"); -@@ -113,5 +_,50 @@ +@@ -111,6 +_,36 @@ } else { return inputDisplay; } @@ -49,22 +49,7 @@ + } + + public static final net.minecraftforge.common.crafting.ingredients.IIngredientSerializer VANILLA_SERIALIZER = -+ new net.minecraftforge.common.crafting.ingredients.IIngredientSerializer() { -+ @Override -+ public com.mojang.serialization.MapCodec codec() { -+ return VANILLA_MAP_CODEC; -+ } -+ -+ @Override -+ public void write(RegistryFriendlyByteBuf buffer, Ingredient value) { -+ VANILLA_CONTENTS_STREAM_CODEC.encode(buffer, value); -+ } -+ -+ @Override -+ public Ingredient read(RegistryFriendlyByteBuf buffer) { -+ return VANILLA_CONTENTS_STREAM_CODEC.decode(buffer); -+ } -+ }; ++ net.minecraftforge.common.crafting.ingredients.IIngredientSerializer.simple(VANILLA_MAP_CODEC, VANILLA_CONTENTS_STREAM_CODEC); + + public net.minecraftforge.common.crafting.ingredients.IIngredientSerializer serializer() { + if (!isVanilla()) throw new IllegalStateException("Modders must implement Ingredient.codec in their custom Ingredients: " + getClass()); @@ -83,4 +68,5 @@ + buf.append(']'); + return buf.toString(); } - } + + public Optional> getSingleItem() { diff --git a/patches/minecraft/net/minecraft/world/item/crafting/RecipeManager.java.patch b/patches/minecraft/net/minecraft/world/item/crafting/RecipeManager.java.patch deleted file mode 100644 index c46060b222..0000000000 --- a/patches/minecraft/net/minecraft/world/item/crafting/RecipeManager.java.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- a/net/minecraft/world/item/crafting/RecipeManager.java -+++ b/net/minecraft/world/item/crafting/RecipeManager.java -@@ -61,15 +_,22 @@ - private SelectableRecipe.SingleInputSet stonecutterRecipes = SelectableRecipe.SingleInputSet.empty(); - private List allDisplays = List.of(); - private Map>, List> recipeToDisplay = Map.of(); -+ private final net.minecraftforge.common.crafting.conditions.ICondition.IContext context; //Forge: add context - -+ /** @deprecated Forge: use {@linkplain RecipeManager#RecipeManager(net.minecraftforge.common.crafting.conditions.ICondition.IContext) constructor with context}. */ - public RecipeManager(final HolderLookup.Provider registries) { -+ this(registries, net.minecraftforge.common.crafting.conditions.ICondition.IContext.EMPTY); -+ } -+ -+ public RecipeManager(HolderLookup.Provider registries, net.minecraftforge.common.crafting.conditions.ICondition.IContext context) { - this.registries = registries; -+ this.context = context; - } - - protected RecipeMap prepare(final ResourceManager manager, final ProfilerFiller profiler) { - SortedMap> recipes = new TreeMap<>(); - SimpleJsonResourceReloadListener.scanDirectory( -- manager, RECIPE_LISTER, this.registries.createSerializationContext(JsonOps.INSTANCE), Recipe.CODEC, recipes -+ manager, RECIPE_LISTER, this.context.wrap(this.registries.createSerializationContext(JsonOps.INSTANCE)), Recipe.CODEC, recipes - ); - List> recipeHolders = new ArrayList<>(recipes.size()); - recipes.forEach((id, recipe) -> { -@@ -86,6 +_,7 @@ - } - - public void finalizeRecipeLoading(final FeatureFlagSet enabledFlags) { -+ //net.minecraftforge.event.ForgeEventFactory.onTagsUpdated(this.registries, false, false); - List> stonecutterRecipes = new ArrayList<>(); - List propertySetCollectors = RECIPE_PROPERTY_SETS.entrySet() - .stream() diff --git a/patches/minecraft/net/minecraft/world/item/crafting/RecipeType.java.patch b/patches/minecraft/net/minecraft/world/item/crafting/RecipeType.java.patch index fdbaee08d9..b70d4cdae4 100644 --- a/patches/minecraft/net/minecraft/world/item/crafting/RecipeType.java.patch +++ b/patches/minecraft/net/minecraft/world/item/crafting/RecipeType.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/crafting/RecipeType.java +++ b/net/minecraft/world/item/crafting/RecipeType.java -@@ -21,4 +_,14 @@ +@@ -22,4 +_,14 @@ } }); } diff --git a/patches/minecraft/net/minecraft/world/item/enchantment/EnchantmentHelper.java.patch b/patches/minecraft/net/minecraft/world/item/enchantment/EnchantmentHelper.java.patch index 77af83fa5c..ea9f0fe09c 100644 --- a/patches/minecraft/net/minecraft/world/item/enchantment/EnchantmentHelper.java.patch +++ b/patches/minecraft/net/minecraft/world/item/enchantment/EnchantmentHelper.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/enchantment/EnchantmentHelper.java +++ b/net/minecraft/world/item/enchantment/EnchantmentHelper.java -@@ -602,7 +_,7 @@ +@@ -601,7 +_,7 @@ public static List getAvailableEnchantmentResults(final int value, final ItemStack itemStack, final Stream> source) { List results = Lists.newArrayList(); boolean isBook = itemStack.is(Items.BOOK); diff --git a/patches/minecraft/net/minecraft/world/item/enchantment/effects/ReplaceDisk.java.patch b/patches/minecraft/net/minecraft/world/item/enchantment/effects/ReplaceDisk.java.patch index bec1e9be00..f4dfc47cc1 100644 --- a/patches/minecraft/net/minecraft/world/item/enchantment/effects/ReplaceDisk.java.patch +++ b/patches/minecraft/net/minecraft/world/item/enchantment/effects/ReplaceDisk.java.patch @@ -5,6 +5,6 @@ if (pos.distToCenterSqr(position.x(), pos.getY() + 0.5, position.z()) < Mth.square(dist) && this.predicate.map(p -> p.test(serverLevel, pos)).orElse(true) + && !net.minecraftforge.event.ForgeEventFactory.onBlockPlace(entity, net.minecraftforge.common.util.BlockSnapshot.create(serverLevel.dimension(), serverLevel, centerBlock), net.minecraft.core.Direction.UP) - && serverLevel.setBlockAndUpdate(pos, this.blockState.getState(serverLevel, random, pos))) { + && serverLevel.setBlockAndUpdate(pos, this.blockState.value().getState(serverLevel, random, pos))) { this.triggerGameEvent.ifPresent(event -> serverLevel.gameEvent(entity, (Holder)event, pos)); } diff --git a/patches/minecraft/net/minecraft/world/level/BaseSpawner.java.patch b/patches/minecraft/net/minecraft/world/level/BaseSpawner.java.patch index 29f5661043..ddfd5d8ae0 100644 --- a/patches/minecraft/net/minecraft/world/level/BaseSpawner.java.patch +++ b/patches/minecraft/net/minecraft/world/level/BaseSpawner.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/BaseSpawner.java +++ b/net/minecraft/world/level/BaseSpawner.java -@@ -152,15 +_,16 @@ +@@ -158,15 +_,16 @@ entity.snapTo(entity.getX(), entity.getY(), entity.getZ(), random.nextFloat() * 360.0F, 0.0F); if (entity instanceof Mob mob) { @@ -21,7 +21,7 @@ } nextSpawnData.getEquipment().ifPresent(mob::equip); -@@ -279,5 +_,14 @@ +@@ -285,5 +_,14 @@ public double getOSpin() { return this.oSpin; diff --git a/patches/minecraft/net/minecraft/world/level/Level.java.patch b/patches/minecraft/net/minecraft/world/level/Level.java.patch index c0ee39b1c6..1f4f61da07 100644 --- a/patches/minecraft/net/minecraft/world/level/Level.java.patch +++ b/patches/minecraft/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 -@@ -90,7 +_,7 @@ +@@ -89,7 +_,7 @@ import org.apache.commons.lang3.mutable.MutableBoolean; import org.jspecify.annotations.Nullable; @@ -9,7 +9,7 @@ public static final Codec> RESOURCE_KEY_CODEC = ResourceKey.codec(Registries.DIMENSION); public static final ResourceKey OVERWORLD = ResourceKey.create(Registries.DIMENSION, Identifier.withDefaultNamespace("overworld")); public static final ResourceKey NETHER = ResourceKey.create(Registries.DIMENSION, Identifier.withDefaultNamespace("the_nether")); -@@ -131,6 +_,11 @@ +@@ -130,6 +_,11 @@ private final DamageSources damageSources; private final PalettedContainerFactory palettedContainerFactory; private long subTickCount; @@ -21,7 +21,7 @@ protected Level( final WritableLevelData levelData, -@@ -219,7 +_,7 @@ +@@ -213,7 +_,7 @@ } @Override @@ -30,7 +30,7 @@ if (!this.isInValidBounds(pos)) { return false; } -@@ -230,12 +_,31 @@ +@@ -224,12 +_,31 @@ LevelChunk chunk = this.getChunkAt(pos); Block block = blockState.getBlock(); @@ -63,7 +63,7 @@ if (newState == blockState) { if (oldState != newState) { this.setBlocksDirty(pos, oldState, newState); -@@ -262,9 +_,8 @@ +@@ -256,9 +_,8 @@ } this.updatePOIOnBlockStateChange(pos, oldState, newState); @@ -74,7 +74,7 @@ } public void updatePOIOnBlockStateChange(final BlockPos pos, final BlockState oldState, final BlockState newState) { -@@ -531,8 +_,27 @@ +@@ -529,8 +_,27 @@ (this.tickingBlockEntities ? this.pendingBlockEntityTickers : this.blockEntityTickers).add(ticker); } @@ -102,7 +102,7 @@ if (!this.pendingBlockEntityTickers.isEmpty()) { this.blockEntityTickers.addAll(this.pendingBlockEntityTickers); this.pendingBlockEntityTickers.clear(); -@@ -555,12 +_,19 @@ +@@ -553,12 +_,19 @@ public void guardEntityTick(final Consumer tick, final T entity) { try { @@ -122,7 +122,7 @@ } } -@@ -716,6 +_,7 @@ +@@ -714,6 +_,7 @@ if (this.isInValidBounds(pos)) { this.getChunkAt(pos).removeBlockEntity(pos); } @@ -130,7 +130,7 @@ } public boolean isLoaded(final BlockPos pos) { -@@ -781,8 +_,8 @@ +@@ -779,8 +_,8 @@ } }); @@ -141,7 +141,7 @@ output.add(dragonPart); } } -@@ -815,8 +_,8 @@ +@@ -813,8 +_,8 @@ } } @@ -152,7 +152,7 @@ T castSubPart = type.tryCast(subEntity); if (castSubPart != null && selector.test(castSubPart)) { output.add(castSubPart); -@@ -1004,17 +_,16 @@ +@@ -1013,17 +_,16 @@ public abstract Scoreboard getScoreboard(); public void updateNeighbourForOutputSignal(final BlockPos pos, final Block changedBlock) { @@ -175,7 +175,7 @@ } } } -@@ -1099,6 +_,20 @@ +@@ -1108,6 +_,20 @@ } public abstract ClockManager clockManager(); diff --git a/patches/minecraft/net/minecraft/world/level/LevelReader.java.patch b/patches/minecraft/net/minecraft/world/level/LevelReader.java.patch index bdbe1d6a2b..972a0b13a2 100644 --- a/patches/minecraft/net/minecraft/world/level/LevelReader.java.patch +++ b/patches/minecraft/net/minecraft/world/level/LevelReader.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/LevelReader.java +++ b/net/minecraft/world/level/LevelReader.java -@@ -175,6 +_,11 @@ +@@ -184,6 +_,11 @@ } @Deprecated diff --git a/patches/minecraft/net/minecraft/world/level/NaturalSpawner.java.patch b/patches/minecraft/net/minecraft/world/level/NaturalSpawner.java.patch index 42d63762ca..5cd0c6d835 100644 --- a/patches/minecraft/net/minecraft/world/level/NaturalSpawner.java.patch +++ b/patches/minecraft/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 -@@ -75,7 +_,7 @@ +@@ -74,7 +_,7 @@ for (Entity entity : entities) { if (!(entity instanceof Mob mob && (mob.isPersistenceRequired() || mob.requiresCustomPersistence()))) { @@ -9,7 +9,7 @@ if (category != MobCategory.MISC) { BlockPos pos = entity.blockPosition(); chunkGetter.query(ChunkPos.pack(pos), chunk -> { -@@ -211,7 +_,7 @@ +@@ -207,7 +_,7 @@ groupSize++; level.addFreshEntityWithPassengers(mob); spawnCallback.run(mob, chunk); @@ -18,7 +18,7 @@ return; } -@@ -288,7 +_,7 @@ +@@ -284,7 +_,7 @@ return nearestPlayerDistanceSqr > mob.getType().getCategory().getDespawnDistance() * mob.getType().getCategory().getDespawnDistance() && mob.removeWhenFarAway(nearestPlayerDistanceSqr) ? false @@ -27,32 +27,32 @@ } private static Optional getRandomSpawnMobAt( -@@ -324,9 +_,11 @@ - final BlockPos pos, - final @Nullable Holder biome +@@ -315,9 +_,11 @@ + private static WeightedList mobsAt( + final ServerLevel level, final StructureManager structureManager, final ChunkGenerator generator, final MobCategory mobCategory, final BlockPos pos ) { - return isInNetherFortressBounds(pos, level, mobCategory, structureManager) - ? NetherFortressStructure.FORTRESS_ENEMIES -- : generator.getMobsAt(biome != null ? biome : level.getBiome(pos), structureManager, mobCategory, pos); +- : generator.getMobsAt(level, structureManager, mobCategory, pos); + return net.minecraftforge.event.ForgeEventFactory.getPotentialSpawns(level, mobCategory, pos, + isInNetherFortressBounds(pos, level, mobCategory, structureManager) + ? structureManager.registryAccess().lookupOrThrow(Registries.STRUCTURE).getOrThrow(BuiltinStructures.FORTRESS).get().spawnOverrides().get(MobCategory.MONSTER).spawns() -+ : generator.getMobsAt(biome != null ? biome : level.getBiome(pos), structureManager, mobCategory, pos) ++ : generator.getMobsAt(level, structureManager, mobCategory, pos) + ); } public static boolean isInNetherFortressBounds( -@@ -417,8 +_,7 @@ +@@ -411,8 +_,7 @@ - entity.snapTo(fx, pos.getY(), fz, random.nextFloat() * 360.0F, 0.0F); - if (entity instanceof Mob mob -- && mob.checkSpawnRules(level, EntitySpawnReason.CHUNK_GENERATION) -- && mob.checkSpawnObstruction(level)) { -+ && net.minecraftforge.event.ForgeEventFactory.checkSpawnPosition(mob, level, EntitySpawnReason.CHUNK_GENERATION)) { - groupSpawnData = mob.finalizeSpawn( - level, level.getCurrentDifficultyAt(mob.blockPosition()), EntitySpawnReason.CHUNK_GENERATION, groupSpawnData - ); -@@ -527,7 +_,7 @@ + entity.snapTo(fx, pos.getY(), fz, random.nextFloat() * 360.0F, 0.0F); + if (entity instanceof Mob mob +- && mob.checkSpawnRules(level, EntitySpawnReason.CHUNK_GENERATION) +- && mob.checkSpawnObstruction(level)) { ++ && net.minecraftforge.event.ForgeEventFactory.checkSpawnPosition(mob, level, EntitySpawnReason.CHUNK_GENERATION)) { + groupSpawnData = mob.finalizeSpawn( + level, level.getCurrentDifficultyAt(mob.blockPosition()), EntitySpawnReason.CHUNK_GENERATION, groupSpawnData + ); +@@ -524,7 +_,7 @@ } this.spawnPotential.addCharge(pos, charge); diff --git a/patches/minecraft/net/minecraft/world/level/biome/Biome.java.patch b/patches/minecraft/net/minecraft/world/level/biome/Biome.java.patch index f847507ef4..592ab5a914 100644 --- a/patches/minecraft/net/minecraft/world/level/biome/Biome.java.patch +++ b/patches/minecraft/net/minecraft/world/level/biome/Biome.java.patch @@ -1,29 +1,21 @@ --- a/net/minecraft/world/level/biome/Biome.java +++ b/net/minecraft/world/level/biome/Biome.java -@@ -35,9 +_,9 @@ - public final class Biome { - public static final Codec DIRECT_CODEC = RecordCodecBuilder.create( - i -> i.group( -- Biome.ClimateSettings.CODEC.forGetter(b -> b.climateSettings), -+ Biome.ClimateSettings.CODEC.forGetter(b -> b.modifiableBiomeInfo().getOriginalBiomeInfo().climateSettings()), // FORGE: Patch codec to ignore field redirect coremods. - EnvironmentAttributeMap.CODEC_ONLY_POSITIONAL.optionalFieldOf("attributes", EnvironmentAttributeMap.EMPTY).forGetter(b -> b.attributes), -- BiomeSpecialEffects.CODEC.fieldOf("effects").forGetter(b -> b.specialEffects), -+ BiomeSpecialEffects.CODEC.fieldOf("effects").forGetter(b -> b.modifiableBiomeInfo().getOriginalBiomeInfo().effects()), // FORGE: Patch codec to ignore field redirect coremods. - BiomeGenerationSettings.CODEC.forGetter(b -> b.generationSettings), - MobSpawnSettings.CODEC.forGetter(b -> b.mobSettings) - ) -@@ -65,8 +_,10 @@ +@@ -71,10 +_,10 @@ @Deprecated(forRemoval = true) - public static final PerlinSimplexNoise BIOME_INFO_NOISE = new PerlinSimplexNoise(new WorldgenRandom(new LegacyRandomSource(2345L)), ImmutableList.of(0)); + public static final Noise BIOME_INFO_NOISE = new SimplexNoise(new WorldgenRandom(new LegacyRandomSource(2345L)), true); private static final int TEMPERATURE_CACHE_SIZE = 1024; -+ /** @deprecated Redirected to {@link #getModifiedClimateSettings()} by field_to_method.js */ - private final Biome.ClimateSettings climateSettings; - private final BiomeGenerationSettings generationSettings; -+ /** @deprecated Redirected to {@link #getModifiedSpecialEffects()} by field_to_method.js */ - private final MobSpawnSettings mobSettings; - private final EnvironmentAttributeMap attributes; - private final BiomeSpecialEffects specialEffects; -@@ -79,6 +_,7 @@ +- private final Biome.ClimateSettings climateSettings; +- private final BiomeGenerationSettings generationSettings; +- private final EnvironmentAttributeMap attributes; +- private final BiomeSpecialEffects specialEffects; ++ private Biome.ClimateSettings climateSettings; ++ private BiomeGenerationSettings generationSettings; ++ private EnvironmentAttributeMap attributes; ++ private BiomeSpecialEffects specialEffects; + private final ThreadLocal temperatureCache = ThreadLocal.withInitial(() -> { + Long2FloatLinkedOpenHashMap map = new Long2FloatLinkedOpenHashMap(1024, 0.25F) { + @Override +@@ -84,6 +_,7 @@ map.defaultReturnValue(Float.NaN); return map; }); @@ -31,20 +23,23 @@ private Biome( final Biome.ClimateSettings climateSettings, -@@ -92,10 +_,11 @@ - this.mobSettings = mobSettings; +@@ -95,6 +_,15 @@ this.attributes = attributes; this.specialEffects = specialEffects; -+ this.modifiableBiomeInfo = new net.minecraftforge.common.world.ModifiableBiomeInfo(new net.minecraftforge.common.world.ModifiableBiomeInfo.BiomeInfo(climateSettings, specialEffects, generationSettings, mobSettings)); // FORGE: cache original biome info on construction so we can bypass our field read coremods where necessary - } - - public MobSpawnSettings getMobSettings() { -- return this.mobSettings; -+ return this.modifiableBiomeInfo().get().mobSpawnSettings(); + this.generationSettings = generationSettings; ++ var info = new net.minecraftforge.common.world.ModifiableBiomeInfo.BiomeInfo(climateSettings, attributes, specialEffects, generationSettings); ++ this.modifiableBiomeInfo = new net.minecraftforge.common.world.ModifiableBiomeInfo(info, this::update); ++ } ++ ++ private void update(net.minecraftforge.common.world.ModifiableBiomeInfo.BiomeInfo info) { ++ this.climateSettings = info.climateSettings(); ++ this.attributes = info.attributes(); ++ this.specialEffects = info.effects(); ++ this.generationSettings = info.generationSettings(); } public boolean hasPrecipitation() { -@@ -197,7 +_,7 @@ +@@ -196,7 +_,7 @@ } public BiomeGenerationSettings getGenerationSettings() { @@ -53,7 +48,7 @@ } public int getGrassColor(final double x, final double z) { -@@ -250,6 +_,31 @@ +@@ -249,6 +_,31 @@ public int getWaterColor() { return this.specialEffects.waterColor(); diff --git a/patches/minecraft/net/minecraft/world/level/biome/BiomeGenerationSettings.java.patch b/patches/minecraft/net/minecraft/world/level/biome/BiomeGenerationSettings.java.patch index 32e97a6bf5..402032df41 100644 --- a/patches/minecraft/net/minecraft/world/level/biome/BiomeGenerationSettings.java.patch +++ b/patches/minecraft/net/minecraft/world/level/biome/BiomeGenerationSettings.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/level/biome/BiomeGenerationSettings.java +++ b/net/minecraft/world/level/biome/BiomeGenerationSettings.java @@ -92,6 +_,17 @@ - protected final List>> carvers = new ArrayList<>(); + protected final List> carvers = new ArrayList<>(); protected final List>> features = new ArrayList<>(); + public BiomeGenerationSettings.PlainBuilder addFrom(BiomeGenerationSettings other) { @@ -29,4 +29,4 @@ + return this.features.get(stage.ordinal()); } - public BiomeGenerationSettings.PlainBuilder addCarver(final Holder> carver) { + public BiomeGenerationSettings.PlainBuilder addCarver(final Holder carver) { diff --git a/patches/minecraft/net/minecraft/world/level/biome/MobSpawnSettings.java.patch b/patches/minecraft/net/minecraft/world/level/biome/MobSpawnSettings.java.patch index fa2f93ca8d..b2c1f31cb4 100644 --- a/patches/minecraft/net/minecraft/world/level/biome/MobSpawnSettings.java.patch +++ b/patches/minecraft/net/minecraft/world/level/biome/MobSpawnSettings.java.patch @@ -1,35 +1,38 @@ --- a/net/minecraft/world/level/biome/MobSpawnSettings.java +++ b/net/minecraft/world/level/biome/MobSpawnSettings.java -@@ -44,6 +_,8 @@ - private final float creatureGenerationProbability; - private final Map> spawners; +@@ -55,6 +_,8 @@ + ); + private final Map> spawnsByCategory; private final Map, MobSpawnSettings.MobSpawnCost> mobSpawnCosts; + private final java.util.Set typesView; + private final java.util.Set> costView; private MobSpawnSettings( - final float creatureGenerationProbability, -@@ -53,6 +_,8 @@ - this.creatureGenerationProbability = creatureGenerationProbability; - this.spawners = ImmutableMap.copyOf(spawners); + final Map> spawnsByCategory, +@@ -62,6 +_,8 @@ + ) { + this.spawnsByCategory = ImmutableMap.copyOf(spawnsByCategory); this.mobSpawnCosts = ImmutableMap.copyOf(mobSpawnCosts); -+ this.typesView = java.util.Collections.unmodifiableSet(this.spawners.keySet()); ++ this.typesView = java.util.Collections.unmodifiableSet(this.spawnsByCategory.keySet()); + this.costView = java.util.Collections.unmodifiableSet(this.mobSpawnCosts.keySet()); } - public WeightedList getMobs(final MobCategory category) { -@@ -65,6 +_,14 @@ + public WeightedList getMobsToSpawn(final MobCategory category) { +@@ -84,8 +_,16 @@ + return this.mobSpawnCosts; + } - public float getCreatureProbability() { - return this.creatureGenerationProbability; -+ } -+ + public java.util.Set getSpawnerTypes() { + return this.typesView; + } + + public java.util.Set> getEntityTypes() { + return this.costView; - } - ++ } ++ public static class Builder { +- private final Map> spawnsByCategory = new EnumMap<>(MobCategory.class); ++ protected final Map> spawnsByCategory = new EnumMap<>(MobCategory.class); + protected final Map, MobSpawnSettings.MobSpawnCost> mobSpawnCosts = Maps.newLinkedHashMap(); + + public MobSpawnSettings.Builder addSpawn(final EntityType type, final int weight, final int minCount, final int maxCount) { diff --git a/patches/minecraft/net/minecraft/world/level/block/AbstractBedBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/AbstractBedBlock.java.patch new file mode 100644 index 0000000000..8dc8f8494f --- /dev/null +++ b/patches/minecraft/net/minecraft/world/level/block/AbstractBedBlock.java.patch @@ -0,0 +1,16 @@ +--- a/net/minecraft/world/level/block/AbstractBedBlock.java ++++ b/net/minecraft/world/level/block/AbstractBedBlock.java +@@ -123,6 +_,13 @@ + } + } + ++ @Override ++ public void setBedOccupied(BlockState state, Level level, BlockPos pos, LivingEntity sleeper, boolean occupied) { ++ level.setBlockAndUpdate(pos, state.setValue(BedBlock.OCCUPIED, occupied)); ++ if (occupied == false) ++ onStopSleeping(level, pos); ++ } ++ + private boolean kickVillagerOutOfBed(final Level level, final BlockPos pos) { + List villagers = level.getEntitiesOfClass(Villager.class, new AABB(pos), LivingEntity::isSleeping); + if (villagers.isEmpty()) { diff --git a/patches/minecraft/net/minecraft/world/level/block/AttachedStemBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/AttachedStemBlock.java.patch index a8c65d1e04..758baa693f 100644 --- a/patches/minecraft/net/minecraft/world/level/block/AttachedStemBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/AttachedStemBlock.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/block/AttachedStemBlock.java +++ b/net/minecraft/world/level/block/AttachedStemBlock.java -@@ -90,7 +_,7 @@ +@@ -73,7 +_,7 @@ @Override protected boolean mayPlaceOn(final BlockState state, final BlockGetter level, final BlockPos pos) { - return state.is(this.supportBlocks); -+ return state.getBlock() instanceof FarmlandBlock; ++ return state.is(this.supportBlocks) || state.getBlock() instanceof FarmlandBlock; } @Override diff --git a/patches/minecraft/net/minecraft/world/level/block/BambooStalkBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/BambooStalkBlock.java.patch index ee5352661c..9273f25189 100644 --- a/patches/minecraft/net/minecraft/world/level/block/BambooStalkBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/BambooStalkBlock.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/level/block/BambooStalkBlock.java +++ b/net/minecraft/world/level/block/BambooStalkBlock.java -@@ -24,7 +_,7 @@ +@@ -23,7 +_,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; import org.jspecify.annotations.Nullable; -public class BambooStalkBlock extends Block implements BonemealableBlock { +public class BambooStalkBlock extends Block implements BonemealableBlock, net.minecraftforge.common.IPlantable { - public static final MapCodec CODEC = simpleCodec(BambooStalkBlock::new); private static final VoxelShape SHAPE_SMALL = Block.column(6.0, 0.0, 16.0); private static final VoxelShape SHAPE_LARGE = Block.column(10.0, 0.0, 16.0); -@@ -119,10 +_,12 @@ + private static final VoxelShape SHAPE_COLLISION = Block.column(3.0, 0.0, 16.0); +@@ -112,10 +_,12 @@ @Override protected void randomTick(final BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) { if (state.getValue(STAGE) == 0) { @@ -24,7 +24,7 @@ } } } -@@ -230,5 +_,11 @@ +@@ -223,5 +_,11 @@ } return height; diff --git a/patches/minecraft/net/minecraft/world/level/block/BaseFireBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/BaseFireBlock.java.patch index a3f3d83125..e9729da658 100644 --- a/patches/minecraft/net/minecraft/world/level/block/BaseFireBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/BaseFireBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/BaseFireBlock.java +++ b/net/minecraft/world/level/block/BaseFireBlock.java -@@ -161,6 +_,7 @@ +@@ -158,6 +_,7 @@ if (!oldState.is(state.getBlock())) { if (inPortalDimension(level)) { Optional optionalShape = PortalShape.findEmptyPortalShape(level, pos, Direction.Axis.X); @@ -8,12 +8,12 @@ if (optionalShape.isPresent()) { optionalShape.get().createPortalBlocks(level); return; -@@ -204,7 +_,7 @@ - boolean hasObsidian = false; +@@ -201,7 +_,7 @@ for (Direction face : Direction.values()) { -- if (level.getBlockState(testPos.set(pos).move(face)).is(Blocks.OBSIDIAN)) { -+ if (level.getBlockState(testPos.set(pos).move(face)).isPortalFrame(level, testPos)) { - hasObsidian = true; - break; - } + BlockState state = level.getBlockState(testPos.set(pos).move(face)); +- if (PortalShape.FRAME.test(state)) { ++ if (PortalShape.FRAME_TEST.test(state, level, testPos)) { + Direction.Axis preferredAxis = forwardDirection.getAxis().isHorizontal() + ? forwardDirection.getCounterClockWise().getAxis() + : Direction.Plane.HORIZONTAL.getRandomAxis(level.getRandom()); diff --git a/patches/minecraft/net/minecraft/world/level/block/BaseRailBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/BaseRailBlock.java.patch index 9ccda93a2a..113ea17a30 100644 --- a/patches/minecraft/net/minecraft/world/level/block/BaseRailBlock.java.patch +++ b/patches/minecraft/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 -@@ -24,7 +_,7 @@ +@@ -23,7 +_,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; import org.jspecify.annotations.Nullable; @@ -9,7 +9,7 @@ public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; private static final VoxelShape SHAPE_FLAT = Block.column(16.0, 0.0, 2.0); private static final VoxelShape SHAPE_SLOPE = Block.column(16.0, 0.0, 8.0); -@@ -81,7 +_,7 @@ +@@ -77,7 +_,7 @@ final BlockState state, final Level level, final BlockPos pos, final Block block, final @Nullable Orientation orientation, final boolean movedByPiston ) { if (!level.isClientSide() && level.getBlockState(pos).is(this)) { @@ -18,7 +18,7 @@ if (shouldBeRemoved(pos, level, shape)) { dropResources(state, level, pos); level.removeBlock(pos, movedByPiston); -@@ -120,7 +_,7 @@ +@@ -116,7 +_,7 @@ @Override protected void affectNeighborsAfterRemoval(final BlockState state, final ServerLevel level, final BlockPos pos, final boolean movedByPiston) { if (!movedByPiston) { @@ -27,7 +27,7 @@ level.updateNeighborsAt(pos.above(), this); } -@@ -141,6 +_,11 @@ +@@ -137,6 +_,11 @@ return state.setValue(this.getShapeProperty(), isEastWest ? RailShape.EAST_WEST : RailShape.NORTH_SOUTH).setValue(WATERLOGGED, isWaterSource); } @@ -39,7 +39,7 @@ public abstract Property getShapeProperty(); protected RailShape rotate(final RailShape shape, final Rotation rotation) { -@@ -296,5 +_,15 @@ +@@ -292,5 +_,15 @@ @Override protected FluidState getFluidState(final BlockState state) { return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); diff --git a/patches/minecraft/net/minecraft/world/level/block/BeehiveBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/BeehiveBlock.java.patch index 887e3eeda0..3ab5314ba0 100644 --- a/patches/minecraft/net/minecraft/world/level/block/BeehiveBlock.java.patch +++ b/patches/minecraft/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 -@@ -161,7 +_,7 @@ +@@ -155,7 +_,7 @@ boolean hiveEmptied = false; if (honeyLevel >= 5) { Item item = itemStack.getItem(); diff --git a/patches/minecraft/net/minecraft/world/level/block/Block.java.patch b/patches/minecraft/net/minecraft/world/level/block/Block.java.patch index c58c556221..fd64e6da69 100644 --- a/patches/minecraft/net/minecraft/world/level/block/Block.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/Block.java.patch @@ -1,12 +1,11 @@ --- a/net/minecraft/world/level/block/Block.java +++ b/net/minecraft/world/level/block/Block.java -@@ -75,11 +_,12 @@ +@@ -75,10 +_,11 @@ import org.jspecify.annotations.Nullable; import org.slf4j.Logger; -public class Block extends BlockBehaviour implements ItemLike { +public class Block extends BlockBehaviour implements ItemLike, net.minecraftforge.common.extensions.IForgeBlock { - public static final MapCodec CODEC = simpleCodec(Block::new); private static final Logger LOGGER = LogUtils.getLogger(); private final Holder.Reference builtInRegistryHolder = BuiltInRegistries.BLOCK.createIntrusiveHolder(this); - public static final IdMapper BLOCK_STATE_REGISTRY = new IdMapper<>(); @@ -15,7 +14,7 @@ private static final LoadingCache SHAPE_FULL_BLOCK_CACHE = CacheBuilder.newBuilder() .maximumSize(512L) .weakKeys() -@@ -247,6 +_,7 @@ +@@ -241,6 +_,7 @@ LOGGER.error("Block classes should end with Block and {} doesn't.", className); } } @@ -23,7 +22,7 @@ } public static boolean isExceptionForConnection(final BlockState state) { -@@ -297,7 +_,12 @@ +@@ -293,7 +_,12 @@ } } @@ -36,7 +35,7 @@ VoxelShape occluder = neighborState.getFaceOcclusionShape(direction.getOpposite()); if (occluder == Shapes.block()) { return false; -@@ -396,17 +_,22 @@ +@@ -392,17 +_,22 @@ } } @@ -61,7 +60,7 @@ } } -@@ -436,7 +_,7 @@ +@@ -432,7 +_,7 @@ } private static void popResource(final Level level, final Supplier entityFactory, final ItemStack itemStack) { @@ -70,7 +69,7 @@ ItemEntity entity = entityFactory.get(); entity.setDefaultPickUpDelay(); level.addFreshEntity(entity); -@@ -444,11 +_,12 @@ +@@ -440,11 +_,12 @@ } public void popExperience(final ServerLevel level, final BlockPos pos, final int amount) { @@ -84,7 +83,7 @@ public float getExplosionResistance() { return this.explosionResistance; } -@@ -473,7 +_,8 @@ +@@ -469,7 +_,8 @@ ) { player.awardStat(Stats.BLOCK_MINED.get(this)); player.causeFoodExhaustion(0.005F); @@ -94,15 +93,15 @@ } public void setPlacedBy(final Level level, final BlockPos pos, final BlockState state, final @Nullable LivingEntity by, final ItemStack itemStack) { -@@ -495,6 +_,7 @@ - return this.bounceRestitution; +@@ -499,6 +_,7 @@ + return this.fallDistanceReduction; } + /** @deprecated Forge: use {@link net.minecraftforge.common.extensions.IForgeBlockState#getFriction(LevelReader, BlockPos, Entity)}*/ public float getFriction() { return this.friction; } -@@ -565,7 +_,7 @@ +@@ -567,7 +_,7 @@ this.item = Item.byBlock(this); } @@ -111,7 +110,7 @@ } public boolean hasDynamicShape() { -@@ -630,6 +_,79 @@ +@@ -632,6 +_,79 @@ public int hashCode() { return System.identityHashCode(this.first) * 31 + System.identityHashCode(this.second); } diff --git a/patches/minecraft/net/minecraft/world/level/block/Blocks.java.patch b/patches/minecraft/net/minecraft/world/level/block/Blocks.java.patch index 60a67065f3..5224736cff 100644 --- a/patches/minecraft/net/minecraft/world/level/block/Blocks.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/Blocks.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/level/block/Blocks.java +++ b/net/minecraft/world/level/block/Blocks.java -@@ -705,7 +_,7 @@ - .pushReaction(PushReaction.DESTROY) +@@ -802,7 +_,7 @@ + .pushReaction(PushReaction.POPPED) ); public static final Block POWERED_RAIL = register( - BlockItemIds.POWERED_RAIL, PoweredRailBlock::new, BlockBehaviour.Properties.of().noCollision().strength(0.7F).sound(SoundType.METAL) @@ -9,18 +9,20 @@ ); public static final Block DETECTOR_RAIL = register( BlockItemIds.DETECTOR_RAIL, DetectorRailBlock::new, BlockBehaviour.Properties.of().noCollision().strength(0.7F).sound(SoundType.METAL) -@@ -5992,14 +_,5 @@ +@@ -5932,16 +_,5 @@ private static Block register(final ResourceKey id, final BlockBehaviour.Properties properties) { return register(id, Block::new, properties); - } - - static { -- for (Block block : BuiltInRegistries.BLOCK) { -- for (BlockState state : block.getStateDefinition().getPossibleStates()) { -- Block.BLOCK_STATE_REGISTRY.add(state); -- state.initCache(); +- SolidDebugger.runAndDump(() -> { +- for (Block block : BuiltInRegistries.BLOCK) { +- for (BlockState state : block.getStateDefinition().getPossibleStates()) { +- Block.BLOCK_STATE_REGISTRY.add(state); +- state.initCache(); +- } - } -- } +- }); } } diff --git a/patches/minecraft/net/minecraft/world/level/block/CactusBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/CactusBlock.java.patch index 577502a100..186edbdd17 100644 --- a/patches/minecraft/net/minecraft/world/level/block/CactusBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/CactusBlock.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/level/block/CactusBlock.java +++ b/net/minecraft/world/level/block/CactusBlock.java -@@ -22,7 +_,7 @@ +@@ -21,7 +_,7 @@ import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; -public class CactusBlock extends Block { +public class CactusBlock extends Block implements net.minecraftforge.common.IPlantable { - public static final MapCodec CODEC = simpleCodec(CactusBlock::new); public static final IntegerProperty AGE = BlockStateProperties.AGE_15; public static final int MAX_AGE = 15; -@@ -45,6 +_,7 @@ + private static final VoxelShape SHAPE = Block.column(14.0, 0.0, 16.0); +@@ -38,6 +_,7 @@ @Override protected void tick(final BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) { @@ -17,7 +17,7 @@ if (!state.canSurvive(level, pos)) { level.destroyBlock(pos, true); } -@@ -63,6 +_,7 @@ +@@ -56,6 +_,7 @@ } } @@ -25,7 +25,7 @@ if (age == 8 && this.canSurvive(this.defaultBlockState(), level, pos.above())) { double chanceToGrowFlower = height >= 3 ? 0.25 : 0.1; if (random.nextDouble() <= chanceToGrowFlower) { -@@ -78,6 +_,7 @@ +@@ -71,6 +_,7 @@ if (age < 15) { level.setBlock(pos, state.setValue(AGE, age + 1), 260); } @@ -33,7 +33,7 @@ } } -@@ -119,7 +_,7 @@ +@@ -112,7 +_,7 @@ } BlockState belowState = level.getBlockState(pos.below()); @@ -42,7 +42,7 @@ } @Override -@@ -142,5 +_,15 @@ +@@ -135,5 +_,15 @@ @Override protected boolean isPathfindable(final BlockState state, final PathComputationType type) { return false; diff --git a/patches/minecraft/net/minecraft/world/level/block/CactusFlowerBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/CactusFlowerBlock.java.patch index 9deaf39f07..ae80879a66 100644 --- a/patches/minecraft/net/minecraft/world/level/block/CactusFlowerBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/CactusFlowerBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/CactusFlowerBlock.java +++ b/net/minecraft/world/level/block/CactusFlowerBlock.java -@@ -31,6 +_,6 @@ +@@ -24,6 +_,6 @@ @Override protected boolean mayPlaceOn(final BlockState state, final BlockGetter level, final BlockPos pos) { BlockState blockBelow = level.getBlockState(pos); diff --git a/patches/minecraft/net/minecraft/world/level/block/CampfireBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/CampfireBlock.java.patch index 9f3bc3982b..7d5944f9a4 100644 --- a/patches/minecraft/net/minecraft/world/level/block/CampfireBlock.java.patch +++ b/patches/minecraft/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 -@@ -271,7 +_,7 @@ +@@ -267,7 +_,7 @@ return true; } diff --git a/patches/minecraft/net/minecraft/world/level/block/ChestBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/ChestBlock.java.patch index 97cdda45c1..6c5f56e07f 100644 --- a/patches/minecraft/net/minecraft/world/level/block/ChestBlock.java.patch +++ b/patches/minecraft/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 -@@ -368,7 +_,8 @@ +@@ -354,7 +_,8 @@ @Override protected BlockState mirror(final BlockState state, final Mirror mirror) { diff --git a/patches/minecraft/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch index ec7947bafe..abe361de7d 100644 --- a/patches/minecraft/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/ChorusFlowerBlock.java +++ b/net/minecraft/world/level/block/ChorusFlowerBlock.java -@@ -65,7 +_,7 @@ +@@ -54,7 +_,7 @@ BlockPos above = pos.above(); if (level.isEmptyBlock(above) && above.getY() <= level.getMaxY()) { int currentAge = state.getValue(AGE); @@ -9,7 +9,7 @@ boolean growUpwards = false; boolean pillarOnSupportBlock = false; BlockState belowState = level.getBlockState(pos.below()); -@@ -121,6 +_,7 @@ +@@ -110,6 +_,7 @@ } else { this.placeDeadFlower(level, pos); } diff --git a/patches/minecraft/net/minecraft/world/level/block/CocoaBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/CocoaBlock.java.patch index 802af346aa..9896641fdc 100644 --- a/patches/minecraft/net/minecraft/world/level/block/CocoaBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/CocoaBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/CocoaBlock.java +++ b/net/minecraft/world/level/block/CocoaBlock.java -@@ -50,10 +_,11 @@ +@@ -43,10 +_,11 @@ @Override protected void randomTick(final BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) { diff --git a/patches/minecraft/net/minecraft/world/level/block/ComparatorBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/ComparatorBlock.java.patch index 52d73a8d8b..a31ab54b6c 100644 --- a/patches/minecraft/net/minecraft/world/level/block/ComparatorBlock.java.patch +++ b/patches/minecraft/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 -@@ -198,4 +_,16 @@ +@@ -191,4 +_,16 @@ protected void createBlockStateDefinition(final StateDefinition.Builder builder) { builder.add(FACING, MODE, POWERED); } diff --git a/patches/minecraft/net/minecraft/world/level/block/ConcretePowderBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/ConcretePowderBlock.java.patch index 2b9bcbec80..eef8ed8830 100644 --- a/patches/minecraft/net/minecraft/world/level/block/ConcretePowderBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/ConcretePowderBlock.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/level/block/ConcretePowderBlock.java +++ b/net/minecraft/world/level/block/ConcretePowderBlock.java -@@ -35,7 +_,7 @@ +@@ -23,7 +_,7 @@ @Override public void onLand(final Level level, final BlockPos pos, final BlockState state, final BlockState replacedBlock, final FallingBlockEntity entity) { - if (shouldSolidify(level, pos, replacedBlock)) { + if (shouldSolidify(level, pos, state, replacedBlock.getFluidState())) { // Forge: Use block of falling entity instead of block at replaced position, and check if shouldSolidify with the FluidState of the replaced block - level.setBlock(pos, this.concrete.defaultBlockState(), 3); + level.setBlockAndUpdate(pos, this.concrete.defaultBlockState()); } } -@@ -48,20 +_,24 @@ +@@ -36,20 +_,24 @@ return shouldSolidify(level, pos, replacedBlock) ? this.concrete.defaultBlockState() : super.getStateForPlacement(context); } @@ -38,7 +38,7 @@ touchesLiquid = true; break; } -@@ -86,7 +_,7 @@ +@@ -74,7 +_,7 @@ final BlockState neighbourState, final RandomSource random ) { diff --git a/patches/minecraft/net/minecraft/world/level/block/CoralBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/CoralBlock.java.patch index 6538cf0c9c..dc7b7c9d04 100644 --- a/patches/minecraft/net/minecraft/world/level/block/CoralBlock.java.patch +++ b/patches/minecraft/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 -@@ -60,9 +_,10 @@ +@@ -48,9 +_,10 @@ } protected boolean scanForWater(final BlockGetter level, final BlockPos blockPos) { diff --git a/patches/minecraft/net/minecraft/world/level/block/CrafterBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/CrafterBlock.java.patch index 7f997a1db0..54d64be5a1 100644 --- a/patches/minecraft/net/minecraft/world/level/block/CrafterBlock.java.patch +++ b/patches/minecraft/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 -@@ -194,12 +_,15 @@ +@@ -187,12 +_,15 @@ final RecipeHolder recipe ) { Direction direction = blockState.getValue(ORIENTATION).front(); @@ -16,7 +16,7 @@ if (!itemStack.isEmpty()) { break; } -@@ -210,10 +_,14 @@ +@@ -203,10 +_,14 @@ while (!remaining.isEmpty()) { int oldSize = remaining.getCount(); remaining = HopperBlockEntity.addItem(blockEntity, into, remaining, direction.getOpposite()); diff --git a/patches/minecraft/net/minecraft/world/level/block/CropBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/CropBlock.java.patch index b1f8f5aa24..066d9ee6d8 100644 --- a/patches/minecraft/net/minecraft/world/level/block/CropBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/CropBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/CropBlock.java +++ b/net/minecraft/world/level/block/CropBlock.java -@@ -47,7 +_,7 @@ +@@ -40,7 +_,7 @@ @Override protected boolean mayPlaceOn(final BlockState state, final BlockGetter level, final BlockPos pos) { @@ -9,7 +9,7 @@ } protected IntegerProperty getAgeProperty() { -@@ -81,8 +_,9 @@ +@@ -74,8 +_,9 @@ int age = this.getAge(state); if (age < this.getMaxAge()) { float growthSpeed = getGrowthSpeed(this, level, pos); @@ -20,7 +20,7 @@ } } } -@@ -105,9 +_,9 @@ +@@ -98,9 +_,9 @@ for (int zz = -1; zz <= 1; zz++) { float blockSpeed = 0.0F; BlockState blockState = level.getBlockState(below.offset(xx, 0, zz)); @@ -32,7 +32,7 @@ blockSpeed = 3.0F; } } -@@ -159,7 +_,7 @@ +@@ -152,7 +_,7 @@ final InsideBlockEffectApplier effectApplier, final boolean isPrecise ) { diff --git a/patches/minecraft/net/minecraft/world/level/block/DetectorRailBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/DetectorRailBlock.java.patch index ef9b8bde3e..932bd26b50 100644 --- a/patches/minecraft/net/minecraft/world/level/block/DetectorRailBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/DetectorRailBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/DetectorRailBlock.java +++ b/net/minecraft/world/level/block/DetectorRailBlock.java -@@ -39,6 +_,10 @@ +@@ -32,6 +_,10 @@ public DetectorRailBlock(final BlockBehaviour.Properties properties) { super(true, properties); @@ -11,7 +11,7 @@ this.registerDefaultState(this.stateDefinition.any().setValue(POWERED, false).setValue(SHAPE, RailShape.NORTH_SOUTH).setValue(WATERLOGGED, false)); } -@@ -154,7 +_,10 @@ +@@ -147,7 +_,10 @@ return commandBlocks.get(0).getCommandBlock().getSuccessCount(); } @@ -23,7 +23,7 @@ if (!entities.isEmpty()) { return AbstractContainerMenu.getRedstoneSignalFromContainer((Container)entities.get(0)); } -@@ -190,6 +_,6 @@ +@@ -183,6 +_,6 @@ @Override protected void createBlockStateDefinition(final StateDefinition.Builder builder) { diff --git a/patches/minecraft/net/minecraft/world/level/block/DiodeBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/DiodeBlock.java.patch index 1bb6cc9725..b9f2f40c7e 100644 --- a/patches/minecraft/net/minecraft/world/level/block/DiodeBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/DiodeBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/DiodeBlock.java +++ b/net/minecraft/world/level/block/DiodeBlock.java -@@ -181,6 +_,9 @@ +@@ -177,6 +_,9 @@ Direction direction = state.getValue(FACING); BlockPos oppositePos = pos.relative(direction.getOpposite()); Orientation orientation = ExperimentalRedstoneUtils.initialOrientation(level, direction.getOpposite(), Direction.UP); diff --git a/patches/minecraft/net/minecraft/world/level/block/DoublePlantBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/DoublePlantBlock.java.patch index 445be8a492..049d366966 100644 --- a/patches/minecraft/net/minecraft/world/level/block/DoublePlantBlock.java.patch +++ b/patches/minecraft/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 -@@ -80,6 +_,7 @@ +@@ -75,6 +_,7 @@ } BlockState belowState = level.getBlockState(pos.below()); diff --git a/patches/minecraft/net/minecraft/world/level/block/DropExperienceBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/DropExperienceBlock.java.patch index d91f08f9ac..556c0a38dc 100644 --- a/patches/minecraft/net/minecraft/world/level/block/DropExperienceBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/DropExperienceBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/DropExperienceBlock.java +++ b/net/minecraft/world/level/block/DropExperienceBlock.java -@@ -29,8 +_,13 @@ +@@ -18,8 +_,13 @@ @Override protected void spawnAfterBreak(final BlockState state, final ServerLevel level, final BlockPos pos, final ItemStack tool, final boolean dropExperience) { super.spawnAfterBreak(state, level, pos, tool, dropExperience); diff --git a/patches/minecraft/net/minecraft/world/level/block/DropperBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/DropperBlock.java.patch index 934255a286..20454b6725 100644 --- a/patches/minecraft/net/minecraft/world/level/block/DropperBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/DropperBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/DropperBlock.java +++ b/net/minecraft/world/level/block/DropperBlock.java -@@ -56,7 +_,7 @@ +@@ -49,7 +_,7 @@ level.levelEvent(1001, pos, 0); } else { ItemStack itemStack = blockEntity.getItem(slot); diff --git a/patches/minecraft/net/minecraft/world/level/block/EnchantingTableBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/EnchantingTableBlock.java.patch index c87f502932..e22dfe6c43 100644 --- a/patches/minecraft/net/minecraft/world/level/block/EnchantingTableBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/EnchantingTableBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/EnchantingTableBlock.java +++ b/net/minecraft/world/level/block/EnchantingTableBlock.java -@@ -46,7 +_,7 @@ +@@ -39,7 +_,7 @@ } public static boolean isValidBookShelf(final Level level, final BlockPos pos, final BlockPos offset) { diff --git a/patches/minecraft/net/minecraft/world/level/block/FarmlandBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/FarmlandBlock.java.patch index a0834c0c7c..2bc93fe3fb 100644 --- a/patches/minecraft/net/minecraft/world/level/block/FarmlandBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/FarmlandBlock.java.patch @@ -1,18 +1,20 @@ --- a/net/minecraft/world/level/block/FarmlandBlock.java +++ b/net/minecraft/world/level/block/FarmlandBlock.java -@@ -108,10 +_,7 @@ +@@ -102,11 +_,8 @@ + @Override public void fallOn(final Level level, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { - if (level instanceof ServerLevel serverLevel -- && level.getRandom().nextFloat() < fallDistance - 0.5 -- && entity instanceof LivingEntity -- && (entity instanceof Player || serverLevel.getGameRules().get(GameRules.MOB_GRIEFING)) -- && entity.getBbWidth() * entity.getBbWidth() * entity.getBbHeight() > 0.512F) { -+ && net.minecraftforge.common.ForgeHooks.onFarmlandTrample(serverLevel, pos, state, fallDistance, entity)) { // Forge: Move logic to Entity#canTrample - turnToDirt(entity, state, level, pos); +- if (level instanceof ServerLevel serverLevel && level.getRandom().nextFloat() < fallDistance - 0.5 && entity instanceof LivingEntity) { +- boolean canTrample = entity instanceof Player player +- ? !level.getServer().isUnderSpawnProtection(serverLevel, pos, player) +- : serverLevel.getGameRules().get(GameRules.MOB_GRIEFING); +- if (canTrample && entity.getBbWidth() * entity.getBbWidth() * entity.getBbHeight() > 0.512F) { ++ if (level instanceof ServerLevel serverLevel) { ++ if (net.minecraftforge.common.ForgeHooks.onFarmlandTrample(serverLevel, pos, state, fallDistance, entity)) { // Forge: Move logic to Entity#canTrample + this.turnToBaseBlock(entity, state, level, pos); + } } - -@@ -125,17 +_,22 @@ +@@ -121,11 +_,16 @@ } private static boolean shouldMaintainFarmland(final BlockGetter level, final BlockPos pos) { @@ -24,16 +26,9 @@ } private static boolean isNearWater(final LevelReader level, final BlockPos pos) { -+ BlockState state = level.getBlockState(pos); - for (BlockPos blockPos : BlockPos.betweenClosed(pos.offset(-4, 0, -4), pos.offset(4, 1, 4))) { -- if (level.getFluidState(blockPos).is(FluidTags.WATER)) { -+ if (state.canBeHydrated(level, pos, level.getFluidState(blockPos), blockPos)) { - return true; - } - } - -- return false; -+ return net.minecraftforge.common.FarmlandWaterManager.hasBlockWaterTicket(level, pos); +- return level.findBlocksIn(pos.offset(-4, 0, -4), pos.offset(4, 1, 4)).filterState(state -> state.getFluidState().is(FluidTags.WATER)).anyMatched(); ++ var hasWater = level.findBlocksIn(pos.offset(-4, 0, -4), pos.offset(4, 1, 4)).forEachUntil((waterPos, state) -> net.minecraft.util.Continuation.abortIf(state.canBeHydrated(level, pos, level.getFluidState(waterPos), waterPos))); ++ return hasWater || net.minecraftforge.common.FarmlandWaterManager.hasBlockWaterTicket(level, pos); } @Override diff --git a/patches/minecraft/net/minecraft/world/level/block/FenceGateBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/FenceGateBlock.java.patch index 097e64d0ce..d3e4ba7bbb 100644 --- a/patches/minecraft/net/minecraft/world/level/block/FenceGateBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/FenceGateBlock.java.patch @@ -1,17 +1,12 @@ --- a/net/minecraft/world/level/block/FenceGateBlock.java +++ b/net/minecraft/world/level/block/FenceGateBlock.java -@@ -57,6 +_,8 @@ +@@ -52,10 +_,18 @@ Util.mapValues(SHAPE_OCCLUSION, v -> v.move(0.0, -0.1875, 0.0).optimize()) ); private final WoodType type; + private final net.minecraft.sounds.SoundEvent openSound; + private final net.minecraft.sounds.SoundEvent closeSound; - @Override - public MapCodec codec() { -@@ -64,8 +_,14 @@ - } - public FenceGateBlock(final WoodType type, final BlockBehaviour.Properties properties) { - super(properties.sound(type.soundType())); + this(type, properties, type.fenceGateOpen(), type.fenceGateClose()); @@ -25,7 +20,7 @@ this.registerDefaultState(this.stateDefinition.any().setValue(OPEN, false).setValue(POWERED, false).setValue(IN_WALL, false)); } -@@ -156,7 +_,7 @@ +@@ -146,7 +_,7 @@ boolean opens = state.getValue(OPEN); level.playSound( @@ -34,7 +29,7 @@ ); level.gameEvent(player, opens ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE, pos); return InteractionResult.SUCCESS; -@@ -170,7 +_,7 @@ +@@ -160,7 +_,7 @@ boolean open = state.getValue(OPEN); level.setBlockAndUpdate(pos, state.setValue(OPEN, !open)); level.playSound( @@ -43,7 +38,7 @@ ); level.gameEvent(open ? GameEvent.BLOCK_CLOSE : GameEvent.BLOCK_OPEN, pos, GameEvent.Context.of(state)); } -@@ -190,7 +_,7 @@ +@@ -180,7 +_,7 @@ level.playSound( null, pos, diff --git a/patches/minecraft/net/minecraft/world/level/block/FireBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/FireBlock.java.patch index c3f5c9deec..82422dc71a 100644 --- a/patches/minecraft/net/minecraft/world/level/block/FireBlock.java.patch +++ b/patches/minecraft/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 -@@ -115,13 +_,13 @@ +@@ -108,13 +_,13 @@ protected BlockState getStateForPlacement(final BlockGetter level, final BlockPos pos) { BlockPos below = pos.below(); BlockState belowState = level.getBlockState(below); @@ -16,7 +16,7 @@ } } -@@ -146,7 +_,7 @@ +@@ -139,7 +_,7 @@ } BlockState belowState = level.getBlockState(pos.below()); @@ -25,7 +25,7 @@ int age = state.getValue(AGE); if (!infiniBurn && level.isRaining() && this.isNearRain(level, pos) && random.nextFloat() < 0.2F + age * 0.03F) { level.removeBlock(pos, false); -@@ -167,7 +_,7 @@ +@@ -160,7 +_,7 @@ return; } @@ -34,7 +34,7 @@ level.removeBlock(pos, false); return; } -@@ -175,12 +_,12 @@ +@@ -168,12 +_,12 @@ boolean increasedBurnout = level.environmentAttributes().getValue(EnvironmentAttributes.INCREASED_FIRE_BURNOUT, pos); int extra = increasedBurnout ? -50 : 0; @@ -53,7 +53,7 @@ BlockPos.MutableBlockPos testPos = new BlockPos.MutableBlockPos(); for (int xx = -1; xx <= 1; xx++) { -@@ -221,33 +_,31 @@ +@@ -214,33 +_,31 @@ || level.isRainingAt(testPos.south()); } @@ -80,7 +80,7 @@ + oldState.onCaughtFire(level, pos, face, null); if (random.nextInt(age + 10) < 5 && !level.isRainingAt(pos)) { int newAge = Math.min(age + random.nextInt(5) / 4, 15); - level.setBlock(pos, this.getStateWithAge(level, pos, newAge), 3); + level.setBlockAndUpdate(pos, this.getStateWithAge(level, pos, newAge)); } else { level.removeBlock(pos, false); } @@ -92,7 +92,7 @@ } } -@@ -258,7 +_,7 @@ +@@ -251,7 +_,7 @@ private boolean isValidFireLocation(final BlockGetter level, final BlockPos pos) { for (Direction direction : Direction.values()) { @@ -101,7 +101,7 @@ return true; } } -@@ -275,12 +_,13 @@ +@@ -268,12 +_,13 @@ for (Direction direction : Direction.values()) { BlockState blockState = level.getBlockState(pos.relative(direction)); @@ -116,7 +116,7 @@ @Override protected boolean canBurn(final BlockState state) { return this.getIgniteOdds(state) > 0; -@@ -302,8 +_,21 @@ +@@ -295,8 +_,21 @@ } private void setFlammable(final Block block, final int igniteOdds, final int burnOdds) { diff --git a/patches/minecraft/net/minecraft/world/level/block/FlowerPotBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/FlowerPotBlock.java.patch index 4ae076fdd6..316ab58df8 100644 --- a/patches/minecraft/net/minecraft/world/level/block/FlowerPotBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/FlowerPotBlock.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/level/block/FlowerPotBlock.java +++ b/net/minecraft/world/level/block/FlowerPotBlock.java -@@ -43,9 +_,31 @@ - } +@@ -33,9 +_,31 @@ + private final Block potted; public FlowerPotBlock(final Block potted, final BlockBehaviour.Properties properties) { + this(Blocks.FLOWER_POT == null ? null : () -> (FlowerPotBlock) net.minecraftforge.registries.ForgeRegistries.BLOCKS.getDelegateOrThrow(Blocks.FLOWER_POT).get(), () -> net.minecraftforge.registries.ForgeRegistries.BLOCKS.getDelegateOrThrow(potted).get(), properties); @@ -34,7 +34,7 @@ } @Override -@@ -64,7 +_,7 @@ +@@ -54,7 +_,7 @@ final BlockHitResult hitResult ) { BlockState newContents = (itemStack.getItem() instanceof BlockItem blockItem @@ -43,16 +43,16 @@ : Blocks.AIR) .defaultBlockState(); if (newContents.isAir()) { -@@ -95,7 +_,7 @@ - player.drop(plant, false); +@@ -85,7 +_,7 @@ + player.drop(plant, false, Prediction.PREDICTED); } -- level.setBlock(pos, Blocks.FLOWER_POT.defaultBlockState(), 3); -+ level.setBlock(pos, getEmptyPot().defaultBlockState(), 3); +- level.setBlockAndUpdate(pos, Blocks.FLOWER_POT.defaultBlockState()); ++ level.setBlockAndUpdate(pos, getEmptyPot().defaultBlockState()); level.gameEvent(player, GameEvent.BLOCK_CHANGE, pos); return InteractionResult.SUCCESS; } -@@ -126,7 +_,7 @@ +@@ -116,7 +_,7 @@ } public Block getPotted() { @@ -61,7 +61,7 @@ } @Override -@@ -161,5 +_,24 @@ +@@ -151,5 +_,24 @@ } else { return state.is(Blocks.POTTED_CLOSED_EYEBLOSSOM) ? Blocks.POTTED_OPEN_EYEBLOSSOM.defaultBlockState() : state; } diff --git a/patches/minecraft/net/minecraft/world/level/block/GrowingPlantHeadBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/GrowingPlantHeadBlock.java.patch index affd25cb75..b2753e38f8 100644 --- a/patches/minecraft/net/minecraft/world/level/block/GrowingPlantHeadBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/GrowingPlantHeadBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/GrowingPlantHeadBlock.java +++ b/net/minecraft/world/level/block/GrowingPlantHeadBlock.java -@@ -48,10 +_,13 @@ +@@ -44,10 +_,13 @@ @Override protected void randomTick(final BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) { diff --git a/patches/minecraft/net/minecraft/world/level/block/LiquidBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/LiquidBlock.java.patch index 02758f99bc..e25da04763 100644 --- a/patches/minecraft/net/minecraft/world/level/block/LiquidBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/LiquidBlock.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/world/level/block/LiquidBlock.java +++ b/net/minecraft/world/level/block/LiquidBlock.java -@@ -52,7 +_,8 @@ - i -> i.group(FLOWING_FLUID.fieldOf("fluid").forGetter(b -> b.fluid), propertiesCodec()).apply(i, LiquidBlock::new) - ); +@@ -37,13 +_,15 @@ + + public class LiquidBlock extends Block implements BucketPickup { public static final IntegerProperty LEVEL = BlockStateProperties.LEVEL; - protected final FlowingFluid fluid; + @Deprecated // Use getFluid @@ -10,15 +10,14 @@ private final List stateCache; public static final ImmutableList POSSIBLE_FLOW_DIRECTIONS = ImmutableList.of( Direction.DOWN, Direction.SOUTH, Direction.NORTH, Direction.EAST, Direction.WEST -@@ -64,6 +_,7 @@ - return CODEC; - } + ); + private static final int BUBBLE_COLUMN_CHECK_DELAY = 20; + @Deprecated // Forge: Use the constructor that takes a supplier public LiquidBlock(final FlowingFluid fluid, final BlockBehaviour.Properties properties) { super(properties); this.fluid = fluid; -@@ -76,6 +_,19 @@ +@@ -56,6 +_,19 @@ this.stateCache.add(fluid.getFlowing(8, true)); this.registerDefaultState(this.stateDefinition.any().setValue(LEVEL, 0)); @@ -38,7 +37,7 @@ } @Override -@@ -124,6 +_,7 @@ +@@ -104,6 +_,7 @@ @Override protected FluidState getFluidState(final BlockState state) { int level = state.getValue(LEVEL); @@ -46,7 +45,7 @@ return this.stateCache.get(Math.min(level, 8)); } -@@ -149,7 +_,7 @@ +@@ -129,7 +_,7 @@ @Override protected void onPlace(final BlockState state, final Level level, final BlockPos pos, final BlockState oldState, final boolean movedByPiston) { @@ -55,7 +54,7 @@ level.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(level)); } -@@ -197,7 +_,7 @@ +@@ -177,7 +_,7 @@ protected void neighborChanged( final BlockState state, final Level level, final BlockPos pos, final Block block, final @Nullable Orientation orientation, final boolean movedByPiston ) { @@ -64,7 +63,7 @@ level.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(level)); } -@@ -213,6 +_,7 @@ +@@ -193,6 +_,7 @@ } } @@ -72,7 +71,7 @@ private boolean shouldSpreadLiquid(final Level level, final BlockPos pos, final BlockState state) { if (this.fluid.is(FluidTags.LAVA)) { boolean isOverSoulSoil = level.getBlockState(pos.below()).is(Blocks.SOUL_SOIL); -@@ -259,5 +_,24 @@ +@@ -239,5 +_,24 @@ @Override public Optional getPickupSound() { return this.fluid.getPickupSound(); diff --git a/patches/minecraft/net/minecraft/world/level/block/MushroomBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/MushroomBlock.java.patch index 09c7d20ef3..04a9fa6eb6 100644 --- a/patches/minecraft/net/minecraft/world/level/block/MushroomBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/MushroomBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/MushroomBlock.java +++ b/net/minecraft/world/level/block/MushroomBlock.java -@@ -83,7 +_,7 @@ +@@ -72,7 +_,7 @@ protected boolean canSurvive(final BlockState state, final LevelReader level, final BlockPos pos) { BlockPos belowPos = pos.below(); BlockState below = level.getBlockState(belowPos); @@ -9,7 +9,7 @@ } public boolean growMushroom(final ServerLevel level, final BlockPos pos, final BlockState state, final RandomSource random) { -@@ -92,8 +_,10 @@ +@@ -81,8 +_,10 @@ return false; } diff --git a/patches/minecraft/net/minecraft/world/level/block/NetherFungusBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/NetherFungusBlock.java.patch index 6aea05dc2f..d0e1c6220b 100644 --- a/patches/minecraft/net/minecraft/world/level/block/NetherFungusBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/NetherFungusBlock.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/world/level/block/NetherFungusBlock.java +++ b/net/minecraft/world/level/block/NetherFungusBlock.java -@@ -81,5 +_,10 @@ +@@ -61,5 +_,10 @@ @Override - public void performBonemeal(final ServerLevel level, final RandomSource random, final BlockPos pos, final BlockState state) { + public void performBonemeal(final ServerLevel level, final RandomSource random, final BlockPos pos, final BlockState state, final BonemealSource source) { this.getFeature(level).ifPresent(feature -> feature.value().place(level, level.getChunkSource().getGenerator(), random, pos)); + this.getFeature(level).ifPresent(feature -> { + var event = net.minecraftforge.event.ForgeEventFactory.blockGrowFeature(level, random, pos, feature); diff --git a/patches/minecraft/net/minecraft/world/level/block/NetherWartBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/NetherWartBlock.java.patch index c42fe54bec..2366ba367a 100644 --- a/patches/minecraft/net/minecraft/world/level/block/NetherWartBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/NetherWartBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/NetherWartBlock.java +++ b/net/minecraft/world/level/block/NetherWartBlock.java -@@ -51,9 +_,10 @@ +@@ -44,9 +_,10 @@ @Override protected void randomTick(BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) { int age = state.getValue(AGE); diff --git a/patches/minecraft/net/minecraft/world/level/block/NoteBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/NoteBlock.java.patch index 96515ff319..3286bf36d6 100644 --- a/patches/minecraft/net/minecraft/world/level/block/NoteBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/NoteBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/NoteBlock.java +++ b/net/minecraft/world/level/block/NoteBlock.java -@@ -123,7 +_,9 @@ +@@ -116,7 +_,9 @@ @Override protected InteractionResult useWithoutItem(BlockState state, final Level level, final BlockPos pos, final Player player, final BlockHitResult hitResult) { if (!level.isClientSide()) { @@ -8,10 +8,10 @@ + int _new = net.minecraftforge.common.ForgeHooks.onNoteChange(level, pos, state, state.getValue(NOTE), state.cycle(NOTE).getValue(NOTE)); + if (_new == -1) return InteractionResult.FAIL; + state = state.setValue(NOTE, _new); - level.setBlock(pos, state, 3); + level.setBlockAndUpdate(pos, state); this.playNote(player, state, level, pos); player.awardStat(Stats.TUNE_NOTEBLOCK); -@@ -146,10 +_,13 @@ +@@ -139,10 +_,13 @@ @Override protected boolean triggerEvent(final BlockState state, final Level level, final BlockPos pos, final int b0, final int b1) { diff --git a/patches/minecraft/net/minecraft/world/level/block/PitcherCropBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/PitcherCropBlock.java.patch index 5364f59da5..00fa8c01e7 100644 --- a/patches/minecraft/net/minecraft/world/level/block/PitcherCropBlock.java.patch +++ b/patches/minecraft/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 -@@ -107,7 +_,7 @@ +@@ -100,7 +_,7 @@ @Override protected boolean mayPlaceOn(final BlockState state, final BlockGetter level, final BlockPos pos) { diff --git a/patches/minecraft/net/minecraft/world/level/block/PoweredRailBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/PoweredRailBlock.java.patch index f487481ef3..19f266dd40 100644 --- a/patches/minecraft/net/minecraft/world/level/block/PoweredRailBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/PoweredRailBlock.java.patch @@ -1,16 +1,11 @@ --- a/net/minecraft/world/level/block/PoweredRailBlock.java +++ b/net/minecraft/world/level/block/PoweredRailBlock.java -@@ -16,6 +_,7 @@ - public static final MapCodec CODEC = simpleCodec(PoweredRailBlock::new); +@@ -14,9 +_,19 @@ + public class PoweredRailBlock extends BaseRailBlock { public static final EnumProperty SHAPE = BlockStateProperties.RAIL_SHAPE_STRAIGHT; public static final BooleanProperty POWERED = BlockStateProperties.POWERED; + private final boolean isActivator; // TRUE for an Activator Rail, FALSE for Powered Rail - @Override - public MapCodec codec() { -@@ -23,7 +_,16 @@ - } - public PoweredRailBlock(final BlockBehaviour.Properties properties) { + this(properties, false); + } @@ -25,7 +20,7 @@ this.registerDefaultState(this.stateDefinition.any().setValue(SHAPE, RailShape.NORTH_SOUTH).setValue(POWERED, false).setValue(WATERLOGGED, false)); } -@@ -36,7 +_,7 @@ +@@ -29,7 +_,7 @@ int y = pos.getY(); int z = pos.getZ(); boolean checkBelow = true; @@ -34,7 +29,7 @@ switch (shape) { case NORTH_SOUTH: if (forward) { -@@ -104,17 +_,17 @@ +@@ -97,17 +_,17 @@ protected boolean isSameRailWithPower(final Level level, final BlockPos pos, final boolean forward, final int searchDepth, final RailShape dir) { BlockState state = level.getBlockState(pos); @@ -55,16 +50,16 @@ } } else { return false; -@@ -133,7 +_,7 @@ +@@ -126,7 +_,7 @@ if (shouldPower != isPowered) { - level.setBlock(pos, state.setValue(POWERED, shouldPower), 3); + level.setBlockAndUpdate(pos, state.setValue(POWERED, shouldPower)); level.updateNeighborsAt(pos.below(), this); - if (state.getValue(SHAPE).isSlope()) { + if (state.getValue(getShapeProperty()).isSlope()) { level.updateNeighborsAt(pos.above(), this); } } -@@ -160,6 +_,10 @@ +@@ -153,6 +_,10 @@ @Override protected void createBlockStateDefinition(final StateDefinition.Builder builder) { diff --git a/patches/minecraft/net/minecraft/world/level/block/PumpkinBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/PumpkinBlock.java.patch index 524f64ecd0..ee706f4b47 100644 --- a/patches/minecraft/net/minecraft/world/level/block/PumpkinBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/PumpkinBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/PumpkinBlock.java +++ b/net/minecraft/world/level/block/PumpkinBlock.java -@@ -43,7 +_,7 @@ +@@ -35,7 +_,7 @@ final InteractionHand hand, final BlockHitResult hitResult ) { diff --git a/patches/minecraft/net/minecraft/world/level/block/RedStoneOreBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/RedStoneOreBlock.java.patch index 0f803fc4b1..87d962d4ba 100644 --- a/patches/minecraft/net/minecraft/world/level/block/RedStoneOreBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/RedStoneOreBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/RedStoneOreBlock.java +++ b/net/minecraft/world/level/block/RedStoneOreBlock.java -@@ -93,7 +_,7 @@ +@@ -86,7 +_,7 @@ @Override protected void spawnAfterBreak(final BlockState state, final ServerLevel level, final BlockPos pos, final ItemStack tool, final boolean dropExperience) { super.spawnAfterBreak(state, level, pos, tool, dropExperience); @@ -9,7 +9,7 @@ this.tryDropExperience(level, pos, tool, UniformInt.of(1, 5)); } } -@@ -125,4 +_,10 @@ +@@ -118,4 +_,10 @@ protected void createBlockStateDefinition(final StateDefinition.Builder builder) { builder.add(LIT); } diff --git a/patches/minecraft/net/minecraft/world/level/block/RedStoneWireBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/RedStoneWireBlock.java.patch index 87973efc87..070eaed570 100644 --- a/patches/minecraft/net/minecraft/world/level/block/RedStoneWireBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/RedStoneWireBlock.java.patch @@ -1,20 +1,20 @@ ---- a/net/minecraft/world/level/block/RedStoneWireBlock.java -+++ b/net/minecraft/world/level/block/RedStoneWireBlock.java -@@ -242,7 +_,7 @@ +--- a/net/minecraft/world/level/block/RedstoneWireBlock.java ++++ b/net/minecraft/world/level/block/RedstoneWireBlock.java +@@ -235,7 +_,7 @@ BlockState relativeState = level.getBlockState(relativePos); if (canConnectUp) { boolean isPlaceableAbove = relativeState.getBlock() instanceof TrapDoorBlock || this.canSurviveOn(level, relativePos, relativeState); -- if (isPlaceableAbove && shouldConnectTo(level.getBlockState(relativePos.above()))) { +- if (isPlaceableAbove && shouldConnectTo(level, relativePos.above())) { + if (isPlaceableAbove && level.getBlockState(relativePos.above()).canRedstoneConnectTo(level, relativePos.above(), null)) { if (relativeState.isFaceSturdy(level, relativePos, direction.getOpposite())) { return RedstoneSide.UP; } -@@ -251,10 +_,14 @@ +@@ -244,10 +_,14 @@ } } -- return !shouldConnectTo(relativeState, direction) -- && (relativeState.isRedstoneConductor(level, relativePos) || !shouldConnectTo(level.getBlockState(relativePos.below()))) +- return !shouldConnectTo(relativeState, level, relativePos, direction) +- && (relativeState.isRedstoneConductor(level, relativePos) || !shouldConnectTo(level, relativePos.below())) - ? RedstoneSide.NONE - : RedstoneSide.SIDE; + if (relativeState.canRedstoneConnectTo(level, relativePos, direction)) { diff --git a/patches/minecraft/net/minecraft/world/level/block/SaplingBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/SaplingBlock.java.patch index 84dea3faff..1b493939e2 100644 --- a/patches/minecraft/net/minecraft/world/level/block/SaplingBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/SaplingBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SaplingBlock.java +++ b/net/minecraft/world/level/block/SaplingBlock.java -@@ -43,6 +_,7 @@ +@@ -35,6 +_,7 @@ @Override protected void randomTick(final BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) { diff --git a/patches/minecraft/net/minecraft/world/level/block/SculkCatalystBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/SculkCatalystBlock.java.patch index 5800c0472c..0823085bcf 100644 --- a/patches/minecraft/net/minecraft/world/level/block/SculkCatalystBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/SculkCatalystBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SculkCatalystBlock.java +++ b/net/minecraft/world/level/block/SculkCatalystBlock.java -@@ -60,8 +_,13 @@ +@@ -53,8 +_,13 @@ @Override protected void spawnAfterBreak(final BlockState state, final ServerLevel level, final BlockPos pos, final ItemStack tool, final boolean dropExperience) { super.spawnAfterBreak(state, level, pos, tool, dropExperience); diff --git a/patches/minecraft/net/minecraft/world/level/block/SculkSensorBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/SculkSensorBlock.java.patch index faaa52905c..a1a3550854 100644 --- a/patches/minecraft/net/minecraft/world/level/block/SculkSensorBlock.java.patch +++ b/patches/minecraft/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 -@@ -288,8 +_,13 @@ +@@ -281,8 +_,13 @@ @Override protected void spawnAfterBreak(final BlockState state, final ServerLevel level, final BlockPos pos, final ItemStack tool, final boolean dropExperience) { super.spawnAfterBreak(state, level, pos, tool, dropExperience); diff --git a/patches/minecraft/net/minecraft/world/level/block/SculkShriekerBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/SculkShriekerBlock.java.patch index a04576377c..e5c7318c44 100644 --- a/patches/minecraft/net/minecraft/world/level/block/SculkShriekerBlock.java.patch +++ b/patches/minecraft/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 -@@ -127,7 +_,7 @@ +@@ -120,7 +_,7 @@ @Override protected void spawnAfterBreak(final BlockState state, final ServerLevel level, final BlockPos pos, final ItemStack tool, final boolean dropExperience) { super.spawnAfterBreak(state, level, pos, tool, dropExperience); @@ -9,7 +9,7 @@ this.tryDropExperience(level, pos, tool, ConstantInt.of(5)); } } -@@ -141,5 +_,10 @@ +@@ -134,5 +_,10 @@ (innerLevel, pos, state, entity) -> VibrationSystem.Ticker.tick(innerLevel, entity.getVibrationData(), entity.getVibrationUser()) ) : null; diff --git a/patches/minecraft/net/minecraft/world/level/block/SoundType.java.patch b/patches/minecraft/net/minecraft/world/level/block/SoundType.java.patch index f1b8ad2ee5..14e47bf9fb 100644 --- a/patches/minecraft/net/minecraft/world/level/block/SoundType.java.patch +++ b/patches/minecraft/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 -@@ -855,6 +_,7 @@ +@@ -879,6 +_,7 @@ private final SoundEvent hitSound; private final SoundEvent fallSound; diff --git a/patches/minecraft/net/minecraft/world/level/block/SpawnerBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/SpawnerBlock.java.patch index 19424b9a3a..de8bac002e 100644 --- a/patches/minecraft/net/minecraft/world/level/block/SpawnerBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/SpawnerBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SpawnerBlock.java +++ b/net/minecraft/world/level/block/SpawnerBlock.java -@@ -40,10 +_,15 @@ +@@ -32,10 +_,15 @@ @Override protected void spawnAfterBreak(final BlockState state, final ServerLevel level, final BlockPos pos, final ItemStack tool, final boolean dropExperience) { super.spawnAfterBreak(state, level, pos, tool, dropExperience); diff --git a/patches/minecraft/net/minecraft/world/level/block/SpongeBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/SpongeBlock.java.patch index 6adf106c89..5df14f41ad 100644 --- a/patches/minecraft/net/minecraft/world/level/block/SpongeBlock.java.patch +++ b/patches/minecraft/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 -@@ -52,6 +_,7 @@ +@@ -45,6 +_,7 @@ } private boolean removeWaterBreadthFirstSearch(final Level level, final BlockPos startPos) { @@ -8,7 +8,7 @@ return BlockPos.breadthFirstTraversal(startPos, 6, 65, (pos, consumer) -> { for (Direction direction : ALL_DIRECTIONS) { consumer.accept(pos.relative(direction)); -@@ -62,7 +_,7 @@ +@@ -55,7 +_,7 @@ } else { BlockState state = level.getBlockState(pos); FluidState fluidState = level.getFluidState(pos); diff --git a/patches/minecraft/net/minecraft/world/level/block/SpreadingSnowyBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/SpreadingSnowyBlock.java.patch index dfb893448b..227efe8b23 100644 --- a/patches/minecraft/net/minecraft/world/level/block/SpreadingSnowyBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/SpreadingSnowyBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SpreadingSnowyBlock.java +++ b/net/minecraft/world/level/block/SpreadingSnowyBlock.java -@@ -52,8 +_,10 @@ +@@ -48,8 +_,10 @@ Optional baseBlock = blocks.getOptional(this.baseBlock); if (!baseBlock.isEmpty()) { if (!canStayAlive(state, level, pos)) { diff --git a/patches/minecraft/net/minecraft/world/level/block/StemBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/StemBlock.java.patch index f254b11706..ada2c30bf2 100644 --- a/patches/minecraft/net/minecraft/world/level/block/StemBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/StemBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/StemBlock.java +++ b/net/minecraft/world/level/block/StemBlock.java -@@ -76,14 +_,16 @@ +@@ -58,14 +_,16 @@ @Override protected boolean mayPlaceOn(final BlockState state, final BlockGetter level, final BlockPos pos) { @@ -19,7 +19,7 @@ int age = state.getValue(AGE); if (age < 7) { state = state.setValue(AGE, age + 1); -@@ -92,7 +_,7 @@ +@@ -74,7 +_,7 @@ Direction direction = Direction.Plane.HORIZONTAL.getRandomDirection(random); BlockPos relative = pos.relative(direction); BlockState stateBelow = level.getBlockState(relative.below()); @@ -28,7 +28,7 @@ Registry blocks = level.registryAccess().lookupOrThrow(Registries.BLOCK); Optional fruit = blocks.getOptional(this.fruit); Optional stem = blocks.getOptional(this.attachedStem); -@@ -102,6 +_,7 @@ +@@ -84,6 +_,7 @@ } } } @@ -36,7 +36,7 @@ } } } -@@ -134,5 +_,10 @@ +@@ -116,5 +_,10 @@ @Override protected void createBlockStateDefinition(final StateDefinition.Builder builder) { builder.add(AGE); diff --git a/patches/minecraft/net/minecraft/world/level/block/SugarCaneBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/SugarCaneBlock.java.patch index 9da411aa67..1afdf6800a 100644 --- a/patches/minecraft/net/minecraft/world/level/block/SugarCaneBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/SugarCaneBlock.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/level/block/SugarCaneBlock.java +++ b/net/minecraft/world/level/block/SugarCaneBlock.java -@@ -19,7 +_,7 @@ +@@ -18,7 +_,7 @@ import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; -public class SugarCaneBlock extends Block { +public class SugarCaneBlock extends Block implements net.minecraftforge.common.IPlantable { - public static final MapCodec CODEC = simpleCodec(SugarCaneBlock::new); public static final IntegerProperty AGE = BlockStateProperties.AGE_15; private static final VoxelShape SHAPE = Block.column(12.0, 0.0, 16.0); -@@ -57,12 +_,15 @@ + +@@ -50,12 +_,15 @@ if (height < 3) { int age = state.getValue(AGE); @@ -25,7 +25,7 @@ } } } -@@ -87,6 +_,8 @@ +@@ -80,6 +_,8 @@ @Override protected boolean canSurvive(final BlockState state, final LevelReader level, final BlockPos pos) { @@ -34,7 +34,7 @@ BlockState stateBelow = level.getBlockState(pos.below()); if (stateBelow.is(this)) { return true; -@@ -98,7 +_,7 @@ +@@ -91,7 +_,7 @@ for (Direction direction : Direction.Plane.HORIZONTAL) { BlockState blockState = level.getBlockState(below.relative(direction)); FluidState fluidState = level.getFluidState(below.relative(direction)); @@ -43,7 +43,7 @@ return true; } } -@@ -110,5 +_,15 @@ +@@ -103,5 +_,15 @@ @Override protected void createBlockStateDefinition(final StateDefinition.Builder builder) { builder.add(AGE); diff --git a/patches/minecraft/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch index 1319def1dc..478bb7de07 100644 --- a/patches/minecraft/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch +++ b/patches/minecraft/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 -@@ -71,10 +_,11 @@ +@@ -64,10 +_,11 @@ @Override protected void randomTick(final BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) { int age = state.getValue(AGE); diff --git a/patches/minecraft/net/minecraft/world/level/block/TntBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/TntBlock.java.patch index 5536967c13..da5bf32e35 100644 --- a/patches/minecraft/net/minecraft/world/level/block/TntBlock.java.patch +++ b/patches/minecraft/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 -@@ -47,7 +_,7 @@ +@@ -43,7 +_,7 @@ @Override protected void onPlace(final BlockState state, final Level level, final BlockPos pos, final BlockState oldState, final boolean movedByPiston) { if (!oldState.is(state.getBlock())) { @@ -9,7 +9,7 @@ level.removeBlock(pos, false); } } -@@ -57,7 +_,7 @@ +@@ -53,7 +_,7 @@ protected void neighborChanged( final BlockState state, final Level level, final BlockPos pos, final Block block, final @Nullable Orientation orientation, final boolean movedByPiston ) { @@ -18,7 +18,7 @@ level.removeBlock(pos, false); } } -@@ -65,7 +_,7 @@ +@@ -61,7 +_,7 @@ @Override public BlockState playerWillDestroy(final Level level, final BlockPos pos, final BlockState state, final Player player) { if (!level.isClientSide() && !player.getAbilities().instabuild && state.getValue(UNSTABLE)) { @@ -27,44 +27,51 @@ } return super.playerWillDestroy(level, pos, state, player); -@@ -80,10 +_,12 @@ +@@ -76,10 +_,12 @@ } } + @Deprecated //Forge: Prefer using IForgeBlock#onCaughtFire public static boolean prime(final Level level, final BlockPos pos) { - return prime(level, pos, null); + return prime(level, pos, null, ItemStack.EMPTY); } + @Deprecated //Forge: Prefer using IForgeBlock#onCaughtFire - private static boolean prime(final Level level, final BlockPos pos, final @Nullable LivingEntity source) { - if (level instanceof ServerLevel serverLevel && serverLevel.getGameRules().get(GameRules.TNT_EXPLODES)) { - PrimedTnt tnt = new PrimedTnt(level, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, source); + public static boolean prime(final Level level, final BlockPos pos, final @Nullable LivingEntity source, final ItemStack itemStack) { + if (!(level instanceof ServerLevel serverLevel && serverLevel.getGameRules().get(GameRules.TNT_EXPLODES))) { + return false; @@ -110,7 +_,7 @@ return super.useItemOn(itemStack, state, level, pos, player, hand, hitResult); } -- if (prime(level, pos, player)) { +- if (prime(level, pos, player, itemStack)) { + if (onCaughtFire(state, level, pos, hitResult.getDirection(), player)) { level.setBlock(pos, Blocks.AIR.defaultBlockState(), 11); Item item = itemStack.getItem(); if (itemStack.is(Items.FLINT_AND_STEEL)) { -@@ -135,7 +_,7 @@ +@@ -135,11 +_,12 @@ Entity owner = projectile.getOwner(); if (projectile.isOnFire() && projectile.mayInteract(serverLevel, pos) -- && prime(level, pos, owner instanceof LivingEntity livingEntity ? livingEntity : null)) { -+ && onCaughtFire(state, level, pos, null, owner instanceof LivingEntity livingEntity ? livingEntity : null)) { +- && prime( ++ && onCaughtFire( ++ state, + level, + pos, +- owner instanceof LivingEntity livingEntity ? livingEntity : null, +- projectile instanceof AbstractArrow arr ? arr.getPickupItemStackOrigin() : ItemStack.EMPTY ++ null, ++ owner instanceof LivingEntity livingEntity ? livingEntity : null + )) { level.removeBlock(pos, false); } - } -@@ -149,5 +_,9 @@ +@@ -154,5 +_,9 @@ @Override protected void createBlockStateDefinition(final StateDefinition.Builder builder) { builder.add(UNSTABLE); + } + + public boolean onCaughtFire(final BlockState state, final Level level, final BlockPos pos, final net.minecraft.core.@Nullable Direction face, final @Nullable LivingEntity igniter) { -+ return prime(level, pos, igniter); ++ return prime(level, pos, igniter, ItemStack.EMPTY); } } diff --git a/patches/minecraft/net/minecraft/world/level/block/TrapDoorBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/TrapDoorBlock.java.patch index 14dbaea906..0cd4a221cf 100644 --- a/patches/minecraft/net/minecraft/world/level/block/TrapDoorBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/TrapDoorBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/TrapDoorBlock.java +++ b/net/minecraft/world/level/block/TrapDoorBlock.java -@@ -192,4 +_,14 @@ +@@ -182,4 +_,14 @@ protected BlockSetType getType() { return this.type; } diff --git a/patches/minecraft/net/minecraft/world/level/block/TripWireBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/TripWireBlock.java.patch index 6a3705dd27..6c4240a373 100644 --- a/patches/minecraft/net/minecraft/world/level/block/TripWireBlock.java.patch +++ b/patches/minecraft/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 -@@ -113,7 +_,7 @@ +@@ -102,7 +_,7 @@ @Override public BlockState playerWillDestroy(final Level level, final BlockPos pos, final BlockState state, final Player player) { diff --git a/patches/minecraft/net/minecraft/world/level/block/TurtleEggBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/TurtleEggBlock.java.patch index df863bdede..ab4b14eeac 100644 --- a/patches/minecraft/net/minecraft/world/level/block/TurtleEggBlock.java.patch +++ b/patches/minecraft/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 -@@ -178,7 +_,7 @@ - if (entity instanceof Turtle || entity instanceof Bat) { - return false; +@@ -174,7 +_,7 @@ + } else if (entity instanceof Player player) { + return !level.getServer().isUnderSpawnProtection(level, pos, player); } else { -- return !(entity instanceof LivingEntity) ? false : entity instanceof Player || level.getGameRules().get(GameRules.MOB_GRIEFING); -+ return !(entity instanceof LivingEntity) ? false : entity instanceof Player || net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(level, entity); +- return entity instanceof LivingEntity ? level.getGameRules().get(GameRules.MOB_GRIEFING) : false; ++ return entity instanceof LivingEntity ? net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(level, entity) : false; } } } diff --git a/patches/minecraft/net/minecraft/world/level/block/VegetationBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/VegetationBlock.java.patch index 07acf2acd8..df8ef71bd5 100644 --- a/patches/minecraft/net/minecraft/world/level/block/VegetationBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/VegetationBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/VegetationBlock.java +++ b/net/minecraft/world/level/block/VegetationBlock.java -@@ -12,7 +_,7 @@ +@@ -11,13 +_,13 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.pathfinder.PathComputationType; @@ -9,8 +9,6 @@ protected VegetationBlock(final BlockBehaviour.Properties properties) { super(properties); } -@@ -21,7 +_,7 @@ - protected abstract MapCodec codec(); protected boolean mayPlaceOn(final BlockState state, final BlockGetter level, final BlockPos pos) { - return state.is(BlockTags.SUPPORTS_VEGETATION); @@ -18,7 +16,7 @@ } @Override -@@ -43,6 +_,9 @@ +@@ -39,6 +_,9 @@ @Override protected boolean canSurvive(final BlockState state, final LevelReader level, final BlockPos pos) { BlockPos below = pos.below(); @@ -28,7 +26,7 @@ return this.mayPlaceOn(level.getBlockState(below), level, below); } -@@ -54,5 +_,11 @@ +@@ -50,5 +_,11 @@ @Override protected boolean isPathfindable(final BlockState state, final PathComputationType type) { return type == PathComputationType.AIR && !this.hasCollision ? true : super.isPathfindable(state, type); diff --git a/patches/minecraft/net/minecraft/world/level/block/VineBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/VineBlock.java.patch index c9fe2eac9c..e242d33ad7 100644 --- a/patches/minecraft/net/minecraft/world/level/block/VineBlock.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/VineBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/VineBlock.java +++ b/net/minecraft/world/level/block/VineBlock.java -@@ -168,7 +_,7 @@ +@@ -163,7 +_,7 @@ @Override protected void randomTick(final BlockState state, final ServerLevel level, final BlockPos pos, final RandomSource random) { if (level.getGameRules().get(GameRules.SPREAD_VINES)) { diff --git a/patches/minecraft/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch b/patches/minecraft/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch index e82a4b0746..caeea5c944 100644 --- a/patches/minecraft/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch +++ b/patches/minecraft/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 -@@ -57,6 +_,7 @@ - private static final short DEFAULT_COOKING_TOTAL_TIME = 0; - private static final short DEFAULT_LIT_TIME_REMAINING = 0; - private static final short DEFAULT_LIT_TOTAL_TIME = 0; +@@ -64,6 +_,7 @@ + private static final int DEFAULT_LIT_TIME_REMAINING = 0; + private static final int DEFAULT_LIT_TOTAL_TIME = 0; + private static final float DEFAULT_SPEED_MULTIPLIER = 1.0F; + private final RecipeType recipeType; protected NonNullList items = NonNullList.withSize(3, ItemStack.EMPTY); private int litTimeRemaining; private int litTotalTime; -@@ -109,6 +_,7 @@ +@@ -117,6 +_,7 @@ ) { super(type, worldPosition, blockState); this.quickCheck = RecipeManager.createCheck(recipeType); @@ -16,76 +16,47 @@ } @Override -@@ -116,10 +_,10 @@ - super.loadAdditional(input); - this.items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); - ContainerHelper.loadAllItems(input, this.items); -- this.cookingTimer = input.getShortOr("cooking_time_spent", (short)0); -- this.cookingTotalTime = input.getShortOr("cooking_total_time", (short)0); -- this.litTimeRemaining = input.getShortOr("lit_time_remaining", (short)0); -- this.litTotalTime = input.getShortOr("lit_total_time", (short)0); -+ this.cookingTimer = input.getIntOr("cooking_time_spent", (short)0); -+ this.cookingTotalTime = input.getIntOr("cooking_total_time", (short)0); -+ this.litTimeRemaining = input.getIntOr("lit_time_remaining", (short)0); -+ this.litTotalTime = input.getIntOr("lit_total_time", (short)0); - this.recipesUsed.clear(); - this.recipesUsed.putAll(input.read("RecipesUsed", RECIPES_USED_CODEC).orElse(Map.of())); - } -@@ -127,10 +_,10 @@ - @Override - protected void saveAdditional(final ValueOutput output) { - super.saveAdditional(output); -- output.putShort("cooking_time_spent", (short)this.cookingTimer); -- output.putShort("cooking_total_time", (short)this.cookingTotalTime); -- output.putShort("lit_time_remaining", (short)this.litTimeRemaining); -- output.putShort("lit_total_time", (short)this.litTotalTime); -+ output.putInt("cooking_time_spent", this.cookingTimer); -+ output.putInt("cooking_total_time", this.cookingTotalTime); -+ output.putInt("lit_time_remaining", this.litTimeRemaining); -+ output.putInt("lit_total_time", this.litTotalTime); - ContainerHelper.saveAllItems(output, this.items); - output.store("RecipesUsed", RECIPES_USED_CODEC, this.recipesUsed); - } -@@ -159,13 +_,13 @@ +@@ -169,7 +_,7 @@ if (recipe != null) { int maxStackSize = entity.getMaxStackSize(); ItemStack burnResult = recipe.value().assemble(input); - if (!burnResult.isEmpty() && canBurn(entity.items, maxStackSize, burnResult)) { + if (!burnResult.isEmpty() && entity.canBurn(entity.items, maxStackSize, burnResult)) { if (!isLit) { - int newLitTime = entity.getBurnDuration(level.fuelValues(), fuel); - entity.litTimeRemaining = newLitTime; - entity.litTotalTime = newLitTime; + int newLitTime = entity.getBurnDuration(level, fuel); + float newSpeedMultiplier = entity.getSpeedMultiplier(level, fuel); +@@ -183,7 +_,7 @@ + } + if (newLitTime > 0) { -- consumeFuel(entity.items, fuel); -+ entity.consumeFuel(entity.items, fuel); +- consumeFuel(level, pos, entity.items, fuel); ++ entity.consumeFuel(level, pos, entity.items, fuel); isLit = true; changed = true; } -@@ -176,7 +_,7 @@ - if (entity.cookingTimer == entity.cookingTotalTime) { +@@ -194,7 +_,7 @@ + if (entity.cookingTimer >= entity.cookingTotalTime) { entity.cookingTimer = 0; - entity.cookingTotalTime = recipe.value().cookingTime(); + entity.cookingTotalTime = getTotalCookTime(recipe, entity); - burn(entity.items, ingredient, burnResult); + entity.burn(entity.items, ingredient, burnResult); entity.setRecipeUsed(recipe); changed = true; } -@@ -205,16 +_,16 @@ +@@ -223,9 +_,8 @@ } } -- private static void consumeFuel(final NonNullList items, final ItemStack fuel) { -+ protected void consumeFuel(final NonNullList items, final ItemStack fuel) { - Item fuelItem = fuel.getItem(); -- fuel.shrink(1); -- if (fuel.isEmpty()) { -- ItemStackTemplate remainder = fuelItem.getCraftingRemainder(); -+ if (fuel.count() == 1) { -+ ItemStackTemplate remainder = fuel.getCraftingRemainder(); - items.set(1, remainder != null ? remainder.create() : ItemStack.EMPTY); - } -+ fuel.shrink(1); +- private static void consumeFuel(final ServerLevel level, final BlockPos pos, final NonNullList items, final ItemStack fuel) { +- Item fuelItem = fuel.getItem(); +- ItemStackTemplate remainder = fuelItem.getCraftingRemainder(); ++ protected void consumeFuel(final ServerLevel level, final BlockPos pos, final NonNullList items, final ItemStack fuel) { ++ ItemStackTemplate remainder = fuel.getCraftingRemainder(); + ItemStack newFuel = fuel; + fuel.shrink(1); + if (remainder != null) { +@@ -239,7 +_,7 @@ + items.set(1, newFuel); } - private static boolean canBurn(final NonNullList items, final int maxStackSize, final ItemStack burnResult) { @@ -93,7 +64,7 @@ ItemStack resultItemStack = items.get(2); if (resultItemStack.isEmpty()) { return true; -@@ -229,7 +_,7 @@ +@@ -254,7 +_,7 @@ return resultCount <= maxResultCount; } @@ -102,7 +73,26 @@ ItemStack resultItemStack = items.get(2); if (resultItemStack.isEmpty()) { items.set(2, result.copy()); -@@ -370,6 +_,35 @@ +@@ -270,7 +_,8 @@ + } + + protected int getBurnDuration(final ServerLevel level, final ItemStack fuelItem) { +- return ResolvableInt.getFromItem(fuelItem, DataComponents.COOKING_FUEL, CookingFuel::burnTime, this.getLootContext(level), 0); ++ var vanilla = ResolvableInt.getFromItem(fuelItem, DataComponents.COOKING_FUEL, CookingFuel::burnTime, this.getLootContext(level), 0); ++ return net.minecraftforge.event.ForgeEventFactory.getItemBurnTime(fuelItem, vanilla, recipeType); + } + + protected float getSpeedMultiplier(final ServerLevel level, final ItemStack fuelItem) { +@@ -348,7 +_,7 @@ + } + + ItemStack fuelSlot = this.items.get(1); +- return itemStack.has(DataComponents.COOKING_FUEL) || itemStack.is(Items.BUCKET) && !fuelSlot.is(Items.BUCKET); ++ return itemStack.has(DataComponents.COOKING_FUEL) || (itemStack.is(Items.BUCKET) && !fuelSlot.is(Items.BUCKET)) || net.minecraftforge.event.ForgeEventFactory.getItemBurnTime(itemStack, 0, recipeType) > 0; + } + + @Override +@@ -407,6 +_,35 @@ for (ItemStack itemStack : this.items) { contents.accountStack(itemStack); } diff --git a/patches/minecraft/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java.patch b/patches/minecraft/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java.patch index a0b2d6e1d1..6f7cb651d9 100644 --- a/patches/minecraft/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java.patch @@ -1,10 +1,9 @@ --- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java -@@ -170,4 +_,27 @@ - output.discard("lock"); +@@ -177,6 +_,29 @@ output.discard("Items"); } -+ + + private net.minecraftforge.common.util.LazyOptional itemHandler = net.minecraftforge.common.util.LazyOptional.of(() -> createUnSidedHandler()); + protected net.minecraftforge.items.IItemHandler createUnSidedHandler() { + return new net.minecraftforge.items.wrapper.InvWrapper(this); @@ -27,4 +26,7 @@ + super.reviveCaps(); + itemHandler = net.minecraftforge.common.util.LazyOptional.of(() -> createUnSidedHandler()); + } - } ++ + protected LootContext getLootContext(final ServerLevel level) { + return new LootContext.Builder( + new LootParams.Builder(level) diff --git a/patches/minecraft/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch b/patches/minecraft/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch index 7bc20415f3..e2ac4ad019 100644 --- a/patches/minecraft/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch @@ -1,28 +1,17 @@ --- a/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java -@@ -177,9 +_,10 @@ - for (int dest = 0; dest < 3; dest++) { - items.set(dest, potionBrewing.mix(ingredient, items.get(dest))); +@@ -235,8 +_,9 @@ + Optional> recipe = entity.quickCheck.getRecipeFor(input, level); + items.set(dest, recipe.isPresent() ? recipe.get().value().assemble(input) : container); } + net.minecraftforge.event.ForgeEventFactory.onPotionBrewed(items); +- ItemStackTemplate remainder = ingredient.getItem().getCraftingRemainder(); + ItemStackTemplate remainder = ingredient.getCraftingRemainder(); ingredient.shrink(1); -- ItemStackTemplate remainder = ingredient.getItem().getCraftingRemainder(); if (remainder != null) { if (ingredient.isEmpty()) { - ingredient = remainder.create(); -@@ -218,6 +_,9 @@ - if (slot == 3) { - PotionBrewing potionBrewing = this.level != null ? this.level.potionBrewing() : PotionBrewing.EMPTY; - return potionBrewing.isIngredient(itemStack); -+ } else if (slot != 4) { -+ PotionBrewing potionbrewing = this.level != null ? this.level.potionBrewing() : PotionBrewing.EMPTY; -+ return this.getItem(slot).isEmpty() && potionbrewing.isValidInput(itemStack); - } else { - return slot == 4 - ? itemStack.is(ItemTags.BREWING_FUEL) -@@ -248,5 +_,34 @@ +@@ -315,5 +_,34 @@ @Override protected AbstractContainerMenu createMenu(final int containerId, final Inventory inventory) { return new BrewingStandMenu(containerId, inventory, this, this.dataAccess); diff --git a/patches/minecraft/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch b/patches/minecraft/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch index 9bae0e2987..6bb0e4c86a 100644 --- a/patches/minecraft/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch @@ -1,13 +1,11 @@ --- a/net/minecraft/world/level/block/entity/ConduitBlockEntity.java +++ b/net/minecraft/world/level/block/entity/ConduitBlockEntity.java -@@ -150,8 +_,8 @@ +@@ -147,7 +_,7 @@ + { BlockPos testPos = worldPosition.offset(ox, oy, oz); BlockState testBlock = level.getBlockState(testPos); - -- for (Block type : VALID_BLOCKS) { -- if (testBlock.is(type)) { -+ { -+ if (testBlock.isConduitFrame(level, testPos, worldPosition)) { - effectBlocks.add(testPos); - } +- if (testBlock.is(BlockTags.CONDUIT_EFFECT_BLOCK)) { ++ if (testBlock.isConduitFrame(level, testPos, worldPosition)) { + effectBlocks.add(testPos); } + } diff --git a/patches/minecraft/net/minecraft/world/level/block/entity/FuelValues.java.patch b/patches/minecraft/net/minecraft/world/level/block/entity/FuelValues.java.patch deleted file mode 100644 index 405f8ffafc..0000000000 --- a/patches/minecraft/net/minecraft/world/level/block/entity/FuelValues.java.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- a/net/minecraft/world/level/block/entity/FuelValues.java -+++ b/net/minecraft/world/level/block/entity/FuelValues.java -@@ -24,7 +_,11 @@ - } - - public boolean isFuel(final ItemStack itemStack) { -- return this.values.containsKey(itemStack.getItem()); -+ return isFuel(itemStack, null); -+ } -+ -+ public boolean isFuel(ItemStack stack, @org.jetbrains.annotations.Nullable net.minecraft.world.item.crafting.RecipeType type) { -+ return burnDuration(stack, type) > 0; - } - - public SequencedSet fuelItems() { -@@ -32,7 +_,16 @@ - } - - public int burnDuration(final ItemStack itemStack) { -- return itemStack.isEmpty() ? 0 : this.values.getInt(itemStack.getItem()); -+ return burnDuration(itemStack, null); -+ } -+ -+ public int burnDuration(final ItemStack itemStack, final @org.jetbrains.annotations.Nullable net.minecraft.world.item.crafting.RecipeType type) { -+ if (itemStack.isEmpty()) -+ return 0; -+ int ret = itemStack.getBurnTime(type); -+ if (ret == -1) -+ ret = this.values.getInt(itemStack.getItem()); -+ return net.minecraftforge.event.ForgeEventFactory.getItemBurnTime(itemStack, ret, type); - } - - public static FuelValues vanillaBurnTimes(final HolderLookup.Provider registries, final FeatureFlagSet enabledFeatures) { diff --git a/patches/minecraft/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch b/patches/minecraft/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch index 70241aed4a..56359d16a1 100644 --- a/patches/minecraft/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/SignBlockEntity.java +++ b/net/minecraft/world/level/block/entity/SignBlockEntity.java -@@ -275,6 +_,11 @@ +@@ -281,6 +_,11 @@ } } diff --git a/patches/minecraft/net/minecraft/world/level/block/entity/SpawnerBlockEntity.java.patch b/patches/minecraft/net/minecraft/world/level/block/entity/SpawnerBlockEntity.java.patch index caf9bdce3c..6ac4fa7768 100644 --- a/patches/minecraft/net/minecraft/world/level/block/entity/SpawnerBlockEntity.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/entity/SpawnerBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/SpawnerBlockEntity.java +++ b/net/minecraft/world/level/block/entity/SpawnerBlockEntity.java -@@ -32,6 +_,13 @@ +@@ -33,6 +_,13 @@ level.sendBlockUpdated(pos, state, state, 260); } } diff --git a/patches/minecraft/net/minecraft/world/level/block/grower/TreeGrower.java.patch b/patches/minecraft/net/minecraft/world/level/block/grower/TreeGrower.java.patch index 264e201f4d..212e837f5a 100644 --- a/patches/minecraft/net/minecraft/world/level/block/grower/TreeGrower.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/grower/TreeGrower.java.patch @@ -1,12 +1,12 @@ --- a/net/minecraft/world/level/block/grower/TreeGrower.java +++ b/net/minecraft/world/level/block/grower/TreeGrower.java -@@ -131,6 +_,9 @@ - .lookupOrThrow(Registries.CONFIGURED_FEATURE) - .get(megaFeatureKey) - .orElse(null); +@@ -114,6 +_,9 @@ + ResourceKey megaFeatureKey = this.getConfiguredMegaFeature(random); + if (megaFeatureKey != null) { + Holder featureHolder = level.registryAccess().lookupOrThrow(Registries.FEATURE).get(megaFeatureKey).orElse(null); + var event = net.minecraftforge.event.ForgeEventFactory.blockGrowFeature(level, random, pos, featureHolder); + featureHolder = event.getFeature(); + if (event.getResult().isDenied()) return false; if (featureHolder != null) { - for (int dx = 0; dx >= -1; dx--) { - for (int dz = 0; dz >= -1; dz--) { + Optional twoByTwoSaplingPos = findTwoByTwoSaplingPos(level, state, pos); + if (twoByTwoSaplingPos.isPresent()) { diff --git a/patches/minecraft/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch b/patches/minecraft/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch index 2cfc4dc425..a8eac0b6a9 100644 --- a/patches/minecraft/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch +++ b/patches/minecraft/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 -@@ -164,6 +_,7 @@ +@@ -153,6 +_,7 @@ RandomSource random = level.getRandom(); if (b0 == 0) { @@ -8,7 +8,7 @@ if (!this.moveBlocks(level, pos, direction, true)) { return false; } -@@ -172,6 +_,7 @@ +@@ -161,6 +_,7 @@ level.playSound(null, pos, SoundEvents.PISTON_EXTEND, SoundSource.BLOCKS, 0.5F, random.nextFloat() * 0.25F + 0.6F); level.gameEvent(GameEvent.BLOCK_ACTIVATE, pos, GameEvent.Context.of(extendedState)); } else if (b0 == 1 || b0 == 2) { @@ -16,7 +16,7 @@ if (level.getBlockEntity(pos.relative(direction)) instanceof PistonMovingBlockEntity pistonMovingBlockEntity) { pistonMovingBlockEntity.finalTick(); } -@@ -220,6 +_,7 @@ +@@ -209,6 +_,7 @@ level.gameEvent(GameEvent.BLOCK_DEACTIVATE, pos, GameEvent.Context.of(movingPistonState)); } @@ -24,7 +24,7 @@ return true; } -@@ -376,6 +_,11 @@ +@@ -361,6 +_,11 @@ @Override protected BlockState rotate(final BlockState state, final Rotation rotation) { return state.setValue(FACING, rotation.rotate(state.getValue(FACING))); diff --git a/patches/minecraft/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch b/patches/minecraft/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch index 8f66434ff9..d5ba3be437 100644 --- a/patches/minecraft/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java +++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -@@ -126,7 +_,7 @@ +@@ -124,7 +_,7 @@ List entities = level.getEntities(null, PistonMath.getMovementArea(aabb, movement, deltaProgress).minmax(aabb)); if (!entities.isEmpty()) { List shapeAabbs = shape.toAabbs(); - boolean causeBounce = self.movedState.is(Blocks.SLIME_BLOCK); + boolean causeBounce = self.movedState.isSlimeBlock(); - Iterator var12 = entities.iterator(); - while (true) { + for (Entity entity : entities) { + if (entity.getPistonPushReaction() != PushReaction.IGNORE_ENTITY) { diff --git a/patches/minecraft/net/minecraft/world/level/block/state/BlockBehaviour.java.patch b/patches/minecraft/net/minecraft/world/level/block/state/BlockBehaviour.java.patch index 4017a55bf9..37e3a7a44c 100644 --- a/patches/minecraft/net/minecraft/world/level/block/state/BlockBehaviour.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/state/BlockBehaviour.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/net/minecraft/world/level/block/state/BlockBehaviour.java -@@ -178,7 +_,7 @@ +@@ -169,7 +_,7 @@ if (!state.isAir() && explosion.getBlockInteraction() != Explosion.BlockInteraction.TRIGGER_BLOCK) { Block block = state.getBlock(); boolean doDropExperienceHack = explosion.getIndirectSourceEntity() instanceof Player; @@ -9,17 +9,17 @@ BlockEntity blockEntity = state.hasBlockEntity() ? level.getBlockEntity(pos) : null; LootParams.Builder params = new LootParams.Builder(level) .withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos)) -@@ -193,8 +_,7 @@ +@@ -184,8 +_,7 @@ state.getDrops(params).forEach(stack -> onHit.accept(stack, pos)); } -- level.setBlock(pos, Blocks.AIR.defaultBlockState(), 3); +- level.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState()); - block.wasExploded(level, pos, explosion); + state.onBlockExploded(level, pos, explosion); } } -@@ -352,11 +_,14 @@ +@@ -347,11 +_,14 @@ return 0.0F; } @@ -36,7 +36,7 @@ } protected void attack(final BlockState state, final Level level, final BlockPos pos, final Player player) { -@@ -407,6 +_,8 @@ +@@ -406,6 +_,8 @@ return this.isRandomlyTicking; } @@ -45,7 +45,7 @@ protected SoundType getSoundType(final BlockState state) { return this.soundType; } -@@ -427,6 +_,10 @@ +@@ -426,6 +_,10 @@ return this.properties.destroyTime; } @@ -56,7 +56,7 @@ public abstract static class BlockStateBase extends StateHolder implements TypedInstance { private static final Direction[] DIRECTIONS = Direction.values(); private static final VoxelShape[] EMPTY_OCCLUSION_SHAPES = Util.make(new VoxelShape[DIRECTIONS.length], s -> Arrays.fill(s, Shapes.empty())); -@@ -582,12 +_,14 @@ +@@ -577,12 +_,14 @@ return this.useShapeForLightOcclusion; } @@ -72,7 +72,7 @@ } public boolean ignitedByLava() { -@@ -600,9 +_,11 @@ +@@ -595,9 +_,11 @@ } public MapColor getMapColor(final BlockGetter level, final BlockPos pos) { @@ -85,7 +85,7 @@ public BlockState rotate(final Rotation rotation) { return this.getBlock().rotate(this.asState(), rotation); } -@@ -660,6 +_,8 @@ +@@ -659,6 +_,8 @@ } public PushReaction getPistonPushReaction() { @@ -94,12 +94,12 @@ return this.pushReaction; } -@@ -1013,7 +_,7 @@ +@@ -1033,7 +_,7 @@ private BlockBehaviour.StateArgumentPredicate> isValidSpawn = (state, level, pos, entityType) -> state.isFaceSturdy( level, pos, Direction.UP ) - && state.getLightEmission() < 14; + && state.getLightEmission(level, pos) < 14; private BlockBehaviour.StatePredicate isRedstoneConductor = BlockBehaviour.BlockStateBase::isCollisionShapeFullBlock; - private BlockBehaviour.StatePredicate isSuffocating = (state, level, pos) -> state.blocksMotion() && state.isCollisionShapeFullBlock(level, pos); - private BlockBehaviour.StatePredicate isViewBlocking = this.isSuffocating; + private BlockBehaviour.StatePredicate isSuffocating = (state, level, pos) -> state.is(BlockTags.CAUSES_SUFFOCATION) + && state.isCollisionShapeFullBlock(level, pos); diff --git a/patches/minecraft/net/minecraft/world/level/block/state/BlockState.java.patch b/patches/minecraft/net/minecraft/world/level/block/state/BlockState.java.patch index 217df8df28..3c0f2016e8 100644 --- a/patches/minecraft/net/minecraft/world/level/block/state/BlockState.java.patch +++ b/patches/minecraft/net/minecraft/world/level/block/state/BlockState.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/block/state/BlockState.java +++ b/net/minecraft/world/level/block/state/BlockState.java -@@ -5,7 +_,7 @@ +@@ -6,7 +_,7 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.properties.Property; -public class BlockState extends BlockBehaviour.BlockStateBase { +public class BlockState extends BlockBehaviour.BlockStateBase implements net.minecraftforge.common.extensions.IForgeBlockState { - public static final Codec CODEC = codec(BuiltInRegistries.BLOCK.byNameCodec(), Block::defaultBlockState, Block::getStateDefinition).stable(); - - public BlockState(final Block owner, final Property[] propertyKeys, final Comparable[] propertyValues) { + public static final Codec FULL_CODEC = codec(BuiltInRegistries.BLOCK.byNameCodec(), Block::defaultBlockState, Block::getStateDefinition) + .stable(); + private static final Codec> CONSTANT_OR_DISPATCH_CODEC = Codec.either(BuiltInRegistries.BLOCK.byNameCodec(), FULL_CODEC); diff --git a/patches/minecraft/net/minecraft/world/level/blockscan/BlockScanUtils.java.patch b/patches/minecraft/net/minecraft/world/level/blockscan/BlockScanUtils.java.patch new file mode 100644 index 0000000000..f4ab5a2a93 --- /dev/null +++ b/patches/minecraft/net/minecraft/world/level/blockscan/BlockScanUtils.java.patch @@ -0,0 +1,33 @@ +--- a/net/minecraft/world/level/blockscan/BlockScanUtils.java ++++ b/net/minecraft/world/level/blockscan/BlockScanUtils.java +@@ -100,14 +_,29 @@ + final Predicate predicate, + final BlockStateConsumer consumer + ) { ++ return findBlocksInSection(section, origin, fromX, fromY, fromX, toX, toY, toZ, (state, pos) -> predicate.test(state), consumer); ++ } ++ ++ public static boolean findBlocksInSection( ++ final LevelChunkSection section, ++ final BlockPos origin, ++ final int fromX, ++ final int fromY, ++ final int fromZ, ++ final int toX, ++ final int toY, ++ final int toZ, ++ final java.util.function.BiPredicate predicate, ++ final BlockStateConsumer consumer ++ ) { + BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); + + for (int y = fromY; y <= toY; y++) { + for (int z = fromZ; z <= toZ; z++) { + for (int x = fromX; x <= toX; x++) { + BlockState blockState = section.getBlockState(x, y, z); +- if (predicate.test(blockState)) { + mutablePos.setWithOffset(origin, x, y, z); ++ if (predicate.test(blockState, mutablePos)) { + if (consumer.apply(mutablePos, blockState).shouldAbort()) { + return true; + } diff --git a/patches/minecraft/net/minecraft/world/level/chunk/ChunkAccess.java.patch b/patches/minecraft/net/minecraft/world/level/chunk/ChunkAccess.java.patch index 55fbda9d78..c5310b7a87 100644 --- a/patches/minecraft/net/minecraft/world/level/chunk/ChunkAccess.java.patch +++ b/patches/minecraft/net/minecraft/world/level/chunk/ChunkAccess.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/net/minecraft/world/level/chunk/ChunkAccess.java -@@ -318,23 +_,28 @@ +@@ -316,10 +_,14 @@ @Override public final void findBlockLightSources(final BiConsumer consumer) { @@ -13,27 +13,19 @@ + } + + public void findBlocks(final java.util.function.BiPredicate predicate, final BiConsumer consumer) { - BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos(); + BlockStateConsumer blockStateConsumer = (pos, state) -> { + consumer.accept(pos, state); + return Continuation.CONTINUE; +@@ -328,7 +_,7 @@ for (int sectionY = this.getMinSectionY(); sectionY <= this.getMaxSectionY(); sectionY++) { LevelChunkSection section = this.getSection(this.getSectionIndexFromSectionY(sectionY)); - if (section.maybeHas(predicate)) { + if (section.maybeHas(state -> predicate.test(state, BlockPos.ZERO))) { BlockPos origin = SectionPos.of(this.chunkPos, sectionY).origin(); - - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++) { - BlockState state = section.getBlockState(x, y, z); -- if (predicate.test(state)) { -- consumer.accept(mutablePos.setWithOffset(origin, x, y, z), state); -+ mutablePos.setWithOffset(origin, x, y, z); -+ if (predicate.test(state, mutablePos.immutable())) { -+ consumer.accept(mutablePos, state); - } - } - } -@@ -499,5 +_,9 @@ + BlockScanUtils.findBlocksInSection(section, origin, 0, 0, 0, 15, 15, 15, predicate, blockStateConsumer); + } +@@ -479,5 +_,9 @@ } public record PackedTicks(List> blocks, List> fluids) { diff --git a/patches/minecraft/net/minecraft/world/level/chunk/ChunkGenerator.java.patch b/patches/minecraft/net/minecraft/world/level/chunk/ChunkGenerator.java.patch index 76bbd27b2d..28fccc8359 100644 --- a/patches/minecraft/net/minecraft/world/level/chunk/ChunkGenerator.java.patch +++ b/patches/minecraft/net/minecraft/world/level/chunk/ChunkGenerator.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/ChunkGenerator.java +++ b/net/minecraft/world/level/chunk/ChunkGenerator.java -@@ -84,7 +_,7 @@ +@@ -91,7 +_,7 @@ .byNameCodec() .dispatchStable(ChunkGenerator::codec, Function.identity()); protected final BiomeSource biomeSource; @@ -9,7 +9,7 @@ private final Function, BiomeGenerationSettings> generationSettingsGetter; public ChunkGenerator(final BiomeSource biomeSource) { -@@ -94,9 +_,14 @@ +@@ -101,9 +_,14 @@ public ChunkGenerator(final BiomeSource biomeSource, final Function, BiomeGenerationSettings> generationSettingsGetter) { this.biomeSource = biomeSource; this.generationSettingsGetter = generationSettingsGetter; diff --git a/patches/minecraft/net/minecraft/world/level/chunk/ImposterProtoChunk.java.patch b/patches/minecraft/net/minecraft/world/level/chunk/ImposterProtoChunk.java.patch index c7377988a8..19379698b1 100644 --- a/patches/minecraft/net/minecraft/world/level/chunk/ImposterProtoChunk.java.patch +++ b/patches/minecraft/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 -@@ -278,4 +_,9 @@ +@@ -258,4 +_,9 @@ public ChunkSkyLightSources getSkyLightSources() { return this.wrapped.getSkyLightSources(); } diff --git a/patches/minecraft/net/minecraft/world/level/chunk/LevelChunk.java.patch b/patches/minecraft/net/minecraft/world/level/chunk/LevelChunk.java.patch index 3de8c270aa..733ead7446 100644 --- a/patches/minecraft/net/minecraft/world/level/chunk/LevelChunk.java.patch +++ b/patches/minecraft/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 -@@ -63,7 +_,7 @@ +@@ -62,7 +_,7 @@ import org.jspecify.annotations.Nullable; import org.slf4j.Logger; @@ -9,7 +9,7 @@ private static final Logger LOGGER = LogUtils.getLogger(); private static final TickingBlockEntity NULL_TICKER = new TickingBlockEntity() { @Override -@@ -123,6 +_,7 @@ +@@ -122,6 +_,7 @@ this.postLoad = postLoad; this.blockTicks = blockTicks; this.fluidTicks = fluidTicks; @@ -17,7 +17,7 @@ } public LevelChunk(final ServerLevel level, final ProtoChunk protoChunk, final LevelChunk.@Nullable PostLoadProcessor postLoad) { -@@ -323,7 +_,7 @@ +@@ -322,7 +_,7 @@ return null; } @@ -26,7 +26,7 @@ state.onPlace(this.level, pos, oldState, movedByPiston); } -@@ -367,6 +_,12 @@ +@@ -366,6 +_,12 @@ public @Nullable BlockEntity getBlockEntity(final BlockPos pos, final LevelChunk.EntityCreationType creationType) { BlockEntity blockEntity = this.blockEntities.get(pos); @@ -39,7 +39,7 @@ if (blockEntity == null) { CompoundTag tag = this.pendingBlockEntities.remove(pos); if (tag != null) { -@@ -384,9 +_,6 @@ +@@ -383,9 +_,6 @@ this.addAndRegisterBlockEntity(blockEntity); } } @@ -49,7 +49,7 @@ } return blockEntity; -@@ -401,6 +_,7 @@ +@@ -400,6 +_,7 @@ this.level.onBlockEntityAdded(blockEntity); this.updateBlockEntityTicker(blockEntity); @@ -57,7 +57,7 @@ } } -@@ -452,9 +_,14 @@ +@@ -451,9 +_,14 @@ public @Nullable CompoundTag getBlockEntityNbtForSaving(final BlockPos blockPos, final HolderLookup.Provider registryAccess) { BlockEntity blockEntity = this.getBlockEntity(blockPos); if (blockEntity != null && !blockEntity.isRemoved()) { @@ -72,8 +72,8 @@ } CompoundTag result = this.pendingBlockEntities.get(blockPos); -@@ -534,7 +_,7 @@ - blockEntities.accept((pos, type, tag) -> { +@@ -531,7 +_,7 @@ + chunkData.forEachBlockEntityTag(chunkX, chunkZ, (pos, type, tag) -> { BlockEntity blockEntity = this.getBlockEntity(pos, LevelChunk.EntityCreationType.IMMEDIATE); if (blockEntity != null && tag != null && blockEntity.getType() == type) { - blockEntity.loadWithComponents(TagValueInput.create(reporter.forChild(blockEntity.problemPath()), this.level.registryAccess(), tag)); @@ -81,7 +81,7 @@ } }); } -@@ -673,6 +_,7 @@ +@@ -670,6 +_,7 @@ } public void clearAllBlockEntities() { @@ -89,7 +89,7 @@ this.blockEntities.values().forEach(BlockEntity::setRemoved); this.blockEntities.clear(); this.tickersInLevel.values().forEach(ticker -> ticker.rebind(NULL_TICKER)); -@@ -680,6 +_,7 @@ +@@ -677,6 +_,7 @@ } public void registerAllBlockEntitiesAfterLevelLoad() { @@ -97,7 +97,7 @@ this.blockEntities.values().forEach(blockEntity -> { if (this.level instanceof ServerLevel serverLevel) { this.addGameEventListener(blockEntity, serverLevel); -@@ -725,6 +_,24 @@ +@@ -722,6 +_,24 @@ return new LevelChunk.BoundTickingBlockEntity<>(blockEntity, ticker); } @@ -122,7 +122,7 @@ private class BoundTickingBlockEntity implements TickingBlockEntity { private final T blockEntity; private final BlockEntityTicker ticker; -@@ -742,6 +_,7 @@ +@@ -739,6 +_,7 @@ if (LevelChunk.this.isTicking(pos)) { try { ProfilerFiller profiler = Profiler.get(); @@ -130,7 +130,7 @@ profiler.push(this::getType); BlockState blockState = LevelChunk.this.getBlockState(pos); if (this.blockEntity.getType().isValid(blockState)) { -@@ -763,6 +_,11 @@ +@@ -760,6 +_,11 @@ CrashReport report = CrashReport.forThrowable(t, "Ticking block entity"); CrashReportCategory category = report.addCategory("Block entity being ticked"); this.blockEntity.fillCrashReportCategory(category); @@ -142,7 +142,7 @@ throw new ReportedException(report); } } -@@ -836,6 +_,33 @@ +@@ -833,6 +_,33 @@ public String toString() { return this.ticker + " "; } diff --git a/patches/minecraft/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch b/patches/minecraft/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch index 71dc0443e4..64316c0f74 100644 --- a/patches/minecraft/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch +++ b/patches/minecraft/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java +++ b/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -@@ -201,9 +_,15 @@ +@@ -204,9 +_,15 @@ levelChunk.setFullStatus(holder::getFullStatus); levelChunk.runPostLoad(); levelChunk.setLoaded(true); diff --git a/patches/minecraft/net/minecraft/world/level/dimension/end/EnderDragonFight.java.patch b/patches/minecraft/net/minecraft/world/level/dimension/end/EnderDragonFight.java.patch index d20866b88c..d7742ddfbd 100644 --- a/patches/minecraft/net/minecraft/world/level/dimension/end/EnderDragonFight.java.patch +++ b/patches/minecraft/net/minecraft/world/level/dimension/end/EnderDragonFight.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/dimension/end/EnderDragonFight.java +++ b/net/minecraft/world/level/dimension/end/EnderDragonFight.java -@@ -580,6 +_,14 @@ +@@ -584,6 +_,14 @@ } } diff --git a/patches/minecraft/net/minecraft/world/level/levelgen/Beardifier.java.patch b/patches/minecraft/net/minecraft/world/level/levelgen/Beardifier.java.patch index 7f345cfec7..1c676577e6 100644 --- a/patches/minecraft/net/minecraft/world/level/levelgen/Beardifier.java.patch +++ b/patches/minecraft/net/minecraft/world/level/levelgen/Beardifier.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/levelgen/Beardifier.java +++ b/net/minecraft/world/level/levelgen/Beardifier.java -@@ -52,6 +_,11 @@ +@@ -62,6 +_,11 @@ for (StructurePiece piece : start.getPieces()) { if (piece.isCloseToChunk(chunkPos, 12)) { diff --git a/patches/minecraft/net/minecraft/world/level/levelgen/DebugLevelSource.java.patch b/patches/minecraft/net/minecraft/world/level/levelgen/DebugLevelSource.java.patch index bf5d375d8f..cc6397681e 100644 --- a/patches/minecraft/net/minecraft/world/level/levelgen/DebugLevelSource.java.patch +++ b/patches/minecraft/net/minecraft/world/level/levelgen/DebugLevelSource.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/levelgen/DebugLevelSource.java +++ b/net/minecraft/world/level/levelgen/DebugLevelSource.java -@@ -140,4 +_,10 @@ +@@ -134,4 +_,10 @@ public int getSeaLevel() { return 63; } diff --git a/patches/minecraft/net/minecraft/world/level/levelgen/feature/MonsterRoomFeature.java.patch b/patches/minecraft/net/minecraft/world/level/levelgen/feature/MonsterRoomFeature.java.patch index 23d9227307..bfc7c3ee04 100644 --- a/patches/minecraft/net/minecraft/world/level/levelgen/feature/MonsterRoomFeature.java.patch +++ b/patches/minecraft/net/minecraft/world/level/levelgen/feature/MonsterRoomFeature.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/levelgen/feature/MonsterRoomFeature.java +++ b/net/minecraft/world/level/levelgen/feature/MonsterRoomFeature.java -@@ -129,6 +_,6 @@ +@@ -128,6 +_,6 @@ } private EntityType randomEntityId(final RandomSource random) { diff --git a/patches/minecraft/net/minecraft/world/level/levelgen/feature/treedecorators/AlterGroundDecorator.java.patch b/patches/minecraft/net/minecraft/world/level/levelgen/feature/treedecorators/AlterGroundDecorator.java.patch index eee77ce551..c223f5dd0e 100644 --- a/patches/minecraft/net/minecraft/world/level/levelgen/feature/treedecorators/AlterGroundDecorator.java.patch +++ b/patches/minecraft/net/minecraft/world/level/levelgen/feature/treedecorators/AlterGroundDecorator.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/world/level/levelgen/feature/treedecorators/AlterGroundDecorator.java +++ b/net/minecraft/world/level/levelgen/feature/treedecorators/AlterGroundDecorator.java -@@ -58,6 +_,7 @@ +@@ -59,6 +_,7 @@ BlockPos cursor = pos.above(dy); - BlockState replaceWith = this.provider.getOptionalState(context.level(), context.random(), cursor); + BlockState replaceWith = this.provider.value().getOptionalState(context.level(), context.random(), cursor); if (replaceWith != null) { + replaceWith = net.minecraftforge.event.ForgeEventFactory.alterGround(context.level(), context.random(), cursor, replaceWith); context.setBlock(cursor, replaceWith); diff --git a/patches/minecraft/net/minecraft/world/level/levelgen/feature/trunkplacers/TrunkPlacer.java.patch b/patches/minecraft/net/minecraft/world/level/levelgen/feature/trunkplacers/TrunkPlacer.java.patch index 36b7e245d8..865b5b0261 100644 --- a/patches/minecraft/net/minecraft/world/level/levelgen/feature/trunkplacers/TrunkPlacer.java.patch +++ b/patches/minecraft/net/minecraft/world/level/levelgen/feature/trunkplacers/TrunkPlacer.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/levelgen/feature/trunkplacers/TrunkPlacer.java +++ b/net/minecraft/world/level/levelgen/feature/trunkplacers/TrunkPlacer.java -@@ -68,6 +_,8 @@ +@@ -63,6 +_,8 @@ ) { - BlockState blockBelowTrunk = config.belowTrunkProvider.getOptionalState(level, random, pos); + BlockState blockBelowTrunk = tree.belowTrunkProvider().value().getOptionalState(level, random, pos); if (blockBelowTrunk != null) { + var levelReader = (net.minecraft.world.level.LevelReader)level; -+ if (!levelReader.getBlockState(pos).onTreeGrow(levelReader, trunkSetter, random, pos, config)) ++ if (!levelReader.getBlockState(pos).onTreeGrow(levelReader, trunkSetter, random, pos, tree)) trunkSetter.accept(pos, blockBelowTrunk); } } diff --git a/patches/minecraft/net/minecraft/world/level/levelgen/structure/Structure.java.patch b/patches/minecraft/net/minecraft/world/level/levelgen/structure/Structure.java.patch index 49ebcafab9..d59e58a0ef 100644 --- a/patches/minecraft/net/minecraft/world/level/levelgen/structure/Structure.java.patch +++ b/patches/minecraft/net/minecraft/world/level/levelgen/structure/Structure.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/world/level/levelgen/structure/Structure.java +++ b/net/minecraft/world/level/levelgen/structure/Structure.java -@@ -46,10 +_,13 @@ +@@ -47,10 +_,13 @@ public abstract class Structure { public static final Codec DIRECT_CODEC = BuiltInRegistries.STRUCTURE_TYPE.byNameCodec().dispatch(Structure::type, StructureType::codec); - public static final Codec> CODEC = RegistryFileCodec.create(Registries.STRUCTURE, DIRECT_CODEC); + public static final Codec> CODEC = RegistryCodecs.holder(Registries.STRUCTURE, DIRECT_CODEC); - protected final Structure.StructureSettings settings; + //Forge: Make this field private so that the redirect coremod can target it + @Deprecated @@ -16,7 +16,7 @@ } public static MapCodec simpleCodec(final Function constructor) { -@@ -58,22 +_,23 @@ +@@ -59,22 +_,23 @@ protected Structure(final Structure.StructureSettings settings) { this.settings = settings; @@ -44,7 +44,7 @@ } public BoundingBox adjustBoundingBox(final BoundingBox boundingBox) { -@@ -209,6 +_,22 @@ +@@ -208,6 +_,22 @@ } public abstract StructureType type(); diff --git a/patches/minecraft/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch b/patches/minecraft/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch index 6c40ecea1b..8bf474c925 100644 --- a/patches/minecraft/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch +++ b/patches/minecraft/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 -@@ -81,6 +_,9 @@ +@@ -82,6 +_,9 @@ } public final CompoundTag createTag(final StructurePieceSerializationContext context) { diff --git a/patches/minecraft/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch b/patches/minecraft/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch index 6678e7627e..4a5ab2bb7e 100644 --- a/patches/minecraft/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch +++ b/patches/minecraft/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 -@@ -249,6 +_,10 @@ +@@ -238,6 +_,10 @@ return transform(pos, settings.getMirror(), settings.getRotation(), settings.getRotationPivot()); } @@ -11,7 +11,7 @@ public boolean placeInWorld( final ServerLevelAccessor level, final BlockPos position, -@@ -276,7 +_,7 @@ +@@ -265,7 +_,7 @@ int maxX = Integer.MIN_VALUE; int maxY = Integer.MIN_VALUE; int maxZ = Integer.MIN_VALUE; @@ -20,7 +20,7 @@ try (ProblemReporter.ScopedCollector reporter = new ProblemReporter.ScopedCollector(LOGGER)) { for (StructureTemplate.StructureBlockInfo blockInfo : processedBlockInfoList) { -@@ -395,10 +_,10 @@ +@@ -384,10 +_,10 @@ position, settings.getMirror(), settings.getRotation(), @@ -33,7 +33,7 @@ ); } } -@@ -440,12 +_,21 @@ +@@ -429,12 +_,21 @@ }); } @@ -56,7 +56,7 @@ ) { List originalBlockInfoList = new ArrayList<>(); List processedBlockInfoList = new ArrayList<>(); -@@ -469,7 +_,7 @@ +@@ -458,7 +_,7 @@ Iterator iterator = settings.getProcessors().iterator(); while (processedBlockInfo != null && iterator.hasNext()) { @@ -65,7 +65,7 @@ } if (processedBlockInfo != null) { -@@ -491,17 +_,17 @@ +@@ -480,17 +_,17 @@ final BlockPos position, final Mirror mirror, final Rotation rotation, @@ -89,7 +89,7 @@ ListTag posTag = new ListTag(); posTag.add(DoubleTag.valueOf(pos.x)); posTag.add(DoubleTag.valueOf(pos.y)); -@@ -523,6 +_,30 @@ +@@ -516,6 +_,30 @@ } } } diff --git a/patches/minecraft/net/minecraft/world/level/material/FlowingFluid.java.patch b/patches/minecraft/net/minecraft/world/level/material/FlowingFluid.java.patch index afd6d6b12b..9fcf0b6fd2 100644 --- a/patches/minecraft/net/minecraft/world/level/material/FlowingFluid.java.patch +++ b/patches/minecraft/net/minecraft/world/level/material/FlowingFluid.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/material/FlowingFluid.java +++ b/net/minecraft/world/level/material/FlowingFluid.java -@@ -168,7 +_,7 @@ +@@ -167,7 +_,7 @@ BlockState blockState = level.getBlockState(relativePos); FluidState fluidState = blockState.getFluidState(); if (fluidState.getType().isSame(this) && canPassThroughWall(direction, level, pos, state, relativePos, blockState)) { @@ -9,7 +9,7 @@ neighbourSources++; } -@@ -176,7 +_,7 @@ +@@ -175,7 +_,7 @@ } } @@ -18,7 +18,7 @@ BlockState belowState = level.getBlockState(mutablePos.setWithOffset(pos, Direction.DOWN)); FluidState belowFluid = belowState.getFluidState(); if (belowState.isSolid() || this.isSourceBlockOfThisType(belowFluid)) { -@@ -263,6 +_,15 @@ +@@ -262,6 +_,15 @@ return this.getSource().defaultFluidState().setValue(FALLING, falling); } diff --git a/patches/minecraft/net/minecraft/world/level/material/FluidState.java.patch b/patches/minecraft/net/minecraft/world/level/material/FluidState.java.patch index d92d39eccc..0bb2658b1b 100644 --- a/patches/minecraft/net/minecraft/world/level/material/FluidState.java.patch +++ b/patches/minecraft/net/minecraft/world/level/material/FluidState.java.patch @@ -9,7 +9,7 @@ public static final Codec CODEC = codec(BuiltInRegistries.FLUID.byNameCodec(), Fluid::defaultFluidState, Fluid::getStateDefinition).stable(); public static final int AMOUNT_MAX = 9; public static final int AMOUNT_FULL = 8; -@@ -109,6 +_,7 @@ +@@ -120,6 +_,7 @@ return this.getType().builtInRegistryHolder(); } diff --git a/patches/minecraft/net/minecraft/world/level/material/LavaFluid.java.patch b/patches/minecraft/net/minecraft/world/level/material/LavaFluid.java.patch index 63a2dcba5e..19f6c5b5ae 100644 --- a/patches/minecraft/net/minecraft/world/level/material/LavaFluid.java.patch +++ b/patches/minecraft/net/minecraft/world/level/material/LavaFluid.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/material/LavaFluid.java +++ b/net/minecraft/world/level/material/LavaFluid.java -@@ -93,7 +_,7 @@ +@@ -94,7 +_,7 @@ BlockState blockState = level.getBlockState(testPos); if (blockState.isAir()) { if (this.hasFlammableNeighbours(level, testPos)) { @@ -8,8 +8,8 @@ + level.setBlockAndUpdate(testPos, net.minecraftforge.event.ForgeEventFactory.fireFluidPlaceBlockEvent(level, testPos, pos, Blocks.FIRE.defaultBlockState())); return; } - } else if (blockState.blocksMotion()) { -@@ -107,8 +_,8 @@ + } else if (blockState.is(BlockTags.BLOCKS_LAVA_FIRE_SPREAD)) { +@@ -108,8 +_,8 @@ return; } @@ -20,7 +20,7 @@ } } } -@@ -124,7 +_,7 @@ +@@ -125,7 +_,7 @@ private boolean hasFlammableNeighbours(final LevelReader level, final BlockPos pos) { for (Direction direction : Direction.values()) { @@ -29,7 +29,7 @@ return true; } } -@@ -132,10 +_,17 @@ +@@ -133,10 +_,17 @@ return false; } @@ -47,12 +47,12 @@ @Override public @Nullable ParticleOptions getDripParticle() { return ParticleTypes.DRIPPING_LAVA; -@@ -206,7 +_,7 @@ +@@ -207,7 +_,7 @@ FluidState fluidState = level.getFluidState(pos); if (this.is(FluidTags.LAVA) && fluidState.is(FluidTags.WATER)) { if (state.getBlock() instanceof LiquidBlock) { -- level.setBlock(pos, Blocks.STONE.defaultBlockState(), 3); -+ level.setBlock(pos, net.minecraftforge.event.ForgeEventFactory.fireFluidPlaceBlockEvent(level, pos, pos, Blocks.STONE.defaultBlockState()), 3); +- level.setBlockAndUpdate(pos, Blocks.STONE.defaultBlockState()); ++ level.setBlockAndUpdate(pos, net.minecraftforge.event.ForgeEventFactory.fireFluidPlaceBlockEvent(level, pos, pos, Blocks.STONE.defaultBlockState())); } this.fizz(level, pos); diff --git a/patches/minecraft/net/minecraft/world/level/pathfinder/PathType.java.patch b/patches/minecraft/net/minecraft/world/level/pathfinder/PathType.java.patch index afe10d46ef..9571fcf176 100644 --- a/patches/minecraft/net/minecraft/world/level/pathfinder/PathType.java.patch +++ b/patches/minecraft/net/minecraft/world/level/pathfinder/PathType.java.patch @@ -1,20 +1,21 @@ --- a/net/minecraft/world/level/pathfinder/PathType.java +++ b/net/minecraft/world/level/pathfinder/PathType.java -@@ -1,6 +_,6 @@ - package net.minecraft.world.level.pathfinder; +@@ -6,7 +_,7 @@ + import net.minecraft.network.codec.StreamCodec; + import net.minecraft.util.ByIdMap; -public enum PathType { +public enum PathType implements net.minecraftforge.common.IExtensibleEnum { - BLOCKED(-1.0F), - OPEN(0.0F), - WALKABLE(0.0F), -@@ -37,5 +_,9 @@ + BLOCKED(0, -1.0F), + OPEN(1, 0.0F), + WALKABLE(2, 0.0F), +@@ -47,5 +_,9 @@ public float getMalus() { return this.malus; + } + -+ public static PathType create(String name, float malus) { ++ public static PathType create(String name, int networkId, float malus) { + throw new IllegalArgumentException("Enum not extended"); } } diff --git a/patches/minecraft/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java.patch b/patches/minecraft/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java.patch index 48ec5af73f..f022259006 100644 --- a/patches/minecraft/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java.patch +++ b/patches/minecraft/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java +++ b/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java -@@ -494,6 +_,16 @@ +@@ -492,6 +_,16 @@ for (int dz = -1; dz <= 1; dz++) { if (dx != 0 || dz != 0) { PathType pathType = context.getPathTypeFromState(x + dx, y + dy, z + dz); @@ -17,7 +17,7 @@ if (pathType == PathType.DAMAGING) { return PathType.DAMAGING_IN_NEIGHBOR; } -@@ -520,6 +_,10 @@ +@@ -518,6 +_,10 @@ protected static PathType getPathTypeFromState(final BlockGetter level, final BlockPos pos) { BlockState blockState = level.getBlockState(pos); Block block = blockState.getBlock(); @@ -28,7 +28,7 @@ if (blockState.isAir()) { return PathType.OPEN; } -@@ -546,6 +_,8 @@ +@@ -544,6 +_,8 @@ if (!blockState.is(Blocks.WITHER_ROSE) && !blockState.is(BlockTags.SPELEOTHEMS)) { FluidState fluidState = blockState.getFluidState(); @@ -37,7 +37,7 @@ if (fluidState.is(FluidTags.LAVA)) { return PathType.LAVA; } -@@ -558,6 +_,8 @@ +@@ -556,6 +_,8 @@ if (blockState.getValue(DoorBlock.OPEN)) { return PathType.DOOR_OPEN; } else { diff --git a/patches/minecraft/net/minecraft/world/level/portal/PortalShape.java.patch b/patches/minecraft/net/minecraft/world/level/portal/PortalShape.java.patch index 3d5eded0bd..dc269d20a1 100644 --- a/patches/minecraft/net/minecraft/world/level/portal/PortalShape.java.patch +++ b/patches/minecraft/net/minecraft/world/level/portal/PortalShape.java.patch @@ -1,11 +1,53 @@ --- a/net/minecraft/world/level/portal/PortalShape.java +++ b/net/minecraft/world/level/portal/PortalShape.java -@@ -28,7 +_,7 @@ +@@ -27,7 +_,9 @@ public static final int MAX_WIDTH = 21; private static final int MIN_HEIGHT = 3; public static final int MAX_HEIGHT = 21; -- private static final BlockBehaviour.StatePredicate FRAME = (state, level, pos) -> state.is(Blocks.OBSIDIAN); -+ private static final BlockBehaviour.StatePredicate FRAME = (state, level, pos) -> state.isPortalFrame(level, pos); ++ /** @deprecated Use location sensitive version with FRAME_TEST */ + public static final Predicate FRAME = state -> state.is(BlockTags.NETHER_PORTAL_FRAME); ++ public static final net.minecraft.world.level.block.state.BlockBehaviour.StatePredicate FRAME_TEST = (state, level, pos) -> state.isPortalFrame(level, pos); private static final float SAFE_TRAVEL_MAX_ENTITY_XY = 4.0F; private static final double SAFE_TRAVEL_MAX_VERTICAL_DELTA = 1.0; private final Direction.Axis axis; +@@ -105,14 +_,14 @@ + blockPos.set(pos).move(direction, width); + BlockState blockState = level.getBlockState(blockPos); + if (!isEmpty(blockState)) { +- if (FRAME.test(blockState)) { ++ if (FRAME_TEST.test(blockState, level, blockPos)) { + return width; + } + break; + } + + BlockState belowState = level.getBlockState(blockPos.move(Direction.DOWN)); +- if (!FRAME.test(belowState)) { ++ if (!FRAME_TEST.test(belowState, level, blockPos)) { + break; + } + } +@@ -133,7 +_,7 @@ + ) { + for (int i = 0; i < width; i++) { + BlockPos.MutableBlockPos framePos = pos.set(bottomLeft).move(Direction.UP, height).move(rightDir, i); +- if (!FRAME.test(level.getBlockState(framePos))) { ++ if (!FRAME_TEST.test(level.getBlockState(framePos), level, framePos)) { + return false; + } + } +@@ -151,12 +_,12 @@ + ) { + for (int height = 0; height < 21; height++) { + pos.set(bottomLeft).move(Direction.UP, height).move(rightDir, -1); +- if (!FRAME.test(level.getBlockState(pos))) { ++ if (!FRAME_TEST.test(level.getBlockState(pos), level, pos)) { + return height; + } + + pos.set(bottomLeft).move(Direction.UP, height).move(rightDir, width); +- if (!FRAME.test(level.getBlockState(pos))) { ++ if (!FRAME_TEST.test(level.getBlockState(pos), level, pos)) { + return height; + } + diff --git a/patches/minecraft/net/minecraft/world/level/storage/PrimaryLevelData.java.patch b/patches/minecraft/net/minecraft/world/level/storage/PrimaryLevelData.java.patch index c9d019189c..d02d1c8d32 100644 --- a/patches/minecraft/net/minecraft/world/level/storage/PrimaryLevelData.java.patch +++ b/patches/minecraft/net/minecraft/world/level/storage/PrimaryLevelData.java.patch @@ -1,23 +1,23 @@ --- a/net/minecraft/world/level/storage/PrimaryLevelData.java +++ b/net/minecraft/world/level/storage/PrimaryLevelData.java -@@ -42,6 +_,7 @@ - private final Set knownServerBrands; +@@ -45,6 +_,7 @@ private boolean wasModded; private final Set removedFeatureFlags; + private List versionHistory; + private boolean confirmedExperimentalWarning = false; private PrimaryLevelData( final @Nullable UUID singlePlayerUUID, -@@ -105,7 +_,7 @@ - settings, +@@ -112,7 +_,7 @@ specialWorldProperty, - worldGenSettingsLifecycle + worldGenSettingsLifecycle, + input.get("version_history").orElseEmptyList().asList(d -> d.asInt(-1)) - ); + ).withConfirmedWarning(worldGenSettingsLifecycle != Lifecycle.stable() && input.get("confirmedExperimentalSettings").asBoolean(false)); } @Override -@@ -142,6 +_,8 @@ +@@ -150,6 +_,8 @@ } tag.store(WorldDataConfiguration.MAP_CODEC, this.settings.dataConfiguration()); @@ -26,7 +26,7 @@ } public static void writeLastPlayed(final CompoundTag tag) { -@@ -327,6 +_,16 @@ +@@ -346,6 +_,16 @@ public LevelSettings getLevelSettings() { return this.settings.copy(); } diff --git a/patches/minecraft/net/minecraft/world/level/storage/loot/LootContext.java.patch b/patches/minecraft/net/minecraft/world/level/storage/loot/LootContext.java.patch index 7a75d879de..50c372313b 100644 --- a/patches/minecraft/net/minecraft/world/level/storage/loot/LootContext.java.patch +++ b/patches/minecraft/net/minecraft/world/level/storage/loot/LootContext.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/storage/loot/LootContext.java +++ b/net/minecraft/world/level/storage/loot/LootContext.java -@@ -25,11 +_,17 @@ +@@ -26,11 +_,17 @@ private final RandomSource random; private final HolderGetter.Provider lootDataResolver; private final Set> visitedElements = Sets.newLinkedHashSet(); @@ -18,7 +18,7 @@ } public boolean hasParameter(final ContextKey key) { -@@ -76,6 +_,10 @@ +@@ -73,6 +_,10 @@ return this.params.getLevel(); } @@ -29,12 +29,12 @@ public static LootContext.VisitedEntry createVisitedEntry(final LootTable table) { return new LootContext.VisitedEntry<>(LootDataType.TABLE, table); } -@@ -88,6 +_,18 @@ - return new LootContext.VisitedEntry<>(LootDataType.MODIFIER, table); +@@ -89,6 +_,18 @@ + return new LootContext.VisitedEntry<>(LootDataType.SLOT_SOURCE, slotSource); } + public int getLootingModifier() { -+ return net.minecraftforge.common.ForgeHooks.getLootingLevel(getOptionalParameter(LootContextParams.THIS_ENTITY), getOptionalParameter(LootContextParams.ATTACKING_ENTITY), getOptionalParameter(LootContextParams.DAMAGE_SOURCE)); ++ return net.minecraftforge.common.ForgeHooks.getLootingLevel(getOptional(LootContextParams.THIS_ENTITY), getOptional(LootContextParams.ATTACKING_ENTITY), getOptional(LootContextParams.DAMAGE_SOURCE)); + } + + public void setQueriedLootTableId(Identifier queriedLootTableId) { @@ -48,7 +48,7 @@ public enum BlockEntityTarget implements StringRepresentable, LootContextArg.SimpleGetter { BLOCK_ENTITY("block_entity", LootContextParams.BLOCK_ENTITY); -@@ -113,11 +_,18 @@ +@@ -114,11 +_,18 @@ public static class Builder { private final LootParams params; private @Nullable RandomSource random; @@ -67,7 +67,7 @@ public LootContext.Builder withOptionalRandomSeed(final long seed) { if (seed != 0L) { this.random = RandomSource.create(seed); -@@ -131,6 +_,11 @@ +@@ -132,6 +_,11 @@ return this; } @@ -79,7 +79,7 @@ public ServerLevel getLevel() { return this.params.getLevel(); } -@@ -139,7 +_,7 @@ +@@ -140,7 +_,7 @@ ServerLevel level = this.getLevel(); MinecraftServer server = level.getServer(); RandomSource random = Optional.ofNullable(this.random).or(() -> randomSequenceKey.map(server::getRandomSequence)).orElseGet(level::getRandom); diff --git a/patches/minecraft/net/minecraft/world/level/storage/loot/LootParams.java.patch b/patches/minecraft/net/minecraft/world/level/storage/loot/LootParams.java.patch index 0a2c7fd3e0..9428a2ed5d 100644 --- a/patches/minecraft/net/minecraft/world/level/storage/loot/LootParams.java.patch +++ b/patches/minecraft/net/minecraft/world/level/storage/loot/LootParams.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/storage/loot/LootParams.java +++ b/net/minecraft/world/level/storage/loot/LootParams.java -@@ -53,6 +_,15 @@ +@@ -54,6 +_,15 @@ this.level = level; } @@ -10,15 +10,15 @@ + this.withLuck(parent.getLuck()); + parent.dynamicDrops.forEach(this::withDynamicDrop); + for (var key : parent.params.keySet()) -+ this.withParameter((ContextKey)key, (Object)parent.contextMap().getOptional(key)); ++ this.withParameter((ContextKey)key, (Object)parent.contextMap().get(key)); + } + public ServerLevel getLevel() { return this.level; } -@@ -92,6 +_,10 @@ +@@ -98,6 +_,10 @@ public LootParams create(final ContextKeySet contextKeySet) { - ContextMap keySet = this.params.create(contextKeySet); + ContextMap keySet = this.params.buildAndValidate(contextKeySet); return new LootParams(this.level, keySet, this.dynamicDrops, this.luck); + } + diff --git a/patches/minecraft/net/minecraft/world/level/storage/loot/LootPool.java.patch b/patches/minecraft/net/minecraft/world/level/storage/loot/LootPool.java.patch index f0e1a9f4d9..9bffed5f81 100644 --- a/patches/minecraft/net/minecraft/world/level/storage/loot/LootPool.java.patch +++ b/patches/minecraft/net/minecraft/world/level/storage/loot/LootPool.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/storage/loot/LootPool.java +++ b/net/minecraft/world/level/storage/loot/LootPool.java -@@ -33,10 +_,13 @@ - LootItemCondition.DIRECT_CODEC.listOf().optionalFieldOf("conditions", List.of()).forGetter(p -> p.conditions), - LootItemFunctions.ROOT_CODEC.listOf().optionalFieldOf("functions", List.of()).forGetter(p -> p.functions), - NumberProviders.CODEC.fieldOf("rolls").forGetter(p -> p.rolls), -- NumberProviders.CODEC.optionalFieldOf("bonus_rolls", ConstantValue.exactly(0.0F)).forGetter(p -> p.bonusRolls) -+ NumberProviders.CODEC.optionalFieldOf("bonus_rolls", ConstantValue.exactly(0.0F)).forGetter(p -> p.bonusRolls), +@@ -33,15 +_,20 @@ + LootItemCondition.CODEC.optionalFieldOf("condition").forGetter(p -> p.condition), + LootItemFunctions.CODEC.optionalFieldOf("modifier").forGetter(p -> p.modifier), + ContextIntProviders.CODEC.fieldOf("rolls").forGetter(p -> p.rolls), +- ContextFloatProviders.CODEC.optionalFieldOf("bonus_rolls", ContextFloatProviders.exactly(0.0F)).forGetter(p -> p.bonusRolls) ++ ContextFloatProviders.CODEC.optionalFieldOf("bonus_rolls", ContextFloatProviders.exactly(0.0F)).forGetter(p -> p.bonusRolls), + Codec.STRING.optionalFieldOf("name").forGetter(p -> p.name.filter(n -> !n.startsWith("custom#"))), + net.minecraftforge.common.crafting.conditions.ICondition.OPTIONAL_FEILD_CODEC.forGetter(p -> p.forge_condition) ) @@ -13,38 +13,34 @@ ); + public static final Codec CONDITIONAL_CODEC = net.minecraftforge.common.crafting.conditions.ConditionCodec.checkingDecode(CODEC, () -> lootPool().build()); private final List entries; - private final List conditions; - private final Predicate compositeCondition; -@@ -44,6 +_,8 @@ - private final BiFunction compositeFunction; - private NumberProvider rolls; - private NumberProvider bonusRolls; + private final Optional> condition; + private final Optional> modifier; + private Holder rolls; + private Holder bonusRolls; + private java.util.Optional name; + private java.util.Optional forge_condition; private LootPool( final List entries, -@@ -52,6 +_,18 @@ - final NumberProvider rolls, - final NumberProvider bonusRolls +@@ -50,11 +_,25 @@ + final Holder rolls, + final Holder bonusRolls ) { -+ this(entries, conditions, functions, rolls, bonusRolls, java.util.Optional.empty(), java.util.Optional.empty()); ++ this(entries, condition, modifier, rolls, bonusRolls, java.util.Optional.empty(), java.util.Optional.empty()); + } + + private LootPool( + final List entries, -+ final List conditions, -+ final List functions, -+ final NumberProvider rolls, -+ final NumberProvider bonusRolls, ++ final Optional> condition, ++ final Optional> modifier, ++ final Holder rolls, ++ final Holder bonusRolls, + final java.util.Optional name, + final java.util.Optional forge_condition + ) { this.entries = entries; - this.conditions = conditions; - this.compositeCondition = Util.allOf(conditions); -@@ -59,6 +_,8 @@ - this.compositeFunction = LootItemFunctions.compose(functions); + this.condition = condition; + this.modifier = modifier; this.rolls = rolls; this.bonusRolls = bonusRolls; + this.name = name; @@ -52,7 +48,7 @@ } private void addRandomItem(final Consumer result, final LootContext context) { -@@ -118,12 +_,35 @@ +@@ -114,18 +_,51 @@ return new LootPool.Builder(); } @@ -70,25 +66,24 @@ + throw new UnsupportedOperationException("Cannot change the name of a pool when it has a name set!"); + this.name = java.util.Optional.of(name); + } -+ public NumberProvider getRolls() { return this.rolls; } -+ public NumberProvider getBonusRolls() { return this.bonusRolls; } -+ public void setRolls (NumberProvider v){ checkFrozen(); this.rolls = v; } -+ public void setBonusRolls(NumberProvider v){ checkFrozen(); this.bonusRolls = v; } ++ public Holder getRolls() { return this.rolls; } ++ public Holder getBonusRolls() { return this.bonusRolls; } ++ public void setRolls (Holder v){ checkFrozen(); this.rolls = v; } ++ public void setBonusRolls(Holder v){ checkFrozen(); this.bonusRolls = v; } + public static class Builder implements FunctionUserBuilder, ConditionUserBuilder { private final ImmutableList.Builder entries = ImmutableList.builder(); - private final ImmutableList.Builder conditions = ImmutableList.builder(); - private final ImmutableList.Builder functions = ImmutableList.builder(); - private NumberProvider rolls = ConstantValue.exactly(1.0F); - private NumberProvider bonusRolls = ConstantValue.exactly(0.0F); + private final ImmutableList.Builder> conditions = ImmutableList.builder(); + private final ImmutableList.Builder> functions = ImmutableList.builder(); + private Holder rolls = ContextIntProviders.exactly(1); + private Holder bonusRolls = ContextFloatProviders.exactly(0.0F); + @org.jetbrains.annotations.Nullable + private String name; + @org.jetbrains.annotations.Nullable + private net.minecraftforge.common.crafting.conditions.ICondition forge_condition; - public LootPool.Builder setRolls(final NumberProvider rolls) { + public LootPool.Builder setRolls(final Holder rolls) { this.rolls = rolls; -@@ -162,8 +_,18 @@ return this; } @@ -102,9 +97,17 @@ + return this; + } + - public LootPool build() { -- return new LootPool(this.entries.build(), this.conditions.build(), this.functions.build(), this.rolls, this.bonusRolls); -+ return new LootPool(this.entries.build(), this.conditions.build(), this.functions.build(), this.rolls, this.bonusRolls, java.util.Optional.ofNullable(this.name), java.util.Optional.ofNullable(forge_condition)); + public LootPool.Builder unwrap() { + return this; + } +@@ -164,7 +_,9 @@ + ConditionUserBuilder.buildCondition(this.conditions.build()), + FunctionUserBuilder.buildFunction(this.functions.build()), + this.rolls, +- this.bonusRolls ++ this.bonusRolls, ++ java.util.Optional.ofNullable(this.name), ++ java.util.Optional.ofNullable(forge_condition) + ); } } - } diff --git a/patches/minecraft/net/minecraft/world/level/storage/loot/LootTable.java.patch b/patches/minecraft/net/minecraft/world/level/storage/loot/LootTable.java.patch index 7f9008ce24..0246eefce6 100644 --- a/patches/minecraft/net/minecraft/world/level/storage/loot/LootTable.java.patch +++ b/patches/minecraft/net/minecraft/world/level/storage/loot/LootTable.java.patch @@ -6,7 +6,7 @@ Identifier.CODEC.optionalFieldOf("random_sequence").forGetter(t -> t.randomSequence), - LootPool.CODEC.listOf().optionalFieldOf("pools", List.of()).forGetter(t -> t.pools), + LootPool.CONDITIONAL_CODEC.listOf().optionalFieldOf("pools", List.of()).forGetter(t -> t.pools), - LootItemFunctions.ROOT_CODEC.listOf().optionalFieldOf("functions", List.of()).forGetter(t -> t.functions) + LootItemFunctions.CODEC.optionalFieldOf("modifier").forGetter(t -> t.modifier) ) .apply(i, LootTable::new) @@ -58,7 +_,7 @@ @@ -15,10 +15,10 @@ this.randomSequence = randomSequence; - this.pools = pools; + this.pools = Lists.newArrayList(pools); - this.functions = functions; - this.compositeFunction = LootItemFunctions.compose(functions); + this.modifier = modifier; } -@@ -81,10 +_,12 @@ + +@@ -80,10 +_,12 @@ }; } @@ -31,7 +31,7 @@ public void getRandomItemsRaw(final LootContext context, final Consumer output) { LootContext.VisitedEntry breadcrumb = LootContext.createVisitedEntry(this); if (context.pushVisitedElement(breadcrumb)) { -@@ -101,18 +_,19 @@ +@@ -100,18 +_,19 @@ } public void getRandomItems(final LootParams params, final long optionalLootTableSeed, final Consumer output) { @@ -55,7 +55,7 @@ } public ObjectArrayList getRandomItems(final LootParams params, final RandomSource randomSource) { -@@ -129,7 +_,8 @@ +@@ -128,7 +_,8 @@ private ObjectArrayList getRandomItems(final LootContext context) { ObjectArrayList result = new ObjectArrayList<>(); @@ -65,7 +65,7 @@ return result; } -@@ -214,6 +_,68 @@ +@@ -213,6 +_,68 @@ public static LootTable.Builder lootTable() { return new LootTable.Builder(); diff --git a/patches/minecraft/net/minecraft/world/level/storage/loot/functions/EnchantedCountIncreaseFunction.java.patch b/patches/minecraft/net/minecraft/world/level/storage/loot/functions/EnchantedCountIncreaseFunction.java.patch index 86b37b2817..3af10c785d 100644 --- a/patches/minecraft/net/minecraft/world/level/storage/loot/functions/EnchantedCountIncreaseFunction.java.patch +++ b/patches/minecraft/net/minecraft/world/level/storage/loot/functions/EnchantedCountIncreaseFunction.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/world/level/storage/loot/functions/EnchantedCountIncreaseFunction.java +++ b/net/minecraft/world/level/storage/loot/functions/EnchantedCountIncreaseFunction.java -@@ -72,8 +_,12 @@ +@@ -71,8 +_,12 @@ @Override public ItemStack run(final ItemStack itemStack, final LootContext context) { - Entity killer = context.getOptionalParameter(LootContextParams.ATTACKING_ENTITY); + Entity killer = context.getOptional(LootContextParams.ATTACKING_ENTITY); - if (killer instanceof LivingEntity entity) { - int level = EnchantmentHelper.getEnchantmentLevel(this.enchantment, entity); + int level = 0; @@ -15,7 +15,7 @@ if (level == 0) { return itemStack; } -@@ -83,7 +_,6 @@ +@@ -82,7 +_,6 @@ if (this.hasLimit()) { itemStack.limitSize(this.limit); } diff --git a/patches/minecraft/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java.patch b/patches/minecraft/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java.patch index 6613f8eca5..21e37637b1 100644 --- a/patches/minecraft/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java.patch +++ b/patches/minecraft/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java +++ b/net/minecraft/world/level/storage/loot/parameters/LootContextParamSets.java -@@ -19,7 +_,7 @@ - REGISTRY.inverse()::get - ); - public static final ContextKeySet EMPTY = register("empty", builder -> {}); +@@ -35,7 +_,7 @@ + .required(LootContextParams.ENCHANTMENT_ACTIVE) + .required(LootContextParams.ENCHANTMENT_LEVEL) + ); - public static final ContextKeySet CHEST = register("chest", builder -> builder.required(LootContextParams.ORIGIN).optional(LootContextParams.THIS_ENTITY)); + public static final ContextKeySet CHEST = register("chest", builder -> builder.required(LootContextParams.ORIGIN).optional(LootContextParams.THIS_ENTITY).optional(LootContextParams.ATTACKING_ENTITY)); //Forge: Chest Minecarts can have killers. public static final ContextKeySet COMMAND = register( "command", builder -> builder.required(LootContextParams.ORIGIN).optional(LootContextParams.THIS_ENTITY) ); -@@ -33,7 +_,7 @@ +@@ -67,7 +_,7 @@ .required(LootContextParams.ADDITIONAL_COST_COMPONENT_ALLOWED) ); public static final ContextKeySet FISHING = register( diff --git a/patches/minecraft/net/minecraft/world/level/storage/loot/predicates/LootItemRandomChanceWithEnchantedBonusCondition.java.patch b/patches/minecraft/net/minecraft/world/level/storage/loot/predicates/LootItemRandomChanceWithEnchantedBonusCondition.java.patch index c85a4d3836..af0010e344 100644 --- a/patches/minecraft/net/minecraft/world/level/storage/loot/predicates/LootItemRandomChanceWithEnchantedBonusCondition.java.patch +++ b/patches/minecraft/net/minecraft/world/level/storage/loot/predicates/LootItemRandomChanceWithEnchantedBonusCondition.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/world/level/storage/loot/predicates/LootItemRandomChanceWithEnchantedBonusCondition.java +++ b/net/minecraft/world/level/storage/loot/predicates/LootItemRandomChanceWithEnchantedBonusCondition.java -@@ -40,7 +_,11 @@ +@@ -39,7 +_,11 @@ public boolean test(final LootContext context) { - Entity killerEntity = context.getOptionalParameter(LootContextParams.ATTACKING_ENTITY); + Entity killerEntity = context.getOptional(LootContextParams.ATTACKING_ENTITY); - int enchantmentLevel = killerEntity instanceof LivingEntity livingKiller ? EnchantmentHelper.getEnchantmentLevel(this.enchantment, livingKiller) : 0; + int enchantmentLevel = 0; + if (this.enchantment.is(Enchantments.LOOTING)) diff --git a/server_files/args.txt b/server_files/args.txt index af830f6a54..2b14028410 100644 --- a/server_files/args.txt +++ b/server_files/args.txt @@ -1 +1 @@ --Djava.net.preferIPv6Addresses=system -XX:+UseCompactObjectHeaders -jar @SHIM_JAR_FILE@ +-Djava.net.preferIPv6Addresses=system -XX:+UseCompactObjectHeaders -XX:StackShadowPages=32 -jar @SHIM_JAR_FILE@ diff --git a/settings.gradle b/settings.gradle index 66b94fb4cd..a5e2fc62f8 100644 --- a/settings.gradle +++ b/settings.gradle @@ -88,7 +88,7 @@ dependencyResolutionManagement.versionCatalogs { library 'binarypatcher', 'net.minecraftforge', 'binarypatcher' version '1.3.4' library 'installer', 'net.minecraftforge', 'installer' version '2.2.+' - library 'installertools', 'net.minecraftforge', 'installertools' version '1.4.5' + library 'installertools', 'net.minecraftforge', 'installertools' version '1.4.6' library 'srg2source', 'net.minecraftforge', 'Srg2Source' version '8.2.0' } @@ -113,7 +113,7 @@ dependencyResolutionManagement.versionCatalogs { library 'unsafe', 'net.minecraftforge', 'unsafe' version '0.9.2' library 'accesstransformers', 'net.minecraftforge', 'accesstransformers' version '8.2.17' library 'coremods-api', 'net.minecraftforge', 'coremods-api' version '5.3.1' - version 'eventbus', '7.0.5' + version 'eventbus', '7.0.6' library 'eventbus', 'net.minecraftforge', 'eventbus' versionRef 'eventbus' library 'eventbus-validator', 'net.minecraftforge', 'eventbus-validator' versionRef 'eventbus' library 'mergetool-api', 'net.minecraftforge', 'mergetool-api' version '1.0' @@ -124,7 +124,7 @@ dependencyResolutionManagement.versionCatalogs { library 'mixinextras-forge', 'io.github.llamalad7', 'mixinextras-forge' versionRef 'mixinextras' library 'mixinextras-common', 'io.github.llamalad7', 'mixinextras-common' versionRef 'mixinextras' library 'jetbrains-annotations', 'org.jetbrains', 'annotations' version '24.0.1' // for ApiStatus annotations - library 'jspecify', 'org.jspecify', 'jspecify' version '1.0.0' // for nullability annotations + library 'jspecify', 'org.jspecify', 'jspecify' version '1.0.1' // for nullability annotations library 'slf4j-api', 'org.slf4j', 'slf4j-api' version '2.0.17' library 'maven-artifact', 'org.apache.maven', 'maven-artifact' version '3.8.8' @@ -184,13 +184,13 @@ dependencyResolutionManagement.versionCatalogs { library 'jopt-simple', 'net.sf.jopt-simple', 'jopt-simple' version '5.0.4' library 'commons-io', 'commons-io', 'commons-io' version '2.20.0' - version 'lwjgl', '3.4.1' + version 'lwjgl', '3.4.3' library 'lwjgl', 'org.lwjgl', 'lwjgl' versionRef 'lwjgl' - library 'lwjgl-glfw', 'org.lwjgl', 'lwjgl-glfw' versionRef 'lwjgl' library 'lwjgl-opengl', 'org.lwjgl', 'lwjgl-opengl' versionRef 'lwjgl' library 'lwjgl-stb', 'org.lwjgl', 'lwjgl-stb' versionRef 'lwjgl' + library 'lwjgl-sdl', 'org.lwjgl', 'lwjgl-sdl' versionRef 'lwjgl' library 'lwjgl-tinyfd', 'org.lwjgl', 'lwjgl-tinyfd' versionRef 'lwjgl' - bundle 'lwjgl', ['lwjgl', 'lwjgl-glfw', 'lwjgl-opengl', 'lwjgl-stb', 'lwjgl-tinyfd'] + bundle 'lwjgl', ['lwjgl', 'lwjgl-opengl', 'lwjgl-stb', 'lwjgl-sdl', 'lwjgl-tinyfd'] } register('earlyDisplayLibs') { @@ -203,10 +203,10 @@ dependencyResolutionManagement.versionCatalogs { library 'powermock-core', 'org.powermock', 'powermock-core' version '2.0.9' library 'lwjgl', 'org.lwjgl', 'lwjgl' withoutVersion() - library 'lwjgl-glfw', 'org.lwjgl', 'lwjgl-glfw' withoutVersion() library 'lwjgl-opengl', 'org.lwjgl', 'lwjgl-opengl' withoutVersion() library 'lwjgl-stb', 'org.lwjgl', 'lwjgl-stb' withoutVersion() - bundle 'lwjgl', ['lwjgl', 'lwjgl-glfw', 'lwjgl-opengl', 'lwjgl-stb'] + library 'lwjgl-sdl', 'org.lwjgl', 'lwjgl-sdl' withoutVersion() + bundle 'lwjgl', ['lwjgl', 'lwjgl-opengl', 'lwjgl-stb', 'lwjgl-sdl'] } //@formatter:on } diff --git a/src/main/generated/data/minecraft/loot_table/blocks/acacia_leaves.json b/src/main/generated/data/minecraft/loot_table/blocks/acacia_leaves.json deleted file mode 100644 index 76b0651a2d..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/acacia_leaves.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "name": "minecraft:acacia_leaves" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chances": [ - 0.05, - 0.0625, - 0.083333336, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "name": "minecraft:acacia_sapling" - } - ] - } - ], - "rolls": 1.0 - }, - { - "conditions": [ - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "chances": [ - 0.02, - 0.022222223, - 0.025, - 0.033333335, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "functions": [ - { - "count": { - "type": "minecraft:uniform", - "max": 2.0, - "min": 1.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:explosion_decay" - } - ], - "name": "minecraft:stick" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/acacia_leaves" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/azalea_leaves.json b/src/main/generated/data/minecraft/loot_table/blocks/azalea_leaves.json deleted file mode 100644 index e2688d9d93..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/azalea_leaves.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "name": "minecraft:azalea_leaves" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chances": [ - 0.05, - 0.0625, - 0.083333336, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "name": "minecraft:azalea" - } - ] - } - ], - "rolls": 1.0 - }, - { - "conditions": [ - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "chances": [ - 0.02, - 0.022222223, - 0.025, - 0.033333335, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "functions": [ - { - "count": { - "type": "minecraft:uniform", - "max": 2.0, - "min": 1.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:explosion_decay" - } - ], - "name": "minecraft:stick" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/azalea_leaves" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/birch_leaves.json b/src/main/generated/data/minecraft/loot_table/blocks/birch_leaves.json deleted file mode 100644 index d785dae910..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/birch_leaves.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "name": "minecraft:birch_leaves" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chances": [ - 0.05, - 0.0625, - 0.083333336, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "name": "minecraft:birch_sapling" - } - ] - } - ], - "rolls": 1.0 - }, - { - "conditions": [ - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "chances": [ - 0.02, - 0.022222223, - 0.025, - 0.033333335, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "functions": [ - { - "count": { - "type": "minecraft:uniform", - "max": 2.0, - "min": 1.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:explosion_decay" - } - ], - "name": "minecraft:stick" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/birch_leaves" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/bush.json b/src/main/generated/data/minecraft/loot_table/blocks/bush.json deleted file mode 100644 index ec187ebbd4..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/bush.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:bush" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/bush" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/cherry_leaves.json b/src/main/generated/data/minecraft/loot_table/blocks/cherry_leaves.json deleted file mode 100644 index 2b06aae023..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/cherry_leaves.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "name": "minecraft:cherry_leaves" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chances": [ - 0.05, - 0.0625, - 0.083333336, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "name": "minecraft:cherry_sapling" - } - ] - } - ], - "rolls": 1.0 - }, - { - "conditions": [ - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "chances": [ - 0.02, - 0.022222223, - 0.025, - 0.033333335, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "functions": [ - { - "count": { - "type": "minecraft:uniform", - "max": 2.0, - "min": 1.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:explosion_decay" - } - ], - "name": "minecraft:stick" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/cherry_leaves" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/cobweb.json b/src/main/generated/data/minecraft/loot_table/blocks/cobweb.json deleted file mode 100644 index dccc612281..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/cobweb.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "name": "minecraft:cobweb" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ], - "name": "minecraft:string" - } - ] - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/cobweb" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/dark_oak_leaves.json b/src/main/generated/data/minecraft/loot_table/blocks/dark_oak_leaves.json deleted file mode 100644 index 835b4f54ba..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/dark_oak_leaves.json +++ /dev/null @@ -1,183 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "name": "minecraft:dark_oak_leaves" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chances": [ - 0.05, - 0.0625, - 0.083333336, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "name": "minecraft:dark_oak_sapling" - } - ] - } - ], - "rolls": 1.0 - }, - { - "conditions": [ - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "chances": [ - 0.02, - 0.022222223, - 0.025, - 0.033333335, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "functions": [ - { - "count": { - "type": "minecraft:uniform", - "max": 2.0, - "min": 1.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:explosion_decay" - } - ], - "name": "minecraft:stick" - } - ], - "rolls": 1.0 - }, - { - "conditions": [ - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chances": [ - 0.005, - 0.0055555557, - 0.00625, - 0.008333334, - 0.025 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "name": "minecraft:apple" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/dark_oak_leaves" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/dead_bush.json b/src/main/generated/data/minecraft/loot_table/blocks/dead_bush.json deleted file mode 100644 index fa44726bc4..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/dead_bush.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - } - ], - "name": "minecraft:dead_bush" - }, - { - "type": "minecraft:item", - "functions": [ - { - "count": { - "type": "minecraft:uniform", - "max": 2.0, - "min": 0.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:explosion_decay" - } - ], - "name": "minecraft:stick" - } - ] - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/dead_bush" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/fern.json b/src/main/generated/data/minecraft/loot_table/blocks/fern.json deleted file mode 100644 index de279d9d4e..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/fern.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - } - ], - "name": "minecraft:fern" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "chance": 0.125, - "condition": "minecraft:random_chance" - } - ], - "functions": [ - { - "enchantment": "minecraft:fortune", - "formula": "minecraft:uniform_bonus_count", - "function": "minecraft:apply_bonus", - "parameters": { - "bonusMultiplier": 2 - } - }, - { - "function": "minecraft:explosion_decay" - } - ], - "name": "minecraft:wheat_seeds" - } - ] - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/fern" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/flowering_azalea_leaves.json b/src/main/generated/data/minecraft/loot_table/blocks/flowering_azalea_leaves.json deleted file mode 100644 index d284eafbc5..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/flowering_azalea_leaves.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "name": "minecraft:flowering_azalea_leaves" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chances": [ - 0.05, - 0.0625, - 0.083333336, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "name": "minecraft:flowering_azalea" - } - ] - } - ], - "rolls": 1.0 - }, - { - "conditions": [ - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "chances": [ - 0.02, - 0.022222223, - 0.025, - 0.033333335, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "functions": [ - { - "count": { - "type": "minecraft:uniform", - "max": 2.0, - "min": 1.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:explosion_decay" - } - ], - "name": "minecraft:stick" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/flowering_azalea_leaves" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/glow_lichen.json b/src/main/generated/data/minecraft/loot_table/blocks/glow_lichen.json deleted file mode 100644 index 56563b3457..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/glow_lichen.json +++ /dev/null @@ -1,115 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - } - ], - "functions": [ - { - "add": true, - "conditions": [ - { - "block": "minecraft:glow_lichen", - "condition": "minecraft:block_state_property", - "properties": { - "down": "true" - } - } - ], - "count": 1.0, - "function": "minecraft:set_count" - }, - { - "add": true, - "conditions": [ - { - "block": "minecraft:glow_lichen", - "condition": "minecraft:block_state_property", - "properties": { - "up": "true" - } - } - ], - "count": 1.0, - "function": "minecraft:set_count" - }, - { - "add": true, - "conditions": [ - { - "block": "minecraft:glow_lichen", - "condition": "minecraft:block_state_property", - "properties": { - "north": "true" - } - } - ], - "count": 1.0, - "function": "minecraft:set_count" - }, - { - "add": true, - "conditions": [ - { - "block": "minecraft:glow_lichen", - "condition": "minecraft:block_state_property", - "properties": { - "south": "true" - } - } - ], - "count": 1.0, - "function": "minecraft:set_count" - }, - { - "add": true, - "conditions": [ - { - "block": "minecraft:glow_lichen", - "condition": "minecraft:block_state_property", - "properties": { - "west": "true" - } - } - ], - "count": 1.0, - "function": "minecraft:set_count" - }, - { - "add": true, - "conditions": [ - { - "block": "minecraft:glow_lichen", - "condition": "minecraft:block_state_property", - "properties": { - "east": "true" - } - } - ], - "count": 1.0, - "function": "minecraft:set_count" - }, - { - "add": true, - "count": -1.0, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:explosion_decay" - } - ], - "name": "minecraft:glow_lichen" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/glow_lichen" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/hanging_roots.json b/src/main/generated/data/minecraft/loot_table/blocks/hanging_roots.json deleted file mode 100644 index da9a870588..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/hanging_roots.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "conditions": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:hanging_roots" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/hanging_roots" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/jungle_leaves.json b/src/main/generated/data/minecraft/loot_table/blocks/jungle_leaves.json deleted file mode 100644 index 2901f7814f..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/jungle_leaves.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "name": "minecraft:jungle_leaves" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chances": [ - 0.025, - 0.027777778, - 0.03125, - 0.041666668, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "name": "minecraft:jungle_sapling" - } - ] - } - ], - "rolls": 1.0 - }, - { - "conditions": [ - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "chances": [ - 0.02, - 0.022222223, - 0.025, - 0.033333335, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "functions": [ - { - "count": { - "type": "minecraft:uniform", - "max": 2.0, - "min": 1.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:explosion_decay" - } - ], - "name": "minecraft:stick" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/jungle_leaves" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/large_fern.json b/src/main/generated/data/minecraft/loot_table/blocks/large_fern.json deleted file mode 100644 index 4dbcfcfd5f..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/large_fern.json +++ /dev/null @@ -1,126 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "conditions": [ - { - "block": "minecraft:large_fern", - "condition": "minecraft:block_state_property", - "properties": { - "half": "lower" - } - }, - { - "condition": "minecraft:location_check", - "offsetY": 1, - "predicate": { - "block": { - "blocks": "minecraft:large_fern", - "state": { - "half": "upper" - } - } - } - } - ], - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - } - ], - "functions": [ - { - "count": 2.0, - "function": "minecraft:set_count" - } - ], - "name": "minecraft:fern" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chance": 0.125, - "condition": "minecraft:random_chance" - } - ], - "name": "minecraft:wheat_seeds" - } - ] - } - ], - "rolls": 1.0 - }, - { - "conditions": [ - { - "block": "minecraft:large_fern", - "condition": "minecraft:block_state_property", - "properties": { - "half": "upper" - } - }, - { - "condition": "minecraft:location_check", - "offsetY": -1, - "predicate": { - "block": { - "blocks": "minecraft:large_fern", - "state": { - "half": "lower" - } - } - } - } - ], - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - } - ], - "functions": [ - { - "count": 2.0, - "function": "minecraft:set_count" - } - ], - "name": "minecraft:fern" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chance": 0.125, - "condition": "minecraft:random_chance" - } - ], - "name": "minecraft:wheat_seeds" - } - ] - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/large_fern" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/mangrove_leaves.json b/src/main/generated/data/minecraft/loot_table/blocks/mangrove_leaves.json deleted file mode 100644 index ab53c93864..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/mangrove_leaves.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "name": "minecraft:mangrove_leaves" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "chances": [ - 0.02, - 0.022222223, - 0.025, - 0.033333335, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "functions": [ - { - "count": { - "type": "minecraft:uniform", - "max": 2.0, - "min": 1.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:explosion_decay" - } - ], - "name": "minecraft:stick" - } - ] - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/mangrove_leaves" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/nether_sprouts.json b/src/main/generated/data/minecraft/loot_table/blocks/nether_sprouts.json deleted file mode 100644 index 67258724b2..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/nether_sprouts.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "conditions": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:nether_sprouts" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/nether_sprouts" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/oak_leaves.json b/src/main/generated/data/minecraft/loot_table/blocks/oak_leaves.json deleted file mode 100644 index 69933a1855..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/oak_leaves.json +++ /dev/null @@ -1,183 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "name": "minecraft:oak_leaves" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chances": [ - 0.05, - 0.0625, - 0.083333336, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "name": "minecraft:oak_sapling" - } - ] - } - ], - "rolls": 1.0 - }, - { - "conditions": [ - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "chances": [ - 0.02, - 0.022222223, - 0.025, - 0.033333335, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "functions": [ - { - "count": { - "type": "minecraft:uniform", - "max": 2.0, - "min": 1.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:explosion_decay" - } - ], - "name": "minecraft:stick" - } - ], - "rolls": 1.0 - }, - { - "conditions": [ - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chances": [ - 0.005, - 0.0055555557, - 0.00625, - 0.008333334, - 0.025 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "name": "minecraft:apple" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/oak_leaves" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/pale_hanging_moss.json b/src/main/generated/data/minecraft/loot_table/blocks/pale_hanging_moss.json deleted file mode 100644 index ddaef52c33..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/pale_hanging_moss.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:pale_hanging_moss" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/pale_hanging_moss" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/pale_oak_leaves.json b/src/main/generated/data/minecraft/loot_table/blocks/pale_oak_leaves.json deleted file mode 100644 index 7e9ae46ff0..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/pale_oak_leaves.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "name": "minecraft:pale_oak_leaves" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chances": [ - 0.05, - 0.0625, - 0.083333336, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "name": "minecraft:pale_oak_sapling" - } - ] - } - ], - "rolls": 1.0 - }, - { - "conditions": [ - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "chances": [ - 0.02, - 0.022222223, - 0.025, - 0.033333335, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "functions": [ - { - "count": { - "type": "minecraft:uniform", - "max": 2.0, - "min": 1.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:explosion_decay" - } - ], - "name": "minecraft:stick" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/pale_oak_leaves" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/seagrass.json b/src/main/generated/data/minecraft/loot_table/blocks/seagrass.json deleted file mode 100644 index c806404eaa..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/seagrass.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "conditions": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:seagrass" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/seagrass" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/short_dry_grass.json b/src/main/generated/data/minecraft/loot_table/blocks/short_dry_grass.json deleted file mode 100644 index 073531704f..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/short_dry_grass.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:short_dry_grass" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/short_dry_grass" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/short_grass.json b/src/main/generated/data/minecraft/loot_table/blocks/short_grass.json deleted file mode 100644 index 6c1b1492fb..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/short_grass.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - } - ], - "name": "minecraft:short_grass" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "chance": 0.125, - "condition": "minecraft:random_chance" - } - ], - "functions": [ - { - "enchantment": "minecraft:fortune", - "formula": "minecraft:uniform_bonus_count", - "function": "minecraft:apply_bonus", - "parameters": { - "bonusMultiplier": 2 - } - }, - { - "function": "minecraft:explosion_decay" - } - ], - "name": "minecraft:wheat_seeds" - } - ] - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/short_grass" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/small_dripleaf.json b/src/main/generated/data/minecraft/loot_table/blocks/small_dripleaf.json deleted file mode 100644 index c7aa5e9724..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/small_dripleaf.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "conditions": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:small_dripleaf" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/small_dripleaf" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/spruce_leaves.json b/src/main/generated/data/minecraft/loot_table/blocks/spruce_leaves.json deleted file mode 100644 index 40d83f352e..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/spruce_leaves.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "name": "minecraft:spruce_leaves" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chances": [ - 0.05, - 0.0625, - 0.083333336, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "name": "minecraft:spruce_sapling" - } - ] - } - ], - "rolls": 1.0 - }, - { - "conditions": [ - { - "condition": "minecraft:inverted", - "term": { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - } - ], - "entries": [ - { - "type": "minecraft:item", - "conditions": [ - { - "chances": [ - 0.02, - 0.022222223, - 0.025, - 0.033333335, - 0.1 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "functions": [ - { - "count": { - "type": "minecraft:uniform", - "max": 2.0, - "min": 1.0 - }, - "function": "minecraft:set_count" - }, - { - "function": "minecraft:explosion_decay" - } - ], - "name": "minecraft:stick" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/spruce_leaves" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/tall_dry_grass.json b/src/main/generated/data/minecraft/loot_table/blocks/tall_dry_grass.json deleted file mode 100644 index cfc332693c..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/tall_dry_grass.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:tall_dry_grass" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/tall_dry_grass" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/tall_grass.json b/src/main/generated/data/minecraft/loot_table/blocks/tall_grass.json deleted file mode 100644 index d0c7d31e68..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/tall_grass.json +++ /dev/null @@ -1,126 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "conditions": [ - { - "block": "minecraft:tall_grass", - "condition": "minecraft:block_state_property", - "properties": { - "half": "lower" - } - }, - { - "condition": "minecraft:location_check", - "offsetY": 1, - "predicate": { - "block": { - "blocks": "minecraft:tall_grass", - "state": { - "half": "upper" - } - } - } - } - ], - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - } - ], - "functions": [ - { - "count": 2.0, - "function": "minecraft:set_count" - } - ], - "name": "minecraft:short_grass" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chance": 0.125, - "condition": "minecraft:random_chance" - } - ], - "name": "minecraft:wheat_seeds" - } - ] - } - ], - "rolls": 1.0 - }, - { - "conditions": [ - { - "block": "minecraft:tall_grass", - "condition": "minecraft:block_state_property", - "properties": { - "half": "upper" - } - }, - { - "condition": "minecraft:location_check", - "offsetY": -1, - "predicate": { - "block": { - "blocks": "minecraft:tall_grass", - "state": { - "half": "lower" - } - } - } - } - ], - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - } - ], - "functions": [ - { - "count": 2.0, - "function": "minecraft:set_count" - } - ], - "name": "minecraft:short_grass" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:survives_explosion" - }, - { - "chance": 0.125, - "condition": "minecraft:random_chance" - } - ], - "name": "minecraft:wheat_seeds" - } - ] - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/tall_grass" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/tall_seagrass.json b/src/main/generated/data/minecraft/loot_table/blocks/tall_seagrass.json deleted file mode 100644 index 452880c35b..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/tall_seagrass.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "conditions": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - } - ], - "entries": [ - { - "type": "minecraft:item", - "functions": [ - { - "count": 2.0, - "function": "minecraft:set_count" - } - ], - "name": "minecraft:seagrass" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/tall_seagrass" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/twisting_vines.json b/src/main/generated/data/minecraft/loot_table/blocks/twisting_vines.json deleted file mode 100644 index 543c463516..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/twisting_vines.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "name": "minecraft:twisting_vines" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "chances": [ - 0.33, - 0.55, - 0.77, - 1.0 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "name": "minecraft:twisting_vines" - } - ] - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/twisting_vines" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/vine.json b/src/main/generated/data/minecraft/loot_table/blocks/vine.json deleted file mode 100644 index 5fc89d2081..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/vine.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "conditions": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - } - ], - "entries": [ - { - "type": "minecraft:item", - "name": "minecraft:vine" - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/vine" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/loot_table/blocks/weeping_vines.json b/src/main/generated/data/minecraft/loot_table/blocks/weeping_vines.json deleted file mode 100644 index ab00aeccc5..0000000000 --- a/src/main/generated/data/minecraft/loot_table/blocks/weeping_vines.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "type": "minecraft:block", - "pools": [ - { - "entries": [ - { - "type": "minecraft:alternatives", - "children": [ - { - "type": "minecraft:item", - "conditions": [ - { - "condition": "minecraft:any_of", - "terms": [ - { - "action": "shears_dig", - "condition": "forge:can_tool_perform_action" - }, - { - "condition": "minecraft:match_tool", - "predicate": { - "predicates": { - "minecraft:enchantments": [ - { - "enchantments": "minecraft:silk_touch", - "levels": { - "min": 1 - } - } - ] - } - } - } - ] - } - ], - "name": "minecraft:weeping_vines" - }, - { - "type": "minecraft:item", - "conditions": [ - { - "chances": [ - 0.33, - 0.55, - 0.77, - 1.0 - ], - "condition": "minecraft:table_bonus", - "enchantment": "minecraft:fortune" - } - ], - "name": "minecraft:weeping_vines" - } - ] - } - ], - "rolls": 1.0 - } - ], - "random_sequence": "minecraft:blocks/weeping_vines" -} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/predicate/tool/can_shear.json b/src/main/generated/data/minecraft/predicate/tool/can_shear.json new file mode 100644 index 0000000000..9cd5dbdcaa --- /dev/null +++ b/src/main/generated/data/minecraft/predicate/tool/can_shear.json @@ -0,0 +1,4 @@ +{ + "type": "forge:can_tool_perform_action", + "action": "shears_dig" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/poplar_chest_boat.json b/src/main/generated/data/minecraft/recipe/poplar_chest_boat.json new file mode 100644 index 0000000000..3eea9c8da2 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/poplar_chest_boat.json @@ -0,0 +1,11 @@ +{ + "type": "minecraft:crafting_shapeless", + "group": "chest_boat", + "ingredients": [ + "#c:chests/wooden", + "minecraft:poplar_boat" + ], + "result": { + "id": "minecraft:poplar_chest_boat" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/poplar_fence.json b/src/main/generated/data/minecraft/recipe/poplar_fence.json new file mode 100644 index 0000000000..2a91136e89 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/poplar_fence.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "group": "wooden_fence", + "key": { + "#": "#c:rods/wooden", + "W": "minecraft:poplar_planks" + }, + "pattern": [ + "W#W", + "W#W" + ], + "result": { + "count": 3, + "id": "minecraft:poplar_fence" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/poplar_fence_gate.json b/src/main/generated/data/minecraft/recipe/poplar_fence_gate.json new file mode 100644 index 0000000000..fd7124ba34 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/poplar_fence_gate.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "group": "wooden_fence_gate", + "key": { + "#": "#c:rods/wooden", + "W": "minecraft:poplar_planks" + }, + "pattern": [ + "#W#", + "#W#" + ], + "result": { + "id": "minecraft:poplar_fence_gate" + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/poplar_sign.json b/src/main/generated/data/minecraft/recipe/poplar_sign.json new file mode 100644 index 0000000000..a48bf2ef5f --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/poplar_sign.json @@ -0,0 +1,17 @@ +{ + "type": "minecraft:crafting_shaped", + "group": "wooden_sign", + "key": { + "#": "minecraft:poplar_planks", + "X": "#c:rods/wooden" + }, + "pattern": [ + "###", + "###", + " X " + ], + "result": { + "count": 3, + "id": "minecraft:poplar_sign" + } +} \ No newline at end of file diff --git a/src/main/generated/pack.mcmeta b/src/main/generated/pack.mcmeta index ed943be2fb..b6853d8c9f 100644 --- a/src/main/generated/pack.mcmeta +++ b/src/main/generated/pack.mcmeta @@ -3,10 +3,7 @@ "description": { "translate": "pack.forge.description" }, - "max_format": 107, - "min_format": [ - 107, - 1 - ] + "max_format": 121, + "min_format": 121 } } \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/client/ClientCommandHandler.java b/src/main/java/net/minecraftforge/client/ClientCommandHandler.java index 0c606ea277..85b168d592 100644 --- a/src/main/java/net/minecraftforge/client/ClientCommandHandler.java +++ b/src/main/java/net/minecraftforge/client/ClientCommandHandler.java @@ -128,8 +128,6 @@ public class ClientCommandHandler { player.position(), player.getRotationVector(), player.permissions(), - player.getName().getString(), - player.getDisplayName(), player ); } diff --git a/src/main/java/net/minecraftforge/client/ClientCommandSourceStack.java b/src/main/java/net/minecraftforge/client/ClientCommandSourceStack.java index 3affac5f77..c1d73161fc 100644 --- a/src/main/java/net/minecraftforge/client/ClientCommandSourceStack.java +++ b/src/main/java/net/minecraftforge/client/ClientCommandSourceStack.java @@ -31,8 +31,8 @@ import java.util.stream.Collectors; * overrides for {@link CommandSourceStack} so that the methods will run successfully client side */ public class ClientCommandSourceStack extends CommandSourceStack { - public ClientCommandSourceStack(CommandSource source, Vec3 position, Vec2 rotation, PermissionSet permission, String plainTextName, Component displayName, Entity executing) { - super(source, position, rotation, null, permission, plainTextName, displayName, null, executing); + public ClientCommandSourceStack(CommandSource source, Vec3 position, Vec2 rotation, PermissionSet permission, Entity executing) { + super(source, position, rotation, null, permission, null, executing); } /** diff --git a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java index ac6ecec55c..f3a678e5c2 100644 --- a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java +++ b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java @@ -51,6 +51,7 @@ import net.minecraft.client.renderer.extract.LevelExtractor; import net.minecraft.client.renderer.fog.FogData; import net.minecraft.client.renderer.state.gui.pip.PictureInPictureRenderState; import net.minecraft.client.renderer.state.level.LevelRenderState; +import net.minecraft.client.renderer.state.level.PlayerRenderState; import net.minecraft.client.renderer.texture.SpriteContents; import net.minecraft.client.renderer.texture.TextureAtlas; import net.minecraft.client.renderer.texture.TextureAtlasSprite; @@ -111,6 +112,9 @@ import net.minecraftforge.client.event.RegisterColorHandlersEvent; import net.minecraftforge.client.event.RegisterKeyMappingsEvent; import net.minecraftforge.client.event.RegisterParticleProvidersEvent; import net.minecraftforge.client.event.RenderBlockScreenEffectEvent; +import net.minecraftforge.client.event.RenderBlockScreenEffectEvent.BlockOverlayEvent; +import net.minecraftforge.client.event.RenderBlockScreenEffectEvent.FireOverlayEvent; +import net.minecraftforge.client.event.RenderBlockScreenEffectEvent.WaterOverlayEvent; import net.minecraftforge.client.event.RenderHandEvent; import net.minecraftforge.client.event.RenderHighlightEvent; import net.minecraftforge.client.event.RenderTooltipEvent; @@ -128,6 +132,7 @@ import net.minecraftforge.client.textures.ForgeTextureMetadata; import net.minecraftforge.client.textures.TextureAtlasSpriteLoaderManager; import net.minecraftforge.common.ForgeI18n; import net.minecraftforge.common.ForgeMod; +import net.minecraftforge.eventbus.api.bus.CancellableEventBus; import net.minecraftforge.fml.IExtensionPoint; import net.minecraftforge.fml.ModList; import net.minecraftforge.network.NetworkContext; @@ -163,7 +168,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; @ApiStatus.Internal -public class ForgeHooksClient { +public final class ForgeHooksClient { private static final Logger LOGGER = LogManager.getLogger(); private static final Marker CLIENTHOOKS = MarkerManager.getMarker("CLIENTHOOKS"); @@ -646,16 +651,19 @@ public class ForgeHooksClient { return font.split(text, maxWidth).stream().map(ClientTooltipComponent::create); } - public static boolean renderFireOverlay(Player player, PoseStack mat) { - return renderBlockOverlay(player, mat, RenderBlockScreenEffectEvent.OverlayType.FIRE, Blocks.FIRE.defaultBlockState(), player.blockPosition()); + public static @Nullable IRenderCallback renderFireOverlay(Player player) { + var event = new FireOverlayEvent(player, Blocks.FIRE.defaultBlockState(), player.blockPosition()); + return FireOverlayEvent.BUS.post(event) ? event.getCustomRenderer() : null; } - public static boolean renderWaterOverlay(Player player, PoseStack mat) { - return renderBlockOverlay(player, mat, RenderBlockScreenEffectEvent.OverlayType.WATER, Blocks.WATER.defaultBlockState(), player.blockPosition()); + public static @Nullable IRenderCallback renderWaterOverlay(Player player, PlayerRenderState state) { + var event = new WaterOverlayEvent(player, Blocks.WATER.defaultBlockState(), player.blockPosition(), state); + return WaterOverlayEvent.BUS.post(event) ? event.getCustomRenderer() : null; } - public static boolean renderBlockOverlay(Player player, PoseStack mat, RenderBlockScreenEffectEvent.OverlayType type, BlockState block, BlockPos pos) { - return RenderBlockScreenEffectEvent.BUS.post(new RenderBlockScreenEffectEvent(player, mat, type, block, pos)); + public static @Nullable IRenderCallback renderBlockOverlay(Player player, BlockState state, BlockPos pos) { + var event = new BlockOverlayEvent(player, state, pos); + return BlockOverlayEvent.BUS.post(event) ? event.getCustomRenderer() : null; } public static int getMaxMipmapLevel(int width, int height) { diff --git a/src/main/java/net/minecraftforge/client/ForgeRenderTypes.java b/src/main/java/net/minecraftforge/client/ForgeRenderTypes.java index 159035b79d..8ecdbfa486 100644 --- a/src/main/java/net/minecraftforge/client/ForgeRenderTypes.java +++ b/src/main/java/net/minecraftforge/client/ForgeRenderTypes.java @@ -5,15 +5,15 @@ package net.minecraftforge.client; -import com.mojang.blaze3d.GpuFormat; -import com.mojang.blaze3d.pipeline.BlendFunction; -import com.mojang.blaze3d.pipeline.ColorTargetState; -import com.mojang.blaze3d.pipeline.RenderPipeline; -import com.mojang.blaze3d.platform.BlendFactor; import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.textures.AddressMode; -import com.mojang.blaze3d.textures.FilterMode; -import com.mojang.blaze3d.textures.GpuSampler; +import com.mojang.renderpearl.api.GpuFormat; +import com.mojang.renderpearl.api.pipeline.BlendFactor; +import com.mojang.renderpearl.api.pipeline.BlendFunction; +import com.mojang.renderpearl.api.pipeline.ColorTargetState; +import com.mojang.renderpearl.api.pipeline.RenderPipeline; +import com.mojang.renderpearl.api.textures.AddressMode; +import com.mojang.renderpearl.api.textures.FilterMode; +import com.mojang.renderpearl.api.textures.GpuSampler; import net.minecraft.util.Util; import net.minecraft.client.renderer.RenderPipelines; diff --git a/src/main/java/net/minecraftforge/client/FramePassManager.java b/src/main/java/net/minecraftforge/client/FramePassManager.java index 2029d2cc16..9c71151e25 100644 --- a/src/main/java/net/minecraftforge/client/FramePassManager.java +++ b/src/main/java/net/minecraftforge/client/FramePassManager.java @@ -7,13 +7,11 @@ package net.minecraftforge.client; import com.mojang.blaze3d.framegraph.FrameGraphBuilder; import com.mojang.blaze3d.framegraph.FramePass; -import net.minecraft.client.DeltaTracker; import net.minecraft.client.renderer.LevelTargetBundle; import net.minecraft.client.renderer.state.level.LevelRenderState; import net.minecraft.resources.Identifier; import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; -import org.jspecify.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -31,11 +29,11 @@ public class FramePassManager { // Note: Pass order is determined automatically within FrameGraphBuilder. It's unclear what must be done to guarantee ordering. @ApiStatus.Internal - public static void insertForgePasses(FrameGraphBuilder graphBuilder, LevelTargetBundle bundle, LevelRenderState state, DeltaTracker deltaTracker) { + public static void insertForgePasses(FrameGraphBuilder graphBuilder, LevelTargetBundle bundle, LevelRenderState state) { for (PassInfo info : addedPasses) { FramePass pass = graphBuilder.addPass(info.name); PassDefinition forgePass = info.pass; - forgePass.extracts(bundle, pass, deltaTracker); + forgePass.extracts(bundle, pass, state); pass.executes(() -> forgePass.executes(state)); } } @@ -71,7 +69,7 @@ public class FramePassManager { /// if you want to take a crack at it. /// /// Satisfying #2 is simple. Any state information you need to extract - /// should be done during {@linkplain PassDefinition#extracts(LevelTargetBundle, FramePass, DeltaTracker)}. + /// should be done during {@linkplain PassDefinition#extracts(LevelTargetBundle, FramePass, LevelRenderState)}. /// No actual rendering should be done at this time. This can happen before or after binding to a target. /// The specific implementation of your render state is up to you, it can even be done with some instance variables. /// @@ -79,23 +77,13 @@ public class FramePassManager { /// during the extracts phase. @NullMarked public interface PassDefinition { - - /** - * @deprecated Prefer {@linkplain PassDefinition#extracts(LevelTargetBundle, FramePass, DeltaTracker)} - */ - @Deprecated(forRemoval = true, since="26.2") - default void extracts(LevelTargetBundle bundle, FramePass pass) {}; - /** * This method exists to do render state extraction. Your instance of a PassDefinition should have * locals or some filled record instance that represents the render state created. * The resulting render state should be consumed by {@linkplain PassDefinition#executes(LevelRenderState)} * You must also use this to define which targets your pass will bind against. See PassDefinition javadocs for details. */ - - default void extracts(LevelTargetBundle bundle, FramePass pass, DeltaTracker deltaTracker) { - extracts(bundle, pass); - }; + void extracts(LevelTargetBundle bundle, FramePass pass, LevelRenderState deltaTracker); /** * Use to define what your pass does during the render stage. This should consume the render state created diff --git a/src/main/java/net/minecraftforge/client/IRenderCallback.java b/src/main/java/net/minecraftforge/client/IRenderCallback.java new file mode 100644 index 0000000000..4c4cef0a54 --- /dev/null +++ b/src/main/java/net/minecraftforge/client/IRenderCallback.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.minecraftforge.client; + +import com.mojang.blaze3d.vertex.PoseStack; + +import net.minecraft.client.renderer.SubmitNodeCollector; + +/** + * Simple callback for the 'submit' stage of the renderer. + * Used for fluid/fire overlays + */ +@FunctionalInterface +public interface IRenderCallback { + void render(PoseStack pose, SubmitNodeCollector collector); +} diff --git a/src/main/java/net/minecraftforge/client/event/AddFramePassEvent.java b/src/main/java/net/minecraftforge/client/event/AddFramePassEvent.java index c8e9ad9a94..4dc79d955d 100644 --- a/src/main/java/net/minecraftforge/client/event/AddFramePassEvent.java +++ b/src/main/java/net/minecraftforge/client/event/AddFramePassEvent.java @@ -15,8 +15,7 @@ import org.jspecify.annotations.NullMarked; /** * Fired during the construction of {@linkplain net.minecraft.client.renderer.LevelRenderer}. * - *

This event is fired on the {@linkplain net.minecraftforge.common.MinecraftForge#EVENT_BUS main Forge event bus}, - * only on the {@linkplain net.minecraftforge.fml.LogicalSide#CLIENT logical client}. + *

This event is fired only on the {@linkplain net.minecraftforge.fml.LogicalSide#CLIENT logical client}. */ @NullMarked public record AddFramePassEvent() implements RecordEvent { diff --git a/src/main/java/net/minecraftforge/client/event/ClientChatEvent.java b/src/main/java/net/minecraftforge/client/event/ClientChatEvent.java index a1d7f911c2..2c4baa3b41 100644 --- a/src/main/java/net/minecraftforge/client/event/ClientChatEvent.java +++ b/src/main/java/net/minecraftforge/client/event/ClientChatEvent.java @@ -21,8 +21,7 @@ import org.jspecify.annotations.Nullable; *

This event is {@linkplain Cancellable cancellable}. * If the event is cancelled, the chat message will not be sent to the server.

* - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

**/ @NullMarked public final class ClientChatEvent extends MutableEvent implements Cancellable { diff --git a/src/main/java/net/minecraftforge/client/event/ClientChatReceivedEvent.java b/src/main/java/net/minecraftforge/client/event/ClientChatReceivedEvent.java index 10a94d5bd5..f7fc53ce57 100644 --- a/src/main/java/net/minecraftforge/client/event/ClientChatReceivedEvent.java +++ b/src/main/java/net/minecraftforge/client/event/ClientChatReceivedEvent.java @@ -8,7 +8,6 @@ package net.minecraftforge.client.event; import net.minecraft.network.chat.ChatType; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.PlayerChatMessage; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.CancellableEventBus; import net.minecraftforge.eventbus.api.event.InheritableEvent; import net.minecraftforge.eventbus.api.event.MutableEvent; @@ -24,8 +23,7 @@ import java.util.UUID; *

This event is {@linkplain Cancellable cancellable}. * If the event is cancelled, the message is not displayed in the chat message window.

* - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

* * @see ChatType */ @@ -80,8 +78,7 @@ public sealed class ClientChatReceivedEvent extends MutableEvent implements Canc *

This event is {@linkplain Cancellable cancellable}. * If the event is cancelled, the message is not displayed in the chat message window.

* - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

* * @see ChatType */ diff --git a/src/main/java/net/minecraftforge/client/event/ClientPlayerNetworkEvent.java b/src/main/java/net/minecraftforge/client/event/ClientPlayerNetworkEvent.java index 14d1bb9741..0876c31e3d 100644 --- a/src/main/java/net/minecraftforge/client/event/ClientPlayerNetworkEvent.java +++ b/src/main/java/net/minecraftforge/client/event/ClientPlayerNetworkEvent.java @@ -8,7 +8,6 @@ package net.minecraftforge.client.event; import net.minecraft.client.multiplayer.MultiPlayerGameMode; import net.minecraft.client.player.LocalPlayer; import net.minecraft.network.Connection; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.InheritableEvent; import net.minecraftforge.fml.LogicalSide; @@ -20,8 +19,7 @@ import org.jspecify.annotations.NullMarked; * Fired for different client connectivity events. * See the various subclasses to listen for specific events. * - *

These events are fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus}, - * only on the {@linkplain LogicalSide#CLIENT logical client}.

+ *

These events are fired only on the {@linkplain LogicalSide#CLIENT logical client}.

* * @see LoggingIn * @see LoggingOut @@ -48,8 +46,7 @@ public sealed interface ClientPlayerNetworkEvent extends InheritableEvent { /** * Fired when the client player logs in to the server. The player should be initialized. * - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ @NullMarked record LoggingIn(MultiPlayerGameMode getMultiPlayerGameMode, LocalPlayer getPlayer, Connection getConnection) @@ -63,8 +60,7 @@ public sealed interface ClientPlayerNetworkEvent extends InheritableEvent { /** * Fired when the client player logs out. This event may also fire when a new integrated server is being created. * - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ @SuppressWarnings("NullableProblems") // Shush IntelliJ, we override non-nullables as nullables in this specific event; see later comment @@ -117,8 +113,7 @@ public sealed interface ClientPlayerNetworkEvent extends InheritableEvent { /** * Fired when the client player respawns, creating a new player instance to replace the old player instance. * - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

* * @param getOldPlayer the previous player instance * @param getNewPlayer the newly created player instance diff --git a/src/main/java/net/minecraftforge/client/event/ComputeFovModifierEvent.java b/src/main/java/net/minecraftforge/client/event/ComputeFovModifierEvent.java index a4fe86f4c0..c8a0f8e54c 100644 --- a/src/main/java/net/minecraftforge/client/event/ComputeFovModifierEvent.java +++ b/src/main/java/net/minecraftforge/client/event/ComputeFovModifierEvent.java @@ -7,7 +7,6 @@ package net.minecraftforge.client.event; import net.minecraft.util.Mth; import net.minecraft.world.entity.player.Player; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.MutableEvent; import net.minecraftforge.fml.LogicalSide; @@ -17,8 +16,7 @@ import org.jspecify.annotations.NullMarked; /** * Fired after the field of vision (FOV) modifier for the player is calculated to allow developers to adjust it further. * - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

* * @see ViewportEvent.ComputeFov */ diff --git a/src/main/java/net/minecraftforge/client/event/ContainerScreenEvent.java b/src/main/java/net/minecraftforge/client/event/ContainerScreenEvent.java index 6db26deaa7..362ff0bfac 100644 --- a/src/main/java/net/minecraftforge/client/event/ContainerScreenEvent.java +++ b/src/main/java/net/minecraftforge/client/event/ContainerScreenEvent.java @@ -17,8 +17,7 @@ import org.jetbrains.annotations.ApiStatus; * Fired for hooking into {@link AbstractContainerScreen} events. * See the subclasses to listen for specific events. * - *

These events are fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus}, - * only on the {@linkplain LogicalSide#CLIENT logical client}.

+ *

These events are fired only on the {@linkplain LogicalSide#CLIENT logical client}.

* * @see Render.Foreground * @see Render.Background @@ -33,8 +32,7 @@ public sealed interface ContainerScreenEvent { * Fired every time an {@link AbstractContainerScreen} renders. * See the two subclasses to listen for foreground or background rendering. * - *

These events are fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus}, - * only on the {@linkplain LogicalSide#CLIENT logical client}.

+ *

These events are fired only on the {@linkplain LogicalSide#CLIENT logical client}.

* * @see Foreground * @see Background @@ -62,8 +60,7 @@ public sealed interface ContainerScreenEvent { *

This can be used for rendering elements that must be above other screen elements, but * below tooltips and the dragged stack, such as slot or item stack specific overlays.

* - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ record Foreground( AbstractContainerScreen getContainerScreen, @@ -81,8 +78,7 @@ public sealed interface ContainerScreenEvent { * Fired after the container screen's background layer and elements are drawn. * This can be used for rendering new background elements. * - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ record Background( AbstractContainerScreen getContainerScreen, diff --git a/src/main/java/net/minecraftforge/client/event/CustomizeGuiOverlayEvent.java b/src/main/java/net/minecraftforge/client/event/CustomizeGuiOverlayEvent.java index fad2e3f6c0..c9cd8b2c04 100644 --- a/src/main/java/net/minecraftforge/client/event/CustomizeGuiOverlayEvent.java +++ b/src/main/java/net/minecraftforge/client/event/CustomizeGuiOverlayEvent.java @@ -39,8 +39,7 @@ public sealed interface CustomizeGuiOverlayEvent { *

This event is {@linkplain Cancellable cancellable}. * Cancelling this event will prevent the given bar from rendering.

* - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ final class BossEventProgress extends MutableEvent implements Cancellable, CustomizeGuiOverlayEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(BossEventProgress.class); @@ -121,8 +120,7 @@ public sealed interface CustomizeGuiOverlayEvent { * Fired before textual information is rendered to the debug screen. * This can be used to add or remove text information. * - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

* * @param getText the modifiable list of text to render on the side * @param getSide the side of the text getting rendered @@ -148,8 +146,7 @@ public sealed interface CustomizeGuiOverlayEvent { /** * Fired before the chat messages overlay is rendered to the screen. * - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ final class Chat extends MutableEvent implements CustomizeGuiOverlayEvent { public static final EventBus BUS = EventBus.create(Chat.class); diff --git a/src/main/java/net/minecraftforge/client/event/ForgeEventFactoryClient.java b/src/main/java/net/minecraftforge/client/event/ForgeEventFactoryClient.java index 5283c7c8ec..3d86291649 100644 --- a/src/main/java/net/minecraftforge/client/event/ForgeEventFactoryClient.java +++ b/src/main/java/net/minecraftforge/client/event/ForgeEventFactoryClient.java @@ -162,8 +162,8 @@ public final class ForgeEventFactoryClient { } public static boolean onClickInputPickBlock(KeyMapping keyBinding) { - var event = new InputEvent.InteractionKeyMappingTriggered(2, keyBinding, InteractionHand.MAIN_HAND); - return InputEvent.InteractionKeyMappingTriggered.BUS.post(event); + var event = new InputEvent.InteractionKeyMappingTriggered.PickBlock(keyBinding, InteractionHand.MAIN_HAND); + return InputEvent.InteractionKeyMappingTriggered.PickBlock.BUS.post(event); } public static void onContainerRenderBackground(AbstractContainerScreen screen, GuiGraphicsExtractor graphics, int mouseX, int mouseY) { diff --git a/src/main/java/net/minecraftforge/client/event/InputEvent.java b/src/main/java/net/minecraftforge/client/event/InputEvent.java index 6f0d49e6b2..997c456b3c 100644 --- a/src/main/java/net/minecraftforge/client/event/InputEvent.java +++ b/src/main/java/net/minecraftforge/client/event/InputEvent.java @@ -18,7 +18,6 @@ import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; import net.minecraftforge.fml.LogicalSide; import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; -import org.lwjgl.glfw.GLFW; /** * Fired when an input is detected from the user's input devices. @@ -174,19 +173,6 @@ public sealed interface InputEvent { return getInfo().key(); } - /** - * {@return the platform-specific scan code} - *

- * The scan code is unique for every key, regardless of whether it has a key code. - * Scan codes are platform-specific but consistent over time, so keys will have different scan codes depending - * on the platform but they are safe to save to disk as custom key bindings. - * - * @see InputConstants#getKey(int, int) - */ - public int getScanCode() { - return getInfo().scancode(); - } - /** * {@return the mouse button's action} * @@ -214,35 +200,31 @@ public sealed interface InputEvent { } } - /** - * Fired when a keymapping that by default involves clicking the mouse buttons is triggered. - * - *

The key bindings that trigger this event are:

- *
    - *
  • Use Item - defaults to left mouse click
  • - *
  • Pick Block - defaults to middle mouse click
  • - *
  • Attack - defaults to right mouse click
  • - *
- * - *

If this event is cancelled, then the keymapping's action is not processed further, and the hand will be swung - * according to {@link #shouldSwingHand()}.

- * - *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

- */ - // TODO: Change the 'button' to sub events. - Lex 0422202 - final class InteractionKeyMappingTriggered extends MutableEvent implements Cancellable, InputEvent { - public static final CancellableEventBus BUS = CancellableEventBus.create(InteractionKeyMappingTriggered.class); - - private final int button; + /// Fired when a keymapping that by default involves clicking the mouse buttons is triggered. + /// + /// The key bindings that trigger this event are: + /// - **Use Item** - defaults to _left mouse click_ + /// - **Pick Block** - defaults to _middle mouse click_ + /// - **Attack** - defaults to _right mouse click_ + /// + /// If this event is cancelled, then the keymapping's action is not processed further, and the hand will be swung + /// according to [#shouldSwingHand()]. + /// + /// This event is fired only on the [logical client][LogicalSide#CLIENT]. + /// + /// @see InteractionKeyMappingTriggered.Attack + /// @see InteractionKeyMappingTriggered.UseItem + /// @see InteractionKeyMappingTriggered.PickBlock + sealed abstract class InteractionKeyMappingTriggered extends MutableEvent implements Cancellable, InputEvent { private final KeyMapping keyMapping; private final InteractionHand hand; private boolean handSwing = true; @ApiStatus.Internal - public InteractionKeyMappingTriggered(int button, KeyMapping keyMapping, InteractionHand hand) { - this.button = button; + protected InteractionKeyMappingTriggered(KeyMapping keyMapping, InteractionHand hand) { this.keyMapping = keyMapping; this.hand = hand; + super(); } /** @@ -272,32 +254,53 @@ public sealed interface InputEvent { return hand; } - /** - * {@return {@code true} if the mouse button is the left mouse button} - */ - public boolean isAttack() { - return button == 0; - } - - /** - * {@return {@code true} if the mouse button is the right mouse button} - */ - public boolean isUseItem() { - return button == 1; - } - - /** - * {@return {@code true} if the mouse button is the middle mouse button} - */ - public boolean isPickBlock() { - return button == 2; - } - /** * {@return the key mapping which triggered this event} */ public KeyMapping getKeyMapping() { return keyMapping; } + + /// The mouse button or input for attacking, typically the left mouse button + public static final class Attack extends InteractionKeyMappingTriggered { + public static final CancellableEventBus BUS = CancellableEventBus.create(Attack.class); + + @ApiStatus.Internal + public Attack(KeyMapping keyMapping, InteractionHand hand) { + super(keyMapping, hand); + } + } + + /// The mouse button or input for using an item, typically the right mouse button + public static final class UseItem extends InteractionKeyMappingTriggered { + public static final CancellableEventBus BUS = CancellableEventBus.create(UseItem.class); + + @ApiStatus.Internal + public UseItem(KeyMapping keyMapping, InteractionHand hand) { + super(keyMapping, hand); + } + } + + /// The mouse button or input for picking a block, typically the middle mouse button (scroll wheel click) + public static final class PickBlock extends InteractionKeyMappingTriggered { + public static final CancellableEventBus BUS = CancellableEventBus.create(PickBlock.class); + + @ApiStatus.Internal + public PickBlock(KeyMapping keyMapping, InteractionHand hand) { + super(keyMapping, hand); + } + + /// @return Always false, as picking a block does not swing the hand and this event doesn't support changing + /// that behaviour + @Override + public boolean shouldSwingHand() { + return false; + } + + @Override + public void setSwingHand(boolean value) { + throw new UnsupportedOperationException("Cannot change hand swing behaviour for pick block input"); + } + } } } diff --git a/src/main/java/net/minecraftforge/client/event/RecipesUpdatedEvent.java b/src/main/java/net/minecraftforge/client/event/RecipesUpdatedEvent.java index 7870b40c92..edbf29f86c 100644 --- a/src/main/java/net/minecraftforge/client/event/RecipesUpdatedEvent.java +++ b/src/main/java/net/minecraftforge/client/event/RecipesUpdatedEvent.java @@ -6,7 +6,6 @@ package net.minecraftforge.client.event; import net.minecraft.client.ClientRecipeBook; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.RecordEvent; import net.minecraftforge.fml.LogicalSide; @@ -15,8 +14,7 @@ import org.jetbrains.annotations.ApiStatus; /** * Fired when the {@link ClientRecipeBook} has updated information about recipes from the server to the client. * - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

* * @param getRecipeBook the recipe manager */ diff --git a/src/main/java/net/minecraftforge/client/event/RenderArmEvent.java b/src/main/java/net/minecraftforge/client/event/RenderArmEvent.java index c515c083ca..0af03d0e72 100644 --- a/src/main/java/net/minecraftforge/client/event/RenderArmEvent.java +++ b/src/main/java/net/minecraftforge/client/event/RenderArmEvent.java @@ -22,6 +22,8 @@ import org.jetbrains.annotations.ApiStatus; *

This event is {@linkplain Cancellable cancellable}. If this event is cancelled, then the arm will not be rendered.

* *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

+ * + * @param getPackedLight the amount of packed (sky and block) light for rendering */ public record RenderArmEvent( PoseStack getPoseStack, @@ -33,13 +35,4 @@ public record RenderArmEvent( @ApiStatus.Internal public RenderArmEvent {} - - /** - * {@return the amount of packed (sky and block) light for rendering} - * - * @see LightTexture - */ - public int getPackedLight() { - return getPackedLight; - } } diff --git a/src/main/java/net/minecraftforge/client/event/RenderBlockScreenEffectEvent.java b/src/main/java/net/minecraftforge/client/event/RenderBlockScreenEffectEvent.java index 8de43943b2..6762210a97 100644 --- a/src/main/java/net/minecraftforge/client/event/RenderBlockScreenEffectEvent.java +++ b/src/main/java/net/minecraftforge/client/event/RenderBlockScreenEffectEvent.java @@ -5,56 +5,101 @@ package net.minecraftforge.client.event; -import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.renderer.state.level.PlayerRenderState; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.client.IRenderCallback; import net.minecraftforge.eventbus.api.bus.CancellableEventBus; -import net.minecraftforge.eventbus.api.event.RecordEvent; +import net.minecraftforge.eventbus.api.event.MutableEvent; import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; import net.minecraftforge.fml.LogicalSide; import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.Nullable; /** * Fired before a block texture will be overlaid on the player's view. * *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

- * - * @param getPlayer The player which the overlay will apply to - * @param getPoseStack The pose stack used for rendering - * @param getOverlayType The type of the overlay - * @param getBlockState The block which the overlay is gotten from - * @param getBlockPos The position of the block which the overlay is gotten from */ -public record RenderBlockScreenEffectEvent( - Player getPlayer, - PoseStack getPoseStack, - OverlayType getOverlayType, - BlockState getBlockState, - BlockPos getBlockPos -) implements Cancellable, RecordEvent { - public static final CancellableEventBus BUS = CancellableEventBus.create(RenderBlockScreenEffectEvent.class); - - /** - * The type of the block overlay to be rendered. - * - * @see RenderBlockScreenEffectEvent - */ - public enum OverlayType { - /** - * The type of the overlay when the player is burning / on fire. - */ - FIRE, - /** - * The type of overlay when the player is suffocating inside a solid block. - */ - BLOCK, - /** - * The type of overlay when the player is underwater. - */ - WATER - } +public abstract sealed class RenderBlockScreenEffectEvent extends MutableEvent implements Cancellable permits + RenderBlockScreenEffectEvent.FireOverlayEvent, + RenderBlockScreenEffectEvent.BlockOverlayEvent, + RenderBlockScreenEffectEvent.WaterOverlayEvent +{ + private final Player player; + private final BlockState blockState; + private final BlockPos blockPos; + private @Nullable IRenderCallback renderer; @ApiStatus.Internal - public RenderBlockScreenEffectEvent {} + protected RenderBlockScreenEffectEvent(Player player, BlockState blockState, BlockPos blockPos) { + this.player = player; + this.blockState = blockState; + this.blockPos = blockPos; + } + + /** The player which the overlay will apply to */ + public Player getPlayer() { return this.player; } + + /** The block which the overlay is gotten from */ + public BlockState getBlockSate() { return this.blockState; } + + /** The position of the block which the overlay is gotten from */ + public BlockPos getBlockPos() { return this.blockPos; } + + /** Returns the custom renderer, if any, that an event handler has registered for this event. */ + public @Nullable IRenderCallback getCustomRenderer() { + return this.renderer; + } + + /** Registers a custom renderer for this event, combine with canceling the event to take effect */ + public void setCustomRenderer(IRenderCallback renderer) { + this.renderer = renderer; + } + + + /** + * Fired when the player is burning / on fire. + */ + public static final class FireOverlayEvent extends RenderBlockScreenEffectEvent { + public static final CancellableEventBus BUS = CancellableEventBus.create(FireOverlayEvent.class); + + @ApiStatus.Internal + public FireOverlayEvent(Player player, BlockState blockState, BlockPos blockPos) { + super(player, blockState, blockPos); + } + } + + /** + * Fired when the player is suffocating inside a solid block. + */ + public static final class BlockOverlayEvent extends RenderBlockScreenEffectEvent { + public static final CancellableEventBus BUS = CancellableEventBus.create(BlockOverlayEvent.class); + + @ApiStatus.Internal + public BlockOverlayEvent(Player player, BlockState blockState, BlockPos blockPos) { + super(player, blockState, blockPos); + } + } + + /** + * Fired when the player is under normal Water. + */ + public static final class WaterOverlayEvent extends RenderBlockScreenEffectEvent { + public static final CancellableEventBus BUS = CancellableEventBus.create(WaterOverlayEvent.class); + + private final PlayerRenderState renderState; + + @ApiStatus.Internal + public WaterOverlayEvent(Player player, BlockState blockState, BlockPos blockPos, PlayerRenderState renderState) { + super(player, blockState, blockPos); + this.renderState = renderState; + } + + /** The current computed render state, waterOverlay is accessible. */ + public PlayerRenderState getRenderState() { + return this.renderState; + } + } } diff --git a/src/main/java/net/minecraftforge/client/event/RenderGuiEvent.java b/src/main/java/net/minecraftforge/client/event/RenderGuiEvent.java deleted file mode 100644 index 16e85a0dd3..0000000000 --- a/src/main/java/net/minecraftforge/client/event/RenderGuiEvent.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -/** Forge 1.20.5 - Removed, Mojang created a layered rendering system that should make this all obsolete finally.. - Lex 042724 -package net.minecraftforge.client.event; - -import com.mojang.blaze3d.platform.Window; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.eventbus.api.Cancelable; -import net.minecraftforge.eventbus.api.Event; -import net.minecraftforge.fml.LogicalSide; -import org.jetbrains.annotations.ApiStatus; -/** - * Fired when the HUD is rendered to the screen. - * See the two subclasses for listening to the two possible phases. - * - * @see Pre - * @see Post - * / -public abstract class RenderGuiEvent extends Event -{ - private final Window window; - private final GuiGraphics guiGraphics; - private final float partialTick; - - @ApiStatus.Internal - protected RenderGuiEvent(Window window, GuiGraphics guiGraphics, float partialTick) - { - this.window = window; - this.guiGraphics = guiGraphics; - this.partialTick = partialTick; - } - - public Window getWindow() - { - return window; - } - - public GuiGraphics getGuiGraphics() - { - return guiGraphics; - } - - public float getPartialTick() - { - return partialTick; - } - - /** - * Fired before the HUD is rendered to the screen. - * - *

This event is {@linkplain Cancelable cancellable}, and does not {@linkplain HasResult have a result}. - * If this event is cancelled, then the overlay will not be rendered, and the corresponding {@link Post} event will - * not be fired.

- * - *

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

- * - * @see Post - * / - @Cancelable - public static class Pre extends RenderGuiEvent - { - @ApiStatus.Internal - public Pre(Window window, GuiGraphics guiGraphics, float partialTick) - { - super(window, guiGraphics, partialTick); - } - } - - /** - * Fired after the HUD is rendered to the screen, if the corresponding {@link Pre} is not cancelled. - * - *

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

- * - *

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

- * / - public static class Post extends RenderGuiEvent - { - @ApiStatus.Internal - public Post(Window window, GuiGraphics guiGraphics, float partialTick) - { - super(window, guiGraphics, partialTick); - } - } -} -*/ diff --git a/src/main/java/net/minecraftforge/client/event/RenderGuiOverlayEvent.java b/src/main/java/net/minecraftforge/client/event/RenderGuiOverlayEvent.java deleted file mode 100644 index 5a086d24b9..0000000000 --- a/src/main/java/net/minecraftforge/client/event/RenderGuiOverlayEvent.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -/** Forge 1.20.5 - Removed, Mojang created a layered rendering system that should make this all obsolete finally.. - Lex 042724 -package net.minecraftforge.client.event; - -import com.mojang.blaze3d.platform.Window; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraftforge.client.gui.overlay.NamedGuiOverlay; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.eventbus.api.Cancelable; -import net.minecraftforge.eventbus.api.Event; -import net.minecraftforge.fml.LogicalSide; -import org.jetbrains.annotations.ApiStatus; - -/** - * Fired when an overlay is rendered to the screen. - * See the two subclasses for listening to the two possible phases. - * - *

An overlay that is not normally active cannot be forced to render. In such cases, this event will not fire.

- * - * @see Pre - * @see Post - * / -public abstract class RenderGuiOverlayEvent extends Event -{ - private final Window window; - private final GuiGraphics guiGraphics; - private final float partialTick; - private final NamedGuiOverlay overlay; - - @ApiStatus.Internal - protected RenderGuiOverlayEvent(Window window, GuiGraphics guiGraphics, float partialTick, NamedGuiOverlay overlay) - { - this.window = window; - this.guiGraphics = guiGraphics; - this.partialTick = partialTick; - this.overlay = overlay; - } - - public Window getWindow() - { - return window; - } - - public GuiGraphics getGuiGraphics() - { - return guiGraphics; - } - - public float getPartialTick() - { - return partialTick; - } - - public NamedGuiOverlay getOverlay() - { - return overlay; - } - - /** - * Fired before a GUI overlay is rendered to the screen. - * - *

This event is {@linkplain Cancelable cancellable}, and does not {@linkplain HasResult have a result}. - * If this event is cancelled, then the overlay will not be rendered, and the corresponding {@link Post} event will - * not be fired.

- * - *

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

- * - * @see Post - * / - @Cancelable - public static class Pre extends RenderGuiOverlayEvent - { - @ApiStatus.Internal - public Pre(Window window, GuiGraphics guiGraphics, float partialTick, NamedGuiOverlay overlay) - { - super(window, guiGraphics, partialTick, overlay); - } - } - - /** - * Fired after an GUI overlay is rendered to the screen, if the corresponding {@link Pre} is not cancelled. - * - *

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

- * - *

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

- * / - public static class Post extends RenderGuiOverlayEvent - { - @ApiStatus.Internal - public Post(Window window, GuiGraphics guiGraphics, float partialTick, NamedGuiOverlay overlay) - { - super(window, guiGraphics, partialTick, overlay); - } - } -} -*/ diff --git a/src/main/java/net/minecraftforge/client/event/RenderHandEvent.java b/src/main/java/net/minecraftforge/client/event/RenderHandEvent.java index 2cb4cfe893..e9da4c97ee 100644 --- a/src/main/java/net/minecraftforge/client/event/RenderHandEvent.java +++ b/src/main/java/net/minecraftforge/client/event/RenderHandEvent.java @@ -24,7 +24,6 @@ import org.jetbrains.annotations.ApiStatus; * * @param getHand The hand being rendered * @param getPoseStack The pose stack used for rendering - * @param getMultiBufferSource The source of rendering buffers * @param getPartialTick The partial tick * @param getInterpolatedPitch The interpolated pitch of the player entity * @param getSwingProgress The swing progress of the hand being rendered @@ -51,8 +50,6 @@ public record RenderHandEvent( /** * {@return the amount of packed (sky and block) light for rendering} - * - * @see LightTexture */ public int getPackedLight() { return getPackedLight; diff --git a/src/main/java/net/minecraftforge/client/event/RenderItemInFrameEvent.java b/src/main/java/net/minecraftforge/client/event/RenderItemInFrameEvent.java index 55cace59e1..f15a90d669 100644 --- a/src/main/java/net/minecraftforge/client/event/RenderItemInFrameEvent.java +++ b/src/main/java/net/minecraftforge/client/event/RenderItemInFrameEvent.java @@ -23,6 +23,8 @@ import org.jetbrains.annotations.ApiStatus; * *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

* + * @param getPackedLight the amount of packed (sky and block) light for rendering + * * @see ItemFrameRenderer */ public record RenderItemInFrameEvent( @@ -36,13 +38,4 @@ public record RenderItemInFrameEvent( @ApiStatus.Internal public RenderItemInFrameEvent {} - - /** - * {@return the amount of packed (sky and block) light for rendering} - * - * @see LightTexture - */ - public int getPackedLight() { - return getPackedLight; - } } diff --git a/src/main/java/net/minecraftforge/client/event/RenderLivingEvent.java b/src/main/java/net/minecraftforge/client/event/RenderLivingEvent.java index fd33050787..883b858f93 100644 --- a/src/main/java/net/minecraftforge/client/event/RenderLivingEvent.java +++ b/src/main/java/net/minecraftforge/client/event/RenderLivingEvent.java @@ -68,8 +68,7 @@ public sealed interface RenderLivingEvent * - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

* * @param the living entity that is being rendered * @param the model for the living entity @@ -90,8 +89,7 @@ public sealed interface RenderLivingEventafter an entity is rendered, if the corresponding {@link RenderLivingEvent.Post} is not cancelled. * - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

* * @param the living entity that was rendered * @param the model for the living entity diff --git a/src/main/java/net/minecraftforge/client/event/RenderTooltipEvent.java b/src/main/java/net/minecraftforge/client/event/RenderTooltipEvent.java index 5cd02c8aa8..48e7522367 100644 --- a/src/main/java/net/minecraftforge/client/event/RenderTooltipEvent.java +++ b/src/main/java/net/minecraftforge/client/event/RenderTooltipEvent.java @@ -111,8 +111,7 @@ public abstract sealed class RenderTooltipEvent extends MutableEvent implements * If this event is cancelled, then the list of components will be empty, causing the tooltip to not be rendered and * the corresponding {@link RenderTooltipEvent.Pre} to not be fired.

* - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ public static final class GatherComponents extends MutableEvent implements Cancellable { public static final CancellableEventBus BUS = CancellableEventBus.create(GatherComponents.class); @@ -192,8 +191,7 @@ public abstract sealed class RenderTooltipEvent extends MutableEvent implements *

This event is {@linkplain Cancellable cancellable}. * If this event is cancelled, then the tooltip will not be rendered * - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ public static final class Pre extends RenderTooltipEvent implements Cancellable { public static final CancellableEventBus
 BUS = CancellableEventBus.create(Pre.class);
@@ -204,7 +202,7 @@ public abstract sealed class RenderTooltipEvent extends MutableEvent implements
         @Nullable
         private Identifier background;
         @Nullable
-        private Identifier originalBackground;
+        private final Identifier originalBackground;
 
         @ApiStatus.Internal
         public Pre(ItemStack stack, GuiGraphicsExtractor graphics, int x, int y, int screenWidth, int screenHeight, Font font, List components, ClientTooltipPositioner positioner, @Nullable Identifier background) {
diff --git a/src/main/java/net/minecraftforge/client/event/ScreenEvent.java b/src/main/java/net/minecraftforge/client/event/ScreenEvent.java
index 96e9ce6d62..043eb9e178 100644
--- a/src/main/java/net/minecraftforge/client/event/ScreenEvent.java
+++ b/src/main/java/net/minecraftforge/client/event/ScreenEvent.java
@@ -12,7 +12,6 @@ import net.minecraft.client.gui.screens.Screen;
 import net.minecraft.client.input.CharacterEvent;
 import net.minecraft.client.input.KeyEvent;
 import net.minecraft.client.input.MouseButtonEvent;
-import net.minecraftforge.common.MinecraftForge;
 import net.minecraftforge.common.util.HasResult;
 import net.minecraftforge.common.util.Result;
 import net.minecraftforge.eventbus.api.bus.CancellableEventBus;
@@ -25,7 +24,6 @@ import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.Nullable;
 import org.jspecify.annotations.NonNull;
 import org.jspecify.annotations.NullMarked;
-import org.lwjgl.glfw.GLFW;
 
 import java.util.Collections;
 import java.util.List;
@@ -35,8 +33,7 @@ import java.util.function.Consumer;
  * Fired on different events/actions when a {@link Screen} is active and visible.
  * See the various subclasses for listening to different events.
  *
- * 

These events are fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus}, - * only on the {@linkplain LogicalSide#CLIENT logical client}.

+ *

These events are fired only on the {@linkplain LogicalSide#CLIENT logical client}.

* * @see Init * @see Render @@ -115,8 +112,7 @@ public sealed interface ScreenEvent { * If the event is cancelled, the initialization method will not be called, and the widgets and children lists * will not be cleared.

* - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ public static final class Pre extends Init implements Cancellable { public static final CancellableEventBus
 BUS = CancellableEventBus.create(Pre.class);
@@ -130,8 +126,7 @@ public sealed interface ScreenEvent {
         /**
          * Fired after the screen's overridable initialization method is called.
          *
-         * 

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ public static final class Post extends Init { public static final EventBus BUS = EventBus.create(Post.class); @@ -177,8 +172,7 @@ public sealed interface ScreenEvent { *

This event is {@linkplain Cancellable cancellable}. * If the event is cancelled, the screen will not be drawn.

* - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ record Pre(Screen getScreen, GuiGraphicsExtractor getGuiGraphics, int getMouseX, int getMouseY, float getPartialTick) implements Cancellable, Render, RecordEvent { @@ -191,8 +185,7 @@ public sealed interface ScreenEvent { /** * Fired after the screen is drawn. * - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ record Post(Screen getScreen, GuiGraphicsExtractor getGuiGraphics, int getMouseX, int getMouseY, float getPartialTick) implements Render, RecordEvent { @@ -207,8 +200,7 @@ public sealed interface ScreenEvent { * Fired directly after the background of the screen is drawn. * Can be used for drawing above the background but below the tooltips. * - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

* * @param getGuiGraphics the gui graphics used for rendering */ @@ -226,8 +218,7 @@ public sealed interface ScreenEvent { * *

This event is {@linkplain Cancellable cancellable}. Cancelling this event will prevent vanilla rendering.

* - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ final class RenderInventoryMobEffects extends MutableEvent implements Cancellable, ScreenEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(RenderInventoryMobEffects.class); @@ -344,8 +335,7 @@ public sealed interface ScreenEvent { * If the event is cancelled, the screen's mouse click handler will be bypassed * and the corresponding {@link MouseButtonPressed.Post} will not be fired.

* - *

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

+ *

This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

*/ record Pre(Screen getScreen, double getMouseX, double getMouseY, MouseButtonEvent getInfo) implements Cancellable, MouseButtonPressed, RecordEvent { @@ -367,8 +357,7 @@ public sealed interface ScreenEvent { *
  • {@link Result#DENY} - forcibly sets the mouse click as not handled.
  • * * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ record Post( Screen getScreen, @@ -416,8 +405,7 @@ public sealed interface ScreenEvent { * If the event is cancelled, the screen's mouse release handler will be bypassed * and the corresponding {@link MouseButtonReleased.Post} will not be fired.

    * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ record Pre(Screen getScreen, double getMouseX, double getMouseY, int getButton) implements Cancellable, MouseButtonReleased, RecordEvent { @@ -439,8 +427,7 @@ public sealed interface ScreenEvent { *
  • {@link Result#DENY} - forcibly sets the mouse release as not handled.
  • * * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ record Post( Screen getScreen, @@ -500,8 +487,7 @@ public sealed interface ScreenEvent { * If the event is cancelled, the screen's mouse drag handler will be bypassed * and the corresponding {@link MouseDragged.Post} will not be fired.

    * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ record Pre( Screen getScreen, @@ -524,8 +510,7 @@ public sealed interface ScreenEvent { *

    This event is not {@linkplain Cancellable cancellable}, and does not {@linkplain HasResult have a result}. * If the event is cancelled, the mouse drag will be set as handled.

    * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ record Post( Screen getScreen, @@ -568,8 +553,7 @@ public sealed interface ScreenEvent { * If the event is cancelled, the screen's mouse scroll handler will be bypassed * and the corresponding {@link MouseScrolled.Post} will not be fired.

    * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ record Pre(Screen getScreen, double getMouseX, double getMouseY, double getDeltaX, double getDeltaY) implements Cancellable, MouseScrolled, RecordEvent { @@ -586,8 +570,7 @@ public sealed interface ScreenEvent { *

    This event is not {@linkplain Cancellable cancellable}, and does not {@linkplain HasResult have a result}. * If the event is cancelled, the mouse scroll will be set as handled.

    * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ record Post(Screen getScreen, double getMouseX, double getMouseY, double getDeltaX, double getDeltaY) implements MouseScrolled, RecordEvent { @@ -625,19 +608,6 @@ public sealed interface ScreenEvent { return getInfo().key(); } - /** - * {@return the platform-specific scan code} - *

    - * The scan code is unique for every key, regardless of whether it has a key code. - * Scan codes are platform-specific but consistent over time, so keys will have different scan codes depending - * on the platform but they are safe to save to disk as custom key bindings. - * - * @see InputConstants#getKey(int, int) - */ - default int getScanCode() { - return getInfo().scancode(); - } - /** * {@return a bit field representing the active modifier keys} * @@ -669,8 +639,7 @@ public sealed interface ScreenEvent { * If the event is cancelled, the screen's key press handler will be bypassed * and the corresponding {@link KeyPressed.Post} will not be fired.

    * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ record Pre(Screen getScreen, KeyEvent getInfo) implements Cancellable, KeyPressed, RecordEvent { public static final CancellableEventBus
     BUS = CancellableEventBus.create(Pre.class);
    @@ -686,8 +655,7 @@ public sealed interface ScreenEvent {
              * 

    This event is {@linkplain Cancellable cancellable}. * If the event is cancelled, the key press will be set as handled.

    * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ record Post(Screen getScreen, KeyEvent getInfo) implements Cancellable, KeyPressed, RecordEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(Post.class); @@ -712,8 +680,7 @@ public sealed interface ScreenEvent { * If the event is cancelled, the screen's key release handler will be bypassed * and the corresponding {@link KeyReleased.Post} will not be fired.

    * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ record Pre(Screen getScreen, KeyEvent getInfo) implements Cancellable, KeyReleased, RecordEvent { public static final CancellableEventBus
     BUS = CancellableEventBus.create(Pre.class);
    @@ -729,8 +696,7 @@ public sealed interface ScreenEvent {
              * 

    This event is {@linkplain Cancellable cancellable}. * If the event is cancelled, the key release will be set as handled.

    * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ record Post(Screen getScreen, KeyEvent getInfo) implements Cancellable, KeyReleased, RecordEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(Post.class); @@ -769,8 +735,7 @@ public sealed interface ScreenEvent { * If the event is cancelled, the screen's character input handler will be bypassed * and the corresponding {@link CharacterTyped.Post} will not be fired.

    * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ record Pre(Screen getScreen, CharacterEvent getInfo) implements Cancellable, CharacterTyped, RecordEvent { public static final CancellableEventBus
     BUS = CancellableEventBus.create(Pre.class);
    @@ -786,8 +751,7 @@ public sealed interface ScreenEvent {
              * 

    This event is {@linkplain Cancellable cancellable}. * If the event is cancelled, the character input will be set as handled.

    * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ record Post(Screen getScreen, CharacterEvent getInfo) implements CharacterTyped, RecordEvent { public static final EventBus BUS = EventBus.create(Post.class); @@ -806,15 +770,14 @@ public sealed interface ScreenEvent { * will remain open. However, cancelling this event will not prevent the closing of screen layers which happened before * this event fired.

    * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ final class Opening extends MutableEvent implements Cancellable, ScreenEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(Opening.class); private final Screen screen; private final @Nullable Screen currentScreen; - private Screen newScreen; + private @Nullable Screen newScreen; @ApiStatus.Internal public Opening(@Nullable Screen currentScreen, Screen screen) { @@ -849,7 +812,7 @@ public sealed interface ScreenEvent { /** * Sets the new screen to be opened if the event is not cancelled. May be null. */ - public void setNewScreen(Screen newScreen) { + public void setNewScreen(@Nullable Screen newScreen) { this.newScreen = newScreen; } } @@ -858,8 +821,7 @@ public sealed interface ScreenEvent { * Fired before a {@link Screen} is closed. * All screen layers on the screen are closed before this event is fired. * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ record Closing(Screen getScreen) implements ScreenEvent, RecordEvent { public static final EventBus BUS = EventBus.create(Closing.class); diff --git a/src/main/java/net/minecraftforge/client/event/ScreenshotEvent.java b/src/main/java/net/minecraftforge/client/event/ScreenshotEvent.java index 1c1be2ff29..b1276e93ea 100644 --- a/src/main/java/net/minecraftforge/client/event/ScreenshotEvent.java +++ b/src/main/java/net/minecraftforge/client/event/ScreenshotEvent.java @@ -27,8 +27,7 @@ import java.io.IOException; * If this event is cancelled, then the screenshot is not written to disk, and the message in the event will be posted * to the player's chat.

    * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    * * @see Screenshot */ diff --git a/src/main/java/net/minecraftforge/client/event/ToastAddEvent.java b/src/main/java/net/minecraftforge/client/event/ToastAddEvent.java index 1552588283..4b0db04006 100644 --- a/src/main/java/net/minecraftforge/client/event/ToastAddEvent.java +++ b/src/main/java/net/minecraftforge/client/event/ToastAddEvent.java @@ -19,8 +19,7 @@ import net.minecraftforge.fml.LogicalSide; *

    This event is {@linkplain Cancellable cancellable}. * Cancelling the event stops the toast from being queued, which means it never renders.

    * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ public record ToastAddEvent(Toast getToast) implements Cancellable, RecordEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(ToastAddEvent.class); diff --git a/src/main/java/net/minecraftforge/client/event/ViewportEvent.java b/src/main/java/net/minecraftforge/client/event/ViewportEvent.java index d8e103f8bc..692dfead4a 100644 --- a/src/main/java/net/minecraftforge/client/event/ViewportEvent.java +++ b/src/main/java/net/minecraftforge/client/event/ViewportEvent.java @@ -10,7 +10,6 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.fog.FogData; import net.minecraft.world.level.material.FogType; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.CancellableEventBus; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.MutableEvent; @@ -26,8 +25,7 @@ import org.jspecify.annotations.NullMarked; * These can be used for customizing the visual features visible to the player. * See the various subclasses for listening to different features. * - *

    These events are fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus}, - * only on the {@linkplain LogicalSide#CLIENT logical client}.

    + *

    These events are fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    * * @see RenderFog * @see ComputeFogColor @@ -56,8 +54,7 @@ public sealed interface ViewportEvent { *

    This event is {@linkplain Cancellable cancellable}.
    * The event must be cancelled for any changes to the plane distances to take effect.

    * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ record RenderFog( GameRenderer getRenderer, @@ -141,8 +138,7 @@ public sealed interface ViewportEvent { /** * Fired for customizing the color of the fog visible to the player. * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ final class ComputeFogColor extends MutableEvent implements ViewportEvent { public static final EventBus BUS = EventBus.create(ComputeFogColor.class); @@ -233,8 +229,7 @@ public sealed interface ViewportEvent { * Fired to allow altering the angles of the player's camera. * This can be used to alter the player's view for different effects, such as applying roll. * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    */ @NullMarked final class ComputeCameraAngles extends MutableEvent implements ViewportEvent { @@ -325,8 +320,7 @@ public sealed interface ViewportEvent { * Fired for altering the raw field of view (FOV). * This is after the FOV settings are applied, and before modifiers such as the Nausea effect. * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    * * @see ComputeFovModifierEvent */ diff --git a/src/main/java/net/minecraftforge/client/event/sound/PlaySoundSourceEvent.java b/src/main/java/net/minecraftforge/client/event/sound/PlaySoundSourceEvent.java index f29e8a9870..57b51dbed8 100644 --- a/src/main/java/net/minecraftforge/client/event/sound/PlaySoundSourceEvent.java +++ b/src/main/java/net/minecraftforge/client/event/sound/PlaySoundSourceEvent.java @@ -9,7 +9,6 @@ import com.mojang.blaze3d.audio.Channel; import net.minecraft.client.resources.sounds.SoundInstance; import net.minecraft.client.sounds.SoundEngine; import net.minecraftforge.client.event.sound.SoundEvent.SoundSourceEvent; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.fml.LogicalSide; import org.jetbrains.annotations.ApiStatus; @@ -19,8 +18,7 @@ import org.jetbrains.annotations.ApiStatus; * in a buffer before being played, and used for most sounds of short length such as sound effects for clicking * buttons. * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    * * @see PlayStreamingSourceEvent */ diff --git a/src/main/java/net/minecraftforge/client/event/sound/PlayStreamingSourceEvent.java b/src/main/java/net/minecraftforge/client/event/sound/PlayStreamingSourceEvent.java index 9ab1548aa9..ec6adcd73d 100644 --- a/src/main/java/net/minecraftforge/client/event/sound/PlayStreamingSourceEvent.java +++ b/src/main/java/net/minecraftforge/client/event/sound/PlayStreamingSourceEvent.java @@ -9,7 +9,6 @@ import com.mojang.blaze3d.audio.Channel; import net.minecraft.client.resources.sounds.SoundInstance; import net.minecraft.client.sounds.SoundEngine; import net.minecraftforge.client.event.sound.SoundEvent.SoundSourceEvent; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.fml.LogicalSide; import org.jetbrains.annotations.ApiStatus; @@ -19,8 +18,7 @@ import org.jetbrains.annotations.ApiStatus; * (such as a file), and used for sounds of long length which are unsuitable to keep fully loaded in-memory in a buffer * (as is done for regular non-streaming sounds), such as background music or music discs. * - *

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

    + *

    This event is fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    * * @see PlayStreamingSourceEvent */ diff --git a/src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java b/src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java index 62bd1479aa..8d71556edd 100644 --- a/src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java +++ b/src/main/java/net/minecraftforge/client/event/sound/SoundEvent.java @@ -8,7 +8,6 @@ package net.minecraftforge.client.event.sound; import net.minecraft.client.resources.sounds.SoundInstance; import net.minecraft.client.sounds.SoundEngine; import com.mojang.blaze3d.audio.Channel; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.InheritableEvent; import net.minecraftforge.fml.LogicalSide; @@ -16,8 +15,7 @@ import net.minecraftforge.fml.LogicalSide; /** * Superclass for sound related events. * - *

    These events are fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus}, - * only on the {@linkplain LogicalSide#CLIENT logical client}.

    + *

    These events are fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    * * @see SoundSourceEvent * @see PlaySoundEvent @@ -32,8 +30,7 @@ public sealed interface SoundEvent permits PlaySoundEvent, SoundEngineLoadEvent, /** * Superclass for when a sound has started to play on an audio channel. * - *

    These events are fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus}, - * only on the {@linkplain LogicalSide#CLIENT logical client}.

    + *

    These events are fired only on the {@linkplain LogicalSide#CLIENT logical client}.

    * * @see PlaySoundSourceEvent * @see PlayStreamingSourceEvent @@ -47,7 +44,7 @@ public sealed interface SoundEvent permits PlaySoundEvent, SoundEngineLoadEvent, SoundInstance getSound(); /** - * {@return the audio channel on which the sound is playing on} + * {@return the audio channel on which the sound is playing} */ Channel getChannel(); diff --git a/src/main/java/net/minecraftforge/client/extensions/IForgeGpuTexture.java b/src/main/java/net/minecraftforge/client/extensions/IForgeGpuTexture.java index 920ff8307c..93ed0fc9d7 100644 --- a/src/main/java/net/minecraftforge/client/extensions/IForgeGpuTexture.java +++ b/src/main/java/net/minecraftforge/client/extensions/IForgeGpuTexture.java @@ -5,14 +5,7 @@ package net.minecraftforge.client.extensions; -import com.mojang.blaze3d.textures.GpuTexture; - public interface IForgeGpuTexture { - @SuppressWarnings("unused") - private GpuTexture self() { - return (GpuTexture) this; - } - default boolean isStencilEnabled() { return false; } diff --git a/src/main/java/net/minecraftforge/client/extensions/IForgePoseStack.java b/src/main/java/net/minecraftforge/client/extensions/IForgePoseStack.java index 855eb0c05c..e038bd7b97 100644 --- a/src/main/java/net/minecraftforge/client/extensions/IForgePoseStack.java +++ b/src/main/java/net/minecraftforge/client/extensions/IForgePoseStack.java @@ -29,11 +29,11 @@ public interface IForgePoseStack { var trans = transformation.translation(); self.translate(trans.x(), trans.y(), trans.z()); - self.mulPose(transformation.leftRotation()); + self.last().rotate(transformation.leftRotation()); var scale = transformation.scale(); self.scale(scale.x(), scale.y(), scale.z()); - self.mulPose(transformation.rightRotation()); + self.last().rotate(transformation.rightRotation()); } } diff --git a/src/main/java/net/minecraftforge/client/extensions/common/IClientBlockExtensions.java b/src/main/java/net/minecraftforge/client/extensions/common/IClientBlockExtensions.java index 32b626b1db..6e7b13f1b9 100644 --- a/src/main/java/net/minecraftforge/client/extensions/common/IClientBlockExtensions.java +++ b/src/main/java/net/minecraftforge/client/extensions/common/IClientBlockExtensions.java @@ -8,6 +8,7 @@ package net.minecraftforge.client.extensions.common; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.particle.ParticleEngine; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.core.registries.Registries; import net.minecraft.tags.FluidTags; import net.minecraft.world.effect.MobEffects; @@ -21,7 +22,6 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.phys.HitResult; import net.minecraftforge.fml.LogicalSide; import org.joml.Vector3d; @@ -51,11 +51,11 @@ public interface IClientBlockExtensions { * * @param state The current state * @param level The current level - * @param target The target the player is looking at {x/y/z/side/sub} + * @param direction The side of the block the player is breaking * @param manager A reference to the current particle manager. * @return True to prevent vanilla digging particles form spawning. */ - default boolean addHitEffects(BlockState state, Level level, HitResult target, ParticleEngine manager) { + default boolean addHitEffects(BlockState state, Level level, Direction direction, ParticleEngine manager) { return false; } diff --git a/src/main/java/net/minecraftforge/client/extensions/common/IClientFluidTypeExtensions.java b/src/main/java/net/minecraftforge/client/extensions/common/IClientFluidTypeExtensions.java index b49d6286db..6158aeb735 100644 --- a/src/main/java/net/minecraftforge/client/extensions/common/IClientFluidTypeExtensions.java +++ b/src/main/java/net/minecraftforge/client/extensions/common/IClientFluidTypeExtensions.java @@ -5,23 +5,23 @@ package net.minecraftforge.client.extensions.common; -import com.mojang.blaze3d.vertex.PoseStack; 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.ScreenEffectRenderer; -import net.minecraft.client.renderer.SubmitNodeCollector; import net.minecraft.client.renderer.block.BlockAndTintGetter; import net.minecraft.client.renderer.block.FluidModel; import net.minecraft.client.renderer.block.FluidRenderer; import net.minecraft.client.renderer.fog.FogData; +import net.minecraft.client.renderer.state.level.PlayerRenderState; import net.minecraft.core.BlockPos; import net.minecraft.resources.Identifier; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.Fluids; import net.minecraft.world.level.material.FogType; +import net.minecraftforge.client.IRenderCallback; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidType; import net.minecraftforge.fml.LogicalSide; @@ -138,12 +138,15 @@ public interface IClientFluidTypeExtensions { * @param mc the client instance * @param poseStack the transformations representing the current rendering position */ - default void renderOverlay(Minecraft mc, PoseStack poseStack, SubmitNodeCollector buffer) { + default @Nullable IRenderCallback renderOverlay(Minecraft mc, PlayerRenderState state) { Identifier texture = this.getRenderOverlayTexture(mc); if (texture != null) - ScreenEffectRenderer.renderFluid(mc, poseStack, buffer, texture); + return (pose, collector) -> ScreenEffectRenderer.submitFluid(state.waterOverlay, pose, collector, texture); + return null; } + + /** * Modifies the color of the fog when the camera is within the fluid. * diff --git a/src/main/java/net/minecraftforge/client/extensions/common/IClientItemExtensions.java b/src/main/java/net/minecraftforge/client/extensions/common/IClientItemExtensions.java index 40dad3827c..bebe7facc7 100644 --- a/src/main/java/net/minecraftforge/client/extensions/common/IClientItemExtensions.java +++ b/src/main/java/net/minecraftforge/client/extensions/common/IClientItemExtensions.java @@ -66,7 +66,7 @@ public interface IClientItemExtensions { */ @Nullable default HumanoidModel.ArmPose getArmPose(LivingEntity entityLiving, InteractionHand hand, ItemStack itemStack) { - return null; + return HumanoidModel.ArmPose.ITEM; } /** diff --git a/src/main/java/net/minecraftforge/client/gui/LoadingErrorScreen.java b/src/main/java/net/minecraftforge/client/gui/LoadingErrorScreen.java index fd0f42538a..621c20b25f 100644 --- a/src/main/java/net/minecraftforge/client/gui/LoadingErrorScreen.java +++ b/src/main/java/net/minecraftforge/client/gui/LoadingErrorScreen.java @@ -6,13 +6,15 @@ package net.minecraftforge.client.gui; import com.google.common.base.Strings; +import com.mojang.blaze3d.Blaze3D; + import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.ErrorScreen; +import net.minecraft.client.gui.components.Button.OnPress; import net.minecraft.client.gui.components.ObjectSelectionList; import net.minecraft.util.FormattedCharSequence; -import net.minecraft.util.Util; import net.minecraft.network.chat.Component; import net.minecraft.ChatFormatting; import net.minecraftforge.common.ForgeI18n; @@ -56,18 +58,27 @@ public class LoadingErrorScreen extends ErrorScreen { this.warningHeader = Component.literal(ChatFormatting.YELLOW + ForgeI18n.parseMessage("fml.loadingerrorscreen.warningheader", this.modLoadWarnings.size()) + ChatFormatting.RESET); int yOffset = 46; - this.addRenderableWidget(new ExtendedButton(50, this.height - yOffset, this.width / 2 - 55, 20, Component.literal(ForgeI18n.parseMessage("fml.button.open.mods.folder")), _ -> Util.getPlatform().openFile(modsDir.toFile()))); - this.addRenderableWidget(new ExtendedButton(this.width / 2 + 5, this.height - yOffset, this.width / 2 - 55, 20, Component.literal(ForgeI18n.parseMessage("fml.button.open.file", logFile.getFileName())), _ -> Util.getPlatform().openFile(logFile.toFile()))); + this.addRenderableWidget(new ExtendedButton(50, this.height - yOffset, this.width / 2 - 55, 20, text("fml.button.open.mods.folder"), open(modsDir))); + this.addRenderableWidget(new ExtendedButton(this.width / 2 + 5, this.height - yOffset, this.width / 2 - 55, 20, text("fml.button.open.file", logFile.getFileName()), open(logFile))); if (this.modLoadErrors.isEmpty()) - this.addRenderableWidget(new ExtendedButton(this.width / 4, this.height - 24, this.width / 2, 20, Component.literal(ForgeI18n.parseMessage("fml.button.continue.launch")), _ -> this.minecraft.gui.setScreen(null))); + this.addRenderableWidget(new ExtendedButton(this.width / 4, this.height - 24, this.width / 2, 20, text("fml.button.continue.launch"), _ -> this.minecraft.gui.setScreen(null))); else - this.addRenderableWidget(new ExtendedButton(this.width / 4, this.height - 24, this.width / 2, 20, Component.literal(ForgeI18n.parseMessage("fml.button.open.file", dumpedLocation.getFileName())), _ -> Util.getPlatform().openFile(dumpedLocation.toFile()))); + this.addRenderableWidget(new ExtendedButton(this.width / 4, this.height - 24, this.width / 2, 20, text("fml.button.open.file", dumpedLocation.getFileName()), open(dumpedLocation))); this.entryList = new LoadingEntryList(this, this.modLoadErrors, this.modLoadWarnings); this.addWidget(this.entryList); this.setFocused(this.entryList); } + + private static Component text(String key, Object... args) { + return Component.literal(ForgeI18n.parseMessage(key, args)); + } + + private static OnPress open(Path path) { + return _ -> Blaze3D.openPath(path); + } + @Override public void extractRenderState(GuiGraphicsExtractor guiGraphics, int mouseX, int mouseY, float partialTick) { this.entryList.extractRenderState(guiGraphics, mouseX, mouseY, partialTick); diff --git a/src/main/java/net/minecraftforge/client/gui/ModListScreen.java b/src/main/java/net/minecraftforge/client/gui/ModListScreen.java index 5c8f9f3ca4..73045798a0 100644 --- a/src/main/java/net/minecraftforge/client/gui/ModListScreen.java +++ b/src/main/java/net/minecraftforge/client/gui/ModListScreen.java @@ -36,11 +36,12 @@ import net.minecraft.client.gui.components.ObjectSelectionList; import net.minecraft.client.gui.components.StringWidget; import net.minecraft.client.renderer.texture.DynamicTexture; + +import com.mojang.blaze3d.Blaze3D; import com.mojang.blaze3d.platform.NativeImage; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.util.FormattedCharSequence; import net.minecraft.resources.Identifier; -import net.minecraft.util.Util; import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.util.Size2i; import net.minecraftforge.common.ForgeI18n; @@ -232,7 +233,7 @@ public class ModListScreen extends Screen { .bounds(((listWidth + PADDING + this.width - doneButtonWidth) / 2), y, doneButtonWidth, BUTTON_HEIGHT) .build(); - openModsFolderButton = Button.builder(Component.translatable("fml.menu.mods.openmodsfolder"), _ -> Util.getPlatform().openFile(FMLPaths.MODSDIR.get().toFile())) + openModsFolderButton = Button.builder(Component.translatable("fml.menu.mods.openmodsfolder"), _ -> Blaze3D.openPath(FMLPaths.MODSDIR.get())) .bounds(6, y, this.listWidth, BUTTON_HEIGHT) .build(); diff --git a/src/main/java/net/minecraftforge/client/gui/ModMismatchDisconnectedScreen.java b/src/main/java/net/minecraftforge/client/gui/ModMismatchDisconnectedScreen.java index 5f4215ec3b..1704768561 100644 --- a/src/main/java/net/minecraftforge/client/gui/ModMismatchDisconnectedScreen.java +++ b/src/main/java/net/minecraftforge/client/gui/ModMismatchDisconnectedScreen.java @@ -17,8 +17,9 @@ import java.util.stream.Collectors; import net.minecraftforge.client.gui.widget.ScrollPanel; import org.apache.commons.lang3.tuple.Pair; +import com.mojang.blaze3d.Blaze3D; + import net.minecraft.ChatFormatting; -import net.minecraft.util.Util; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.TextAlignment; @@ -86,10 +87,10 @@ public class ModMismatchDisconnectedScreen extends Screen { this.addRenderableWidget(new MismatchInfoPanel(minecraft, listWidth, listHeight, (this.height - this.listHeight) / 2, listLeft)); int buttonWidth = Math.min(210, this.width / 2 - 20); - this.addRenderableWidget(Button.builder(Component.literal(ForgeI18n.parseMessage("fml.button.open.file", logFile.getFileName())), _ -> Util.getPlatform().openFile(logFile.toFile())) + this.addRenderableWidget(Button.builder(Component.literal(ForgeI18n.parseMessage("fml.button.open.file", logFile.getFileName())), _ -> Blaze3D.openPath(logFile)) .bounds(Math.max(this.width / 4 - buttonWidth / 2, listLeft), upperButtonHeight, buttonWidth, 20) .build()); - this.addRenderableWidget(Button.builder(Component.literal(ForgeI18n.parseMessage("fml.button.open.mods.folder")), _ -> Util.getPlatform().openFile(modsDir.toFile())) + this.addRenderableWidget(Button.builder(Component.literal(ForgeI18n.parseMessage("fml.button.open.mods.folder")), _ -> Blaze3D.openPath(modsDir)) .bounds(Math.min(this.width * 3 / 4 - buttonWidth / 2, listLeft + listWidth - buttonWidth), upperButtonHeight, buttonWidth, 20) .build()); this.addRenderableWidget(Button.builder(Component.translatable("gui.toMenu"), _ -> this.minecraft.gui.setScreen(this.parent)) diff --git a/src/main/java/net/minecraftforge/client/gui/overlay/IGuiOverlay.java b/src/main/java/net/minecraftforge/client/gui/overlay/IGuiOverlay.java deleted file mode 100644 index bc413926e5..0000000000 --- a/src/main/java/net/minecraftforge/client/gui/overlay/IGuiOverlay.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -/** Forge 1.20.5 - Removed, Mojang created a layered rendering system that should make this all obsolete finally.. - Lex 042724 -package net.minecraftforge.client.gui.overlay; - -import net.minecraft.client.gui.GuiGraphics; -import net.minecraftforge.client.event.RegisterGuiOverlaysEvent; - -/** - * A HUD overlay. - * - * @see RegisterGuiOverlaysEvent - * / -@FunctionalInterface -public interface IGuiOverlay { - void render(ForgeGui gui, GuiGraphics guiGraphics, float partialTick, int screenWidth, int screenHeight); -} -*/ diff --git a/src/main/java/net/minecraftforge/client/gui/widget/ForgeSlider.java b/src/main/java/net/minecraftforge/client/gui/widget/ForgeSlider.java index 74ea2653ab..5e77bba99c 100644 --- a/src/main/java/net/minecraftforge/client/gui/widget/ForgeSlider.java +++ b/src/main/java/net/minecraftforge/client/gui/widget/ForgeSlider.java @@ -12,10 +12,11 @@ import net.minecraft.client.input.MouseButtonEvent; import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.network.chat.Component; import net.minecraft.util.Mth; -import org.lwjgl.glfw.GLFW; import java.text.DecimalFormat; +import com.mojang.blaze3d.platform.InputConstants; + /** * Slider widget implementation which allows inputting values in a certain range with optional step size. */ @@ -134,8 +135,8 @@ public class ForgeSlider extends AbstractSliderButton { @Override public boolean keyPressed(KeyEvent info) { - boolean flag = info.key() == GLFW.GLFW_KEY_LEFT; - if (flag || info.key() == GLFW.GLFW_KEY_RIGHT) { + boolean flag = info.key() == InputConstants.KEY_LEFT; + if (flag || info.key() == InputConstants.KEY_RIGHT) { if (this.minValue > this.maxValue) flag = !flag; float f = flag ? -1F : 1F; diff --git a/src/main/java/net/minecraftforge/client/loading/ForgeLoadingOverlay.java b/src/main/java/net/minecraftforge/client/loading/ForgeLoadingOverlay.java index 7d9e391434..8b7cdbd783 100644 --- a/src/main/java/net/minecraftforge/client/loading/ForgeLoadingOverlay.java +++ b/src/main/java/net/minecraftforge/client/loading/ForgeLoadingOverlay.java @@ -5,8 +5,9 @@ package net.minecraftforge.client.loading; -import com.mojang.blaze3d.opengl.GlTexture; import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.renderpearl.backend.opengl.GlTexture; + import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.screens.LoadingOverlay; diff --git a/src/main/java/net/minecraftforge/client/loading/NoVizFallback.java b/src/main/java/net/minecraftforge/client/loading/NoVizFallback.java index 3d4a8c0947..ce4991b59f 100644 --- a/src/main/java/net/minecraftforge/client/loading/NoVizFallback.java +++ b/src/main/java/net/minecraftforge/client/loading/NoVizFallback.java @@ -7,26 +7,28 @@ package net.minecraftforge.client.loading; import com.mojang.blaze3d.platform.Monitor; import com.mojang.blaze3d.platform.Window; -import com.mojang.blaze3d.systems.GpuBackend; +import com.mojang.renderpearl.api.device.GpuBackend; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.LoadingOverlay; import net.minecraft.server.packs.resources.ReloadInstance; +import static org.lwjgl.sdl.SDLVideo.SDL_GL_CONTEXT_MAJOR_VERSION; +import static org.lwjgl.sdl.SDLVideo.SDL_GL_CONTEXT_MINOR_VERSION; +import static org.lwjgl.sdl.SDLVideo.SDL_GL_GetAttribute; + import java.util.Optional; import java.util.function.Consumer; import java.util.function.IntConsumer; import java.util.function.LongSupplier; import java.util.function.Supplier; -import org.lwjgl.glfw.GLFW; - public final class NoVizFallback { private static long WINDOW; - public static LongSupplier windowHandoff(int width, int height, String title, long monitor, Supplier backend) { + public static LongSupplier windowHandoff(int width, int height, String title, Supplier backend) { return () -> { try { - return WINDOW = Window.createGlfwWindow(width, height, title, monitor, (GpuBackend)backend.get()); + return WINDOW = Window.createWindowStatic((GpuBackend)backend.get(), width, height, title); } catch (Throwable e) { return sneak(e); } @@ -49,9 +51,13 @@ public final class NoVizFallback { public static String glVersion() { if (WINDOW != 0) { - var maj = GLFW.glfwGetWindowAttrib(WINDOW, GLFW.GLFW_CONTEXT_VERSION_MAJOR); - var min = GLFW.glfwGetWindowAttrib(WINDOW, GLFW.GLFW_CONTEXT_VERSION_MINOR); - return maj+"."+min; + try (var stack = org.lwjgl.system.MemoryStack.stackPush()) { + var majBuf = stack.mallocInt(1); + var minBuf = stack.mallocInt(1); + SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, majBuf); + SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minBuf); + return majBuf.get(0) + "." + minBuf.get(0); + } } else { return "3.2"; } diff --git a/src/main/java/net/minecraftforge/client/model/DynamicFluidContainerModel.java b/src/main/java/net/minecraftforge/client/model/DynamicFluidContainerModel.java index 263c3b71d8..9164933eea 100644 --- a/src/main/java/net/minecraftforge/client/model/DynamicFluidContainerModel.java +++ b/src/main/java/net/minecraftforge/client/model/DynamicFluidContainerModel.java @@ -147,7 +147,7 @@ public class DynamicFluidContainerModel implements UnbakedGeometry { private static MaterialInfo info(final ModelBaker baker, final Material.Baked material, final int tintIndex) { return baker.interner().materialInfo( - MaterialInfo.of(material, material.sprite().transparency(), tintIndex, true, 0) + MaterialInfo.of(material, material.sprite().transparency(), tintIndex, null, 0) ); } diff --git a/src/main/java/net/minecraftforge/client/model/obj/ObjMaterialLibrary.java b/src/main/java/net/minecraftforge/client/model/obj/ObjMaterialLibrary.java index 6625068cdb..065698fbda 100644 --- a/src/main/java/net/minecraftforge/client/model/obj/ObjMaterialLibrary.java +++ b/src/main/java/net/minecraftforge/client/model/obj/ObjMaterialLibrary.java @@ -12,7 +12,6 @@ import java.io.IOException; import java.util.Arrays; import java.util.Map; import java.util.NoSuchElementException; -import java.util.stream.Collectors; /** * An OBJ material library (MTL), composed of named {@link Material materials}. @@ -37,7 +36,7 @@ public class ObjMaterialLibrary { case "newmtl": { - String name = Arrays.asList(Arrays.copyOfRange(line, 1, line.length)).stream().collect(Collectors.joining(" ")); + String name = String.join(" ", Arrays.copyOfRange(line, 1, line.length)); currentMaterial = new Material(name); materials.put(name, currentMaterial); break; diff --git a/src/main/java/net/minecraftforge/client/model/obj/ObjModel.java b/src/main/java/net/minecraftforge/client/model/obj/ObjModel.java index 8f0bbfb95d..173795d691 100644 --- a/src/main/java/net/minecraftforge/client/model/obj/ObjModel.java +++ b/src/main/java/net/minecraftforge/client/model/obj/ObjModel.java @@ -316,9 +316,9 @@ public class ObjModel { if (emissiveAmbient) { int fakeLight = (int) ((ambientColor.x() + ambientColor.y() + ambientColor.z()) * 15 / 3.0f); uv2 = LightCoordsUtil.pack(fakeLight, fakeLight); - quadBaker.setShade(fakeLight == 0 && shadeQuads); + quadBaker.setShade(fakeLight == 0 && shadeQuads ? Direction.UP : null); } else - quadBaker.setShade(shadeQuads); + quadBaker.setShade(shadeQuads ? Direction.UP : null); boolean hasTransform = !transform.isIdentity(); // The incoming transform is referenced on the center of the block, but our coords are referenced on the corner diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/BakedQuadBuilder.java b/src/main/java/net/minecraftforge/client/model/pipeline/BakedQuadBuilder.java index 1c28878184..c8193d3434 100644 --- a/src/main/java/net/minecraftforge/client/model/pipeline/BakedQuadBuilder.java +++ b/src/main/java/net/minecraftforge/client/model/pipeline/BakedQuadBuilder.java @@ -18,6 +18,7 @@ import net.minecraftforge.client.textures.UnitTextureAtlasSprite; import java.util.function.Consumer; import org.joml.Vector3f; +import org.jspecify.annotations.Nullable; /** * Vertex consumer that outputs {@linkplain BakedQuad baked quads}. @@ -36,7 +37,7 @@ public class BakedQuadBuilder implements VertexConsumer { private int tintIndex; private Direction direction = Direction.DOWN; private TextureAtlasSprite sprite = UnitTextureAtlasSprite.INSTANCE; - private boolean shade; + private @Nullable Direction shade; private int lightEmission; public BakedQuadBuilder(Consumer quadConsumer) { @@ -104,6 +105,13 @@ public class BakedQuadBuilder implements VertexConsumer { return this; } + /** Will not actually do anything, vanilla implementations ignore if passed invalid data so we do as well */ + @Override + public VertexConsumer setUv3(float u, float v) { + //throw new IllegalStateException("UV2 is not supported in BakedQuads anymore, you can't bake lighting per vertex anymore"); + return this; + } + private void setup() { this.positions = new Vector3f[]{ new Vector3f(), new Vector3f(), new Vector3f(), new Vector3f() }; this.uvs = new long[4]; @@ -139,7 +147,7 @@ public class BakedQuadBuilder implements VertexConsumer { this.sprite = sprite; } - public void setShade(boolean shade) { + public void setShade(@Nullable Direction shade) { this.shade = shade; } diff --git a/src/main/java/net/minecraftforge/client/model/pipeline/VertexConsumerWrapper.java b/src/main/java/net/minecraftforge/client/model/pipeline/VertexConsumerWrapper.java index 1dc8033b4a..e83e6ac067 100644 --- a/src/main/java/net/minecraftforge/client/model/pipeline/VertexConsumerWrapper.java +++ b/src/main/java/net/minecraftforge/client/model/pipeline/VertexConsumerWrapper.java @@ -55,6 +55,12 @@ public class VertexConsumerWrapper implements VertexConsumer { return this; } + @Override + public VertexConsumer setUv3(float u, float v) { + parent.setUv3(u, v); + return this; + } + @Override public VertexConsumer setNormal(float x, float y, float z) { parent.setNormal(x, y, z); diff --git a/src/main/java/net/minecraftforge/client/model/renderable/CompositeRenderable.java b/src/main/java/net/minecraftforge/client/model/renderable/CompositeRenderable.java index 85d3b0db35..05dd1d006e 100644 --- a/src/main/java/net/minecraftforge/client/model/renderable/CompositeRenderable.java +++ b/src/main/java/net/minecraftforge/client/model/renderable/CompositeRenderable.java @@ -39,13 +39,9 @@ public class CompositeRenderable implements IRenderable children = new ArrayList<>(); - private final List meshes = new ArrayList<>(); - - public Component(String name) { - this.name = name; + private record Component(String name, List children, List meshes) { + private Component(String name) { + this(name, new ArrayList<>(), new ArrayList<>()); } public void render(PoseStack poseStack, ITextureRenderTypeLookup textureRenderTypeLookup, int lightmap, int overlay, Transforms context) { @@ -66,13 +62,12 @@ public class CompositeRenderable implements IRenderable quads = new ArrayList<>(); - private final QuadInstance quadInstance = new QuadInstance(); + private record Mesh(List quads, QuadInstance quadInstance) { +// private final Identifier texture; - public Mesh(Identifier texture) { - this.texture = texture; + private Mesh(Identifier texture) { +// this.texture = texture; + this(new ArrayList<>(), new QuadInstance()); } public void render(PoseStack poseStack, ITextureRenderTypeLookup textureRenderTypeLookup, int lightmap, int overlay) { @@ -85,20 +80,16 @@ public class CompositeRenderable implements IRenderable child(String name) { var child = new Component(name); - renderable.components.add(child); + get.components.add(child); return new PartBuilder<>(this, child); } - - public CompositeRenderable get() { - return renderable; - } } public static class PartBuilder { diff --git a/src/main/java/net/minecraftforge/client/settings/KeyModifier.java b/src/main/java/net/minecraftforge/client/settings/KeyModifier.java index f763315421..33a3d4cbf6 100644 --- a/src/main/java/net/minecraftforge/client/settings/KeyModifier.java +++ b/src/main/java/net/minecraftforge/client/settings/KeyModifier.java @@ -15,7 +15,6 @@ import com.mojang.blaze3d.platform.InputConstants; import net.minecraft.network.chat.Component; import org.jetbrains.annotations.Nullable; -import org.lwjgl.glfw.GLFW; public enum KeyModifier { CONTROL { @@ -40,7 +39,7 @@ public enum KeyModifier { SHIFT { @Override public boolean matches(InputConstants.Key key) { - return key.getValue() == GLFW.GLFW_KEY_LEFT_SHIFT || key.getValue() == GLFW.GLFW_KEY_RIGHT_SHIFT; + return key.getValue() == InputConstants.KEY_LSHIFT || key.getValue() == InputConstants.KEY_RSHIFT; } @Override @@ -56,7 +55,7 @@ public enum KeyModifier { ALT { @Override public boolean matches(InputConstants.Key key) { - return key.getValue() == GLFW.GLFW_KEY_LEFT_ALT || key.getValue() == GLFW.GLFW_KEY_RIGHT_ALT; + return key.getValue() == InputConstants.KEY_LALT || key.getValue() == InputConstants.KEY_RALT; } @Override diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index b6bb7bee81..3be6643690 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -35,7 +35,6 @@ import com.mojang.serialization.Decoder; import com.mojang.serialization.DynamicOps; import com.mojang.serialization.JsonOps; import com.mojang.serialization.Lifecycle; - import io.netty.handler.codec.DecoderException; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.commands.CommandSourceStack; @@ -68,6 +67,7 @@ import net.minecraft.tags.TagKey; import net.minecraft.util.CrudeIncrementalIntIdentityHashBiMap; import net.minecraft.util.GsonHelper; import net.minecraft.util.Mth; +import net.minecraft.util.Prediction; import net.minecraft.util.datafix.fixes.StructuresBecomeConfiguredFix; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; @@ -91,7 +91,6 @@ import net.minecraft.world.level.material.Fluids; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.WorldData; import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.LootDataType; import net.minecraft.world.level.storage.loot.LootPool; import net.minecraft.world.level.storage.loot.LootTable; import net.minecraft.world.level.block.state.BlockState; @@ -133,8 +132,8 @@ import net.minecraftforge.event.BuildCreativeModeTabContentsEvent; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.event.GrindstoneEvent; import net.minecraftforge.event.ModMismatchEvent; -import net.minecraftforge.event.ServerChatEvent; import net.minecraftforge.event.RegisterStructureConversionsEvent; +import net.minecraftforge.event.ServerChatEvent; import net.minecraftforge.event.entity.EntityAttributeCreationEvent; import net.minecraftforge.event.entity.EntityAttributeModificationEvent; import net.minecraftforge.event.entity.item.ItemTossEvent; @@ -168,11 +167,11 @@ import net.minecraftforge.network.NetworkDirection; import net.minecraftforge.network.NetworkInitialization; import net.minecraftforge.network.NetworkRegistry; import net.minecraftforge.network.packets.SpawnEntity; -import net.minecraftforge.resource.ResourcePackLoader; import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistry; import net.minecraftforge.registries.GameData; import net.minecraftforge.registries.RegistryManager; +import net.minecraftforge.resource.ResourcePackLoader; import net.minecraftforge.server.permission.PermissionAPI; import org.apache.logging.log4j.LogManager; @@ -307,9 +306,12 @@ public final class ForgeHooks { @SuppressWarnings("resource") @Nullable - public static ItemEntity onPlayerTossEvent(@NotNull Player player, @NotNull ItemStack item, boolean includeName) { + public static ItemEntity onPlayerTossEvent(@NotNull Player player, @NotNull ItemStack item, boolean thrownFromHand, Prediction prediction) { + if (item.isEmpty()) + return null; + player.captureDrops(new ArrayList<>()); - ItemEntity ret = player.drop(item, false, includeName); + ItemEntity ret = player.drop(item, thrownFromHand, prediction); player.captureDrops(null); if (ret == null) @@ -1213,7 +1215,7 @@ public final class ForgeHooks { buf.writeVarInt(-1); // Our Marker buf.writeIdentifier(key); } - serializer.write(buf, value); + serializer.streamCodec().encode(buf, value); }, (buf) -> { buf.markReaderIndex(); @@ -1227,7 +1229,7 @@ public final class ForgeHooks { if (serializer == null) throw new DecoderException("Could not read ingredient of type: " + key); } - return serializer.read(buf); + return serializer.streamCodec().decode(buf); } ); } @@ -1254,7 +1256,7 @@ public final class ForgeHooks { @SuppressWarnings("unchecked") public static T onJsonDataParsed(Codec codec, Identifier key, T value) { - if (codec == LootDataType.TABLE.codec()) { + if (codec == LootTable.DIRECT_CODEC) { var table = (LootTable)value; table.setLootTableId(key); value = (T)net.minecraftforge.event.ForgeEventFactory.onLoadLootTable(key, table); diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java index cf0b5a8dd0..74964bdf73 100644 --- a/src/main/java/net/minecraftforge/common/ForgeMod.java +++ b/src/main/java/net/minecraftforge/common/ForgeMod.java @@ -36,6 +36,7 @@ import net.minecraft.sounds.SoundEvent; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.pathfinder.PathType; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import net.minecraft.world.level.storage.loot.predicates.LootPredicates; import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.ForgeAtlasProvider; @@ -47,9 +48,9 @@ import net.minecraftforge.common.data.ForgeEnchantmentTagsProvider; import net.minecraftforge.common.data.ForgeEntityTypeTagsProvider; import net.minecraftforge.common.data.ForgeFluidTagsProvider; import net.minecraftforge.common.data.ForgeItemTagsProvider; -import net.minecraftforge.common.data.ForgeLootTableProvider; import net.minecraftforge.common.data.ForgeRecipeProvider; import net.minecraftforge.common.data.ForgeStructureTagsProvider; +import net.minecraftforge.common.data.RegistryDataBuilder; import net.minecraftforge.common.data.VanillaSoundDefinitionsProvider; import net.minecraftforge.common.loot.CanToolPerformAction; import net.minecraftforge.common.loot.LootTableIdCondition; @@ -428,6 +429,16 @@ public class ForgeMod { PackOutput packOutput = gen.getPackOutput(); CompletableFuture lookupProvider = event.getLookupProvider(); + var dataLayers = RegistryDataBuilder.of() + .name("forge") + .reloadable(set -> set + .add(Registries.PREDICATE, ctx -> + // Replace vanilla's MatchTool(shears) -> CanToolPerformAction(SHEARS_DIG) + ctx.register(LootPredicates.TOOL_CAN_SHEAR, CanToolPerformAction.canToolPerformAction(ToolActions.SHEARS_DIG).build()) + ) + .add(ForgeRecipeProvider.create()) + ); + ExistingFileHelper existingFileHelper = event.getExistingFileHelper(); gen.addProvider(true, new PackMetadataGenerator(packOutput) .add(PackMetadataSection.SERVER_TYPE, new PackMetadataSection( @@ -441,8 +452,7 @@ public class ForgeMod { gen.addProvider(event.includeServer(), new ForgeEntityTypeTagsProvider(packOutput, lookupProvider, existingFileHelper)); gen.addProvider(event.includeServer(), new ForgeFluidTagsProvider(packOutput, lookupProvider, existingFileHelper)); gen.addProvider(event.includeServer(), new ForgeEnchantmentTagsProvider(packOutput, lookupProvider, existingFileHelper)); - gen.addProvider(event.includeServer(), new ForgeRecipeProvider.Runner(packOutput, lookupProvider)); - gen.addProvider(event.includeServer(), new ForgeLootTableProvider(packOutput, lookupProvider)); + gen.addProvider(event.includeServer(), dataLayers.reloadableGenerator(packOutput)); gen.addProvider(event.includeServer(), new ForgeBiomeTagsProvider(packOutput, lookupProvider, existingFileHelper)); gen.addProvider(event.includeServer(), new ForgeStructureTagsProvider(packOutput, lookupProvider, existingFileHelper)); diff --git a/src/main/java/net/minecraftforge/common/Tags.java b/src/main/java/net/minecraftforge/common/Tags.java index 7977a14959..48fd055190 100644 --- a/src/main/java/net/minecraftforge/common/Tags.java +++ b/src/main/java/net/minecraftforge/common/Tags.java @@ -16,7 +16,6 @@ import net.minecraft.tags.TagKey; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.decoration.ItemFrame; -import net.minecraft.world.entity.monster.EnderMan; import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemUseAnimation; @@ -269,9 +268,6 @@ public class Tags { * This is patched into the following method: {@link EnderMan.EndermanLeaveBlockGoal#canPlaceBlock(Level, BlockPos, BlockState, BlockState, BlockState, BlockPos)} */ public static final TagKey ENDERMAN_PLACE_ON_BLACKLIST = forgeTag("enderman_place_on_blacklist"); - public static final TagKey NEEDS_WOOD_TOOL = forgeTag("needs_wood_tool"); - public static final TagKey NEEDS_GOLD_TOOL = forgeTag("needs_gold_tool"); - public static final TagKey NEEDS_NETHERITE_TOOL = forgeTag("needs_netherite_tool"); public static final TagKey STORAGE_BLOCKS_AMETHYST = BlockItems.STORAGE_BLOCKS_AMETHYST.block(); public static final TagKey STORAGE_BLOCKS_QUARTZ = BlockItems.STORAGE_BLOCKS_QUARTZ.block(); //endregion @@ -1224,10 +1220,6 @@ public class Tags { private static TagKey cTag(String name) { return FluidTags.create(Identifier.fromNamespaceAndPath("c", name)); } - - private static TagKey forgeTag(String name) { - return FluidTags.create(Identifier.fromNamespaceAndPath("forge", name)); - } } public static class Enchantments { @@ -1513,10 +1505,6 @@ public class Tags { private static TagKey cTag(String name) { return TagKey.create(Registries.BIOME, Identifier.fromNamespaceAndPath("c", name)); } - - private static TagKey forgeTag(String name) { - return TagKey.create(Registries.BIOME, Identifier.fromNamespaceAndPath("forge", name)); - } } public static class Structures { diff --git a/src/main/java/net/minecraftforge/common/ToolActions.java b/src/main/java/net/minecraftforge/common/ToolActions.java index bc2e420bcf..cf9297909f 100644 --- a/src/main/java/net/minecraftforge/common/ToolActions.java +++ b/src/main/java/net/minecraftforge/common/ToolActions.java @@ -6,65 +6,19 @@ package net.minecraftforge.common; import com.google.common.collect.Sets; -import net.minecraftforge.common.extensions.IForgeBlock; import net.minecraftforge.common.extensions.IForgeItem; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -public class ToolActions -{ - /** - * Exposed by axes to allow querying tool behaviours - */ - public static final ToolAction AXE_DIG = ToolAction.get("axe_dig"); - - /** - * Exposed by pickaxes to allow querying tool behaviours - */ - public static final ToolAction PICKAXE_DIG = ToolAction.get("pickaxe_dig"); - - /** - * Exposed by shovels to allow querying tool behaviours - */ - public static final ToolAction SHOVEL_DIG = ToolAction.get("shovel_dig"); - - /** - * Exposed by hoes to allow querying tool behaviours - */ - public static final ToolAction HOE_DIG = ToolAction.get("hoe_dig"); - - /** - * Exposed by swords to allow querying tool behaviours - */ - public static final ToolAction SWORD_DIG = ToolAction.get("sword_dig"); +public class ToolActions { /** * Exposed by shears to allow querying tool behaviours */ public static final ToolAction SHEARS_DIG = ToolAction.get("shears_dig"); - /** - * Passed onto {@link IForgeBlock#getToolModifiedState} when an axe wants to strip a log - */ - public static final ToolAction AXE_STRIP = ToolAction.get("axe_strip"); - - /** - * Passed onto {@link IForgeBlock#getToolModifiedState} when an axe wants to scrape oxidization off copper - */ - public static final ToolAction AXE_SCRAPE = ToolAction.get("axe_scrape"); - - /** - * Passed onto {@link IForgeBlock#getToolModifiedState} when an axe wants to remove wax out of copper - */ - public static final ToolAction AXE_WAX_OFF = ToolAction.get("axe_wax_off"); - - /** - * Passed onto {@link IForgeBlock#getToolModifiedState} when a shovel wants to turn dirt into path - */ - public static final ToolAction SHOVEL_FLATTEN = ToolAction.get("shovel_flatten"); - /** * Used during player attack to figure out if a sweep attack should be performed * @@ -90,24 +44,12 @@ public class ToolActions */ public static final ToolAction SHEARS_DISARM = ToolAction.get("shears_disarm"); - /** - * Passed onto {@link IForgeBlock#getToolModifiedState} when a hoe wants to turn dirt into soil - */ - public static final ToolAction HOE_TILL = ToolAction.get("till"); - /** * This action corresponds to right-clicking the fishing rod. */ public static final ToolAction FISHING_ROD_CAST = ToolAction.get("fishing_rod_cast"); // Default actions supported by each tool type - public static final Set DEFAULT_AXE_ACTIONS = of(AXE_DIG, AXE_STRIP, AXE_SCRAPE, AXE_WAX_OFF); - public static final Set DEFAULT_HOE_ACTIONS = of(HOE_DIG, HOE_TILL); - public static final Set DEFAULT_SHOVEL_ACTIONS = of(SHOVEL_DIG, SHOVEL_FLATTEN); - @Deprecated(since = "1.21.5") - public static final Set DEFAULT_PICKAXE_ACTIONS = of(PICKAXE_DIG); - @Deprecated(since = "1.21.5") - public static final Set DEFAULT_SWORD_ACTIONS = of(SWORD_DIG, SWORD_SWEEP); public static final Set DEFAULT_SHEARS_ACTIONS = of(SHEARS_DIG, SHEARS_HARVEST, SHEARS_CARVE, SHEARS_DISARM); public static final Set DEFAULT_FISHING_ROD_ACTIONS = of(FISHING_ROD_CAST); diff --git a/src/main/java/net/minecraftforge/common/brewing/BrewingRecipe.java b/src/main/java/net/minecraftforge/common/brewing/BrewingRecipe.java deleted file mode 100644 index 9beae4e873..0000000000 --- a/src/main/java/net/minecraftforge/common/brewing/BrewingRecipe.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.common.brewing; - -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Ingredient; -import org.jetbrains.annotations.NotNull; - -public class BrewingRecipe implements IBrewingRecipe { - @NotNull private final Ingredient input; - @NotNull private final Ingredient ingredient; - @NotNull private final ItemStack output; - - public BrewingRecipe(Ingredient input, Ingredient ingredient, ItemStack output) { - this.input = input; - this.ingredient = ingredient; - this.output = output; - } - - @Override - public boolean isInput(@NotNull ItemStack stack) { - return this.input.test(stack); - } - - @Override - public ItemStack getOutput(ItemStack input, ItemStack ingredient) { - return isInput(input) && isIngredient(ingredient) ? getOutput().copy() : ItemStack.EMPTY; - } - - public Ingredient getInput() { - return input; - } - - public Ingredient getIngredient() { - return ingredient; - } - - public ItemStack getOutput() { - return output; - } - - @Override - public boolean isIngredient(ItemStack ingredient) { - return this.ingredient.test(ingredient); - } -} diff --git a/src/main/java/net/minecraftforge/common/brewing/BrewingRecipeRegistry.java b/src/main/java/net/minecraftforge/common/brewing/BrewingRecipeRegistry.java deleted file mode 100644 index 3883adde5f..0000000000 --- a/src/main/java/net/minecraftforge/common/brewing/BrewingRecipeRegistry.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.common.brewing; - -/* -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.core.NonNullList; - -public class BrewingRecipeRegistry { - - /** - * Returns the output ItemStack obtained by brewing the passed input and - * ingredient. - * / - public static ItemStack getOutput(ItemStack input, ItemStack ingredient) { - if (input.isEmpty() || input.getCount() != 1) return ItemStack.EMPTY; - if (ingredient.isEmpty()) return ItemStack.EMPTY; - - for (IBrewingRecipe recipe : recipes) { - ItemStack output = recipe.getOutput(input, ingredient); - if (!output.isEmpty()) { - return output; - } - } - return ItemStack.EMPTY; - } - - /** - * Returns true if the passed input and ingredient have an output - * / - public static boolean hasOutput(ItemStack input, ItemStack ingredient) { - return !getOutput(input, ingredient).isEmpty(); - } - - /** - * Used by the brewing stand to determine if its contents can be brewed. - * Extra parameters exist to allow modders to create bigger brewing stands - * without much hassle - * / - public static boolean canBrew(NonNullList inputs, ItemStack ingredient, int[] inputIndexes) { - if (ingredient.isEmpty()) return false; - - for (int i : inputIndexes) { - if (hasOutput(inputs.get(i), ingredient)) { - return true; - } - } - - return false; - } - - /** - * Used by the brewing stand to brew its inventory Extra parameters exist to - * allow modders to create bigger brewing stands without much hassle - * / - public static void brewPotions(NonNullList inputs, ItemStack ingredient, int[] inputIndexes) { - for (int i : inputIndexes) { - ItemStack output = getOutput(inputs.get(i), ingredient); - if (!output.isEmpty()) { - inputs.set(i, output); - } - } - } -} -*/ diff --git a/src/main/java/net/minecraftforge/common/brewing/IBrewingRecipe.java b/src/main/java/net/minecraftforge/common/brewing/IBrewingRecipe.java deleted file mode 100644 index 131e7ec283..0000000000 --- a/src/main/java/net/minecraftforge/common/brewing/IBrewingRecipe.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.common.brewing; - -import net.minecraft.world.item.ItemStack; - -public interface IBrewingRecipe { - - /** - * Returns true is the passed ItemStack is an input for this recipe. "Input" - * being the item that goes in one of the three bottom slots of the brewing - * stand (e.g: water bottle) - */ - boolean isInput(ItemStack input); - - /** - * Returns true if the passed ItemStack is an ingredient for this recipe. - * "Ingredient" being the item that goes in the top slot of the brewing - * stand (e.g: nether wart) - */ - boolean isIngredient(ItemStack ingredient); - - /** - * Returns the output when the passed input is brewed with the passed - * ingredient. Empty if invalid input or ingredient. - */ - ItemStack getOutput(ItemStack input, ItemStack ingredient); -} diff --git a/src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java b/src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java deleted file mode 100644 index d07e60e58a..0000000000 --- a/src/main/java/net/minecraftforge/common/brewing/VanillaBrewingRecipe.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.common.brewing; - -import java.util.function.BiFunction; - -import net.minecraft.world.inventory.BrewingStandMenu; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.alchemy.PotionBrewing; - -/** - * Used in BrewingRecipeRegistry to maintain the vanilla behaviour. - * - * Most of the code was simply adapted from net.minecraft.tileentity.TileEntityBrewingStand - */ -public class VanillaBrewingRecipe implements IBrewingRecipe { - private final PotionBrewing vanilla; - private final BiFunction vanillaMix; - - public VanillaBrewingRecipe(PotionBrewing vanilla, BiFunction vanillaMix) { - this.vanilla = vanilla; - this.vanillaMix = vanillaMix; - } - - /** - * Code adapted from TileEntityBrewingStand.isItemValidForSlot(int index, ItemStack stack) - */ - @Override - public boolean isInput(ItemStack stack) { - return BrewingStandMenu.PotionSlot.mayPlaceItem(stack); - } - - /** - * Code adapted from TileEntityBrewingStand.isItemValidForSlot(int index, ItemStack stack) - */ - @Override - public boolean isIngredient(ItemStack stack) { - return vanilla.isContainerIngredient(stack) || vanilla.isPotionIngredient(stack); - } - - /** - * Code copied from TileEntityBrewingStand.brewPotions() - * It brews the potion by doing the bit-shifting magic and then checking if the new PotionEffect list is different to the old one, - * or if the new potion is a splash potion when the old one wasn't. - */ - @Override - public ItemStack getOutput(ItemStack input, ItemStack ingredient) { - if (!input.isEmpty() && !ingredient.isEmpty() && isIngredient(ingredient)) { - ItemStack result = vanillaMix.apply(ingredient, input); - if (result != input) { - return result; - } - return ItemStack.EMPTY; - } - - return ItemStack.EMPTY; - } -} diff --git a/src/main/java/net/minecraftforge/common/brewing/package-info.java b/src/main/java/net/minecraftforge/common/brewing/package-info.java deleted file mode 100644 index 9e3d98f4bd..0000000000 --- a/src/main/java/net/minecraftforge/common/brewing/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -@NullMarked -package net.minecraftforge.common.brewing; - -import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/net/minecraftforge/common/crafting/ConditionalAdvancement.java b/src/main/java/net/minecraftforge/common/crafting/ConditionalAdvancement.java index fc3240f28c..65c3eade50 100644 --- a/src/main/java/net/minecraftforge/common/crafting/ConditionalAdvancement.java +++ b/src/main/java/net/minecraftforge/common/crafting/ConditionalAdvancement.java @@ -7,20 +7,30 @@ package net.minecraftforge.common.crafting; import java.util.ArrayList; import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.mojang.serialization.JsonOps; +import java.util.stream.Stream; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.DynamicOps; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.MapDecoder; +import com.mojang.serialization.MapEncoder; +import com.mojang.serialization.MapLike; +import com.mojang.serialization.RecordBuilder; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementHolder; -import net.minecraft.core.HolderLookup; import net.minecraft.resources.Identifier; -import net.minecraftforge.common.ForgeHooks; +import net.minecraftforge.common.crafting.conditions.ConditionCodec; import net.minecraftforge.common.crafting.conditions.ICondition; /** - * A `ConditionalAdvancement` is a single advancment file that contains multiple advancements, each having a condition. + * A `ConditionalAdvancement` is a single advancement file that contains multiple advancements, each having a condition. * When loaded it will return the first advancement that the conditions pass. * * This allows for multiple variants of an advancement to share the same name in the registry. Which allows dependents @@ -29,7 +39,7 @@ import net.minecraftforge.common.crafting.conditions.ICondition; * This is most likely useful when you have variants of a recipe based on what mods/resources are installed but want * to maintain the same 'entry' in the advancement book. */ -public class ConditionalAdvancement { +public record ConditionalAdvancement(ICondition condition, Optional child) { public static Builder builder() { return new Builder(); } @@ -37,7 +47,7 @@ public class ConditionalAdvancement { public static class Builder { private static final Identifier DOESNT_MATTER = Identifier.fromNamespaceAndPath("doesnt", "matter"); - private List advancements = new ArrayList<>(); + private List advancements = new ArrayList<>(); private ICondition condition; public Builder condition(ICondition value) { @@ -58,50 +68,132 @@ public class ConditionalAdvancement { return advancement(holder.value()); } - public Builder advancement(JsonObject value) { - return advancement(null, value); - } - private Builder advancement(Advancement value) { - return advancement(value, null); - } - - private Builder advancement(Advancement value, JsonObject json) { if (condition == null) throw new IllegalStateException("Can not add a advancement with no conditions."); if (value == null) throw new IllegalStateException("Can not add a null advancement"); - this.advancements.add(new Adv(this.condition, value, json)); + this.advancements.add(new ConditionalAdvancement(this.condition, Optional.of(value))); this.condition = null; return this; } - public JsonObject build(HolderLookup.Provider lookup) { - var json = new JsonObject(); - var array = new JsonArray(); - json.add("forge:conditional", array); + public AdvancementHolder build(final Identifier id) { + if (this.advancements.isEmpty()) + throw new IllegalStateException("Can not build an empty ConditionalAdvancement"); - var ops = lookup.createSerializationContext(JsonOps.INSTANCE); - - for (var pair : advancements) { - JsonObject holder = null; - if (pair.json != null) - holder = pair.json; - else - holder = (JsonObject)Advancement.CODEC.encodeStart(ops, pair.adv()).getOrThrow(IllegalStateException::new); - - if (holder.has(ICondition.DEFAULT_FIELD)) - throw new IllegalStateException("Recipe already serialized conditions!"); - ForgeHooks.writeCondition(pair.condition(), holder); - - array.add(holder); + var list = new ArrayList(); + Advancement root = null; + for (var child : advancements) { + if (root == null) { + var adv = child.child.get(); + root = new Advancement( + adv.parent(), + adv.display(), + adv.rewards(), + adv.criteria(), + adv.requirements(), + adv.sendsTelemetryEvent(), + adv.name(), + Optional.of(list) + ); + list.add(new ConditionalAdvancement(child.condition, Optional.empty())); + } else { + list.add(child); + } } - return json; + + return new AdvancementHolder(id, root); } } - private record Adv(ICondition condition, Advancement adv, JsonObject json) {} + + + private static final String KEY = "forge:children"; + public static final Codec wrapCodec(MapCodec vanilla) { + var vanillaCodec = vanilla.codec(); + var childCodec = RecordCodecBuilder.create(i -> i.group( + ICondition.SAFE_CODEC.fieldOf(ICondition.DEFAULT_FIELD).forGetter(ConditionalAdvancement::condition), + vanillaCodec.optionalFieldOf("child").forGetter(ConditionalAdvancement::child) + ).apply(i, ConditionalAdvancement::new)).listOf(); + + return Codec.of(new MapEncoder.Implementation() { + @Override + public RecordBuilder encode(Advancement input, DynamicOps ops, RecordBuilder prefix) { + var root = vanilla.encode(input, ops, prefix); + if (!input.forgeConditions().isPresent()) + return root; + + var children = input.forgeConditions().get(); + if (children.isEmpty()) + return root; + + if (children.size() != 1) + root.add(KEY, childCodec.encodeStart(ops, children)); + + var outerCondition = ConditionalRecipe.aggregate(null, children, ConditionalAdvancement::condition); + if (outerCondition != null) + root.add(ICondition.DEFAULT_FIELD, ICondition.CODEC.encodeStart(ops, outerCondition)); + + return root; + } + + @Override + public Stream keys(DynamicOps ops) { + return Stream.concat(vanilla.keys(ops), List.of(ops.createString(KEY)).stream()); + } + }, new MapDecoder.Implementation() { + @Override + public DataResult decode(DynamicOps ops, MapLike input) { + var root = vanilla.decode(ops, input); + var children = input.get(KEY); + if (children == null) + return root; + + var context = ConditionCodec.getContext(ops); + return ops.getStream(children).flatMap(stream -> { + var count = new AtomicInteger(); + var ret = stream.map(entry -> accept(context, ops, count, entry, root)) + .filter(Objects::nonNull) + .findFirst() + .orElse(null); + + if (ret != null) + return ret; + + return DataResult.error(() -> "No advancement passed conditions, if this is the case, you should have an outer condition."); + }); + } + + private DataResult accept(ICondition.IContext context, DynamicOps ops, AtomicInteger count, T entry, DataResult root) { + count.getAndIncrement(); + var map = ops.getMap(entry).result().orElse(null); + if (map == null) + return DataResult.error(() -> "Entry " + count.get() + " was not MapLike " + entry.getClass()); + + if (map.get(ICondition.DEFAULT_FIELD) != null) { + var parsed = ICondition.SAFE_CODEC.parse(ops, (T)map.get(ICondition.DEFAULT_FIELD)); + if (parsed.result().isPresent()) { + var condition = parsed.result().get(); + if (!condition.test(context, ops)) + return null; + } + } + + var child = map.get("child"); + if (child != null) + return vanillaCodec.parse(ops, (T)child); + return root; + } + + @Override + public Stream keys(DynamicOps ops) { + return Stream.concat(vanilla.keys(ops), List.of(ops.createString(KEY)).stream()); + } + }).codec(); + } + } diff --git a/src/main/java/net/minecraftforge/common/crafting/ConditionalRecipe.java b/src/main/java/net/minecraftforge/common/crafting/ConditionalRecipe.java index 20cedb7996..eb995197bc 100644 --- a/src/main/java/net/minecraftforge/common/crafting/ConditionalRecipe.java +++ b/src/main/java/net/minecraftforge/common/crafting/ConditionalRecipe.java @@ -8,16 +8,15 @@ package net.minecraftforge.common.crafting; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.function.Consumer; +import java.util.function.Function; import java.util.stream.Stream; -import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.DynamicOps; -import com.mojang.serialization.JsonOps; import com.mojang.serialization.MapCodec; import com.mojang.serialization.MapDecoder; import com.mojang.serialization.MapEncoder; @@ -26,25 +25,30 @@ import com.mojang.serialization.RecordBuilder; import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementHolder; -import net.minecraft.core.HolderLookup.Provider; +import net.minecraft.core.Holder.Reference; +import net.minecraft.core.HolderGetter; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; -import net.minecraft.data.recipes.RecipeBuilder; +import net.minecraft.data.recipes.RecipeCategory; import net.minecraft.data.recipes.RecipeOutput; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.CraftingInput; import net.minecraft.world.item.crafting.PlacementInfo; import net.minecraft.world.item.crafting.Recipe; -import net.minecraft.world.item.crafting.RecipeBookCategories; import net.minecraft.world.item.crafting.RecipeBookCategory; +import net.minecraft.world.item.crafting.RecipeInput; import net.minecraft.world.item.crafting.RecipeSerializer; import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.level.Level; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.Identifier; import net.minecraftforge.common.crafting.conditions.ConditionCodec; import net.minecraftforge.common.crafting.conditions.ICondition; import net.minecraftforge.common.crafting.conditions.ICondition.IContext; +import net.minecraftforge.common.crafting.conditions.OrCondition; +import net.minecraftforge.common.crafting.conditions.TrueCondition; import org.jetbrains.annotations.Nullable; /** @@ -58,53 +62,40 @@ import org.jetbrains.annotations.Nullable; * This also means that you can wrap ALL recipes in a Conditional even those that don't explicitly * have support for them in their data gen. */ -public class ConditionalRecipe { - public static Builder builder() { - return new Builder(); +public class ConditionalRecipe implements Recipe { + public static Builder builder(RecipeOutput output) { + return new Builder(output); + } + + private final @Nullable ICondition mainCondition; + private final List children; + private final Recipe first; + + @SuppressWarnings("unchecked") + private ConditionalRecipe(@Nullable ICondition mainCondition, List children) { + this.mainCondition = mainCondition; + this.children = children; + this.first = (Recipe)children.getFirst().recipe(); } public static class Builder { private final List recipes = new ArrayList<>(); private final List advancements = new ArrayList<>(); + private final Bouncer bouncer; - private final RecipeOutput bouncer = new RecipeOutput() { - @Override - public void accept(ResourceKey> id, Recipe value, @Nullable AdvancementHolder advancement) { - recipe(id, value, advancement); - } + @Nullable private ICondition condition; + @Nullable private ICondition mainCondition; + @Nullable private Identifier advancementId; + @Nullable private RecipeCategory category = null; - @SuppressWarnings("removal") - @Override - public Advancement.Builder advancement() { - return Advancement.Builder.recipeAdvancement().parent(RecipeBuilder.ROOT_RECIPE_ADVANCEMENT); - } + private Builder(RecipeOutput output) { + this.bouncer = new Bouncer(output, this); + } - @Override - public void accept(ResourceKey> id, Recipe recipe, Identifier advancementId, JsonElement advancement) { - AdvancementHolder holder = null; - if (advancement != null) { - Advancement adv = Advancement.CODEC.parse(JsonOps.INSTANCE, advancement).getOrThrow(JsonParseException::new); - holder = new AdvancementHolder(advancementId, adv); - } - accept(id, recipe, holder); - } - - @Override - public Provider registry() { - return null; - } - - @Override - public void includeRootAdvancement() { } - }; - - @Nullable - private ICondition condition; - @Nullable - private ICondition mainCondition; - - @Nullable - private Identifier advancementId; + public Builder category(RecipeCategory category) { + this.category = category; + return this; + } public Builder mainCondition(ICondition value) { if (this.mainCondition != null) @@ -151,81 +142,94 @@ public class ConditionalRecipe { if (recipes.isEmpty()) throw new IllegalStateException("Invalid ConditionalRecipe builder, No recipes"); - JsonElement advancement = null; + AdvancementHolder advancement = null; if (!advancements.isEmpty()) { var adv = ConditionalAdvancement.builder(); for (var data : advancements) { adv.condition(data.condition()); - if (data.json != null) - adv.advancement(data.json()); - else - adv.advancement(data.advancement()); + adv.advancement(data.advancement()); } - if (advancementId == null) - advancementId = id.withPrefix("recipes/"); - advancement = adv.build(out.registry()); - } else { - advancementId = null; + if (advancementId == null) { + if (this.category == null) + advancementId = id.withPrefix("recipes/"); + else + advancementId = id.withPrefix("recipes/" + category.getFolderName() + '/'); + } + advancement = adv.build(advancementId); } - var key = ResourceKey.create(Registries.RECIPE, id); - out.accept(key, new Wrapper(mainCondition, recipes), advancementId, advancement); + out.accept(ResourceKey.create(Registries.RECIPE, id), new ConditionalRecipe(mainCondition, recipes), advancement); + } + + private record Bouncer(RecipeOutput wrapped, Builder builder) implements RecipeOutput { + @Override + public void accept(ResourceKey> id, Recipe value, @Nullable AdvancementHolder advancement) { + builder.recipe(id, value, advancement); + } + + @Override + public Advancement.Builder advancement() { + return wrapped.advancement(); + } + + @Override + public HolderGetter lookup(ResourceKey> key) { + return wrapped.lookup(key); + } + + @SuppressWarnings("deprecation") + @Override + public Stream> listContextElements(ResourceKey> key) { + return wrapped.listContextElements(key); + } + + @Override + public Optional> registryLookup(ResourceKey> registry) { + return wrapped.registryLookup(registry); + } } } private record InnerRecipe(ICondition condition, Recipe recipe) {} private record InnerAdvancement(ICondition condition, AdvancementHolder advancement, JsonObject json) {} - private static class Wrapper implements Recipe { - @Override public boolean matches(CraftingInput inv, Level level) { return false; } - @Override public ItemStack assemble(CraftingInput inv) { return null; } - @Override public boolean showNotification() { return false; } - @Override public String group() { return "ungrouped wrapper"; } + // In order to not error during data loading when all elements are filtered out, we need to add an outer condition so we can read it from the top level + static @Nullable ICondition aggregate(@Nullable ICondition main, List conditionals, Function getter) { + if (main != null) + return main; + if (conditionals.isEmpty()) + return null; + if (conditionals.size() == 1) + return getter.apply(conditionals.getFirst()); - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public RecipeSerializer> getSerializer() { - return (RecipeSerializer)ConditionalRecipe.SERIALZIER; + var list = new ArrayList(conditionals.size()); + for (var entry : conditionals) { + var condition = getter.apply(entry); + if (condition == null || condition == TrueCondition.INSTANCE) + return null; + list.add(condition); } - - @Override public RecipeType> getType() { throw new UnsupportedOperationException(); } - - @Nullable private final ICondition main; - private final List recipes; - private Wrapper(@Nullable ICondition main, List recipes) { - this.main = main; - this.recipes = recipes; - } - - @Override - public PlacementInfo placementInfo() { - return PlacementInfo.NOT_PLACEABLE; - } - - @Override - public RecipeBookCategory recipeBookCategory() { - return RecipeBookCategories.STONECUTTER; - } - + return new OrCondition(list); } + private static final MapCodec> CODEC = Codec.of(new MapEncoder.Implementation<>() { @Override public RecordBuilder encode(Recipe input, DynamicOps ops, RecordBuilder prefix) { - if (!(input instanceof Wrapper)) - new IllegalStateException("ConditionalRecipe.CODEC can only be used during data gen, how did you get here?"); - Wrapper wrapper = (Wrapper)input; + if (!(input instanceof ConditionalRecipe)) + new IllegalStateException("ConditionalRecipe.CODEC can only be used for ConditionRecipes, how did you get here?"); - if (wrapper.main != null) - prefix.add(ICondition.DEFAULT_FIELD, ICondition.CODEC.encodeStart(ops, wrapper.main)); - else if (wrapper.recipes.size() == 1) - prefix.add(ICondition.DEFAULT_FIELD, ICondition.CODEC.encodeStart(ops, wrapper.recipes.get(0).condition())); + var wrapper = (ConditionalRecipe)input; + + var outerCondition = aggregate(wrapper.mainCondition, wrapper.children, InnerRecipe::condition); + if (outerCondition != null) + prefix.add(ICondition.DEFAULT_FIELD, ICondition.CODEC.encodeStart(ops, outerCondition)); var recipes = ops.listBuilder(); - for (var recipe : wrapper.recipes) { + for (var recipe : wrapper.children) { var map = ops.mapBuilder(); - if (wrapper.main != null || wrapper.recipes.size() != 1) + if (wrapper.mainCondition != null || wrapper.children.size() != 1) map.add(ICondition.DEFAULT_FIELD, recipe.condition(), ICondition.CODEC); - map.add("recipe", recipe.recipe(), Recipe.CODEC); + map.add("recipe", recipe.recipe(), Recipe.DIRECT_CODEC); recipes.add(map.build(ops.emptyMap())); } prefix.add("recipes", recipes.build(ops.emptyList())); @@ -274,7 +278,7 @@ public class ConditionalRecipe { if (recipe == null) return DataResult.error(() -> "Missing `recipe` entry " + count.value); - var ret = Recipe.CODEC.parse(ops, (T)recipe); + var ret = Recipe.DIRECT_CODEC.parse(ops, (T)recipe); return ret; } @@ -284,14 +288,61 @@ public class ConditionalRecipe { } }); - public static final RecipeSerializer> SERIALZIER = new RecipeSerializer>(CODEC, - StreamCodec.of( - (_, _) -> new UnsupportedOperationException("ConditionaRecipe.SERIALIZER does not support encoding to network"), - _ -> { throw new UnsupportedOperationException("ConditionaRecipe.SERIALIZER does not support encoding to network"); } - ) + private static final StreamCodec STREAM_CODEC = StreamCodec.of( + (_, _) -> new UnsupportedOperationException("ConditionaRecipe.SERIALIZER does not support encoding to network"), + _ -> { throw new UnsupportedOperationException("ConditionaRecipe.SERIALIZER does not support encoding to network"); } ); + @SuppressWarnings({ "unchecked", "rawtypes" }) + private static MapCodec typedCodec() { + return (MapCodec)(MapCodec)CODEC; + } + public static final RecipeSerializer SERIALZIER = new RecipeSerializer<>(typedCodec(), STREAM_CODEC); + private static final class Holder { private T value; } + + @Override + public RecipeSerializer getSerializer() { + return SERIALZIER; + } + + // This should never happen, as we're just doing this during data gen. + // But we need to have a full Recipe object in order for datagen to work. + @Override + public boolean matches(RecipeInput input, Level level) { + return this.first.matches(input, level); + } + + @Override + public ItemStack assemble(RecipeInput input) { + return this.first.assemble((RecipeInput)input); + } + + @Override + public boolean showNotification() { + return this.first.showNotification(); + } + + @Override + public String group() { + return this.first.group(); + } + + @SuppressWarnings("unchecked") + @Override + public RecipeType> getType() { + return (RecipeType>)this.first.getType(); + } + + @Override + public PlacementInfo placementInfo() { + return this.first.placementInfo(); + } + + @Override + public RecipeBookCategory recipeBookCategory() { + return this.first.recipeBookCategory(); + } } diff --git a/src/main/java/net/minecraftforge/common/crafting/conditions/ICondition.java b/src/main/java/net/minecraftforge/common/crafting/conditions/ICondition.java index 640c961e34..844b7b91cc 100644 --- a/src/main/java/net/minecraftforge/common/crafting/conditions/ICondition.java +++ b/src/main/java/net/minecraftforge/common/crafting/conditions/ICondition.java @@ -37,8 +37,10 @@ public interface ICondition { @ApiStatus.Internal public static Identifier KEY = Identifier.fromNamespaceAndPath("forge", "condition_context"); - default > O wrap(O ops) { - return ops.withContext(KEY, this); + default > DynamicOps wrap(O ops) { + @SuppressWarnings("unchecked") + var delegate = (ops instanceof DelegatingOps del) ? (DelegatingOps)del : new DelegatingOps<>(ops) {}; + return delegate.withContext(KEY, this); } IContext EMPTY = new IContext() { diff --git a/src/main/java/net/minecraftforge/common/crafting/conditions/TagEmptyCondition.java b/src/main/java/net/minecraftforge/common/crafting/conditions/TagEmptyCondition.java index 4c9bbca4a8..7db89c3892 100644 --- a/src/main/java/net/minecraftforge/common/crafting/conditions/TagEmptyCondition.java +++ b/src/main/java/net/minecraftforge/common/crafting/conditions/TagEmptyCondition.java @@ -22,6 +22,8 @@ public record TagEmptyCondition(TagKey tag) implements ICondition { @Override public boolean test(ICondition.IContext context, DynamicOps ops) { + if (tag.toString().contains("dirt")) + System.currentTimeMillis(); return context.getTag(tag).isEmpty(); } diff --git a/src/main/java/net/minecraftforge/common/crafting/ingredients/CompoundIngredient.java b/src/main/java/net/minecraftforge/common/crafting/ingredients/CompoundIngredient.java index 6ce9566780..913ce26aa1 100644 --- a/src/main/java/net/minecraftforge/common/crafting/ingredients/CompoundIngredient.java +++ b/src/main/java/net/minecraftforge/common/crafting/ingredients/CompoundIngredient.java @@ -19,6 +19,8 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.core.Holder; import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -85,21 +87,10 @@ public class CompoundIngredient extends AbstractIngredient { ).apply(builder, CompoundIngredient::new) ); - public static final IIngredientSerializer SERIALIZER = new IIngredientSerializer<>() { - @Override - public MapCodec codec() { - return CODEC; - } + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + Ingredient.CONTENTS_STREAM_CODEC.apply(ByteBufCodecs.list()), i -> i.children, + CompoundIngredient::new + ); - @Override - public void write(RegistryFriendlyByteBuf buffer, CompoundIngredient value) { - buffer.writeCollection(value.children, (_, child) -> Ingredient.CONTENTS_STREAM_CODEC.encode(buffer, child)); - } - - @Override - public CompoundIngredient read(RegistryFriendlyByteBuf buffer) { - var children = buffer.readCollection(ArrayList::new, _ -> Ingredient.CONTENTS_STREAM_CODEC.decode(buffer)); - return new CompoundIngredient(children); - } - }; + public static final IIngredientSerializer SERIALIZER = IIngredientSerializer.simple(CODEC, STREAM_CODEC); } diff --git a/src/main/java/net/minecraftforge/common/crafting/ingredients/DifferenceIngredient.java b/src/main/java/net/minecraftforge/common/crafting/ingredients/DifferenceIngredient.java index f9562747d4..455e6dc83c 100644 --- a/src/main/java/net/minecraftforge/common/crafting/ingredients/DifferenceIngredient.java +++ b/src/main/java/net/minecraftforge/common/crafting/ingredients/DifferenceIngredient.java @@ -10,6 +10,7 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.Holder; import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; @@ -81,23 +82,11 @@ public class DifferenceIngredient extends AbstractIngredient { ).apply(builder, DifferenceIngredient::new) ); - public static final IIngredientSerializer SERIALIZER = new IIngredientSerializer<>() { - @Override - public MapCodec codec() { - return CODEC; - } + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + Ingredient.CONTENTS_STREAM_CODEC, i -> i.base, + Ingredient.CONTENTS_STREAM_CODEC, i -> i.subtracted, + DifferenceIngredient::new + ); - @Override - public DifferenceIngredient read(RegistryFriendlyByteBuf buffer) { - Ingredient base = Ingredient.CONTENTS_STREAM_CODEC.decode(buffer); - Ingredient without = Ingredient.CONTENTS_STREAM_CODEC.decode(buffer); - return new DifferenceIngredient(base, without); - } - - @Override - public void write(RegistryFriendlyByteBuf buffer, DifferenceIngredient ingredient) { - Ingredient.CONTENTS_STREAM_CODEC.encode(buffer, ingredient.base); - Ingredient.CONTENTS_STREAM_CODEC.encode(buffer, ingredient.subtracted); - } - }; + public static final IIngredientSerializer SERIALIZER = IIngredientSerializer.simple(CODEC, STREAM_CODEC); } diff --git a/src/main/java/net/minecraftforge/common/crafting/ingredients/IIngredientSerializer.java b/src/main/java/net/minecraftforge/common/crafting/ingredients/IIngredientSerializer.java index dab86c7d10..9097cb69bf 100644 --- a/src/main/java/net/minecraftforge/common/crafting/ingredients/IIngredientSerializer.java +++ b/src/main/java/net/minecraftforge/common/crafting/ingredients/IIngredientSerializer.java @@ -8,11 +8,15 @@ package net.minecraftforge.common.crafting.ingredients; import com.mojang.serialization.MapCodec; import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.item.crafting.Ingredient; public interface IIngredientSerializer { - MapCodec codec(); + MapCodec codec(); + StreamCodec streamCodec(); - void write(RegistryFriendlyByteBuf buffer, T value); - T read(RegistryFriendlyByteBuf buffer); + record Simple(MapCodec codec, StreamCodec streamCodec) implements IIngredientSerializer { } + public static Simple simple(MapCodec codec, StreamCodec streamCodec) { + return new Simple<>(codec, streamCodec); + } } diff --git a/src/main/java/net/minecraftforge/common/crafting/ingredients/IntersectionIngredient.java b/src/main/java/net/minecraftforge/common/crafting/ingredients/IntersectionIngredient.java index 98fec62695..124bfa4a13 100644 --- a/src/main/java/net/minecraftforge/common/crafting/ingredients/IntersectionIngredient.java +++ b/src/main/java/net/minecraftforge/common/crafting/ingredients/IntersectionIngredient.java @@ -10,6 +10,8 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.Holder; import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; @@ -100,21 +102,10 @@ public class IntersectionIngredient extends AbstractIngredient { .apply(builder, IntersectionIngredient::new) ); - public static final IIngredientSerializer SERIALIZER = new IIngredientSerializer<>() { - @Override - public MapCodec codec() { - return CODEC; - } + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + Ingredient.CONTENTS_STREAM_CODEC.apply(ByteBufCodecs.list()), i -> i.children, + IntersectionIngredient::new + ); - @Override - public IntersectionIngredient read(RegistryFriendlyByteBuf buffer) { - var children = buffer.readCollection(ArrayList::new, _ -> Ingredient.CONTENTS_STREAM_CODEC.decode(buffer)); - return new IntersectionIngredient(children); - } - - @Override - public void write(RegistryFriendlyByteBuf buffer, IntersectionIngredient value) { - buffer.writeCollection(value.children, (_, child) -> Ingredient.CONTENTS_STREAM_CODEC.encode(buffer, child)); - } - }; + public static final IIngredientSerializer SERIALIZER = IIngredientSerializer.simple(CODEC, STREAM_CODEC); } diff --git a/src/main/java/net/minecraftforge/common/crafting/ingredients/NBTIngredient.java b/src/main/java/net/minecraftforge/common/crafting/ingredients/NBTIngredient.java index e11d283a54..ecd9aa15b9 100644 --- a/src/main/java/net/minecraftforge/common/crafting/ingredients/NBTIngredient.java +++ b/src/main/java/net/minecraftforge/common/crafting/ingredients/NBTIngredient.java @@ -26,7 +26,6 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Objects; /** Ingredient that matches the given items, performing a partial NBT match unless strict is set. */ public class NBTIngredient extends AbstractIngredient { @@ -104,29 +103,15 @@ public class NBTIngredient extends AbstractIngredient { ).apply(builder, NBTIngredient::new) ); - public static final IIngredientSerializer SERIALIZER = new IIngredientSerializer<>() { - private final StreamCodec> HOLDER_SET = ByteBufCodecs.holderSet(Registries.ITEM); + private static final StreamCodec> HOLDER_SET_CODEC = ByteBufCodecs.holderSet(Registries.ITEM); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + HOLDER_SET_CODEC, i -> i.values, + ByteBufCodecs.COMPOUND_TAG, i -> i.nbt, + ByteBufCodecs.BOOL, i -> i.strict, + NBTIngredient::new + ); - @Override - public MapCodec codec() { - return CODEC; - } - - @Override - public NBTIngredient read(RegistryFriendlyByteBuf buffer) { - var items = HOLDER_SET.decode(buffer); - var nbt = buffer.readNbt(); - var strict = buffer.readBoolean(); - return new NBTIngredient(items, Objects.requireNonNull(nbt), strict); - } - - @Override - public void write(RegistryFriendlyByteBuf buffer, NBTIngredient value) { - HOLDER_SET.encode(buffer, value.values); - buffer.writeNbt(value.nbt); - buffer.writeBoolean(value.strict); - } - }; + public static final IIngredientSerializer SERIALIZER = IIngredientSerializer.simple(CODEC, STREAM_CODEC); public static class Builder { private final List items = new ArrayList<>(); diff --git a/src/main/java/net/minecraftforge/common/data/DatapackBuiltinEntriesProvider.java b/src/main/java/net/minecraftforge/common/data/DatapackBuiltinEntriesProvider.java deleted file mode 100644 index 8afbbd3427..0000000000 --- a/src/main/java/net/minecraftforge/common/data/DatapackBuiltinEntriesProvider.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.common.data; - -import net.minecraft.core.*; -import net.minecraft.data.PackOutput; -import net.minecraft.data.registries.RegistriesDatapackGenerator; -import net.minecraft.data.registries.RegistryPatchGenerator; -import net.minecraft.data.tags.TagsProvider; -import java.util.Set; -import java.util.concurrent.CompletableFuture; - -/** - * An extension of the {@link RegistriesDatapackGenerator} which properly handles - * referencing existing dynamic registry objects within another dynamic registry - * object. - */ -public class DatapackBuiltinEntriesProvider extends RegistriesDatapackGenerator { - - private final CompletableFuture fullRegistries; - - /** - * Constructs a new datapack provider which generates all registry objects - * from the provided mods using the holder. - * - * @param output the target directory of the data generator - * @param registries a future of patched registries - * @param modId The mod id to generate the dynamic registry objects of - */ - public DatapackBuiltinEntriesProvider(PackOutput output, CompletableFuture registries, String modId) { - this(output, registries, Set.of(modId)); - } - - /** - * Constructs a new datapack provider which generates all registry objects - * from the provided mods using the holder. - * - * @param output the target directory of the data generator - * @param registries a future of patched registries - * @param modIds a set of mod ids to generate the dynamic registry objects of - */ - public DatapackBuiltinEntriesProvider(PackOutput output, CompletableFuture registries, Set modIds) { - super(output, registries.thenApply(RegistrySetBuilder.PatchedRegistries::patches), modIds); - this.fullRegistries = registries.thenApply(RegistrySetBuilder.PatchedRegistries::full); - } - - /** - * Constructs a new datapack provider which generates all registry objects - * from the provided mods using the holder. All entries that need to be - * bootstrapped are provided within the {@link RegistrySetBuilder}. - * - * @param output the target directory of the data generator - * @param registries a future of a lookup for registries and their objects - * @param registryBuilder a builder containing the dynamic registry objects added by this provider - * @param modId The mod id to generate the dynamic registry objects of - */ - public DatapackBuiltinEntriesProvider(PackOutput output, CompletableFuture registries, RegistrySetBuilder registryBuilder, String modId) { - this(output, registries, registryBuilder, Set.of(modId)); - } - - /** - * Constructs a new datapack provider which generates all registry objects - * from the provided mods using the holder. All entries that need to be - * bootstrapped are provided within the {@link RegistrySetBuilder}. - * - * @param output the target directory of the data generator - * @param registries a future of a lookup for registries and their objects - * @param registryBuilder a builder containing the dynamic registry objects added by this provider - * @param modIds a set of mod ids to generate the dynamic registry objects of - */ - public DatapackBuiltinEntriesProvider(PackOutput output, CompletableFuture registries, RegistrySetBuilder registryBuilder, Set modIds) { - this(output, RegistryPatchGenerator.createLookup(registries, registryBuilder), modIds); - } - - /** - * Gets the future of the full registry lookup containing all added elements.
    - * The returned full registry lookup can also be used for other data providers.
    - *
    {@code
    -     * var provider = new DatapackBuiltinEntriesProvider(generator.getPackOutput(), event.getLookupProvider(), new RegistrySetBuilder(), Set.of("example_mod"));
    -     * }
    - * An example use case is the {@link TagsProvider}. - * @return the future of the full registry lookup - */ - public CompletableFuture getFullRegistries() { - return this.fullRegistries; - } -} diff --git a/src/main/java/net/minecraftforge/common/data/ExistingFileHelper.java b/src/main/java/net/minecraftforge/common/data/ExistingFileHelper.java index c82cf63278..80aae54ce2 100644 --- a/src/main/java/net/minecraftforge/common/data/ExistingFileHelper.java +++ b/src/main/java/net/minecraftforge/common/data/ExistingFileHelper.java @@ -24,11 +24,16 @@ import net.minecraft.data.DataProvider; import net.minecraft.network.chat.Component; import net.minecraft.server.packs.PackLocationInfo; import net.minecraft.server.packs.repository.FolderRepositorySource; +import net.minecraft.server.packs.repository.Pack; +import net.minecraft.server.packs.repository.PackCompatibility; import net.minecraft.server.packs.repository.PackSource; +import net.minecraft.server.packs.repository.RepositorySource; import net.minecraft.server.packs.repository.ServerPacksSource; import net.minecraft.server.packs.resources.MultiPackResourceManager; import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.world.flag.FeatureFlagSet; +import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.validation.DirectoryValidator; import net.minecraft.world.level.validation.ForbiddenSymlinkInfo; import net.minecraft.server.packs.PackResources; @@ -96,44 +101,67 @@ public class ExistingFileHelper { * @param assetsDir the directory in which to find vanilla assets and indexes */ public ExistingFileHelper(Collection existingPacks, final Set existingMods, @Nullable final String assetIndex, @Nullable final File assetsDir) { - List candidateClientResources = new ArrayList<>(); - List candidateServerResources = new ArrayList<>(); + var client = new ArrayList(); + var server = new ArrayList(); + + if (assetIndex != null && assetsDir != null && assetsDir.exists()) { + for (var pack : getVanillaClient(assetIndex, assetsDir)) + pack.open().forEach(client::add); - if (assetIndex != null && assetsDir != null && assetsDir.exists()) - { - candidateClientResources.add(ClientPackSource.createVanillaPackSource(IndexedAssetSource.createIndexFs(assetsDir.toPath(), assetIndex))); } - candidateServerResources.add(ServerPacksSource.createVanillaPackSource()); + for (var pack : getVanillaServer()) + pack.open().forEach(server::add); var symlinks = new ArrayList(); - var folder = new FolderRepositorySource.FolderPackDetector(new DirectoryValidator(_ -> true)); + var folder = new FolderRepositorySource.FolderPackDetector(new DirectoryValidator(_ -> true)); for (Path existing : existingPacks) { try { var info = new PackLocationInfo(existing.getFileName().toString(), Component.literal("data_gen"), PackSource.DEFAULT, Optional.empty()); var supplier = folder.detectPackResources(existing, symlinks, false); - PackResources pack = supplier.openPrimary(info); - candidateClientResources.add(pack); - candidateServerResources.add(pack); - }catch (IOException e) { - throw new RuntimeException(e); + add(client, server, info, supplier); + } catch (IOException e) { + throw new RuntimeException("Failed to read pack at: " + existing, e); } } for (String existingMod : existingMods) { IModFileInfo modFileInfo = ModList.getModFileById(existingMod); if (modFileInfo != null) { - var root = modFileInfo.getFile().findResource("/"); - var supplier = new PathResourcesSupplier(root); var info = new PackLocationInfo("mod:" + existingMod, Component.literal("data_gen:" + existingMod), PackSource.DEFAULT, Optional.empty()); - var pack = supplier.openPrimary(info); - candidateClientResources.add(pack); - candidateServerResources.add(pack); + var supplier = new PathResourcesSupplier(modFileInfo.getFile().findResource("/")); + add(client, server, info, supplier); } } - this.clientResources = new MultiPackResourceManager(PackType.CLIENT_RESOURCES, candidateClientResources); - this.serverData = new MultiPackResourceManager(PackType.SERVER_DATA, candidateServerResources); + this.clientResources = new MultiPackResourceManager(PackType.CLIENT_RESOURCES, client); + this.serverData = new MultiPackResourceManager(PackType.SERVER_DATA, server); + } + + private static List getVanillaClient(@Nullable final String assetIndex, @Nullable final File assetsDir) { + var indexed = IndexedAssetSource.createIndexFs(assetsDir.toPath(), assetIndex); + var validator = LevelStorageSource.parseValidator(indexed.resolve(LevelStorageSource.ALLOWED_SYMLINKS_CONFIG_NAME)); + var vanilla = new ClientPackSource(indexed, validator); + return toList(vanilla); + } + + private static List getVanillaServer() { + var vanilla = new ServerPacksSource(new DirectoryValidator(path -> true)); + return toList(vanilla); + } + + private static List toList(RepositorySource source) { + var ret = new ArrayList(); + source.loadPacks(ret::add); + return ret; + } + + private static final Pack.Metadata META = new Pack.Metadata(Component.empty(), PackCompatibility.COMPATIBLE, FeatureFlagSet.of(), List.of()); + private void add(List client, List server, PackLocationInfo info, Pack.ResourcesSupplier resources) { + for (var pack : resources.openResources(info, META).toList()) { + client.add(pack); + server.add(pack); + } } private ResourceManager getManager(PackType packType) { diff --git a/src/main/java/net/minecraftforge/common/data/ForgeAdvancementProvider.java b/src/main/java/net/minecraftforge/common/data/ForgeAdvancementProvider.java deleted file mode 100644 index aad4500b28..0000000000 --- a/src/main/java/net/minecraftforge/common/data/ForgeAdvancementProvider.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.common.data; - -import net.minecraft.advancements.AdvancementHolder; -import net.minecraft.core.HolderLookup; -import net.minecraft.data.PackOutput; -import net.minecraft.data.advancements.AdvancementProvider; -import net.minecraft.data.advancements.AdvancementSubProvider; -import net.minecraft.resources.Identifier; - -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; - -/** - * An extension of the {@link AdvancementProvider} to provide a feature-complete - * experience to generate modded advancements. - */ -@SuppressWarnings("deprecation") -public class ForgeAdvancementProvider extends AdvancementProvider { - /** - * Constructs an advancement provider using the generators to write the - * advancements to a file. - * - * @param output the target directory of the data generator - * @param registries a future of a lookup for registries and their objects - * @param existingFileHelper a helper used to find whether a file exists - * @param subProviders the generators used to create the advancements - */ - public ForgeAdvancementProvider(PackOutput output, CompletableFuture registries, ExistingFileHelper existingFileHelper, List subProviders) { - super(output, registries, subProviders.stream().map(generator -> generator.toSubProvider(existingFileHelper)).toList()); - } - - /** - * An interface used to generated modded advancements. This is parallel to - * vanilla's {@link AdvancementSubProvider} with access to the {@link ExistingFileHelper}. - * - * @see AdvancementSubProvider - */ - public interface AdvancementGenerator { - /** - * A method used to generate advancements for a mod. Advancements should be - * built via {@link net.minecraftforge.common.extensions.IForgeAdvancementBuilder#save(Consumer, Identifier, ExistingFileHelper)}. - * - * @param registries a lookup for registries and their objects - * @param saver a consumer used to write advancements to a file - * @param existingFileHelper a helper used to find whether a file exists - */ - void generate(HolderLookup.Provider registries, Consumer saver, ExistingFileHelper existingFileHelper); - - /** - * Creates an {@link AdvancementSubProvider} from this generator. - * - * @param existingFileHelper a helper used to find whether a file exists - * @return a sub provider wrapping this generator - */ - default AdvancementSubProvider toSubProvider(ExistingFileHelper existingFileHelper) { - return (registries, saver) -> this.generate(registries, saver, existingFileHelper); - } - } -} diff --git a/src/main/java/net/minecraftforge/common/data/ForgeLootTableProvider.java b/src/main/java/net/minecraftforge/common/data/ForgeLootTableProvider.java deleted file mode 100644 index 13d6ff36c7..0000000000 --- a/src/main/java/net/minecraftforge/common/data/ForgeLootTableProvider.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.common.data; - -import net.minecraft.advancements.predicates.ItemPredicate; -import net.minecraft.core.HolderLookup; -import net.minecraft.core.Registry; -import net.minecraft.data.PackOutput; -import net.minecraft.data.loot.LootTableProvider; -import net.minecraft.data.loot.LootTableSubProvider; -import net.minecraft.data.loot.packs.VanillaLootTableProvider; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.Items; -import net.minecraft.util.ProblemReporter; -import net.minecraft.world.level.storage.loot.predicates.CompositeLootItemCondition; -import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; -import net.minecraft.world.level.storage.loot.predicates.InvertedLootItemCondition; -import net.minecraft.world.level.storage.loot.predicates.MatchTool; -import net.minecraftforge.common.ToolAction; -import net.minecraftforge.common.ToolActions; -import net.minecraftforge.common.loot.CanToolPerformAction; -import net.minecraftforge.fml.util.ObfuscationReflectionHelper; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; - -import com.google.common.collect.ImmutableList; - -import net.minecraft.world.level.storage.loot.LootPool; -import net.minecraft.world.level.storage.loot.LootTable; -import net.minecraft.world.level.storage.loot.ValidationContextSource; -import net.minecraft.world.level.storage.loot.entries.CompositeEntryBase; -import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; - -/** - * Currently used only for replacing shears item to shears_dig tool action - */ -public final class ForgeLootTableProvider extends LootTableProvider { - private static final String POOLS = "pools"; // LootTable.Builder.pools - private static final String ENTRIES = "entries"; // LootPool.entries - private static final String CONDITIONS = "conditions"; // LootPool.conditions - private static final String CHILDREN = "children"; // CompositeEntryBase.children - private static final String ENTRY_CONDITION = "conditions"; // LootPoolEntryContainer.conditions - private static final String TERMS = "terms"; // CompositeLootItemCondition.terms - - public ForgeLootTableProvider(PackOutput pack, CompletableFuture lookup) { - super(pack, Set.of(), VanillaLootTableProvider.create(pack, lookup).getTables(), lookup); - } - - @Override - protected void validate(Registry map, ValidationContextSource validationcontext, ProblemReporter report) { - // Do not validate against all registered loot tables - } - - @Override - public List getTables() { - return super.getTables().stream().map(entry -> { - // Provides new sub provider with filtering only changed loot tables and replacing condition item to condition tag - return new LootTableProvider.SubProviderEntry(provider -> replaceAndFilterChangesOnly(entry.provider().apply(provider)), entry.paramSet()); - }).collect(Collectors.toList()); - } - - private LootTableSubProvider replaceAndFilterChangesOnly(LootTableSubProvider subProvider) { - return (newConsumer) -> subProvider.generate((Identifier, builder) -> { - if (findAndReplaceInLootTableBuilder(builder, Items.SHEARS, ToolActions.SHEARS_DIG)) { - newConsumer.accept(Identifier, builder); - } - }); - } - - private boolean findAndReplaceInLootTableBuilder(LootTable.Builder builder, Item from, ToolAction toolAction) { - ImmutableList.Builder lootPools = ObfuscationReflectionHelper.getPrivateValue(LootTable.Builder.class, builder, POOLS); - boolean found = false; - - if (lootPools == null) { - throw new IllegalStateException(LootTable.Builder.class.getName() + " is missing field " + POOLS); - } - - for (LootPool lootPool : lootPools.build()) { - if (findAndReplaceInLootPool(lootPool, from, toolAction)) { - found = true; - } - } - - return found; - } - - private boolean findAndReplaceInLootPool(LootPool lootPool, Item from, ToolAction toolAction) { - List lootEntries = ObfuscationReflectionHelper.getPrivateValue(LootPool.class, lootPool, ENTRIES); - List lootConditions = ObfuscationReflectionHelper.getPrivateValue(LootPool.class, lootPool, CONDITIONS); - boolean found = false; - - if (lootEntries == null) - throw new IllegalStateException(LootPool.class.getName() + " is missing field " + ENTRIES); - - for (LootPoolEntryContainer lootEntry : lootEntries) { - if (findAndReplaceInLootEntry(lootEntry, from, toolAction)) - found = true; - - if (lootEntry instanceof CompositeEntryBase) { - if (findAndReplaceInParentedLootEntry((CompositeEntryBase) lootEntry, from, toolAction)) - found = true; - } - } - - if (lootConditions == null) - throw new IllegalStateException(LootPool.class.getName() + " is missing field " + CONDITIONS); - else { - lootConditions = new ArrayList<>(lootConditions); - ObfuscationReflectionHelper.setPrivateValue(LootPool.class, lootPool, lootConditions, CONDITIONS); - } - - for (int i = 0; i < lootConditions.size(); i++) { - LootItemCondition lootCondition = lootConditions.get(i); - if (lootCondition instanceof MatchTool matchTool && checkMatchTool(matchTool, from)) { - lootConditions.set(i, CanToolPerformAction.canToolPerformAction(toolAction).build()); - found = true; - } else if (lootCondition instanceof InvertedLootItemCondition inverted) { - LootItemCondition invLootCondition = inverted.term(); - - if (invLootCondition instanceof MatchTool matchTool && checkMatchTool(matchTool, from)) { - lootConditions.set(i, InvertedLootItemCondition.invert(CanToolPerformAction.canToolPerformAction(toolAction)).build()); - found = true; - } else if (invLootCondition instanceof CompositeLootItemCondition compositeLootItemCondition && findAndReplaceInComposite(compositeLootItemCondition, from, toolAction)) { - found = true; - } - } else if (lootCondition instanceof CompositeLootItemCondition compositeLootItemCondition && findAndReplaceInComposite(compositeLootItemCondition, from, toolAction)) { - found = true; - } - } - - return found; - } - - private boolean findAndReplaceInParentedLootEntry(CompositeEntryBase entry, Item from, ToolAction toolAction) { - List lootEntries = ObfuscationReflectionHelper.getPrivateValue(CompositeEntryBase.class, entry, CHILDREN); - boolean found = false; - - if (lootEntries == null) { - throw new IllegalStateException(CompositeEntryBase.class.getName() + " is missing field " + CHILDREN); - } - - for (LootPoolEntryContainer lootEntry : lootEntries) { - if (findAndReplaceInLootEntry(lootEntry, from, toolAction)) { - found = true; - } - } - - return found; - } - - private boolean findAndReplaceInLootEntry(LootPoolEntryContainer entry, Item from, ToolAction toolAction) { - List lootConditions = ObfuscationReflectionHelper.getPrivateValue(LootPoolEntryContainer.class, entry, ENTRY_CONDITION); - boolean found = false; - - if (lootConditions == null) - throw new IllegalStateException(LootPoolEntryContainer.class.getName() + " is missing field f_7963" + "6_"); - else { - lootConditions = new ArrayList<>(lootConditions); - ObfuscationReflectionHelper.setPrivateValue(LootPoolEntryContainer.class, entry, lootConditions, ENTRY_CONDITION); - } - - for (int i = 0; i < lootConditions.size(); i++) { - var condition = lootConditions.get(i); - if (condition instanceof CompositeLootItemCondition composite && findAndReplaceInComposite(composite, from, toolAction)) { - found = true; - } else if (condition instanceof MatchTool matchTool && checkMatchTool(matchTool, from)) { - lootConditions.set(i, CanToolPerformAction.canToolPerformAction(toolAction).build()); - found = true; - } - } - - return found; - } - - private boolean findAndReplaceInComposite(CompositeLootItemCondition alternative, Item from, ToolAction toolAction) { - List lootConditions = ObfuscationReflectionHelper.getPrivateValue(CompositeLootItemCondition.class, alternative, TERMS); - boolean found = false; - - if (lootConditions == null) - throw new IllegalStateException(CompositeLootItemCondition.class.getName() + " is missing field " + TERMS); - else { - lootConditions = new ArrayList<>(lootConditions); - ObfuscationReflectionHelper.setPrivateValue(CompositeLootItemCondition.class, alternative, lootConditions, TERMS); - } - - for (int i = 0; i < lootConditions.size(); i++) { - if (lootConditions.get(i) instanceof MatchTool matchTool && checkMatchTool(matchTool, from)) { - lootConditions.set(i, CanToolPerformAction.canToolPerformAction(toolAction).build()); - found = true; - } - } - - return found; - } - - @SuppressWarnings("deprecation") - private boolean checkMatchTool(MatchTool lootCondition, Item expected) { - return lootCondition.predicate().flatMap(ItemPredicate::items).filter(s -> s.contains(expected.builtInRegistryHolder())).isPresent(); - } -} diff --git a/src/main/java/net/minecraftforge/common/data/ForgeRecipeProvider.java b/src/main/java/net/minecraftforge/common/data/ForgeRecipeProvider.java index e35675b7bd..699c5a07fb 100644 --- a/src/main/java/net/minecraftforge/common/data/ForgeRecipeProvider.java +++ b/src/main/java/net/minecraftforge/common/data/ForgeRecipeProvider.java @@ -5,20 +5,22 @@ package net.minecraftforge.common.data; -import com.google.gson.JsonElement; +import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementHolder; import net.minecraft.advancements.Advancement.Builder; import net.minecraft.core.Holder; +import net.minecraft.core.Holder.Reference; +import net.minecraft.core.HolderGetter; import net.minecraft.core.HolderLookup; -import net.minecraft.core.HolderLookup.Provider; -import net.minecraft.core.HolderLookup.RegistryLookup; import net.minecraft.core.HolderSet; +import net.minecraft.core.Registry; import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.MultiRegistryBootstrap; 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.VanillaBrewingProvider; import net.minecraft.data.recipes.packs.VanillaRecipeProvider; +import net.minecraft.data.worldgen.BootstrapContext; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.Identifier; import net.minecraft.tags.TagKey; @@ -38,29 +40,48 @@ import net.minecraftforge.unsafe.UnsafeHacks; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; -import java.util.concurrent.CompletableFuture; +import java.util.stream.Stream; public final class ForgeRecipeProvider extends VanillaRecipeProvider { private static final Logger LOGGER = LogManager.getLogger(); - private final RegistryLookup items; + private final HolderGetter items; private final Map> replacements = HashMap.newHashMap(12); private final Set>> excludes = HashSet.newHashSet(16); private final UnsafeFieldAccess> INGREDIENTS = UnsafeHacks.findField(ShapelessRecipe.class, "ingredients"); private final UnsafeFieldAccess PATTERN = UnsafeHacks.findField(ShapedRecipe.class, "pattern"); private final UnsafeFieldAccess> VALUES = UnsafeHacks.findField(Ingredient.class, "values"); - private ForgeRecipeProvider(HolderLookup.Provider lookup, RecipeOutput output) { - super(lookup, new Wrapped(output)); - ((Wrapped)this.output).setSelf(this); - this.items = lookup.lookupOrThrow(Registries.ITEM); + public static MultiRegistryBootstrap create() { + return new MultiRegistryBootstrap() { + @Override + public Set>> requestedRegistries() { + return Set.of(Registries.RECIPE, Registries.ADVANCEMENT); + } + + @Override + public void run(BootstrapGetter registries) { + new ForgeRecipeProvider(registries.get(Registries.RECIPE), registries.get(Registries.ADVANCEMENT)).buildRecipes(); + } + }; + } + + private ForgeRecipeProvider(final BootstrapContext> recipeOutput, final BootstrapContext advancementOutput) { + super(recipeOutput, advancementOutput); + this.items = recipeOutput.lookup(Registries.ITEM); + + // Not having access to 'this' in super calls is really annoying + this.output = new RecipeOutputWrapper(this.output, this); + this.advancementOutput = new ContextWrapper<>(this.advancementOutput); + this.brewingProvider = new VanillaBrewingProvider(this.output); } private void exclude(ItemLike item) { @@ -185,37 +206,10 @@ public final class ForgeRecipeProvider extends VanillaRecipeProvider { return ret; } - public static class Runner extends RecipeProvider.Runner { - public Runner(PackOutput output, CompletableFuture registries) { - super(output, registries); - } - + private record RecipeOutputWrapper(RecipeOutput wrapped, ForgeRecipeProvider forge) implements RecipeOutput { @Override - public String getName() { - return ForgeRecipeProvider.class.getSimpleName(); - } - - @Override - protected RecipeProvider createRecipeProvider(Provider registries, RecipeOutput output) { - return new ForgeRecipeProvider(registries, output); - } - } - - private static class Wrapped implements RecipeOutput { - private final RecipeOutput wrapped; - private ForgeRecipeProvider self; - - private Wrapped(RecipeOutput wrapped) { - this.wrapped = wrapped; - } - - private void setSelf(ForgeRecipeProvider self) { - this.self = self; - } - - @Override - public void accept(ResourceKey> id, Recipe recipe, AdvancementHolder advancement) { - var modified = self.enhance(id, recipe); + public void accept(ResourceKey> id, Recipe recipe, @Nullable AdvancementHolder advancement) { + var modified = forge.enhance(id, recipe); if (modified != null) wrapped.accept(id, modified, null); } @@ -226,18 +220,37 @@ public final class ForgeRecipeProvider extends VanillaRecipeProvider { } @Override - public void accept(ResourceKey> id, Recipe recipe, Identifier advancementId, JsonElement advancement) { - var modified = self.enhance(id, recipe); - if (modified != null) - wrapped.accept(id, modified, null); + public HolderGetter lookup(ResourceKey> key) { + return wrapped.lookup(key); + } + + @SuppressWarnings("deprecation") + @Override + public Stream> listContextElements(ResourceKey> key) { + return wrapped.listContextElements(key); } @Override - public Provider registry() { - return wrapped.registry(); + public Optional> registryLookup(ResourceKey> registry) { + return wrapped.registryLookup(registry); + } + } + + private record ContextWrapper(BootstrapContext wrapped) implements BootstrapContext { + @Override + public HolderGetter lookup(ResourceKey> key) { + return wrapped.lookup(key); + } + + @SuppressWarnings("deprecation") + @Override + public Stream> listContextElements(ResourceKey> key) { + return wrapped.listContextElements(key); } @Override - public void includeRootAdvancement() {} + public Reference register(ResourceKey key, T value) { + return wrapped.lookup(key.registryKey()).getOrThrow(key); + } } } diff --git a/src/main/java/net/minecraftforge/common/data/RegistryDataBuilder.java b/src/main/java/net/minecraftforge/common/data/RegistryDataBuilder.java new file mode 100644 index 0000000000..f4c7b6b34c --- /dev/null +++ b/src/main/java/net/minecraftforge/common/data/RegistryDataBuilder.java @@ -0,0 +1,233 @@ +/* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.minecraftforge.common.data; + +import net.minecraft.core.Holder.Reference; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.HolderLookup.RegistryLookup; +import net.minecraft.core.HolderSet.Named; +import net.minecraft.core.Registry; +import net.minecraft.core.RegistrySetBuilder; +import net.minecraft.core.RegistrySetBuilder.PatchedRegistries; +import net.minecraft.data.PackOutput; +import net.minecraft.data.registries.RegistriesDatapackGenerator; +import net.minecraft.data.registries.RegistryPatchGenerator; +import net.minecraft.data.registries.VanillaRegistries; +import net.minecraft.resources.RegistryDataLoader; +import net.minecraft.resources.ResourceKey; +import net.minecraft.tags.TagKey; +import net.minecraft.util.Util; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.stream.Stream; + +import org.jspecify.annotations.Nullable; + +import com.mojang.serialization.Lifecycle; + +/** + * An extension of the {@link RegistriesDatapackGenerator} which properly handles + * referencing existing dynamic registry objects within another dynamic registry + * object. + */ +public class RegistryDataBuilder { + public static RegistryDataBuilder of() { + return new RegistryDataBuilder(); + } + + private static final CompletableFuture VANILLA_WORLD = CompletableFuture.supplyAsync(VanillaRegistries::createWorldLookup, Util.backgroundExecutor()); + private static final CompletableFuture VANILLA_RELOADABLE = VANILLA_WORLD.thenApplyAsync(VanillaRegistries::createReloadableLookup, Util.backgroundExecutor()); + + public static CompletableFuture vanillaWorld() { + return VANILLA_WORLD; + } + public static CompletableFuture vanillaReloadable() { + return VANILLA_RELOADABLE; + } + + private static RegistrySetBuilder fill(Consumer filler) { + var ret = new RegistrySetBuilder(); + filler.accept(ret); + return ret; + } + + private CompletableFuture world = null; + private CompletableFuture worldFull = VANILLA_WORLD.thenApply(p -> addMissing(p, RegistryDataLoader.WORLD_REGISTRIES)); + + private CompletableFuture reload = null; + private CompletableFuture reloadFull = VANILLA_RELOADABLE.thenApply(p -> addMissing(p, RegistryDataLoader.RELOADABLE_REGISTRIES)); + + private Set modIds; + private Predicate> filter; + + private RegistryDataBuilder() { + resetFilter(); + } + + private @Nullable String name; + /** Sets the name for the DataGenerator, will be suffixed by "world" or "reloadable" */ + public RegistryDataBuilder name(String value) { + this.name = value; + return this; + } + + /** Adds a modid to the output filter. If the name is unset, will set it to the mod id */ + public RegistryDataBuilder modid(String value) { + this.modIds.add(value); + if (this.name == null) + name(value); + return this; + } + + /** Resets the modid list, and output filter to default values */ + public RegistryDataBuilder resetFilter() { + this.modIds = new HashSet<>(); + this.filter = key -> modIds.isEmpty() || modIds.contains(key.identifier().getNamespace()); + return this; + } + + /** Sets the entry filter that will be used in the data generators, */ + public RegistryDataBuilder filter(Predicate> value) { + this.filter = value; + return this; + } + + /** Adds a new layer, which is populated by the provided consumers */ + public RegistryDataBuilder layer(Consumer world, Consumer reloadable) { + layer(fill(world), fill(reloadable)); + return this; + } + + /** Adds a new layer using pre-built Registry Sets */ + public RegistryDataBuilder layer(RegistrySetBuilder world, RegistrySetBuilder reloadable) { + return world(world).reloadable(reloadable); + } + + /** Adds a new world layer populated by the provided consumer */ + public RegistryDataBuilder world(Consumer filler) { + return world(fill(filler)); + } + + /** Adds a new world layer using a pre-built Registry Set */ + public RegistryDataBuilder world(RegistrySetBuilder layer) { + world = RegistryPatchGenerator.createWorldLookup(worldFull, layer); + worldFull = world.thenApply(PatchedRegistries::full); + return this; + } + + /** Returns the patch subset for the current world layer. Throws IllegalStateException if called with out calling {@link #world(RegistrySetBulder)} */ + public CompletableFuture world() { + if (world == null) + throw new IllegalStateException("Attempted to get world layer patches without defining a world layer"); + return world.thenApply(PatchedRegistries::patches); + } + + /** Returns the full registry context for the current world layer. Useful for passing to other data providers */ + public CompletableFuture worldFull() { + return worldFull; + } + + /** Creates a DataGenerator for the patches of the current world layer. Throws IllegalStateException if called with out calling {@link #world(RegistrySetBulder)} */ + public RegistriesDatapackGenerator worldGenerator(final PackOutput output) { + return new RegistriesDatapackGenerator(output, name == null ? "world" : name + " world", RegistryDataLoader.getWorldAndDimensionRegistries(), world(), filter); + } + + /** Adds a new reloadable layer populated by the provided consumer */ + public RegistryDataBuilder reloadable(Consumer filler) { + return reloadable(fill(filler)); + } + + /** Adds a new reloadable layer using a pre-built Registry Set */ + public RegistryDataBuilder reloadable(RegistrySetBuilder layer) { + if (world == null) // We called reloadable without any world info. So make an empty layer + world(_ -> {}); + + reload = RegistryPatchGenerator.createReloadableLookup(worldFull, reloadFull, layer); + reloadFull = world.thenApply(PatchedRegistries::full); + return this; + } + + /** Returns the patch subset for the current reloadable layer. Throws IllegalStateException if called with out calling {@link #reloadable(RegistrySetBulder)} */ + public CompletableFuture reloadable() { + if (reload == null) + throw new IllegalStateException("Attempted to get reloadable layer patches without defining a reloadable layer"); + return reload.thenApply(PatchedRegistries::patches); + } + + /** Returns the full registry context for the current reloadable layer. Useful for passing to other data providers */ + public CompletableFuture reloadableFull() { + return reloadFull; + } + + /** Creates a DataGenerator for the patches of the current world layer. Throws IllegalStateException if called with out calling {@link #reloadable(RegistrySetBulder)} */ + public RegistriesDatapackGenerator reloadableGenerator(final PackOutput output) { + return new RegistriesDatapackGenerator(output, name == null ? "reloadable" : name + " reloadable", RegistryDataLoader.RELOADABLE_REGISTRIES, reloadable(), filter); + } + + private static HolderLookup.Provider addMissing(HolderLookup.Provider base, List> expected) { + var registries = new HashMap>, HolderLookup.RegistryLookup>(); + base.listRegistries().forEach(p -> registries.put(p.key(), p)); + + for (var data : expected) { + @SuppressWarnings("unchecked") + var key = (ResourceKey>)data.key(); + if (!registries.containsKey(key)) + registries.put(key, new DummyRegistry<>(key)); + } + + return new ProviderWrapper(Collections.unmodifiableMap(registries)); + } + + private record ProviderWrapper(Map>, HolderLookup.RegistryLookup> map) implements HolderLookup.Provider { + @Override + public Stream>> listRegistryKeys() { + return map.keySet().stream(); + } + + @Override + public Optional> lookup(ResourceKey> key) { + @SuppressWarnings("unchecked") + var ret = (HolderLookup.RegistryLookup)map.get(key); + return Optional.ofNullable(ret); + } + } + + private record DummyRegistry(ResourceKey> key) implements HolderLookup.RegistryLookup { + @Override + public Stream> listElements() { + return Stream.empty(); + } + + @Override + public Stream> listTags() { + return Stream.empty(); + } + + @Override + public Optional> get(ResourceKey id) { + return Optional.empty(); + } + + @Override + public Optional> get(TagKey id) { + return Optional.empty(); + } + + @Override + public Lifecycle registryLifecycle() { + return Lifecycle.stable(); + } + } +} diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java b/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java index ebbcb7009e..b4e05465e3 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeBlock.java @@ -6,6 +6,7 @@ package net.minecraftforge.common.extensions; import java.util.Optional; +import java.util.OptionalDouble; import java.util.function.BiConsumer; import net.minecraft.client.Camera; @@ -23,13 +24,10 @@ import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.FishingHook; import net.minecraft.world.entity.projectile.hurtingprojectile.WitherSkull; -import net.minecraft.world.item.*; -import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.SignalGetter; import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.MapColor; import net.minecraft.world.level.material.PushReaction; @@ -51,8 +49,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.common.ToolAction; -import net.minecraftforge.common.ToolActions; +import net.minecraft.world.level.levelgen.feature.TreeFeature; import org.jetbrains.annotations.Nullable; @SuppressWarnings("deprecation") @@ -241,7 +238,6 @@ public interface IForgeBlock { * @param occupied True if we are occupying the bed, or false if they are stopping use of the bed */ default void setBedOccupied(BlockState state, Level level, BlockPos pos, LivingEntity sleeper, boolean occupied) { - level.setBlock(pos, state.setValue(BedBlock.OCCUPIED, occupied), 3); } /** @@ -257,6 +253,17 @@ public interface IForgeBlock { return state.getValue(HorizontalDirectionalBlock.FACING); } + /** + * Returns the height the player will appear to lay down and sleep at if this is a bed. + * + * @param level The current level + * @param pos Block position in level + * @return The height, or empty if this isn't a bed + */ + default OptionalDouble getBedHeight(BlockState state, Level level, BlockPos pos) { + return self() instanceof AbstractBedBlock bed ? bed.getSleepHeight(state, level, pos) : OptionalDouble.empty(); + } + /** * Location sensitive version of getExplosionResistance * @@ -340,7 +347,7 @@ public interface IForgeBlock { * @param config Configuration of the trunk placer. Consider azalea trees, which should place rooted dirt instead of regular dirt. * @return True to ignore vanilla behaviour */ - default boolean onTreeGrow(BlockState state, LevelReader level, BiConsumer placeFunction, RandomSource randomSource, BlockPos pos, TreeConfiguration config) { + default boolean onTreeGrow(BlockState state, LevelReader level, BiConsumer placeFunction, RandomSource randomSource, BlockPos pos, TreeFeature config) { return false; } @@ -369,10 +376,7 @@ public interface IForgeBlock { * @return True, to support the conduit, and make it active with this block. */ default boolean isConduitFrame(BlockState state, LevelReader level, BlockPos pos, BlockPos conduit) { - return state.getBlock() == Blocks.PRISMARINE || - state.getBlock() == Blocks.PRISMARINE_BRICKS || - state.getBlock() == Blocks.SEA_LANTERN || - state.getBlock() == Blocks.DARK_PRISMARINE; + return state.is(BlockTags.CONDUIT_EFFECT_BLOCK); } /** @@ -657,7 +661,7 @@ public interface IForgeBlock { * @param explosion The explosion instance affecting the block */ default void onBlockExploded(BlockState state, ServerLevel level, BlockPos pos, Explosion explosion) { - level.setBlock(pos, Blocks.AIR.defaultBlockState(), 3); + level.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState()); self().wasExploded(level, pos, explosion); } @@ -681,50 +685,6 @@ public interface IForgeBlock { default boolean shouldDisplayFluidOverlay(BlockState state, BlockAndTintGetter level, BlockPos pos, FluidState fluidState) { return state.getBlock() instanceof HalfTransparentBlock || state.getBlock() instanceof LeavesBlock; } - - /** - * Returns the state that this block should transform into when right-clicked by a tool. - * For example: Used to determine if {@link ToolActions#AXE_STRIP an axe can strip}, - * {@link ToolActions#SHOVEL_FLATTEN a shovel can path}, or {@link ToolActions#HOE_TILL a hoe can till}. - * Returns {@code null} if nothing should happen. - * - * @param state The current state - * @param context The use on context that the action was performed in - * @param toolAction The action being performed by the tool - * @param simulate If {@code true}, no actions that modify the world in any way should be performed. If {@code false}, the world may be modified. - * @return The resulting state after the action has been performed - */ - @Nullable - default BlockState getToolModifiedState(BlockState state, UseOnContext context, ToolAction toolAction, boolean simulate) { - ItemStack itemStack = context.getItemInHand(); - if (!itemStack.canPerformAction(toolAction)) - return null; - - if (ToolActions.AXE_STRIP == toolAction) { - return AxeItem.getAxeStrippingState(state); - } else if (ToolActions.AXE_SCRAPE == toolAction) { - return WeatheringCopper.getPrevious(state).orElse(null); - } else if (ToolActions.AXE_WAX_OFF == toolAction) { - return Optional.ofNullable(HoneycombItem.WAX_OFF_BY_BLOCK.get().get(state.getBlock())).map(block -> block.withPropertiesOf(state)).orElse(null); - } else if (ToolActions.SHOVEL_FLATTEN == toolAction) { - return ShovelItem.getShovelPathingState(state); - } else if (ToolActions.HOE_TILL == toolAction) { - // Logic copied from HoeItem#TILLABLES; needs to be kept in sync during updating - Block block = state.getBlock(); - if (block == Blocks.ROOTED_DIRT) { - if (!simulate && !context.getLevel().isClientSide()) { - Block.popResourceFromFace(context.getLevel(), context.getClickedPos(), context.getClickedFace(), new ItemStack(Items.HANGING_ROOTS)); - } - return Blocks.DIRT.defaultBlockState(); - } else if ((block == Blocks.GRASS_BLOCK || block == Blocks.DIRT_PATH || block == Blocks.DIRT || block == Blocks.COARSE_DIRT) && - context.getLevel().getBlockState(context.getClickedPos().above()).isAir()) { - return block == Blocks.COARSE_DIRT ? Blocks.DIRT.defaultBlockState() : Blocks.FARMLAND.defaultBlockState(); - } - } - - return null; - } - /** * Checks if a player or entity handles movement on this block like scaffolding. * diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeBlockState.java b/src/main/java/net/minecraftforge/common/extensions/IForgeBlockState.java index 496168cb6e..092f259d7b 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeBlockState.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeBlockState.java @@ -6,6 +6,7 @@ package net.minecraftforge.common.extensions; import java.util.Optional; +import java.util.OptionalDouble; import java.util.function.BiConsumer; import net.minecraft.client.Camera; @@ -19,9 +20,8 @@ import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.FishingHook; -import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.SignalGetter; -import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration; +import net.minecraft.world.level.levelgen.feature.TreeFeature; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.pathfinder.PathType; import net.minecraft.core.BlockPos; @@ -38,8 +38,6 @@ import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.common.ToolAction; -import net.minecraftforge.common.ToolActions; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -186,6 +184,17 @@ public interface IForgeBlockState { return self().getBlock().getBedDirection(self(), level, pos); } + /** + * Returns the height the player will appear to lay down and sleep at if this is a bed. + * + * @param level The current level + * @param pos Block position in level + * @return The height, or empty if this isn't a bed + */ + default OptionalDouble getBedHeight(Level level, BlockPos pos) { + return self().getBlock().getBedHeight(self(), level, pos); + } + /** * Location sensitive version of getExplosionResistance * @@ -267,7 +276,7 @@ public interface IForgeBlockState { * @param config Configuration of the trunk placer. Consider azalea trees, which should place rooted dirt instead of regular dirt. * @return True to ignore vanilla behaviour */ - default boolean onTreeGrow(LevelReader level, BiConsumer placeFunction, RandomSource randomSource, BlockPos pos, TreeConfiguration config) { + default boolean onTreeGrow(LevelReader level, BiConsumer placeFunction, RandomSource randomSource, BlockPos pos, TreeFeature config) { return self().getBlock().onTreeGrow(self(), level, placeFunction, randomSource, pos, config); } @@ -587,23 +596,6 @@ public interface IForgeBlockState { return self().getBlock().shouldDisplayFluidOverlay(self(), level, pos, fluidState); } - /** - * Returns the state that this block should transform into when right-clicked by a tool. - * For example: Used to determine if {@link ToolActions#AXE_STRIP an axe can strip}, - * {@link ToolActions#SHOVEL_FLATTEN a shovel can path}, or {@link ToolActions#HOE_TILL a hoe can till}. - * Returns {@code null} if nothing should happen. - * - * @param context The use on context that the action was performed in - * @param toolAction The action being performed by the tool - * @param simulate If {@code true}, no actions that modify the world in any way should be performed. If {@code false}, the world may be modified. - * @return The resulting state after the action has been performed - */ - @Nullable - default BlockState getToolModifiedState(UseOnContext context, ToolAction toolAction, boolean simulate) { - BlockState eventState = net.minecraftforge.event.ForgeEventFactory.onToolUse(self(), context, toolAction, simulate); - return eventState != self() ? eventState : self().getBlock().getToolModifiedState(self(), context, toolAction, simulate); - } - /** * Checks if a player or entity handles movement on this block like scaffolding. * diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeItem.java b/src/main/java/net/minecraftforge/common/extensions/IForgeItem.java index ec27cbdac2..19237d2a12 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeItem.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeItem.java @@ -319,10 +319,7 @@ public interface IForgeItem { */ default boolean canPerformAction(ItemStack stack, ToolAction toolAction) { if (stack.is(ItemTags.SWORDS)) - return ToolActions.DEFAULT_SWORD_ACTIONS.contains(toolAction); - else if (stack.is(ItemTags.PICKAXES)) - return ToolActions.DEFAULT_PICKAXE_ACTIONS.contains(toolAction); - + return toolAction == ToolActions.SWORD_SWEEP; return false; } @@ -470,7 +467,7 @@ public interface IForgeItem { * @apiNote If the item stack is not {@linkplain ItemStack#isDamageableItem() damageable} or the player * {@linkplain Player#hasInfiniteMaterials() has infinite materials}, this method will not be called. */ - default int damageItem(ItemStack stack, int damage, ServerLevel level, @Nullable ServerPlayer player, boolean canBreak, Consumer onBroken) { + default int damageItem(ItemStack stack, int damage, ServerLevel level, @Nullable ServerPlayer player, boolean canBreak, Consumer onBroken) { return damage; } diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeItemStack.java b/src/main/java/net/minecraftforge/common/extensions/IForgeItemStack.java index a0f5be3279..bea599b6c0 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeItemStack.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeItemStack.java @@ -369,7 +369,7 @@ public interface IForgeItemStack { * {@linkplain Player#hasInfiniteMaterials() has infinite materials}, this method will not be called. * @see IForgeItem#damageItem(ItemStack, int, ServerLevel, ServerPlayer, boolean, Consumer) */ - default int damageItem(int damage, ServerLevel level, @Nullable ServerPlayer player, boolean canBreak, Consumer onBroken) { + default int damageItem(int damage, ServerLevel level, @Nullable ServerPlayer player, boolean canBreak, Consumer onBroken) { return self().getItem().damageItem(self(), damage, level, player, canBreak, onBroken); } diff --git a/src/main/java/net/minecraftforge/common/extensions/IForgeRegistrySetBuilder.java b/src/main/java/net/minecraftforge/common/extensions/IForgeRegistrySetBuilder.java index 22e4b21bae..d30d792586 100644 --- a/src/main/java/net/minecraftforge/common/extensions/IForgeRegistrySetBuilder.java +++ b/src/main/java/net/minecraftforge/common/extensions/IForgeRegistrySetBuilder.java @@ -5,9 +5,10 @@ package net.minecraftforge.common.extensions; -import com.mojang.serialization.Lifecycle; - +import net.minecraft.core.HolderLookup; +import net.minecraft.core.RegistryAccess; import net.minecraft.core.RegistrySetBuilder; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraftforge.registries.DeferredRegisterData; public interface IForgeRegistrySetBuilder { @@ -19,7 +20,11 @@ public interface IForgeRegistrySetBuilder { return self().add(dr.getRegistryKey(), dr); } - default RegistrySetBuilder add(DeferredRegisterData dr, Lifecycle lifecycle) { - return self().add(dr.getRegistryKey(), lifecycle, dr); + default RegistrySetBuilder copy() { + return new RegistrySetBuilder().add(self()); + } + + default HolderLookup.Provider buildBuiltIn() { + return self().build(RegistryAccess.fromRegistryOfRegistries(BuiltInRegistries.REGISTRY)); } } diff --git a/src/main/java/net/minecraftforge/common/loot/CanToolPerformAction.java b/src/main/java/net/minecraftforge/common/loot/CanToolPerformAction.java index 93d53ae5a4..45452e6689 100644 --- a/src/main/java/net/minecraftforge/common/loot/CanToolPerformAction.java +++ b/src/main/java/net/minecraftforge/common/loot/CanToolPerformAction.java @@ -40,7 +40,7 @@ public record CanToolPerformAction(ToolAction action) implements LootItemConditi @Override public boolean test(LootContext ctx) { - var instance = ctx.getOptionalParameter(LootContextParams.TOOL); + var instance = ctx.getOptional(LootContextParams.TOOL); ItemStack item = null; if (instance instanceof ItemStack stack) item = stack; diff --git a/src/main/java/net/minecraftforge/common/world/BiomeModifier.java b/src/main/java/net/minecraftforge/common/world/BiomeModifier.java index 07d17e4d9f..e4442f8226 100644 --- a/src/main/java/net/minecraftforge/common/world/BiomeModifier.java +++ b/src/main/java/net/minecraftforge/common/world/BiomeModifier.java @@ -10,8 +10,7 @@ import com.mojang.serialization.MapCodec; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; -import net.minecraft.core.RegistryCodecs; -import net.minecraft.resources.RegistryFileCodec; +import net.minecraft.core.registries.codec.RegistryCodecs; import net.minecraft.resources.RegistryOps; import net.minecraft.world.level.biome.Biome; import net.minecraftforge.common.world.ModifiableBiomeInfo.BiomeInfo; @@ -43,13 +42,13 @@ public interface BiomeModifier { * Codec for referring to biome modifiers by id in other datapack registry files. * Can only be used with {@link RegistryOps}. */ - Codec> REFERENCE_CODEC = RegistryFileCodec.create(ForgeRegistries.Keys.BIOME_MODIFIERS, DIRECT_CODEC); + Codec> REFERENCE_CODEC = RegistryCodecs.holder(ForgeRegistries.Keys.BIOME_MODIFIERS, DIRECT_CODEC); /** * Codec for referring to biome modifiers by id, list of id, or tags. * Can only be used with {@link RegistryOps}. */ - Codec> LIST_CODEC = RegistryCodecs.homogeneousList(ForgeRegistries.Keys.BIOME_MODIFIERS, DIRECT_CODEC); + Codec> LIST_CODEC = RegistryCodecs.holderSet(ForgeRegistries.Keys.BIOME_MODIFIERS, DIRECT_CODEC); /** * Modifies the information via the provided biome builder. diff --git a/src/main/java/net/minecraftforge/common/world/ClimateSettingsBuilder.java b/src/main/java/net/minecraftforge/common/world/ClimateSettingsBuilder.java index af9164b282..cc3d0d4c81 100644 --- a/src/main/java/net/minecraftforge/common/world/ClimateSettingsBuilder.java +++ b/src/main/java/net/minecraftforge/common/world/ClimateSettingsBuilder.java @@ -11,8 +11,7 @@ import net.minecraft.world.level.biome.Biome.TemperatureModifier; /** * Builder for {@link ClimateSettings}. */ -public class ClimateSettingsBuilder -{ +public class ClimateSettingsBuilder { private boolean hasPrecipitation; private float temperature; private TemperatureModifier temperatureModifier; @@ -22,8 +21,7 @@ public class ClimateSettingsBuilder * @param settings Existing ClimateSettings. * @return A new builder with a copy of that ClimateSettings's values. */ - public static ClimateSettingsBuilder copyOf(ClimateSettings settings) - { + public static ClimateSettingsBuilder copyOf(ClimateSettings settings) { return create(settings.hasPrecipitation(), settings.temperature(), settings.temperatureModifier(), settings.downfall()); } @@ -37,13 +35,11 @@ public class ClimateSettingsBuilder * Biomes with downfall > 0.85 count as humid, inhibiting fire spread. * @return a new builder with the given values */ - public static ClimateSettingsBuilder create(boolean hasPrecipitation, float temperature, TemperatureModifier temperatureModifier, float downfall) - { + public static ClimateSettingsBuilder create(boolean hasPrecipitation, float temperature, TemperatureModifier temperatureModifier, float downfall) { return new ClimateSettingsBuilder(hasPrecipitation, temperature, temperatureModifier, downfall); } - private ClimateSettingsBuilder(boolean hasPrecipitation, float temperature, TemperatureModifier temperatureModifier, float downfall) - { + private ClimateSettingsBuilder(boolean hasPrecipitation, float temperature, TemperatureModifier temperatureModifier, float downfall) { this.hasPrecipitation = hasPrecipitation; this.temperature = temperature; this.temperatureModifier = temperatureModifier; @@ -53,24 +49,21 @@ public class ClimateSettingsBuilder /** * @return A new ClimateSettings with the finalized values. */ - public ClimateSettings build() - { + public ClimateSettings build() { return new ClimateSettings(this.hasPrecipitation, this.temperature, this.temperatureModifier, this.downfall); } /** * @return Synced to clients, determines weather effects. */ - public boolean hasPrecipitation() - { + public boolean hasPrecipitation() { return hasPrecipitation; } /** * @param hasPrecipitation Synced to clients, determines weather effects. */ - public void setHasPrecipitation(boolean hasPrecipitation) - { + public void setHasPrecipitation(boolean hasPrecipitation) { this.hasPrecipitation = hasPrecipitation; } @@ -78,8 +71,7 @@ public class ClimateSettingsBuilder * {@return Synced to clients, affects foliage color, freezing, and weather effects} * Vanilla values are in the range [-0.5, 2.0]. */ - public float getTemperature() - { + public float getTemperature() { return temperature; } @@ -87,8 +79,7 @@ public class ClimateSettingsBuilder * @param temperature Synced to clients, affects foliage color, freezing, and weather effects. * Vanilla values are in the range [-0.5, 2.0]. */ - public void setTemperature(float temperature) - { + public void setTemperature(float temperature) { this.temperature = temperature; } @@ -96,8 +87,7 @@ public class ClimateSettingsBuilder * {@return temperatureModifier Synced to clients, applies a positional modifier to temperature.} * Frozen Oceans use this to have occasional warm patches. */ - public TemperatureModifier getTemperatureModifier() - { + public TemperatureModifier getTemperatureModifier() { return temperatureModifier; } @@ -105,8 +95,7 @@ public class ClimateSettingsBuilder * @param temperatureModifier Synced to clients, applies a positional modifier to temperature. * Frozen Oceans use this to have occasional warm patches. */ - public void setTemperatureModifier(TemperatureModifier temperatureModifier) - { + public void setTemperatureModifier(TemperatureModifier temperatureModifier) { this.temperatureModifier = temperatureModifier; } @@ -114,8 +103,7 @@ public class ClimateSettingsBuilder * {@return Synced to clients, affects foliage color.} * Biomes with downfall > 0.85 count as humid, inhibiting fire spread. */ - public float getDownfall() - { + public float getDownfall() { return downfall; } @@ -123,8 +111,7 @@ public class ClimateSettingsBuilder * @param downfall Synced to clients, affects foliage color. * Biomes with downfall > 0.85 count as humid, inhibiting fire spread. */ - public void setDownfall(float downfall) - { + public void setDownfall(float downfall) { this.downfall = downfall; } } diff --git a/src/main/java/net/minecraftforge/common/world/ForgeBiomeModifiers.java b/src/main/java/net/minecraftforge/common/world/ForgeBiomeModifiers.java index 4f700b08ea..e23ad6bbcb 100644 --- a/src/main/java/net/minecraftforge/common/world/ForgeBiomeModifiers.java +++ b/src/main/java/net/minecraftforge/common/world/ForgeBiomeModifiers.java @@ -8,6 +8,9 @@ package net.minecraftforge.common.world; import java.util.EnumSet; import java.util.List; import java.util.Set; + +import org.jspecify.annotations.Nullable; + import com.mojang.datafixers.util.Either; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; @@ -15,9 +18,11 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; -import net.minecraft.core.RegistryCodecs; +import net.minecraft.core.registries.codec.RegistryCodecs; import net.minecraft.util.random.Weighted; import net.minecraft.util.random.WeightedList; +import net.minecraft.world.attribute.EnvironmentAttributes; +import net.minecraft.world.attribute.modifier.MobSpawnSettingsModifier; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.level.biome.Biome; @@ -30,6 +35,17 @@ import net.minecraftforge.registries.ForgeRegistries; public final class ForgeBiomeModifiers { private ForgeBiomeModifiers() {} // Utility class. + private static @Nullable MobSpawnSettingsBuilder get(Builder builder) { + var entry = builder.attributes().get(EnvironmentAttributes.NATURAL_MOB_SPAWNS); + if (entry == null || entry.modifier() != MobSpawnSettingsModifier.overlay()) + return null; + return new MobSpawnSettingsBuilder(entry.cast(MobSpawnSettingsModifier.overlay())); + } + + private static void set(Builder builder, MobSpawnSettingsBuilder spawns) { + builder.attributes().modify(EnvironmentAttributes.NATURAL_MOB_SPAWNS, MobSpawnSettingsModifier.overlay(), spawns.build()); + } + /** *

    Stock biome modifier that adds features to biomes. Has the following json format:

    *
    @@ -56,7 +72,7 @@ public final class ForgeBiomeModifiers {
             @Override
             public void modify(Holder biome, Phase phase, Builder builder) {
                 if (phase == Phase.ADD && this.biomes.contains(biome)) {
    -                var generationSettings = builder.getGenerationSettings();
    +                var generationSettings = builder.generationSettings();
                     this.features.forEach(holder -> generationSettings.addFeature(this.step, holder));
                 }
             }
    @@ -105,7 +121,7 @@ public final class ForgeBiomeModifiers {
             @Override
             public void modify(Holder biome, Phase phase, Builder builder) {
                 if (phase == Phase.REMOVE && this.biomes.contains(biome)) {
    -                var generationSettings = builder.getGenerationSettings();
    +                var generationSettings = builder.generationSettings();
                     for (Decoration step : this.steps)
                         generationSettings.getFeatures(step).removeIf(this.features::contains);
                 }
    @@ -176,10 +192,13 @@ public final class ForgeBiomeModifiers {
             @Override
             public void modify(Holder biome, Phase phase, Builder builder) {
                 if (phase == Phase.ADD && this.biomes.contains(biome)) {
    -                var spawns = builder.getMobSpawnSettings();
    -                for (var weighted : this.spawners.unwrap()) {
    -                    var spawner = weighted.value();
    -                    spawns.addSpawn(spawner.type().getCategory(), weighted.weight(), spawner);
    +                var spawns = get(builder);
    +                if (spawns != null) {
    +                    for (var weighted : this.spawners.unwrap()) {
    +                        var spawner = weighted.value();
    +                        spawns.addSpawn(spawner.type(), weighted.weight(), spawner.count());
    +                    }
    +                    set(builder, spawns);
                     }
                 }
             }
    @@ -207,15 +226,18 @@ public final class ForgeBiomeModifiers {
             public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(builder ->
                 builder.group(
                     Biome.LIST_CODEC.fieldOf("biomes").forGetter(RemoveSpawnsBiomeModifier::biomes),
    -                RegistryCodecs.homogeneousList(ForgeRegistries.Keys.ENTITY_TYPES).fieldOf("entity_types").forGetter(RemoveSpawnsBiomeModifier::entityTypes)
    +                RegistryCodecs.holderSet(ForgeRegistries.Keys.ENTITY_TYPES).fieldOf("entity_types").forGetter(RemoveSpawnsBiomeModifier::entityTypes)
                 ).apply(builder, RemoveSpawnsBiomeModifier::new));
     
             @Override
             public void modify(Holder biome, Phase phase, Builder builder) {
                 if (phase == Phase.REMOVE && this.biomes.contains(biome)) {
    -                var spawns = builder.getMobSpawnSettings();
    -                for (var category : MobCategory.values())
    -                    spawns.getSpawner(category).removeIf(data -> this.entityTypes.contains(ForgeRegistries.ENTITY_TYPES.getHolder(data.type()).orElseThrow()));
    +                var spawns = get(builder);
    +                if (spawns != null) {
    +                    for (var category : MobCategory.values())
    +                        spawns.getSpawner(category).removeIf(data -> this.entityTypes.contains(ForgeRegistries.ENTITY_TYPES.getHolder(data.type()).orElseThrow()));
    +                    set(builder, spawns);
    +                }
                 }
             }
     
    diff --git a/src/main/java/net/minecraftforge/common/world/MobSpawnSettingsBuilder.java b/src/main/java/net/minecraftforge/common/world/MobSpawnSettingsBuilder.java
    index dbd6a0d2b0..7af03de312 100644
    --- a/src/main/java/net/minecraftforge/common/world/MobSpawnSettingsBuilder.java
    +++ b/src/main/java/net/minecraftforge/common/world/MobSpawnSettingsBuilder.java
    @@ -15,15 +15,14 @@ import net.minecraft.world.level.biome.MobSpawnSettings;
     import org.jetbrains.annotations.Nullable;
     
     public class MobSpawnSettingsBuilder extends MobSpawnSettings.Builder {
    -    private final Set typesView = Collections.unmodifiableSet(this.spawners.keySet());
    +    private final Set typesView = Collections.unmodifiableSet(this.spawnsByCategory.keySet());
         private final Set> costView = Collections.unmodifiableSet(this.mobSpawnCosts.keySet());
     
         public MobSpawnSettingsBuilder(MobSpawnSettings orig) {
             orig.getSpawnerTypes().forEach(k ->
    -            spawners.put(k, WeightedList.builder().addAll(orig.getMobs(k).unwrap()))
    +            spawnsByCategory.put(k, WeightedList.builder().addAll(orig.getMobsToSpawn(k).unwrap()))
             );
             orig.getEntityTypes().forEach(k -> mobSpawnCosts.put(k, orig.getMobSpawnCost(k)));
    -        creatureGenerationProbability = orig.getCreatureProbability();
         }
     
         public Set getSpawnerTypes() {
    @@ -31,7 +30,7 @@ public class MobSpawnSettingsBuilder extends MobSpawnSettings.Builder {
         }
     
         public WeightedList.Builder getSpawner(MobCategory type) {
    -        return this.spawners.get(type);
    +        return this.spawnsByCategory.get(type);
         }
     
         public Set> getEntityTypes() {
    @@ -43,10 +42,6 @@ public class MobSpawnSettingsBuilder extends MobSpawnSettings.Builder {
             return this.mobSpawnCosts.get(type);
         }
     
    -    public float getProbability() {
    -        return this.creatureGenerationProbability;
    -    }
    -
         public MobSpawnSettingsBuilder disablePlayerSpawn() {
             return this;
         }
    diff --git a/src/main/java/net/minecraftforge/common/world/ModifiableBiomeInfo.java b/src/main/java/net/minecraftforge/common/world/ModifiableBiomeInfo.java
    index 0d72cf6f4c..b9723e8aeb 100644
    --- a/src/main/java/net/minecraftforge/common/world/ModifiableBiomeInfo.java
    +++ b/src/main/java/net/minecraftforge/common/world/ModifiableBiomeInfo.java
    @@ -7,17 +7,18 @@ package net.minecraftforge.common.world;
     
     import java.util.List;
     import java.util.Locale;
    +import java.util.function.Consumer;
     
     import org.jetbrains.annotations.ApiStatus;
     import org.jetbrains.annotations.NotNull;
     import org.jetbrains.annotations.Nullable;
     
     import net.minecraft.core.Holder;
    +import net.minecraft.world.attribute.EnvironmentAttributeMap;
     import net.minecraft.world.level.biome.Biome;
     import net.minecraft.world.level.biome.Biome.ClimateSettings;
     import net.minecraft.world.level.biome.BiomeGenerationSettings;
     import net.minecraft.world.level.biome.BiomeSpecialEffects;
    -import net.minecraft.world.level.biome.MobSpawnSettings;
     
     /**
      * Holds lazy-evaluable modified biome info.
    @@ -27,14 +28,18 @@ import net.minecraft.world.level.biome.MobSpawnSettings;
     public class ModifiableBiomeInfo {
         @NotNull
         private final BiomeInfo originalBiomeInfo;
    +    @NotNull
    +    private final Consumer callback;
         @Nullable
         private BiomeInfo modifiedBiomeInfo = null;
     
         /**
          * @param originalBiomeInfo BiomeInfo representing the original state of a biome when the biome was constructed.
          */
    -    public ModifiableBiomeInfo(@NotNull final BiomeInfo originalBiomeInfo) {
    +    @ApiStatus.Internal
    +    public ModifiableBiomeInfo(@NotNull final BiomeInfo originalBiomeInfo, @NotNull final Consumer callback) {
             this.originalBiomeInfo = originalBiomeInfo;
    +        this.callback = callback;
         }
     
         /**
    @@ -77,12 +82,13 @@ public class ModifiableBiomeInfo {
                 throw new IllegalStateException(String.format(Locale.ENGLISH, "Biome %s already modified", biome));
     
             var original = this.getOriginalBiomeInfo();
    -        var builder = BiomeInfo.Builder.copyOf(original);
    +        var builder = original.builder();
             for (var phase : BiomeModifier.Phase.values()) {
                 for (var modifier : biomeModifiers)
                     modifier.modify(biome, phase, builder);
             }
             this.modifiedBiomeInfo = builder.build();
    +        this.callback.accept(this.modifiedBiomeInfo);
         }
     
         /**
    @@ -92,57 +98,46 @@ public class ModifiableBiomeInfo {
          * @param generationSettings Worldgen features and carvers.
          * @param mobSpawnSettings Mob spawn settings.
          */
    -    public record BiomeInfo(ClimateSettings climateSettings, BiomeSpecialEffects effects, BiomeGenerationSettings generationSettings, MobSpawnSettings mobSpawnSettings) {
    -        public static class Builder {
    -            private ClimateSettingsBuilder climateSettings;
    -            private BiomeSpecialEffectsBuilder effects;
    -            private BiomeGenerationSettings.PlainBuilder generationSettings;
    -            private MobSpawnSettingsBuilder mobSpawnSettings;
    +    public record BiomeInfo(
    +        ClimateSettings climateSettings,
    +        EnvironmentAttributeMap attributes,
    +        BiomeSpecialEffects effects,
    +        BiomeGenerationSettings generationSettings
    +    ) {
    +        /**
    +         * @param original the biome to copy
    +         * @return A ModifiedBiomeInfo.Builder with a copy of the biome's data
    +         */
    +        private Builder builder() {
    +            var climateBuilder = ClimateSettingsBuilder.copyOf(climateSettings());
    +            var attributes = EnvironmentAttributeMap.builder().putAll(attributes());
    +            var effectsBuilder = BiomeSpecialEffectsBuilder.copyOf(effects());
    +            var generationBuilder = new BiomeGenerationSettings.PlainBuilder();
    +            generationBuilder.addFrom(generationSettings());
     
    -            /**
    -             * @param original the biome to copy
    -             * @return A ModifiedBiomeInfo.Builder with a copy of the biome's data
    -             */
    -            public static Builder copyOf(final BiomeInfo original) {
    -                final ClimateSettingsBuilder climateBuilder = ClimateSettingsBuilder.copyOf(original.climateSettings());
    -                final BiomeSpecialEffectsBuilder effectsBuilder = BiomeSpecialEffectsBuilder.copyOf(original.effects());
    -                final var generationBuilder = new BiomeGenerationSettings.PlainBuilder();
    -                generationBuilder.addFrom(original.generationSettings());
    -                final MobSpawnSettingsBuilder mobSpawnBuilder = new MobSpawnSettingsBuilder(original.mobSpawnSettings());
    +            return new Builder(
    +                climateBuilder,
    +                attributes,
    +                effectsBuilder,
    +                generationBuilder
    +            );
    +        }
     
    -                return new Builder(
    -                    climateBuilder,
    -                    effectsBuilder,
    -                    generationBuilder,
    -                    mobSpawnBuilder
    -                );
    -            }
     
    -            private Builder(final ClimateSettingsBuilder climateSettings, final BiomeSpecialEffectsBuilder effects, final BiomeGenerationSettings.PlainBuilder generationSettings, final MobSpawnSettingsBuilder mobSpawnSettings) {
    -                this.climateSettings = climateSettings;
    -                this.effects = effects;
    -                this.generationSettings = generationSettings;
    -                this.mobSpawnSettings = mobSpawnSettings;
    -            }
     
    +        public record Builder(
    +            ClimateSettingsBuilder climateSettings,
    +            EnvironmentAttributeMap.Builder attributes,
    +            BiomeSpecialEffectsBuilder effects,
    +            BiomeGenerationSettings.PlainBuilder generationSettings
    +        ) {
                 public BiomeInfo build() {
    -                return new BiomeInfo(this.climateSettings.build(), this.effects.build(), this.generationSettings.build(), this.mobSpawnSettings.build());
    -            }
    -
    -            public ClimateSettingsBuilder getClimateSettings() {
    -                return climateSettings;
    -            }
    -
    -            public BiomeSpecialEffectsBuilder getSpecialEffects() {
    -                return effects;
    -            }
    -
    -            public BiomeGenerationSettings.PlainBuilder getGenerationSettings() {
    -                return generationSettings;
    -            }
    -
    -            public MobSpawnSettingsBuilder getMobSpawnSettings() {
    -                return mobSpawnSettings;
    +                return new BiomeInfo(
    +                    this.climateSettings.build(),
    +                    this.attributes.build(),
    +                    this.effects.build(),
    +                    this.generationSettings.build()
    +                );
                 }
             }
         }
    diff --git a/src/main/java/net/minecraftforge/common/world/StructureModifier.java b/src/main/java/net/minecraftforge/common/world/StructureModifier.java
    index 94b56b0820..b39dfcfdfc 100644
    --- a/src/main/java/net/minecraftforge/common/world/StructureModifier.java
    +++ b/src/main/java/net/minecraftforge/common/world/StructureModifier.java
    @@ -11,8 +11,7 @@ import com.mojang.serialization.MapCodec;
     import java.util.function.Function;
     import net.minecraft.core.Holder;
     import net.minecraft.core.HolderSet;
    -import net.minecraft.core.RegistryCodecs;
    -import net.minecraft.resources.RegistryFileCodec;
    +import net.minecraft.core.registries.codec.RegistryCodecs;
     import net.minecraft.resources.RegistryOps;
     import net.minecraft.world.level.levelgen.structure.Structure;
     import net.minecraftforge.common.world.ModifiableStructureInfo.StructureInfo;
    @@ -43,13 +42,13 @@ public interface StructureModifier {
          * Codec for referring to structure modifiers by id in other datapack registry files.
          * Can only be used with {@link RegistryOps}.
          */
    -    Codec> REFERENCE_CODEC = RegistryFileCodec.create(ForgeRegistries.Keys.STRUCTURE_MODIFIERS, DIRECT_CODEC);
    +    Codec> REFERENCE_CODEC = RegistryCodecs.holder(ForgeRegistries.Keys.STRUCTURE_MODIFIERS, DIRECT_CODEC);
     
         /**
          * Codec for referring to structure modifiers by id, list of id, or tags.
          * Can only be used with {@link RegistryOps}.
          */
    -    Codec> LIST_CODEC = RegistryCodecs.homogeneousList(ForgeRegistries.Keys.STRUCTURE_MODIFIERS, DIRECT_CODEC);
    +    Codec> LIST_CODEC = RegistryCodecs.holderSet(ForgeRegistries.Keys.STRUCTURE_MODIFIERS, DIRECT_CODEC);
     
         /**
          * Modifies the information via the provided structure builder.
    diff --git a/src/main/java/net/minecraftforge/data/loading/DatagenModLoader.java b/src/main/java/net/minecraftforge/data/loading/DatagenModLoader.java
    index 65c3173adc..ab330e5e99 100644
    --- a/src/main/java/net/minecraftforge/data/loading/DatagenModLoader.java
    +++ b/src/main/java/net/minecraftforge/data/loading/DatagenModLoader.java
    @@ -91,7 +91,8 @@ public final class DatagenModLoader {
             if (genClient)
                 ClientBootstrap.bootstrap();
             ModLoader.gatherAndInitializeMods(ModWorkManager.syncExecutor(), ModWorkManager.parallelExecutor(), ()->{});
    -        var lookupProvider = CompletableFuture.supplyAsync(VanillaRegistries::createLookup, Util.backgroundExecutor());
    +        var lookupProvider = CompletableFuture.supplyAsync(VanillaRegistries::createWorldLookup, Util.backgroundExecutor())
    +                .thenApplyAsync(VanillaRegistries::createReloadableLookup, Util.backgroundExecutor());
     
             var mods = new HashSet();
             for (var pattern : patterns) {
    diff --git a/src/main/java/net/minecraftforge/event/AddPackFindersEvent.java b/src/main/java/net/minecraftforge/event/AddPackFindersEvent.java
    index 565593d123..208732150e 100644
    --- a/src/main/java/net/minecraftforge/event/AddPackFindersEvent.java
    +++ b/src/main/java/net/minecraftforge/event/AddPackFindersEvent.java
    @@ -10,22 +10,20 @@ import net.minecraft.server.packs.repository.PackRepository;
     import net.minecraft.server.packs.repository.RepositorySource;
     import net.minecraftforge.eventbus.api.bus.EventBus;
     import net.minecraftforge.eventbus.api.event.RecordEvent;
    +import org.jspecify.annotations.NullMarked;
     
     import java.util.function.Consumer;
     
    -/**
    - * Fired on {@link PackRepository} creation to allow mods to add new pack finders.
    - *
    - * @param getPackType the {@link PackType} of the pack repository being constructed.
    - */
    +/// Fired on [PackRepository] creation to allow mods to add new pack finders.
    +///
    +/// @param getPackType the [PackType] of the pack repository being constructed.
    +@NullMarked
     public record AddPackFindersEvent(PackType getPackType, Consumer sourceAdder) implements RecordEvent {
         public static final EventBus BUS = EventBus.create(AddPackFindersEvent.class);
     
    -    /**
    -     * Adds a new source to the list of pack finders.
    -     *
    -     * @param source the pack finder
    -     */
    +    /// Adds a new source to the list of pack finders.
    +    ///
    +    /// @param source the pack finder
         public void addRepositorySource(RepositorySource source) {
             sourceAdder.accept(source);
         }
    diff --git a/src/main/java/net/minecraftforge/event/AddReloadListenerEvent.java b/src/main/java/net/minecraftforge/event/AddReloadListenerEvent.java
    index ee93168dd4..e0d1b4cc7f 100644
    --- a/src/main/java/net/minecraftforge/event/AddReloadListenerEvent.java
    +++ b/src/main/java/net/minecraftforge/event/AddReloadListenerEvent.java
    @@ -19,10 +19,9 @@ import java.util.List;
     import java.util.concurrent.CompletableFuture;
     import java.util.concurrent.Executor;
     
    -/**
    - * The main ResourceManager is recreated on each reload, just after {@link ReloadableServerResources}'s creation.
    - * 

    The event is fired on each reload and lets modders add their own ReloadListeners, for server-side resources.

    - */ +/// The main ResourceManager is recreated on each reload, just after [ReloadableServerResources]'s creation. +/// +/// The event is fired on each reload and lets modders add their own ReloadListeners, for server-side resources. @NullMarked public final class AddReloadListenerEvent extends MutableEvent { public static final EventBus BUS = EventBus.create(AddReloadListenerEvent.class); @@ -37,10 +36,8 @@ public final class AddReloadListenerEvent extends MutableEvent { this.registries = registries; } - /** - * @param listener the listener to add to the ResourceManager on reload - */ - public void addListener(PreparableReloadListener listener) { + /// @param listener the listener to add to the ResourceManager on reload + public void addListener(PreparableReloadListener listener) { listeners.add(new WrappedStateAwareListener(listener)); } @@ -49,26 +46,20 @@ public final class AddReloadListenerEvent extends MutableEvent { return List.copyOf(listeners); } - /** - * @return The ReloableServerResources being reloaded. - */ + /// @return The [ReloadableServerResources] being reloaded. public ReloadableServerResources getServerResources() { return serverResources; } - /** - * This context object holds data relevant to the current reload, such as staged tags. - * @return The condition context for the currently active reload. - */ + /// This context object holds data relevant to the current reload, such as staged tags. + /// @return The condition context for the currently active reload. public ICondition.IContext getConditionContext() { return serverResources.getConditionContext(); } - /** - * @return A holder lookup provider containing the registries with updated tags. - * - * @see net.minecraft.server.ReloadableServerRegistries.LoadResult#lookupWithUpdatedTags() - */ + /// @return A holder lookup provider containing the registries with updated tags. + /// + /// @see net.minecraft.server.ReloadableServerRegistries.LoadResult#lookupWithUpdatedTags() public HolderLookup.Provider getRegistries() { return registries; } diff --git a/src/main/java/net/minecraftforge/event/DifficultyChangeEvent.java b/src/main/java/net/minecraftforge/event/DifficultyChangeEvent.java index affb64b101..356ba2ac40 100644 --- a/src/main/java/net/minecraftforge/event/DifficultyChangeEvent.java +++ b/src/main/java/net/minecraftforge/event/DifficultyChangeEvent.java @@ -8,12 +8,12 @@ package net.minecraftforge.event; import net.minecraft.world.Difficulty; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.RecordEvent; +import org.jspecify.annotations.NullMarked; -/** - * DifficultyChangeEvent is fired when difficulty is changing.
    - *
    - * This event is fired via the {@link ForgeEventFactory#onDifficultyChange(Difficulty, Difficulty)}.
    - */ +/// This event is fired when difficulty is changing. +/// +/// This event is fired from [ForgeEventFactory#onDifficultyChange(Difficulty, Difficulty)]. +@NullMarked public record DifficultyChangeEvent(Difficulty getDifficulty, Difficulty getOldDifficulty) implements RecordEvent { public static final EventBus BUS = EventBus.create(DifficultyChangeEvent.class); } diff --git a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java index e1cf718988..52a5ee8af1 100644 --- a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java +++ b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java @@ -66,6 +66,7 @@ import net.minecraft.world.DifficultyInstance; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.attribute.BedRule; +import net.minecraft.world.attribute.EnvironmentAttributes; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectInstance; @@ -76,14 +77,12 @@ import net.minecraft.world.entity.npc.villager.AbstractVillager; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.Projectile; import net.minecraft.world.entity.projectile.throwableitemprojectile.ThrownEnderpearl; -import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.ClickAction; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ItemUtils; import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.item.alchemy.PotionBrewing.Builder; -import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.trading.MerchantOffer; import net.minecraft.world.level.BaseSpawner; @@ -95,6 +94,7 @@ import net.minecraft.world.level.LevelSimulatedReader; import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.SpawnData; import net.minecraft.world.level.biome.MobSpawnSettings; +import net.minecraft.world.level.block.AbstractBedBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.NoteBlockInstrument; import net.minecraft.world.level.chunk.ChunkAccess; @@ -102,18 +102,16 @@ import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.status.ChunkType; import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.gamerules.GameRules; -import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.portal.PortalShape; import net.minecraft.world.level.storage.ServerLevelData; import net.minecraft.world.level.storage.ValueInput; import net.minecraft.world.level.storage.loot.LootTable; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.common.ToolAction; import net.minecraftforge.common.capabilities.CapabilityDispatcher; import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.util.BlockSnapshot; -import net.minecraftforge.event.brewing.BrewingRecipeRegisterEvent; import net.minecraftforge.event.brewing.PlayerBrewedPotionEvent; import net.minecraftforge.event.brewing.PotionBrewEvent; import net.minecraftforge.event.enchanting.EnchantmentLevelSetEvent; @@ -180,7 +178,6 @@ import net.minecraftforge.event.entity.player.TradeWithVillagerEvent; import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent; import net.minecraftforge.event.level.AlterGroundEvent; import net.minecraftforge.event.level.BlockEvent; -import net.minecraftforge.event.level.BlockEvent.BlockToolModificationEvent; import net.minecraftforge.event.level.BlockEvent.CreateFluidSourceEvent; import net.minecraftforge.event.level.BlockEvent.EntityMultiPlaceEvent; import net.minecraftforge.event.level.BlockEvent.NeighborNotifyEvent; @@ -355,8 +352,8 @@ public final class ForgeEventFactory { return BlockEvent.FluidPlaceBlockEvent.BUS.fire(new BlockEvent.FluidPlaceBlockEvent(level, pos, liquidPos, state)).getNewState(); } - public static ItemTooltipEvent onItemTooltip(ItemStack itemStack, @Nullable Player entityPlayer, List list, TooltipFlag flags, Item.TooltipContext context, TooltipDisplay display) { - return ItemTooltipEvent.BUS.fire(new ItemTooltipEvent(itemStack, entityPlayer, list, flags, context, display)); + public static void onItemTooltip(ItemStack itemStack, @Nullable Player entityPlayer, List list, TooltipFlag flags, Item.TooltipContext context, TooltipDisplay display) { + ItemTooltipEvent.BUS.post(new ItemTooltipEvent(itemStack, entityPlayer, list, flags, context, display)); } public static SummonAidEvent fireZombieSummonAid(Zombie zombie, Level level, int x, int y, int z, LivingEntity attacker, double summonChance) { @@ -401,12 +398,6 @@ public final class ForgeEventFactory { PlayerEvent.SaveToFile.BUS.post(new PlayerEvent.SaveToFile(player, playerDirectory, uuidString)); } - @Nullable - public static BlockState onToolUse(BlockState originalState, UseOnContext context, ToolAction toolAction, boolean simulate) { - var event = new BlockToolModificationEvent(originalState, context, toolAction, simulate); - return BlockToolModificationEvent.BUS.post(event) ? null : event.getFinalState(); - } - public static int onApplyBonemeal(@Nullable Player player, Level level, BlockPos pos, BlockState state, ItemStack stack) { if (player == null) return 0; @@ -427,19 +418,9 @@ public final class ForgeEventFactory { if (FillBucketEvent.BUS.post(event)) return InteractionResult.FAIL; - if (event.getResult() == Result.ALLOW) { - if (player.getAbilities().instabuild) - return InteractionResult.SUCCESS.heldItemTransformedTo(stack); + if (event.getResult() == Result.ALLOW) + return InteractionResult.SUCCESS.heldItemTransformedTo(ItemUtils.createFilledResult(stack, player, event.getFilledBucket())); - stack.shrink(1); - if (stack.isEmpty()) - return InteractionResult.SUCCESS.heldItemTransformedTo(event.getFilledBucket()); - - if (!player.getInventory().add(event.getFilledBucket())) - player.drop(event.getFilledBucket(), false); - - return InteractionResult.SUCCESS.heldItemTransformedTo(stack); - } return null; } @@ -497,7 +478,7 @@ public final class ForgeEventFactory { PlayerFlyableFallEvent.BUS.post(new PlayerFlyableFallEvent(player, distance, multiplier)); } - public static boolean onPlayerSpawnSet(ServerPlayer player, ServerPlayer.RespawnConfig config) { + public static boolean onPlayerSpawnSet(ServerPlayer player, ServerPlayer.@Nullable RespawnConfig config) { return PlayerSetSpawnEvent.BUS.post(new PlayerSetSpawnEvent(player, config)); } @@ -575,20 +556,26 @@ public final class ForgeEventFactory { Result canContinueSleep = evt.getResult(); if (canContinueSleep == Result.DEFAULT) - return player.getSleepingPos().map(pos -> player.level().getBlockState(pos).isBed(player.level(), pos, player)).orElse(false); + return player.getSleepingPos().map(pos -> player.level().getBlockState(pos).getBedHeight(player.level(), sleepingLocation).isPresent()).orElse(false); else return canContinueSleep == Result.ALLOW; } + public static boolean onSleepingTimeCheck(Player player, Optional sleepingLocation) { + var state = player.getInBlockState(); + var rule = state.getBlock() instanceof AbstractBedBlock bed ? bed.getBedRule(player.level(), player.blockPosition()) : player.level().environmentAttributes().getValue(EnvironmentAttributes.BED_RULE, player.blockPosition()); + return onSleepingTimeCheck(player, sleepingLocation, rule); + } + public static boolean onSleepingTimeCheck(Player player, Optional sleepingLocation, BedRule rule) { var evt = new SleepingTimeCheckEvent(player, sleepingLocation); SleepingTimeCheckEvent.BUS.post(evt); var canContinueSleep = evt.getResult(); - if (canContinueSleep == Result.DEFAULT) - return rule.canSleep(player.level()); - else + if (canContinueSleep != Result.DEFAULT) return canContinueSleep == Result.ALLOW; + + return rule.canSleep(player.level()); } public static InteractionResult onArrowNock(ItemStack item, Level level, Player player, InteractionHand hand, boolean hasAmmo) { @@ -644,8 +631,7 @@ public final class ForgeEventFactory { return result == Result.DEFAULT ? level.getGameRules().get(GameRules.MOB_GRIEFING) : result == Result.ALLOW; } - @SuppressWarnings("removal") - public static BlockFeatureGrowEvent blockGrowFeature(LevelAccessor level, RandomSource randomSource, BlockPos pos, @Nullable Holder> holder) { + public static BlockFeatureGrowEvent blockGrowFeature(LevelAccessor level, RandomSource randomSource, BlockPos pos, @Nullable Holder holder) { return BlockFeatureGrowEvent.BUS.fire(new BlockFeatureGrowEvent(level, randomSource, pos, holder)); } @@ -709,9 +695,9 @@ public final class ForgeEventFactory { return EntityTeleportEvent.SpreadPlayersCommand.BUS.post(event) ? null : event; } - public static EntityTeleportEvent.@Nullable EnderEntity onEnderManTeleport(LivingEntity entity, double targetX, double targetY, double targetZ) { - var event = new EntityTeleportEvent.EnderEntity(entity, targetX, targetY, targetZ); - return EntityTeleportEvent.EnderEntity.BUS.post(event) ? null : event; + public static EntityTeleportEvent.@Nullable EntityRandom onEntityRandomTeleport(LivingEntity entity, double targetX, double targetY, double targetZ) { + var event = new EntityTeleportEvent.EntityRandom(entity, targetX, targetY, targetZ); + return EntityTeleportEvent.EntityRandom.BUS.post(event) ? null : event; } public static EntityTeleportEvent.@Nullable EnderPearl onEnderPearlLand(ServerPlayer entity, double targetX, double targetY, double targetZ, ThrownEnderpearl pearlEntity, float attackDamage, HitResult hitResult) { @@ -1022,10 +1008,6 @@ public final class ForgeEventFactory { return GrindstoneEvent.OnPlaceItem.BUS.post(event) ? null : event; } - public static void onBrewingRecipeRegister(Builder builder, FeatureFlagSet features) { - BrewingRecipeRegisterEvent.BUS.post(new BrewingRecipeRegisterEvent(builder, features)); - } - public static boolean onItemStackedOn(ItemStack carriedItem, ItemStack stackedOnItem, Slot slot, ClickAction action, Player player, SlotAccess carriedSlotAccess) { return ItemStackedOnOtherEvent.BUS.post(new ItemStackedOnOtherEvent(carriedItem, stackedOnItem, slot, action, player, carriedSlotAccess)); } diff --git a/src/main/java/net/minecraftforge/event/PlayLevelSoundEvent.java b/src/main/java/net/minecraftforge/event/PlayLevelSoundEvent.java index ee9c1353cc..ac7cb54c41 100644 --- a/src/main/java/net/minecraftforge/event/PlayLevelSoundEvent.java +++ b/src/main/java/net/minecraftforge/event/PlayLevelSoundEvent.java @@ -143,10 +143,6 @@ public sealed class PlayLevelSoundEvent extends MutableEvent implements Cancella *

    * This event is {@link Cancellable cancellable}. * If this event is cancelled, the sound is not played. - *

    - * This event does not have a result. - *

    - * This event is fired on the {@link MinecraftForge#EVENT_BUS}. */ public static final class AtEntity extends PlayLevelSoundEvent { public static final EventBus BUS = EventBus.create(AtEntity.class); @@ -172,10 +168,6 @@ public sealed class PlayLevelSoundEvent extends MutableEvent implements Cancella *

    * This event is {@link Cancellable cancellable}. * If this event is cancelled, the sound is not played. - *

    - * This event does not have a result. - *

    - * This event is fired on the {@link MinecraftForge#EVENT_BUS}. */ public static final class AtPosition extends PlayLevelSoundEvent { public static final EventBus BUS = EventBus.create(AtPosition.class); diff --git a/src/main/java/net/minecraftforge/event/TickEvent.java b/src/main/java/net/minecraftforge/event/TickEvent.java index 7f3f554895..dc7bc852eb 100644 --- a/src/main/java/net/minecraftforge/event/TickEvent.java +++ b/src/main/java/net/minecraftforge/event/TickEvent.java @@ -23,18 +23,13 @@ public sealed interface TickEvent { sealed interface ServerTickEvent extends TickEvent { BooleanSupplier haveTimeSupplier(); - /** - * @return {@code true} whether the server has enough time to perform any - * additional tasks (usually IO related) during the current tick, - * otherwise {@code false} - */ + /// @return `true` whether the server has enough time to perform any + /// additional tasks (usually IO related) during the current tick, otherwise `false` default boolean haveTime() { return haveTimeSupplier().getAsBoolean(); } - /** - * {@return the server instance} - */ + /// @return the server instance MinecraftServer server(); record Pre(BooleanSupplier haveTimeSupplier, MinecraftServer server) implements RecordEvent, ServerTickEvent { @@ -67,8 +62,7 @@ public sealed interface TickEvent { /** * @return {@code true} whether the server has enough time to perform any - * additional tasks (usually IO related) during the current tick, - * otherwise {@code false} + * additional tasks (usually IO related) during the current tick, otherwise {@code false} * @see ServerTickEvent#haveTime() */ default boolean haveTime() { @@ -85,6 +79,8 @@ public sealed interface TickEvent { } sealed interface PlayerTickEvent extends TickEvent { + Player player(); + LogicalSide side(); record Pre(Player player, LogicalSide side) implements RecordEvent, PlayerTickEvent { @@ -105,6 +101,8 @@ public sealed interface TickEvent { } sealed interface RenderTickEvent extends TickEvent { + DeltaTracker timer(); + record Pre(DeltaTracker timer) implements RecordEvent, RenderTickEvent { public static final EventBus

     BUS = EventBus.create(Pre.class);
             }
    diff --git a/src/main/java/net/minecraftforge/event/brewing/BrewingRecipeRegisterEvent.java b/src/main/java/net/minecraftforge/event/brewing/BrewingRecipeRegisterEvent.java
    deleted file mode 100644
    index 74663ca183..0000000000
    --- a/src/main/java/net/minecraftforge/event/brewing/BrewingRecipeRegisterEvent.java
    +++ /dev/null
    @@ -1,51 +0,0 @@
    -/*
    - * Copyright (c) Forge Development LLC and contributors
    - * SPDX-License-Identifier: LGPL-2.1-only
    - */
    -
    -package net.minecraftforge.event.brewing;
    -
    -import net.minecraftforge.eventbus.api.bus.EventBus;
    -import net.minecraftforge.eventbus.api.event.RecordEvent;
    -import org.jetbrains.annotations.ApiStatus;
    -
    -import net.minecraft.world.flag.FeatureFlagSet;
    -import net.minecraft.world.item.ItemStack;
    -import net.minecraft.world.item.alchemy.PotionBrewing;
    -import net.minecraft.world.item.crafting.Ingredient;
    -import net.minecraftforge.common.brewing.BrewingRecipe;
    -import net.minecraftforge.common.brewing.IBrewingRecipe;
    -import org.jspecify.annotations.NullMarked;
    -
    -@NullMarked
    -public record BrewingRecipeRegisterEvent(PotionBrewing.Builder getBuilder, FeatureFlagSet getFeatures) implements RecordEvent {
    -    public static final EventBus BUS = EventBus.create(BrewingRecipeRegisterEvent.class);
    -
    -    @ApiStatus.Internal
    -    public BrewingRecipeRegisterEvent {
    -        assert getBuilder != null;
    -        assert getFeatures != null;
    -    }
    -
    -    /**
    -     * Adds a recipe to the registry. Due to the nature of the brewing stand
    -     * inputs that stack (a.k.a max stack size > 1) are not allowed.
    -     *
    -     * @param input      The Ingredient that goes in same slots as the water bottles
    -     *                   would.
    -     * @param ingredient The Ingredient that goes in the same slot as nether wart would.
    -     * @param output     The ItemStack that will replace the input once the brewing is
    -     *                   done.
    -     */
    -    public void addRecipe(Ingredient input, Ingredient ingredient, ItemStack output) {
    -        addRecipe(new BrewingRecipe(input, ingredient, output));
    -    }
    -
    -    /**
    -     * Adds a recipe to the registry. Due to the nature of the brewing stand
    -     * inputs that stack (a.k.a max stack size > 1) are not allowed.
    -     */
    -    public void addRecipe(IBrewingRecipe recipe) {
    -        getBuilder.add(recipe);
    -    }
    -}
    diff --git a/src/main/java/net/minecraftforge/event/brewing/PotionBrewEvent.java b/src/main/java/net/minecraftforge/event/brewing/PotionBrewEvent.java
    index 0c8054236a..a20b1bc9ba 100644
    --- a/src/main/java/net/minecraftforge/event/brewing/PotionBrewEvent.java
    +++ b/src/main/java/net/minecraftforge/event/brewing/PotionBrewEvent.java
    @@ -51,8 +51,6 @@ public sealed abstract class PotionBrewEvent extends MutableEvent implements Inh
          * This event is {@link Cancellable}.
    * If the event is not cancelled, the vanilla brewing will take place instead of modded brewing. *
    - * This event is fired on the {@link MinecraftForge#EVENT_BUS}.
    - *
    * If this event is canceled, and items have been modified, PotionBrewEvent.Post will automatically be fired. **/ public static final class Pre extends PotionBrewEvent implements Cancellable { @@ -69,8 +67,6 @@ public sealed abstract class PotionBrewEvent extends MutableEvent implements Inh * The event is fired during the {@code BrewingStandBlockEntity#doBrew(Level, BlockPos, NonNullList)} method invocation.
    *
    * {@link #stacks} contains the itemstack array from the TileEntityBrewer holding all items in Brewer.
    - *
    - * This event is fired on the {@link MinecraftForge#EVENT_BUS}.
    **/ public static final class Post extends PotionBrewEvent { public static final EventBus BUS = EventBus.create(Post.class); diff --git a/src/main/java/net/minecraftforge/event/entity/EntityEvent.java b/src/main/java/net/minecraftforge/event/entity/EntityEvent.java index 7c88a7ecd1..abcd944ca4 100644 --- a/src/main/java/net/minecraftforge/event/entity/EntityEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/EntityEvent.java @@ -10,71 +10,50 @@ import net.minecraft.world.entity.Entity; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.RecordEvent; -/** - * EntityEvent is a marker interface for when an event involving any Entity occurs. - */ +/// EntityEvent is a marker interface for when an event involving any Entity occurs. public interface EntityEvent { - /** - * @return the entity that caused this event to occur. - */ + /// @return the entity that caused this event to occur. Entity getEntity(); - /** - * EntityConstructing is fired when an Entity is being created. - *

    This event is fired within the constructor of the Entity.

    - **/ + /// EntityConstructing is fired when an Entity is being created. + /// + /// This event is fired within the constructor of the Entity. record EntityConstructing(Entity getEntity) implements RecordEvent, EntityEvent { public static final EventBus BUS = EventBus.create(EntityConstructing.class); } - /** - * This event is fired on server and client after an Entity has entered a different section.
    - * Sections are 16x16x16 block grids of the world.
    - * This event does not fire when a new entity is spawned, only when an entity moves from one section to another one. - * Use {@link EntityJoinLevelEvent} to detect new entities joining the world. - **/ + /// This event is fired on server and client after an Entity has entered a different section. + /// + /// Sections are 16x16x16 block grids of the world. + /// + /// This event does not fire when a new entity is spawned, only when an entity moves from one section to another one. + /// Use [EntityJoinLevelEvent] to detect new entities joining the world. + /// + /// @param getPackedOldPos the packed position of the old section's position. This is to be used with the various + /// methods in [SectionPos], such as [SectionPos#of(long)] or [SectionPos#x(long)] to avoid + /// allocation. + /// @param getPackedNewPos the packed position of the new section's position. This is to be used with the various + /// methods in [SectionPos], such as [SectionPos#of(long)] or [SectionPos#x(long)] to avoid + /// allocation. record EnteringSection(Entity getEntity, long getPackedOldPos, long getPackedNewPos) implements RecordEvent, EntityEvent { public static final EventBus BUS = EventBus.create(EnteringSection.class); - /** - * A packed version of the old section's position. This is to be used with the various methods in {@link SectionPos}, - * such as {@link SectionPos#of(long)} or {@link SectionPos#x(long)} to avoid allocation. - * @return the packed position of the old section - */ - public long getPackedOldPos() { - return getPackedOldPos; - } - - /** - * A packed version of the new section's position. This is to be used with the various methods in {@link SectionPos}, - * such as {@link SectionPos#of(long)} or {@link SectionPos#x(long)} to avoid allocation. - * @return the packed position of the new section - */ - public long getPackedNewPos() { - return getPackedNewPos; - } - - /** - * @return the position of the old section - */ + /// @return the position of the old section public SectionPos getOldPos() { return SectionPos.of(getPackedOldPos); } - /** - * @return the position of the new section - */ + /// @return the position of the new section public SectionPos getNewPos() { return SectionPos.of(getPackedNewPos); } - /** - * Whether the chunk has changed as part of this event. If this method returns false, only the Y position of the - * section has changed. - */ + /// Whether the chunk has changed as part of this event. If this method returns false, only the Y position of + /// the section has changed. public boolean didChunkChange() { - return SectionPos.x(getPackedOldPos) != SectionPos.x(getPackedNewPos) || SectionPos.z(getPackedOldPos) != SectionPos.z(getPackedNewPos); + return SectionPos.x(getPackedOldPos) != SectionPos.x(getPackedNewPos) + || SectionPos.z(getPackedOldPos) != SectionPos.z(getPackedNewPos); } } } diff --git a/src/main/java/net/minecraftforge/event/entity/EntityJoinLevelEvent.java b/src/main/java/net/minecraftforge/event/entity/EntityJoinLevelEvent.java index 23ede0ca5a..7da11abfeb 100644 --- a/src/main/java/net/minecraftforge/event/entity/EntityJoinLevelEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/EntityJoinLevelEvent.java @@ -8,7 +8,6 @@ package net.minecraftforge.event.entity; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.CancellableEventBus; import net.minecraftforge.eventbus.api.event.RecordEvent; import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; @@ -25,9 +24,8 @@ import net.minecraftforge.fml.LogicalSide; * This event is {@linkplain Cancellable cancellable}. * If the event is cancelled, the entity will not be added to the level. *

    - * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus} - * on both logical sides. - **/ + * This event is fired on both logical sides. + */ public record EntityJoinLevelEvent(Entity getEntity, Level getLevel, boolean loadedFromDisk) implements Cancellable, EntityEvent, RecordEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(EntityJoinLevelEvent.class); diff --git a/src/main/java/net/minecraftforge/event/entity/EntityLeaveLevelEvent.java b/src/main/java/net/minecraftforge/event/entity/EntityLeaveLevelEvent.java index c7b60649e0..6e7370f46d 100644 --- a/src/main/java/net/minecraftforge/event/entity/EntityLeaveLevelEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/EntityLeaveLevelEvent.java @@ -8,7 +8,6 @@ package net.minecraftforge.event.entity; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; import net.minecraft.world.level.entity.LevelCallback; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.RecordEvent; @@ -16,8 +15,8 @@ import net.minecraftforge.eventbus.api.event.RecordEvent; * This event is fired whenever an {@link Entity} leaves a {@link Level}. * This event is fired whenever an entity is removed from the level in {@link LevelCallback#onTrackingEnd(Object)}. *

    - * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus} on both logical sides. - **/ + * This event is fired on both logical sides. + */ public record EntityLeaveLevelEvent(Entity getEntity, Level getLevel) implements RecordEvent, EntityEvent { public static final EventBus BUS = EventBus.create(EntityLeaveLevelEvent.class); diff --git a/src/main/java/net/minecraftforge/event/entity/EntityMountEvent.java b/src/main/java/net/minecraftforge/event/entity/EntityMountEvent.java index 7d98123c08..8dc595b4f3 100644 --- a/src/main/java/net/minecraftforge/event/entity/EntityMountEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/EntityMountEvent.java @@ -10,18 +10,16 @@ import net.minecraft.world.level.Level; import net.minecraftforge.eventbus.api.bus.CancellableEventBus; import net.minecraftforge.eventbus.api.event.RecordEvent; import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; +import org.jspecify.annotations.Nullable; -/** - * This event gets fired whenever a entity mounts/dismounts another entity.
    - * entityBeingMounted can be null, be sure to check for that. - *
    - *
    - * This event is {@linkplain Cancellable cancellable}.
    - * If this event is cancelled, the entity does not mount/dismount the other entity. - */ +/// This event gets fired whenever a entity mounts/dismounts another entity. +/// +/// **entityBeingMounted can be null**, be sure to check for that. +/// +/// This event is [Cancellable]. If this event is cancelled, the entity does not mount/dismount the other entity. public record EntityMountEvent( Entity getEntityMounting, - Entity getEntityBeingMounted, + @Nullable Entity getEntityBeingMounted, Level getLevel, boolean isMounting ) implements Cancellable, EntityEvent, RecordEvent { diff --git a/src/main/java/net/minecraftforge/event/entity/EntityTeleportEvent.java b/src/main/java/net/minecraftforge/event/entity/EntityTeleportEvent.java index 205e9475e0..e76f3ca58a 100644 --- a/src/main/java/net/minecraftforge/event/entity/EntityTeleportEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/EntityTeleportEvent.java @@ -88,18 +88,18 @@ public sealed abstract class EntityTeleportEvent implements Cancellable, EntityE } /** - * EntityTeleportEvent.EnderEntity is fired before an Enderman or Shulker randomly teleports. + * EntityTeleportEvent.EntityRandom is fired before an Entity randomly teleports. *
    * This event is {@linkplain Cancellable cancelable}. If the event is cancelled, the entity will not be teleported. *
    * This event is only fired on the {@link LogicalSide#SERVER} side. */ - public static final class EnderEntity extends EntityTeleportEvent { - public static final CancellableEventBus BUS = CancellableEventBus.create(EnderEntity.class); + public static final class EntityRandom extends EntityTeleportEvent { + public static final CancellableEventBus BUS = CancellableEventBus.create(EntityRandom.class); private final LivingEntity entityLiving; - public EnderEntity(LivingEntity entity, double targetX, double targetY, double targetZ) { + public EntityRandom(LivingEntity entity, double targetX, double targetY, double targetZ) { super(entity, targetX, targetY, targetZ); this.entityLiving = entity; } diff --git a/src/main/java/net/minecraftforge/event/entity/ProjectileImpactEvent.java b/src/main/java/net/minecraftforge/event/entity/ProjectileImpactEvent.java index cb85587455..1b92ce7153 100644 --- a/src/main/java/net/minecraftforge/event/entity/ProjectileImpactEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/ProjectileImpactEvent.java @@ -8,7 +8,6 @@ package net.minecraftforge.event.entity; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.projectile.Projectile; import net.minecraft.world.phys.HitResult; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.MutableEvent; @@ -17,7 +16,6 @@ import org.jetbrains.annotations.NotNull; import java.util.Objects; /** - * This event is fired on the {@link MinecraftForge#EVENT_BUS}.
    * This event is fired when a projectile entity impacts something.
    * This event is fired via {@link ForgeEventFactory#onProjectileImpact(Projectile, HitResult)} * This event is fired for all vanilla projectiles by Forge, diff --git a/src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java b/src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java index 5c8c6287c9..68eecf6b36 100644 --- a/src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/living/BabyEntitySpawnEvent.java @@ -11,7 +11,6 @@ import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.animal.Animal; import net.minecraft.world.entity.animal.fox.Fox; import net.minecraft.world.entity.player.Player; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.CancellableEventBus; import net.minecraftforge.eventbus.api.event.MutableEvent; @@ -20,7 +19,7 @@ import org.jetbrains.annotations.Nullable; /** * BabyEntitySpawnEvent is fired just before a baby entity is about to be spawned.
    - * Parents will have disengaged their relationship. {@link Cancelable}
    + * Parents will have disengaged their relationship. {@link Cancellable}
    * It is possible to change the child completely by using {@link #setChild(AgeableMob)}
    * This event is fired from {@link Animal#spawnChildFromBreeding(ServerLevel, Animal)} and * {@link Fox#spawnChildFromBreeding(ServerLevel, Animal)}
    @@ -33,9 +32,7 @@ import org.jetbrains.annotations.Nullable; * This event is {@link Cancellable}.
    * If this event is cancelled, the child Entity is not added to the world, and the parents
    * will no longer attempt to mate. - *
    - * This event is fired on the {@link MinecraftForge#EVENT_BUS}. - **/ + */ public final class BabyEntitySpawnEvent extends MutableEvent implements Cancellable { public static final CancellableEventBus BUS = CancellableEventBus.create(BabyEntitySpawnEvent.class); diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingEvent.java b/src/main/java/net/minecraftforge/event/entity/living/LivingEvent.java index f3556e19b4..251fb92223 100644 --- a/src/main/java/net/minecraftforge/event/entity/living/LivingEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/living/LivingEvent.java @@ -17,32 +17,23 @@ import net.minecraftforge.eventbus.api.event.RecordEvent; import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; import org.jetbrains.annotations.Nullable; -/** - * LivingEvent is a marker interface for whenever an event involving a {@link LivingEntity} occurs. - */ +/// LivingEvent is a marker interface for whenever an event involving a [LivingEntity] occurs. public interface LivingEvent extends EntityEvent { @Override LivingEntity getEntity(); - /** - * LivingUpdateEvent is fired when a LivingEntity is ticked in {@link LivingEntity#tick()}.
    - *
    - * This event is fired via the {@link ForgeEventFactory#onLivingTick(LivingEntity)}.
    - *
    - * This event is {@linkplain Cancellable cancellable}. If this event is cancelled, the Entity does not update. - */ + /// LivingUpdateEvent is fired when a LivingEntity is ticked in [LivingEntity#tick()]. + /// + /// This event is fired via the [ForgeEventFactory#onLivingTick(LivingEntity)]. + /// + /// This event is [Cancellable]. If this event is cancelled, the Entity does not update. record LivingTickEvent(LivingEntity getEntity) implements Cancellable, LivingEvent, RecordEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(LivingTickEvent.class); } - /** - * LivingJumpEvent is fired when an Entity jumps.
    - * This event is fired whenever an Entity jumps in - * {@code LivingEntity#jumpFromGround()}, {@code MagmaCube#jumpFromGround()}, - * and {@code Horse#jumpFromGround()}.
    - *
    - * This event is fired via the {@link ForgeHooks#onLivingJump(LivingEntity)}. - **/ + /// LivingJumpEvent is fired when an Entity jumps, such as a player, magma cube, horse, etc... + /// + /// This event is fired via the [ForgeHooks#onLivingJump(LivingEntity)]. record LivingJumpEvent(LivingEntity getEntity) implements LivingEvent, RecordEvent { public static final EventBus BUS = EventBus.create(LivingJumpEvent.class); } @@ -66,23 +57,17 @@ public interface LivingEvent extends EntityEvent { return livingEntity; } - /** - * @param mod Is multiplied with the current modifier - */ + /// @param mod Is multiplied with the current modifier public void modifyVisibility(double mod) { visibilityModifier *= mod; } - /** - * @return The current modifier - */ + /// @return The current modifier public double getVisibilityModifier() { return visibilityModifier; } - /** - * @return The entity trying to see this LivingEntity, if available - */ + /// @return The entity trying to see this LivingEntity, if available @Nullable public Entity getLookingEntity() { return lookingEntity; diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingHealEvent.java b/src/main/java/net/minecraftforge/event/entity/living/LivingHealEvent.java index 78843cf427..fd830cb196 100644 --- a/src/main/java/net/minecraftforge/event/entity/living/LivingHealEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/living/LivingHealEvent.java @@ -12,16 +12,13 @@ import net.minecraftforge.eventbus.api.event.MutableEvent; import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; import org.jspecify.annotations.NullMarked; -/** - * LivingHealEvent is fired when an Entity is set to be healed.
    - * This event is fired whenever an Entity is healed in {@link LivingEntity#heal(float)}
    - *
    - * This event is fired via the {@link ForgeEventFactory#onLivingHeal(LivingEntity, float)}.
    - *
    - * {@link #amount} contains the amount of healing done to the Entity that was healed.
    - *
    - * This event is {@linkplain Cancellable cancellable}. If this event is cancelled, the Entity is not healed. - **/ +/// LivingHealEvent is fired when an Entity is set to be healed. +/// +/// This event is fired whenever an Entity is healed in [LivingEntity#heal(float)] +/// +/// This event is fired via the [ForgeEventFactory#onLivingHeal(LivingEntity, float)]. +/// +/// This event is [Cancellable]. If this event is cancelled, the Entity is not healed. @NullMarked public final class LivingHealEvent extends MutableEvent implements Cancellable, LivingEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(LivingHealEvent.class); @@ -39,10 +36,12 @@ public final class LivingHealEvent extends MutableEvent implements Cancellable, return entity; } + /// @return the amount of healing done to the Entity that was healed. public float getAmount() { return amount; } + /// Sets the amount of healing done to the Entity that was healed. public void setAmount(float amount) { this.amount = amount; } diff --git a/src/main/java/net/minecraftforge/event/entity/living/LivingUseTotemEvent.java b/src/main/java/net/minecraftforge/event/entity/living/LivingUseTotemEvent.java index 63ca8f4c19..c7e2ffc754 100644 --- a/src/main/java/net/minecraftforge/event/entity/living/LivingUseTotemEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/living/LivingUseTotemEvent.java @@ -13,15 +13,18 @@ import net.minecraftforge.eventbus.api.bus.CancellableEventBus; import net.minecraftforge.eventbus.api.event.RecordEvent; import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; import net.minecraftforge.fml.LogicalSide; +import org.jetbrains.annotations.ApiStatus; -/** - * Fired when an Entity attempts to use a totem to prevent its death. - * - *

    This event is {@linkplain Cancellable cancellable}. - * If this event is cancelled, the totem will not prevent the entity's death.

    - * - *

    This event is fired only on the {@linkplain LogicalSide#SERVER logical server}.

    - */ +/// Fired when an Entity attempts to use a totem to prevent its death. +/// +/// This event is [Cancellable]. +/// If this event is cancelled, the totem will not prevent the entity's death. +/// +/// This event is fired only on the [logical server][LogicalSide#SERVER]. +/// +/// @param getSource The damage source that caused the entity to die +/// @param getTotem The totem of undying being used from the entity's inventory +/// @param getHandHolding The hand holding the totem public record LivingUseTotemEvent( LivingEntity getEntity, DamageSource getSource, @@ -30,24 +33,6 @@ public record LivingUseTotemEvent( ) implements Cancellable, LivingEvent, RecordEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(LivingUseTotemEvent.class); - /** - * {@return the damage source that caused the entity to die} - */ - public DamageSource getSource() { - return getSource; - } - - /** - * {@return the totem of undying being used from the entity's inventory} - */ - public ItemStack getTotem() { - return getTotem; - } - - /** - * {@return the hand holding the totem} - */ - public InteractionHand getHandHolding() { - return getHandHolding; - } + @ApiStatus.Internal + public LivingUseTotemEvent {} } diff --git a/src/main/java/net/minecraftforge/event/entity/living/MobEffectEvent.java b/src/main/java/net/minecraftforge/event/entity/living/MobEffectEvent.java index 07d4bb0f65..c58dbb8b79 100644 --- a/src/main/java/net/minecraftforge/event/entity/living/MobEffectEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/living/MobEffectEvent.java @@ -22,8 +22,6 @@ import org.jetbrains.annotations.Nullable; /** * This event is fired when an interaction between a {@link LivingEntity} and {@link MobEffectInstance} happens. - *

    - * All children of this event are fired on the {@link MinecraftForge#EVENT_BUS}. */ public sealed interface MobEffectEvent extends LivingEvent, InheritableEvent { EventBus BUS = EventBus.create(MobEffectEvent.class); diff --git a/src/main/java/net/minecraftforge/event/entity/living/MobSpawnEvent.java b/src/main/java/net/minecraftforge/event/entity/living/MobSpawnEvent.java index 0efaafd904..b404b2357a 100644 --- a/src/main/java/net/minecraftforge/event/entity/living/MobSpawnEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/living/MobSpawnEvent.java @@ -23,7 +23,6 @@ import net.minecraft.world.level.BaseSpawner; import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.storage.ValueInput; import net.minecraftforge.common.ForgeInternalHandler; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.event.entity.EntityEvent; import net.minecraftforge.event.entity.SpawnPlacementRegisterEvent; @@ -101,8 +100,7 @@ public abstract sealed class MobSpawnEvent extends MutableEvent implements Entit *

  • Default - The value of the vanilla check will be used to determine success.
  • *
  • Deny - The check will fail, and the spawn process will abort.
  • * - * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus}, - * only on the {@linkplain LogicalSide#SERVER logical server}. + * This event is fired only on the {@linkplain LogicalSide#SERVER logical server}. *

    * This event is not fired for mob spawners which utilize {@link CustomSpawnRules}, as they do not check spawn placements. * @apiNote If your modifications are for a single entity, and do not vary at runtime, use {@link SpawnPlacementRegisterEvent}. @@ -210,8 +208,7 @@ public abstract sealed class MobSpawnEvent extends MutableEvent implements Entit *

  • Default - The position will be accepted if {@link Mob#checkSpawnRules} and {@link Mob#checkSpawnObstruction} are both true.
  • *
  • Deny - The position will not be accepted. The spawn process will abort, and further events will not be called.
  • * - * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus}, - * only on the {@linkplain LogicalSide#SERVER logical server}. + * This event is fired only on the {@linkplain LogicalSide#SERVER logical server}. * * @apiNote This event fires after Spawn Placement checks, which are the primary set of spawn checks. * @see {@link SpawnPlacementRegisterEvent} To modify spawn placements statically at startup. @@ -269,7 +266,7 @@ public abstract sealed class MobSpawnEvent extends MutableEvent implements Entit * Canceling this event will result in {@link Mob#finalizeSpawn} not being called, and the returned value always being null, instead of propagating the SpawnGroupData.
    * The entity will still be spawned. If you want to prevent the spawn, use {@link FinalizeSpawn#setSpawnCancelled}, which will cause Forge to prevent the spawn. *

    - * This event is fired on {@link MinecraftForge#EVENT_BUS}, and is only fired on the logical server. + * This event is fired only on the {@linkplain LogicalSide#SERVER logical server}. * @see ForgeEventFactory#onFinalizeSpawn * @apiNote Callers do not need to check if the entity's spawn was cancelled, as the spawn will be blocked by Forge. */ @@ -399,13 +396,12 @@ public abstract sealed class MobSpawnEvent extends MutableEvent implements Entit * It fires once per tick per mob that is attempting to despawn.
    * It is not fired if the mob is persistent (meaning it may not despawn).
    *

    - * This event is not {@linkplain Cancelable cancellable}, but does {@linkplain HasResult have a result}. + * This event is not {@linkplain Cancellable cancellable}, but does {@linkplain HasResult have a result}. * {@link Result#DEFAULT} indicates that default despawn mechanics should be used. * {@link Result#ALLOW} indicates that the mob should forcefully despawn. * {@link Result#DENY} indicates that the mob should forcefully stay spawned. *

    - * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus}, - * only on the {@linkplain LogicalSide#SERVER logical server}. + * This event is fired only on the {@linkplain LogicalSide#SERVER logical server}. * * @see LivingEntity#checkDespawn() * @author cpw diff --git a/src/main/java/net/minecraftforge/event/entity/living/ZombieEvent.java b/src/main/java/net/minecraftforge/event/entity/living/ZombieEvent.java index f9ab2e5928..008767457d 100644 --- a/src/main/java/net/minecraftforge/event/entity/living/ZombieEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/living/ZombieEvent.java @@ -8,7 +8,6 @@ package net.minecraftforge.event.entity.living; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.monster.zombie.Zombie; import net.minecraft.world.level.Level; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.util.HasResult; import net.minecraftforge.common.util.Result; import net.minecraftforge.event.ForgeEventFactory; @@ -20,7 +19,7 @@ import net.minecraftforge.eventbus.api.event.InheritableEvent; * ZombieEvent is fired whenever a zombie is spawned for aid. * If a method utilizes this event as its parameter, the method will * receive every child event of this class. - **/ + */ public sealed abstract class ZombieEvent implements EntityEvent, InheritableEvent { public static final EventBus BUS = EventBus.create(ZombieEvent.class); @@ -55,9 +54,7 @@ public sealed abstract class ZombieEvent implements EntityEvent, InheritableEven *

  • {@link Result#ALLOW} Zombie is summoned.
  • *
  • {@link Result#DENY} Zombie is not summoned.
  • * - * - * This event is fired on the {@link MinecraftForge#EVENT_BUS}. - **/ + */ public static final class SummonAidEvent extends ZombieEvent implements HasResult { public static final EventBus BUS = EventBus.create(SummonAidEvent.class); diff --git a/src/main/java/net/minecraftforge/event/entity/player/AdvancementEvent.java b/src/main/java/net/minecraftforge/event/entity/player/AdvancementEvent.java index 4c9fbb68fa..bb2ad2dbb5 100644 --- a/src/main/java/net/minecraftforge/event/entity/player/AdvancementEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/player/AdvancementEvent.java @@ -12,42 +12,37 @@ import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.RecordEvent; import net.minecraftforge.fml.LogicalSide; -/** - * Base class used for advancement-related events. Should not be used directly. - * @see AdvancementEarnEvent - * @see AdvancementProgressEvent - */ +/// Base interface shared among advancement-related events +/// +/// @see AdvancementEarnEvent +/// @see AdvancementProgressEvent public sealed interface AdvancementEvent extends PlayerEvent { AdvancementHolder getAdvancement(); - /** - * Fired when the player earns an advancement. An advancement is earned once its requirements are complete. - * - *

    Note that advancements may be hidden from the player or used in background mechanics, such as recipe - * advancements for unlocking recipes in the recipe book.

    - * - *

    This event is fired only on the {@linkplain LogicalSide#SERVER logical server}.

    - * - * @see AdvancementProgress#isDone() - */ + /// Fired when the player earns an advancement. An advancement is earned once its requirements are complete. + /// + /// Note that advancements may be hidden from the player or used in background mechanics, such as recipe + /// advancements for unlocking recipes in the recipe book. + /// + /// This event is fired only on the [logical server][LogicalSide#SERVER]. + /// + /// @see AdvancementProgress#isDone() record AdvancementEarnEvent(Player getEntity, AdvancementHolder getAdvancement) implements RecordEvent, AdvancementEvent { public static final EventBus BUS = EventBus.create(AdvancementEarnEvent.class); } - /** - * Fired when the player's progress on an advancement criterion is granted or revoked. - * - *

    This event is fired only on the {@linkplain LogicalSide#SERVER logical server}.

    - * - * @param getAdvancementProgress the progress of the advancement - * @param getCriterionName the name of the criterion that was progressed - * @param getProgressType the type of progress for the criterion in this event - * - * @see AdvancementEarnEvent - * @see net.minecraft.server.PlayerAdvancements#award(AdvancementHolder, String) - * @see net.minecraft.server.PlayerAdvancements#revoke(AdvancementHolder, String) - */ + /// Fired when the player's progress on an advancement criterion is granted or revoked. + /// + /// This event is fired only on the [logical server][LogicalSide#SERVER]. + /// + /// @param getAdvancementProgress the progress of the advancement + /// @param getCriterionName the name of the criterion that was progressed + /// @param getProgressType the type of progress for the criterion in this event + /// + /// @see AdvancementEarnEvent + /// @see net.minecraft.server.PlayerAdvancements#award(AdvancementHolder, String) + /// @see net.minecraft.server.PlayerAdvancements#revoke(AdvancementHolder, String) record AdvancementProgressEvent( Player getEntity, AdvancementHolder getAdvancement, diff --git a/src/main/java/net/minecraftforge/event/entity/player/ArrowNockEvent.java b/src/main/java/net/minecraftforge/event/entity/player/ArrowNockEvent.java index 2557a2e955..daf85c0243 100644 --- a/src/main/java/net/minecraftforge/event/entity/player/ArrowNockEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/player/ArrowNockEvent.java @@ -15,11 +15,9 @@ import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.MutableEvent; import org.jetbrains.annotations.NotNull; -/** - * ArrowNockEvent is fired when a player begins using a bow.
    - * This event is fired whenever a player begins using a bow in - * {@link BowItem#use(Level, Player, InteractionHand)}. - **/ +/// ArrowNockEvent is fired when a player begins using a bow. +/// +/// This event is fired whenever a player begins using a bow in [BowItem#use(Level, Player, InteractionHand)]. public final class ArrowNockEvent extends MutableEvent implements PlayerEvent { public static final EventBus BUS = EventBus.create(ArrowNockEvent.class); diff --git a/src/main/java/net/minecraftforge/event/entity/player/AttackEntityEvent.java b/src/main/java/net/minecraftforge/event/entity/player/AttackEntityEvent.java index 890bb7c633..5418ed8917 100644 --- a/src/main/java/net/minecraftforge/event/entity/player/AttackEntityEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/player/AttackEntityEvent.java @@ -11,15 +11,12 @@ import net.minecraftforge.eventbus.api.bus.CancellableEventBus; import net.minecraftforge.eventbus.api.event.RecordEvent; import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; -/** - * AttackEntityEvent is fired when a player attacks an Entity.
    - * This event is fired whenever a player attacks an Entity in - * {@link Player#attack(Entity)}.
    - *
    - * {@link #getTarget()} contains the Entity that was damaged by the player.
    - *
    - * This event is {@linkplain Cancellable cancellable}. If this event is cancelled, the player does not attack the Entity. - **/ +/// AttackEntityEvent is fired when a player attacks an Entity in [Player#attack(Entity)]. +/// +/// This event is [cancellable][Cancellable]. If this event is cancelled, the player does not attack the Entity. +/// +/// @param getEntity the player that attacked the entity +/// @param getTarget the entity that was attacked by the player public record AttackEntityEvent(Player getEntity, Entity getTarget) implements Cancellable, PlayerEvent, RecordEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(AttackEntityEvent.class); } diff --git a/src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java b/src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java index 14ffd146c3..91f0568333 100644 --- a/src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/player/ItemFishedEvent.java @@ -17,12 +17,10 @@ import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; import javax.annotation.Nonnegative; import java.util.List; -/** - * This event is called when a player fishes an item. - *
    - * This event is {@linkplain Cancellable cancellable}. If cancelled, the player will not receive any items, but the hook - * will still take the damage specified - */ +/// This event is called when a player fishes an item. +/// +/// This event is [cancellable][Cancellable]. If cancelled, the player will not receive any items, but the hook +/// will still take the damage specified public final class ItemFishedEvent extends MutableEvent implements Cancellable, PlayerEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(ItemFishedEvent.class); @@ -43,36 +41,31 @@ public final class ItemFishedEvent extends MutableEvent implements Cancellable, return player; } - /** - * Get the damage the rod will take. - * @return The damage the rod will take - */ + /// @return The damage the rod will take public int getRodDamage() { return rodDamage; } - /** - * Specifies the amount of damage that the fishing rod should take. - * This is not added to the pre-existing damage to be taken. - * @param rodDamage The damage the rod will take. Must be nonnegative - */ + /// Specifies the amount of damage that the fishing rod should take. + /// + /// This is not added to the pre-existing damage to be taken. + /// + /// @param rodDamage The damage the rod will take. Must be nonnegative public void damageRodBy(@Nonnegative int rodDamage) { Preconditions.checkArgument(rodDamage >= 0); this.rodDamage = rodDamage; } - /** - * Use this to get the items the player will receive. - * You cannot use this to modify the drops the player will get. - * If you want to affect the loot, you should use LootTables. - */ + /// Use this to get the items the player will receive. + /// + /// You cannot use this to modify the drops the player will get. + /// + /// If you want to affect the loot, you should use LootTables. public NonNullList getDrops() { return stacks; } - /** - * Use this to stuff related to the hook itself, like the position of the bobber. - */ + /// Use this to stuff related to the hook itself, like the position of the bobber. public FishingHook getHookEntity() { return hook; } diff --git a/src/main/java/net/minecraftforge/event/entity/player/ItemTooltipEvent.java b/src/main/java/net/minecraftforge/event/entity/player/ItemTooltipEvent.java index faa36fba87..ece240608d 100644 --- a/src/main/java/net/minecraftforge/event/entity/player/ItemTooltipEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/player/ItemTooltipEvent.java @@ -8,94 +8,39 @@ package net.minecraftforge.event.entity.player; import java.util.List; import net.minecraft.client.Minecraft; -import net.minecraft.world.item.Item; +import net.minecraft.world.item.Item.TooltipContext; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.network.chat.Component; import net.minecraft.world.item.component.TooltipDisplay; import net.minecraftforge.eventbus.api.bus.EventBus; -import net.minecraftforge.eventbus.api.event.MutableEvent; +import net.minecraftforge.eventbus.api.event.RecordEvent; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public final class ItemTooltipEvent extends MutableEvent implements PlayerEvent { +/// This event is fired in {@link ItemStack#getTooltipLines(TooltipContext, Player, TooltipFlag)}, which in turn is +/// called from its respective Container. +/// +/// Tooltips are also gathered with a null player during startup by {@link Minecraft#createSearchTrees()}. +/// +/// @param getItemStack The [ItemStack] with the tooltip. +/// @param getEntity null during startup when populating search trees for tooltips +/// @param getToolTip The tooltip lines for the [ItemStack] that you can modify +/// @param getFlags Use to determine if the advanced information on item tooltips is being shown, toggled by F3+H. +/// @param getContext The [TooltipContext] for this tooltip. +/// @param getDisplay The [TooltipDisplay] for this tooltip. +public record ItemTooltipEvent( + @NotNull ItemStack getItemStack, + @Nullable Player getEntity, + List getToolTip, + TooltipFlag getFlags, + TooltipContext getContext, + TooltipDisplay getDisplay +) implements RecordEvent, PlayerEvent { public static final EventBus BUS = EventBus.create(ItemTooltipEvent.class); - private final Player player; - private final TooltipFlag flags; - @NotNull - private final ItemStack itemStack; - private final List toolTip; - private final Item.TooltipContext context; - private final TooltipDisplay display; - - /** - * - * This event is fired in {@link ItemStack#getTooltipLines(Item.TooltipContext, Player, TooltipFlag)}, which in turn is called from its respective GUIContainer. - * Tooltips are also gathered with a null player during startup by {@link Minecraft#createSearchTrees()}. - */ @ApiStatus.Internal - public ItemTooltipEvent(@NotNull ItemStack itemStack, @Nullable Player player, List list, TooltipFlag flags, Item.TooltipContext context, TooltipDisplay display) - { - this.player = player; - this.itemStack = itemStack; - this.toolTip = list; - this.flags = flags; - this.context = context; - this.display = display; - } - - - /** - * The {@link net.minecraft.world.item.Item.TooltipContext} for this tooltip. - */ - public Item.TooltipContext getContext() - { - return context; - } - - /** - * The {@link net.minecraft.world.item.component.TooltipDisplay} for this tooltip. - */ - public TooltipDisplay getDisplay() - { - return display; - } - - /** - * Use to determine if the advanced information on item tooltips is being shown, toggled by F3+H. - */ - public TooltipFlag getFlags() - { - return flags; - } - - /** - * The {@link ItemStack} with the tooltip. - */ - @NotNull - public ItemStack getItemStack() - { - return itemStack; - } - - /** - * The {@link ItemStack} tooltip. - */ - public List getToolTip() - { - return toolTip; - } - - /** - * This event is fired with a null player during startup when populating search trees for tooltips. - */ - @Override - @Nullable - public Player getEntity() - { - return player; - } + public ItemTooltipEvent {} } diff --git a/src/main/java/net/minecraftforge/event/entity/player/PermissionsChangedEvent.java b/src/main/java/net/minecraftforge/event/entity/player/PermissionsChangedEvent.java index af63b79d0d..d73df45f73 100644 --- a/src/main/java/net/minecraftforge/event/entity/player/PermissionsChangedEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/player/PermissionsChangedEvent.java @@ -10,18 +10,25 @@ import net.minecraft.server.permissions.LevelBasedPermissionSet; import net.minecraftforge.eventbus.api.bus.CancellableEventBus; import net.minecraftforge.eventbus.api.event.RecordEvent; import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; +import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; -/** - * This event will fire when the player is opped or deopped. - *

    - * This event is cancelable which will stop the op or deop from happening. - * @param getNewLevel The new permission level. - * @param getOldLevel The old permission level. - */ +/// This event will fire when the player is made a server operator ("opped") or stripped of such ("deopped"). +/// +/// This event is cancelable which will stop the op or deop from happening. +/// +/// @param getEntity The player who is being oped or deopped. +/// @param getNewLevel The new permission level. +/// @param getOldLevel The old permission level. @NullMarked -public record PermissionsChangedEvent(ServerPlayer getEntity, @Nullable LevelBasedPermissionSet getNewLevel, @Nullable LevelBasedPermissionSet getOldLevel) - implements Cancellable, PlayerEvent, RecordEvent { +public record PermissionsChangedEvent( + ServerPlayer getEntity, + @Nullable LevelBasedPermissionSet getNewLevel, + @Nullable LevelBasedPermissionSet getOldLevel +) implements Cancellable, PlayerEvent, RecordEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(PermissionsChangedEvent.class); + + @ApiStatus.Internal + public PermissionsChangedEvent {} } diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerEvent.java b/src/main/java/net/minecraftforge/event/entity/player/PlayerEvent.java index d7cb08bc04..bc5a7b77d8 100644 --- a/src/main/java/net/minecraftforge/event/entity/player/PlayerEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/player/PlayerEvent.java @@ -92,14 +92,14 @@ public interface PlayerEvent extends LivingEvent { private final BlockState state; private final float originalSpeed; private float newSpeed = 0.0f; - private final Optional pos; // Y position of -1 notes unknown location + private final @Nullable BlockPos pos; // Y position of -1 notes unknown location public BreakSpeed(Player player, BlockState state, float original, @Nullable BlockPos pos) { this.player = player; this.state = state; this.originalSpeed = original; this.setNewSpeed(original); - this.pos = Optional.ofNullable(pos); + this.pos = pos; } @Override @@ -111,7 +111,7 @@ public interface PlayerEvent extends LivingEvent { public float getOriginalSpeed() { return originalSpeed; } public float getNewSpeed() { return newSpeed; } public void setNewSpeed(float newSpeed) { this.newSpeed = newSpeed; } - public Optional getPosition() { return this.pos; } + public @Nullable BlockPos getPosition() { return this.pos; } } /** diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerFlyableFallEvent.java b/src/main/java/net/minecraftforge/event/entity/player/PlayerFlyableFallEvent.java index 578742a108..b1f836244e 100644 --- a/src/main/java/net/minecraftforge/event/entity/player/PlayerFlyableFallEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/player/PlayerFlyableFallEvent.java @@ -10,9 +10,7 @@ import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.MutableEvent; import org.jspecify.annotations.NullMarked; -/** - * Occurs when a player falls, but is able to fly. Doesn't need to be cancelable, this is mainly for notification purposes. - */ +/// Occurs when a player falls, but is able to fly. Doesn't need to be cancelable, this is mainly for notification purposes. @NullMarked public final class PlayerFlyableFallEvent extends MutableEvent implements PlayerEvent { public static final EventBus BUS = EventBus.create(PlayerFlyableFallEvent.class); diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerInteractEvent.java b/src/main/java/net/minecraftforge/event/entity/player/PlayerInteractEvent.java index a75afa4cd2..679a349e37 100644 --- a/src/main/java/net/minecraftforge/event/entity/player/PlayerInteractEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/player/PlayerInteractEvent.java @@ -22,7 +22,6 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import net.minecraft.world.level.Level; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.util.Result; import net.minecraftforge.eventbus.api.bus.CancellableEventBus; @@ -39,9 +38,8 @@ import java.util.Objects; /** * PlayerInteractEvent is fired when a player interacts in some way. - * All subclasses are fired on {@link MinecraftForge#EVENT_BUS}. * See the individual documentation on each subevent for more details. - **/ + */ public sealed abstract class PlayerInteractEvent implements PlayerEvent, InheritableEvent { public static final EventBus BUS = EventBus.create(PlayerInteractEvent.class); diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerSetSpawnEvent.java b/src/main/java/net/minecraftforge/event/entity/player/PlayerSetSpawnEvent.java index f621059db6..fb54991206 100644 --- a/src/main/java/net/minecraftforge/event/entity/player/PlayerSetSpawnEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/player/PlayerSetSpawnEvent.java @@ -8,33 +8,17 @@ package net.minecraftforge.event.entity.player; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import net.minecraftforge.eventbus.api.bus.CancellableEventBus; -import net.minecraftforge.eventbus.api.event.MutableEvent; +import net.minecraftforge.eventbus.api.event.RecordEvent; import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; import org.jetbrains.annotations.Nullable; -/** - * This event is fired when a player's spawn point is set or reset. - *

    - * The event can be canceled, which will prevent the spawn point from being changed. - */ -public final class PlayerSetSpawnEvent extends MutableEvent implements Cancellable, PlayerEvent { +/// This event is fired when a player's spawn point is set or reset. +/// +/// This event is [Cancellable]. Cancelling will prevent the spawn point from being changed. +/// +/// @param getEntity The player whose spawn point is being set or reset. +/// @param getConfig The config for the player respawn, or null if the spawn point is being reset. +public record PlayerSetSpawnEvent(Player getEntity, ServerPlayer.@Nullable RespawnConfig getConfig) + implements Cancellable, RecordEvent, PlayerEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(PlayerSetSpawnEvent.class); - - private final Player player; - private final @Nullable ServerPlayer.RespawnConfig config; - - public PlayerSetSpawnEvent(ServerPlayer player, @Nullable ServerPlayer.RespawnConfig config) { - this.player = player; - this.config = config; - } - - @Override - public Player getEntity() { - return player; - } - - /** @return The config for the player respawn */ - public @Nullable ServerPlayer.RespawnConfig getConfig() { - return this.config; - } } diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerWakeUpEvent.java b/src/main/java/net/minecraftforge/event/entity/player/PlayerWakeUpEvent.java index 7a306f271e..f58af8101c 100644 --- a/src/main/java/net/minecraftforge/event/entity/player/PlayerWakeUpEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/player/PlayerWakeUpEvent.java @@ -10,25 +10,19 @@ import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.RecordEvent; import org.jspecify.annotations.NullMarked; -/** - * This event is fired when the player is waking up.
    - * This is merely for purposes of listening for this to happen.
    - * There is nothing that can be manipulated with this event. - */ +/// This readonly event is fired when the player is waking up. +/// +/// @param getEntity the player that is waking up @NullMarked public record PlayerWakeUpEvent(Player getEntity, boolean wakeImmediately, boolean updateLevel) implements RecordEvent, PlayerEvent { public static final EventBus BUS = EventBus.create(PlayerWakeUpEvent.class); - /** - * Used for the 'wake up animation'. - * This is false if the player is considered 'sleepy' and the overlay should slowly fade away. - */ + /// Used for the 'wake up animation'. + /// This is false if the player is considered 'sleepy' and the overlay should slowly fade away. public boolean wakeImmediately() { return wakeImmediately; } - /** - * Indicates if the server should be notified of sleeping changes. - * This will only be false if the server is considered 'up to date' already, because, for example, it initiated the call. - */ + /// Indicates if the server should be notified of sleeping changes. + /// This will only be false if the server is considered 'up to date' already, because, for example, it initiated the call. public boolean updateLevel() { return updateLevel; } } diff --git a/src/main/java/net/minecraftforge/event/entity/player/PlayerXpEvent.java b/src/main/java/net/minecraftforge/event/entity/player/PlayerXpEvent.java index f0d455c13f..6300e4bca9 100644 --- a/src/main/java/net/minecraftforge/event/entity/player/PlayerXpEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/player/PlayerXpEvent.java @@ -7,32 +7,26 @@ package net.minecraftforge.event.entity.player; import net.minecraft.world.entity.ExperienceOrb; import net.minecraft.world.entity.player.Player; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.CancellableEventBus; import net.minecraftforge.eventbus.api.event.MutableEvent; import net.minecraftforge.eventbus.api.event.RecordEvent; import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; import org.jspecify.annotations.NullMarked; -/** - * PlayerXpEvent is fired whenever an event involving player experience occurs. - *
    - * All children of this event are fired on the {@link MinecraftForge#EVENT_BUS}. - */ +/// PlayerXpEvent is fired whenever an event involving player experience occurs. @NullMarked public sealed interface PlayerXpEvent extends PlayerEvent { - /** - * This event is fired after the player collides with an experience orb, but before the player has been given the experience. - * It can be cancelled, and no further processing will be done. - */ + /// This event is fired after the player collides with an experience orb, but before the player has been given the experience. + /// This event is [Cancellable]. If cancelled, no further processing will be done. + /// + /// @param getEntity The player that is colliding with the experience orb. + /// @param getOrb The experience orb that the player is colliding with. record PickupXp(Player getEntity, ExperienceOrb getOrb) implements Cancellable, PlayerXpEvent, RecordEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(PickupXp.class); } - /** - * This event is fired when the player's experience changes through the {@link Player#giveExperiencePoints(int)} method. - * It can be cancelled, and no further processing will be done. - */ + /// This event is fired when the player's experience changes through the {@link Player#giveExperiencePoints(int)} method. + /// This event is [Cancellable]. If cancelled, no further processing will be done. final class XpChange extends MutableEvent implements Cancellable, PlayerXpEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(XpChange.class); @@ -58,10 +52,8 @@ public sealed interface PlayerXpEvent extends PlayerEvent { } } - /** - * This event is fired when the player's experience level changes through the {@link Player#giveExperienceLevels(int)} method. - * It can be cancelled, and no further processing will be done. - */ + /// This event is fired when the player's experience level changes through the [Player#giveExperienceLevels(int)] method. + /// This event is [Cancellable]. If cancelled, no further processing will be done. final class LevelChange extends MutableEvent implements Cancellable, PlayerXpEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(LevelChange.class); diff --git a/src/main/java/net/minecraftforge/event/entity/player/TradeWithVillagerEvent.java b/src/main/java/net/minecraftforge/event/entity/player/TradeWithVillagerEvent.java index 7f700fa981..22756f8285 100644 --- a/src/main/java/net/minecraftforge/event/entity/player/TradeWithVillagerEvent.java +++ b/src/main/java/net/minecraftforge/event/entity/player/TradeWithVillagerEvent.java @@ -13,14 +13,13 @@ import net.minecraftforge.eventbus.api.event.RecordEvent; import net.minecraftforge.fml.LogicalSide; import org.jetbrains.annotations.ApiStatus; -/** - * Fired when a player trades with an {@link AbstractVillager}. - * - *

    This event is fired only on the {@linkplain LogicalSide#SERVER logical server}.

    - * - * @param getMerchantOffer the {@link MerchantOffer} selected by the player to trade with - * @param getAbstractVillager the villager the player traded with - */ +/// Fired when a player trades with an [AbstractVillager]. +/// +/// This event is fired only on the [logical server][LogicalSide#SERVER]. +/// +/// @param getEntity the player that traded with the villager +/// @param getMerchantOffer the [MerchantOffer] selected by the player to trade with +/// @param getAbstractVillager the villager the player traded with public record TradeWithVillagerEvent( Player getEntity, MerchantOffer getMerchantOffer, diff --git a/src/main/java/net/minecraftforge/event/level/AlterGroundEvent.java b/src/main/java/net/minecraftforge/event/level/AlterGroundEvent.java index f2169183a3..63ecbd0973 100644 --- a/src/main/java/net/minecraftforge/event/level/AlterGroundEvent.java +++ b/src/main/java/net/minecraftforge/event/level/AlterGroundEvent.java @@ -10,7 +10,6 @@ import net.minecraft.util.RandomSource; import net.minecraft.world.level.LevelSimulatedReader; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.feature.treedecorators.TreeDecorator; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.MutableEvent; import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; @@ -22,8 +21,7 @@ import org.jetbrains.annotations.ApiStatus; *

    * This event is not {@linkplain Cancellable cancellable}. *

    - * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus} - * only on the {@linkplain net.minecraftforge.fml.LogicalSide#SERVER logical server}. + * This event is fired only on the {@linkplain net.minecraftforge.fml.LogicalSide#SERVER logical server}. */ public final class AlterGroundEvent extends MutableEvent { public static final EventBus BUS = EventBus.create(AlterGroundEvent.class); diff --git a/src/main/java/net/minecraftforge/event/level/BlockEvent.java b/src/main/java/net/minecraftforge/event/level/BlockEvent.java index b2394776b9..fce5e442b0 100644 --- a/src/main/java/net/minecraftforge/event/level/BlockEvent.java +++ b/src/main/java/net/minecraftforge/event/level/BlockEvent.java @@ -9,7 +9,6 @@ import java.util.EnumSet; import java.util.List; import net.minecraft.core.registries.Registries; -import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.level.block.BaseFireBlock; import net.minecraft.world.level.portal.PortalShape; @@ -17,14 +16,11 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.enchantment.Enchantments; -import net.minecraft.world.item.ItemStack; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.Level; import net.minecraftforge.common.ForgeHooks; -import net.minecraftforge.common.ToolAction; -import net.minecraftforge.common.ToolActions; import net.minecraftforge.common.util.BlockSnapshot; import net.minecraftforge.common.util.HasResult; import net.minecraftforge.common.util.Result; @@ -37,9 +33,10 @@ import net.minecraftforge.eventbus.api.event.RecordEvent; import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.NullMarked; public sealed interface BlockEvent - permits BlockEvent.BlockToolModificationEvent, BlockEvent.BreakEvent, BlockEvent.CropGrowEvent, + permits BlockEvent.BreakEvent, BlockEvent.CropGrowEvent, BlockEvent.EntityPlaceEvent, BlockEvent.FarmlandTrampleEvent, BlockEvent.FluidPlaceBlockEvent, BlockEvent.NeighborNotifyEvent, BlockEvent.PortalSpawnEvent, NoteBlockEvent, PistonEvent { boolean DEBUG = Boolean.parseBoolean(System.getProperty("forge.debugBlockEvent", "false")); @@ -50,10 +47,9 @@ public sealed interface BlockEvent BlockState getState(); - /** - * Event that is fired when an Block is about to be broken by a player - * Setting the result to {@link Result#DENY} will prevent the Block from being broken. - */ + /// Event that is fired when an Block is about to be broken by a player. + /// + /// Setting the result to [Result#DENY] will prevent the Block from being broken. final class BreakEvent extends MutableEvent implements Cancellable, BlockEvent, HasResult { public static final CancellableEventBus BUS = CancellableEventBus.create(BreakEvent.class); @@ -61,7 +57,7 @@ public sealed interface BlockEvent private final BlockPos pos; private final BlockState state; - /** Reference to the Player who broke the block. If no player is available, use a EntityFakePlayer */ + /// Reference to the Player who broke the block private final Player player; private int exp; private Result result; @@ -103,20 +99,16 @@ public sealed interface BlockEvent return player; } - /** - * Get the experience dropped by the block after the event has processed - * - * @return The experience to drop or 0 if the event was denied - */ + /// Get the experience dropped by the block after the event has processed + /// + /// @return The experience to drop or 0 if the event was denied public int getExpToDrop() { return this.getResult().isDenied() ? 0 : exp; } - /** - * Set the amount of experience dropped by the block after the event has processed - * - * @param exp 1 or higher to drop experience, else nothing will drop - */ + /// Set the amount of experience dropped by the block after the event has processed + /// + /// @param exp 1 or higher to drop experience, else nothing will drop public void setExpToDrop(int exp) { this.exp = exp; } @@ -132,11 +124,9 @@ public sealed interface BlockEvent } } - /** - * Called when a block is placed. - * - * If a Block Place event is cancelled, the block will not be placed. - */ + /// Called when a block is placed. + /// + /// If a Block Place event is cancelled, the block will not be placed. sealed class EntityPlaceEvent extends MutableEvent implements Cancellable, BlockEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(EntityPlaceEvent.class); @@ -247,14 +237,9 @@ public sealed interface BlockEvent } } - /** - * Fired when a liquid places a block. Use {@link #setNewState(BlockState)} to change the result of - * a cobblestone generator or add variants of obsidian. Alternatively, you could execute - * arbitrary code when lava sets blocks on fire, even preventing it. - * - * {@link #getState()} will return the block that was originally going to be placed. - * {@link #getPos()} will return the position of the block to be changed. - */ + /// Fired when a liquid places a block. Use [#setNewState(BlockState)] to change the result of + /// a cobblestone generator or add variants of obsidian. Alternatively, you could execute + /// arbitrary code when lava sets blocks on fire, even preventing it. final class FluidPlaceBlockEvent extends MutableEvent implements Cancellable, BlockEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(FluidPlaceBlockEvent.class); @@ -280,26 +265,24 @@ public sealed interface BlockEvent return level; } + /// @return The position of the block to be changed. @Override public BlockPos getPos() { return pos; } + /// @return The block that was originally going to be placed. @Override public BlockState getState() { return state; } - /** - * @return The position of the liquid this event originated from. This may be the same as {@link #getPos()}. - */ + /// @return The position of the liquid this event originated from. This may be the same as [#getPos()]. public BlockPos getLiquidPos() { return liquidPos; } - /** - * @return The block state that will be placed after this event resolves. - */ + /// @return The block state that will be placed after this event resolves. public BlockState getNewState() { return newState; } @@ -308,29 +291,22 @@ public sealed interface BlockEvent this.newState = state; } - /** - * @return The state of the block to be changed before the event was fired. - */ + /// @return The state of the block to be changed before the event was fired. public BlockState getOriginalState() { return origState; } } - /** - * Fired when a crop block grows. See subevents. - */ + /// Fired when a crop block grows. See subevents. sealed interface CropGrowEvent extends BlockEvent, InheritableEvent { EventBus BUS = EventBus.create(CropGrowEvent.class); - /** - * Fired when any "growing age" blocks (for example cacti, chorus plants, or crops - * in vanilla) attempt to advance to the next growth age state during a random tick.
    - *
    - * {@link Result#DEFAULT} will pass on to the vanilla growth mechanics.
    - * {@link Result#ALLOW} will force the plant to advance a growth stage.
    - * {@link Result#DENY} will prevent the plant from advancing a growth stage.
    - *
    - */ + /// Fired when any "growing age" blocks (for example cacti, chorus plants, or crops + /// in vanilla) attempt to advance to the next growth age state during a random tick. + /// + /// - [Result#DEFAULT] will pass on to the vanilla growth mechanics. + /// - [Result#ALLOW] will force the plant to advance a growth stage. + /// - [Result#DENY] will prevent the plant from advancing a growth stage. record Pre(LevelAccessor getLevel, BlockPos getPos, BlockState getState, Result.Holder resultHolder) implements CropGrowEvent, HasResult.Record { public static final EventBus

     BUS = EventBus.create(Pre.class);
    @@ -340,20 +316,23 @@ public sealed interface BlockEvent
                 }
             }
     
    -        /**
    -         * Fired when "growing age" blocks (for example cacti, chorus plants, or crops
    -         * in vanilla) have successfully grown. The block's original state is available,
    -         * in addition to its new state.
    - */ + /// Fired when "growing age" blocks (for example cacti, chorus plants, or crops in vanilla) have successfully + /// grown. The block's original state is available, in addition to its new state. record Post(LevelAccessor getLevel, BlockPos getPos, BlockState getState, BlockState getOriginalState) implements CropGrowEvent { public static final EventBus BUS = EventBus.create(Post.class); } } - /** - * Fired when farmland gets trampled - */ + /// Fired when farmland gets trampled by an entity and is about to turn into dirt. + /// + /// This event is [Cancellable]. Cancelling prevents the farmland from turning into dirt. + /// + /// @param getLevel The level the farmland block is in + /// @param getPos The position of the farmland block in the level + /// @param getFallDistance The distance the entity fell before landing on the farmland block + /// @param getEntity The entity that trampled the farmland block + @NullMarked record FarmlandTrampleEvent( LevelAccessor getLevel, BlockPos getPos, @@ -364,127 +343,13 @@ public sealed interface BlockEvent public static final CancellableEventBus BUS = CancellableEventBus.create(FarmlandTrampleEvent.class); } - /** Fired when an attempt is made to spawn a nether portal from - * {@link BaseFireBlock#onPlace(BlockState, Level, BlockPos, BlockState, boolean)}. - *
    - * If cancelled, the portal will not be spawned. - */ + /// Fired when an attempt is made to spawn a nether portal from + /// [BaseFireBlock#onPlace(BlockState, Level, BlockPos, BlockState, boolean)]. + /// + /// This event is [Cancellable]. If cancelled, the portal will not be spawned. + @NullMarked record PortalSpawnEvent(LevelAccessor getLevel, BlockPos getPos, BlockState getState, PortalShape getPortalSize) implements Cancellable, BlockEvent, RecordEvent { public static final CancellableEventBus BUS = CancellableEventBus.create(PortalSpawnEvent.class); } - - /** - * Fired when a block is right-clicked by a tool to change its state. - * For example: Used to determine if {@link ToolActions#AXE_STRIP an axe can strip}, - * {@link ToolActions#SHOVEL_FLATTEN a shovel can path}, or {@link ToolActions#HOE_TILL a hoe can till}. - *

    - * Care must be taken to ensure level-modifying events are only performed if {@link #isSimulated()} returns {@code false}. - *

    - * This event is {@linkplain Cancellable cancellable}. If cancelled, this will prevent the tool from changing - * the block's state. - */ - final class BlockToolModificationEvent extends MutableEvent implements Cancellable, BlockEvent { - public static final CancellableEventBus BUS = CancellableEventBus.create(BlockToolModificationEvent.class); - - private final LevelAccessor level; - private final BlockPos pos; - private final BlockState originalState; - - private final UseOnContext context; - private final ToolAction toolAction; - private final boolean simulate; - private BlockState state; - - public BlockToolModificationEvent(BlockState originalState, @NotNull UseOnContext context, ToolAction toolAction, boolean simulate) { - this.level = context.getLevel(); - this.pos = context.getClickedPos(); - this.originalState = originalState; - - this.context = context; - this.state = originalState; - this.toolAction = toolAction; - this.simulate = simulate; - } - - @Override - public LevelAccessor getLevel() { - return level; - } - - @Override - public BlockPos getPos() { - return pos; - } - - @Override - public BlockState getState() { - return originalState; - } - - /** - * @return the player using the tool. - * May be null based on what was provided by {@link #getContext() the use on context}. - */ - @Nullable - public Player getPlayer() { - return this.context.getPlayer(); - } - - /** - * @return the tool being used - */ - public ItemStack getHeldItemStack() { - return this.context.getItemInHand(); - } - - /** - * @return the action being performed - */ - public ToolAction getToolAction() { - return this.toolAction; - } - - /** - * Returns {@code true} if this event should not perform any actions that modify the level. - * If {@code false}, then level-modifying actions can be performed. - * - * @return {@code true} if this event should not perform any actions that modify the level. - * If {@code false}, then level-modifying actions can be performed. - */ - public boolean isSimulated() { - return this.simulate; - } - - /** - * Returns the nonnull use on context that this event was performed in. - * - * @return the nonnull use on context that this event was performed in - */ - @NotNull - public UseOnContext getContext() { - return context; - } - - /** - * Sets the state to transform the block into after tool use. - * - * @param finalState the state to transform the block into after tool use - * @see #getFinalState() - */ - public void setFinalState(@Nullable BlockState finalState) { - this.state = finalState; - } - - /** - * Returns the state to transform the block into after tool use. - * If {@link #setFinalState(BlockState)} is not called, this will return the original state. - * If {@link #isCanceled()} is {@code true}, this value will be ignored and the tool action will be canceled. - * - * @return the state to transform the block into after tool use - */ - public BlockState getFinalState() { - return state; - } - } } diff --git a/src/main/java/net/minecraftforge/event/level/BlockFeatureGrowEvent.java b/src/main/java/net/minecraftforge/event/level/BlockFeatureGrowEvent.java index 3cf96ac609..d3dae8e589 100644 --- a/src/main/java/net/minecraftforge/event/level/BlockFeatureGrowEvent.java +++ b/src/main/java/net/minecraftforge/event/level/BlockFeatureGrowEvent.java @@ -11,8 +11,7 @@ import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.util.RandomSource; import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; -import net.minecraftforge.common.MinecraftForge; +import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraftforge.common.util.HasResult; import net.minecraftforge.common.util.Result; import net.minecraftforge.eventbus.api.bus.EventBus; @@ -27,8 +26,7 @@ import org.jetbrains.annotations.Nullable; * using the features set on the event. * {@linkplain Result#DENY DENY} will prevent the sapling from growing. *

    - * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus} - * only on the {@linkplain net.minecraftforge.fml.LogicalSide#SERVER logical server}. + * This event is fired only on the {@linkplain net.minecraftforge.fml.LogicalSide#SERVER logical server}. */ public final class BlockFeatureGrowEvent implements LevelEvent, HasResult { public static final EventBus BUS = EventBus.create(BlockFeatureGrowEvent.class); @@ -37,10 +35,10 @@ public final class BlockFeatureGrowEvent implements LevelEvent, HasResult { private final RandomSource randomSource; private final BlockPos pos; @Nullable - private Holder> feature; + private Holder feature; private Result result = Result.DEFAULT; - public BlockFeatureGrowEvent(LevelAccessor level, RandomSource randomSource, BlockPos pos, @Nullable Holder> feature) { + public BlockFeatureGrowEvent(LevelAccessor level, RandomSource randomSource, BlockPos pos, @Nullable Holder feature) { this.level = level; this.randomSource = randomSource; this.pos = pos; @@ -70,22 +68,22 @@ public final class BlockFeatureGrowEvent implements LevelEvent, HasResult { * {@return the holder of the feature which will be placed, possibly null} */ @Nullable - public Holder> getFeature() { + public Holder getFeature() { return feature; } /** * @param feature a {@linkplain Holder} referencing a tree feature to be placed instead of the current feature. */ - public void setFeature(@Nullable Holder> feature) { + public void setFeature(@Nullable Holder feature) { this.feature = feature; } /** * @param featureKey a {@linkplain ResourceKey} referencing a tree feature to be placed instead of the current feature. */ - public void setFeature(ResourceKey> featureKey) { - this.feature = this.getLevel().registryAccess().lookupOrThrow(Registries.CONFIGURED_FEATURE).get(featureKey).orElse(null); + public void setFeature(ResourceKey featureKey) { + this.feature = this.getLevel().registryAccess().lookupOrThrow(Registries.FEATURE).get(featureKey).orElse(null); } @Override diff --git a/src/main/java/net/minecraftforge/event/level/ChunkTicketLevelUpdatedEvent.java b/src/main/java/net/minecraftforge/event/level/ChunkTicketLevelUpdatedEvent.java index 40554dee44..72aca59e27 100644 --- a/src/main/java/net/minecraftforge/event/level/ChunkTicketLevelUpdatedEvent.java +++ b/src/main/java/net/minecraftforge/event/level/ChunkTicketLevelUpdatedEvent.java @@ -7,7 +7,6 @@ package net.minecraftforge.event.level; import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ServerLevel; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.RecordEvent; import net.minecraftforge.fml.LogicalSide; @@ -25,8 +24,7 @@ import org.jspecify.annotations.NullMarked; * is by first changing it from 31 to 46, and then queuing the update from 46 to 32. However, when going from 32 to 31, * vanilla is able to go directly. *

    - * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus} - * only on the {@linkplain LogicalSide#SERVER logical server}. + * This event is fired only on the {@linkplain LogicalSide#SERVER logical server}. * * @param getLevel the server level containing the chunk * @param getChunkPos the long representation of the chunk position the ticket level changed for diff --git a/src/main/java/net/minecraftforge/event/level/ChunkWatchEvent.java b/src/main/java/net/minecraftforge/event/level/ChunkWatchEvent.java index 0e8e9eaa3a..325b212586 100644 --- a/src/main/java/net/minecraftforge/event/level/ChunkWatchEvent.java +++ b/src/main/java/net/minecraftforge/event/level/ChunkWatchEvent.java @@ -9,7 +9,6 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.level.ChunkPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.InheritableEvent; import net.minecraftforge.fml.LogicalSide; @@ -20,9 +19,8 @@ import net.minecraftforge.fml.LogicalSide; * The {@linkplain #getPlayer() player}'s level may not be the same as the {@linkplain #getLevel() level of the chunk} * when the player is teleporting to another dimension. *

    - * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus} - * only on the {@linkplain LogicalSide#SERVER logical server}. - **/ + * This event is fired only on the {@linkplain LogicalSide#SERVER logical server}. + */ public sealed interface ChunkWatchEvent extends InheritableEvent { EventBus BUS = EventBus.create(ChunkWatchEvent.class); @@ -46,9 +44,8 @@ public sealed interface ChunkWatchEvent extends InheritableEvent { *

    * This event may be used to send additional chunk-related data to the client. *

    - * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus} - * only on the {@linkplain LogicalSide#SERVER logical server}. - **/ + * This event is fired only on the {@linkplain LogicalSide#SERVER logical server}. + */ record Watch(ServerPlayer getPlayer, ChunkPos getPos, LevelChunk getChunk, ServerLevel getLevel) implements ChunkWatchEvent { public static final EventBus BUS = EventBus.create(Watch.class); @@ -61,9 +58,8 @@ public sealed interface ChunkWatchEvent extends InheritableEvent { /** * This event is fired when server sends "forget chunk" packet to the {@link ServerPlayer}. *

    - * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus} - * only on the {@linkplain LogicalSide#SERVER logical server}. - **/ + * This event is fired only on the {@linkplain LogicalSide#SERVER logical server}. + */ record UnWatch(ServerPlayer getPlayer, ChunkPos getPos, ServerLevel getLevel) implements ChunkWatchEvent { public static final EventBus BUS = EventBus.create(UnWatch.class); } diff --git a/src/main/java/net/minecraftforge/event/level/LevelEvent.java b/src/main/java/net/minecraftforge/event/level/LevelEvent.java index b8340ce4bf..43b6f28aed 100644 --- a/src/main/java/net/minecraftforge/event/level/LevelEvent.java +++ b/src/main/java/net/minecraftforge/event/level/LevelEvent.java @@ -25,7 +25,6 @@ import net.minecraft.world.level.StructureManager; import net.minecraft.world.level.biome.MobSpawnSettings; import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.storage.ServerLevelData; -import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.bus.CancellableEventBus; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.InheritableEvent; @@ -53,9 +52,8 @@ public sealed interface LevelEvent extends InheritableEvent * This event is fired whenever a level loads in ClientLevel's constructor and * {@literal MinecraftServer#createLevels(ChunkProgressListener)}. *

    - * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus} - * on both logical sides. - **/ + * This event is fired on both logical sides. + */ record Load(LevelAccessor getLevel) implements LevelEvent { public static final EventBus BUS = EventBus.create(Load.class); } @@ -67,9 +65,8 @@ public sealed interface LevelEvent extends InheritableEvent * {@link MinecraftServer#stopServer()}, * {@link Minecraft#clearClientLevel(Screen)}. *

    - * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus} - * on both logical sides. - **/ + * This event is fired on both logical sides. + */ record Unload(LevelAccessor getLevel) implements LevelEvent { public static final EventBus BUS = EventBus.create(Unload.class); } @@ -79,9 +76,8 @@ public sealed interface LevelEvent extends InheritableEvent * This event is fired when a level is saved in * {@link ServerLevel#save(ProgressListener, boolean, boolean)}. *

    - * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus} - * only on the {@linkplain LogicalSide#SERVER logical server}. - **/ + * This event is fired only on the {@linkplain LogicalSide#SERVER logical server}. + */ record Save(LevelAccessor getLevel) implements LevelEvent { public static final EventBus BUS = EventBus.create(Save.class); } @@ -93,8 +89,7 @@ public sealed interface LevelEvent extends InheritableEvent * This event is {@linkplain Cancellable cancellable}. * If the event is cancelled, the vanilla logic to choose a spawn position will be skipped. *

    - * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus} - * only on the {@linkplain LogicalSide#SERVER logical server}. + * This event is fired only on the {@linkplain LogicalSide#SERVER logical server}. * * @see ServerLevelData#isInitialized() */ diff --git a/src/main/java/net/minecraftforge/event/level/PistonEvent.java b/src/main/java/net/minecraftforge/event/level/PistonEvent.java index 6b12bba88d..d46c9afa01 100644 --- a/src/main/java/net/minecraftforge/event/level/PistonEvent.java +++ b/src/main/java/net/minecraftforge/event/level/PistonEvent.java @@ -18,37 +18,25 @@ import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; -/** - * Base piston event, use {@link PistonEvent.Post} and {@link PistonEvent.Pre} - */ +/// Base piston event, use [PistonEvent.Post] and [PistonEvent.Pre] @NullMarked public sealed interface PistonEvent extends BlockEvent { - /** - * @return The position of the piston - */ + /// @return The position of the piston @Override BlockPos getPos(); - /** - * @return The move direction of the piston - */ + /// @return The move direction of the piston Direction getDirection(); - /** - * Helper method that gets the piston position offset by its facing - */ + /// Helper method that gets the piston position offset by its facing default BlockPos getFaceOffsetPos() { return this.getPos().relative(getDirection()); } - /** - * @return The movement type of the piston (extension, retraction) - */ + /// @return The movement type of the piston (extension, retraction) PistonMoveType getPistonMoveType(); - /** - * @return A piston structure helper for this movement. Returns null if the world stored is not a {@link Level} - */ + /// @return A piston structure helper for this movement. Returns null if the world stored is not a [Level] @Nullable default PistonStructureResolver getStructureHelper() { if (getLevel() instanceof Level) { @@ -58,9 +46,13 @@ public sealed interface PistonEvent extends BlockEvent { } } - /** - * Fires before the piston has updated block states. Cancellation prevents movement. - */ + /// Fires before the piston has updated block states. + /// + /// This event is [Cancellable]. Cancelling prevents movement. + /// + /// @param getLevel The level the piston is in + /// @param getPos The position of the piston in the level + /// @param getPistonMoveType The movement type of the piston (extension, retraction) record Pre( LevelAccessor getLevel, BlockPos getPos, @@ -75,9 +67,7 @@ public sealed interface PistonEvent extends BlockEvent { } } - /** - * Fires after the piston has moved and set surrounding states. This will not fire if {@link PistonEvent.Pre} is cancelled. - */ + /// Fires after the piston has moved and set surrounding states. This will not fire if [PistonEvent.Pre] is cancelled. record Post( LevelAccessor getLevel, BlockPos getPos, diff --git a/src/main/java/net/minecraftforge/event/village/VillageSiegeEvent.java b/src/main/java/net/minecraftforge/event/village/VillageSiegeEvent.java index 6c1252065d..e44780f872 100644 --- a/src/main/java/net/minecraftforge/event/village/VillageSiegeEvent.java +++ b/src/main/java/net/minecraftforge/event/village/VillageSiegeEvent.java @@ -13,12 +13,10 @@ import net.minecraftforge.eventbus.api.bus.CancellableEventBus; import net.minecraftforge.eventbus.api.event.RecordEvent; import net.minecraftforge.eventbus.api.event.characteristic.Cancellable; -/** - * VillageSiegeEvent is fired just before a zombie siege finds a successful location in - * {@code VillageSiege#tryToSetupSiege(ServerLevel)}, to give mods the chance to stop the siege.
    - *
    - * Cancelling this event stops the siege.
    - */ +/// VillageSiegeEvent is fired just before a zombie siege finds a successful location, to give mods the chance to stop +/// the siege. +/// +/// This event is [Cancellable]. Cancelling this event stops the siege. public record VillageSiegeEvent( VillageSiege getSiege, Level getLevel, diff --git a/src/main/java/net/minecraftforge/gametest/ForgeGameTestHooks.java b/src/main/java/net/minecraftforge/gametest/ForgeGameTestHooks.java index 96c63c1b9f..c5c910338e 100644 --- a/src/main/java/net/minecraftforge/gametest/ForgeGameTestHooks.java +++ b/src/main/java/net/minecraftforge/gametest/ForgeGameTestHooks.java @@ -6,10 +6,12 @@ package net.minecraftforge.gametest; import net.minecraft.SharedConstants; +import net.minecraft.core.registries.Registries; import net.minecraft.gametest.framework.GameTestEnvironments; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.gametest.framework.TestData; import net.minecraft.resources.Identifier; +import net.minecraft.resources.ResourceKey; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.loading.FMLLoader; import org.jetbrains.annotations.ApiStatus; @@ -138,8 +140,13 @@ public class ForgeGameTestHooks { ? Identifier.withDefaultNamespace(gametest.environment()) : key(namespace, "", gametest.environment()); + var dim = ResourceKey.create(Registries.DIMENSION, GameTest.DEFAULT_DIMENSION.equals(gametest.dimension()) + ? Identifier.parse(gametest.dimension()) + : key(namespace, "", gametest.dimension())); + var data = new TestData( env, + dim, structure, gametest.maxTicks(), gametest.setupTicks(), diff --git a/src/main/java/net/minecraftforge/gametest/GameTest.java b/src/main/java/net/minecraftforge/gametest/GameTest.java index ba5df3ebe3..de16988cd8 100644 --- a/src/main/java/net/minecraftforge/gametest/GameTest.java +++ b/src/main/java/net/minecraftforge/gametest/GameTest.java @@ -21,6 +21,8 @@ public @interface GameTest { static final String DEFAULT_STRUCTURE = "forge:empty3x3x3"; String environment() default GameTestEnvironments.DEFAULT; + static final String DEFAULT_DIMENSION = "minecraft:overworld"; + String dimension() default DEFAULT_DIMENSION; String structure() default DEFAULT_STRUCTURE; int maxTicks() default 100; int setupTicks() default 0; diff --git a/src/main/java/net/minecraftforge/network/NetworkContext.java b/src/main/java/net/minecraftforge/network/NetworkContext.java index a155b96653..c0cdf46a06 100644 --- a/src/main/java/net/minecraftforge/network/NetworkContext.java +++ b/src/main/java/net/minecraftforge/network/NetworkContext.java @@ -16,9 +16,12 @@ import org.jetbrains.annotations.ApiStatus; import io.netty.util.AttributeKey; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.minecraft.network.Connection; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.Identifier; import net.minecraft.server.network.ConfigurationTask; import net.minecraft.server.network.ServerConfigurationPacketListenerImpl; +import net.minecraftforge.network.NetworkContext.NetworkMismatchData.Version; import net.minecraftforge.network.packets.ModVersions; public class NetworkContext { @@ -152,6 +155,6 @@ public class NetworkContext { boolean fromServer, Map mods ) { - public record Version(String received, String had) {} + public record Version(String received, String had) { } } } diff --git a/src/main/java/net/minecraftforge/network/packets/ChannelVersions.java b/src/main/java/net/minecraftforge/network/packets/ChannelVersions.java index 66b1f25dbb..9320470347 100644 --- a/src/main/java/net/minecraftforge/network/packets/ChannelVersions.java +++ b/src/main/java/net/minecraftforge/network/packets/ChannelVersions.java @@ -11,22 +11,19 @@ import org.jetbrains.annotations.NotNull; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.Identifier; import net.minecraftforge.network.NetworkRegistry; public record ChannelVersions(Map channels) { - public static StreamCodec STREAM_CODEC = StreamCodec.ofMember(ChannelVersions::encode, ChannelVersions::decode); + public static StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.map(Object2IntOpenHashMap::new, Identifier.STREAM_CODEC, ByteBufCodecs.VAR_INT), + ChannelVersions::channels, + ChannelVersions::new + ); public ChannelVersions() { this(NetworkRegistry.buildChannelVersions()); } - - public static ChannelVersions decode(FriendlyByteBuf buf) { - return new ChannelVersions(buf.readMap(Object2IntOpenHashMap::new, FriendlyByteBuf::readIdentifier, FriendlyByteBuf::readVarInt)); - } - - public void encode(FriendlyByteBuf buf) { - buf.writeMap(channels, FriendlyByteBuf::writeIdentifier, FriendlyByteBuf::writeVarInt); - } } \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/network/packets/MismatchData.java b/src/main/java/net/minecraftforge/network/packets/MismatchData.java index 3f9fdac5a9..941fdfa954 100644 --- a/src/main/java/net/minecraftforge/network/packets/MismatchData.java +++ b/src/main/java/net/minecraftforge/network/packets/MismatchData.java @@ -5,11 +5,14 @@ package net.minecraftforge.network.packets; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import io.netty.buffer.ByteBuf; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.Identifier; import net.minecraftforge.network.NetworkContext.NetworkMismatchData; @@ -23,37 +26,21 @@ public record MismatchData( Map mismatched, Set missing ) { - public static final StreamCodec STREAM_CODEC = StreamCodec.ofMember(MismatchData::encode, MismatchData::decode); private static final int MAX_LENGTH = 0x100; + private static final StreamCodec STRING_CODEC = ByteBufCodecs.stringUtf8(MAX_LENGTH); + private static final StreamCodec IDENNTIFIER_CODEC = STRING_CODEC.map(Identifier::parse, Identifier::toString); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.map(HashMap::new, + IDENNTIFIER_CODEC, + StreamCodec.composite(STRING_CODEC, Version::received, STRING_CODEC, Version::had, Version::new) + ), + MismatchData::mismatched, + ByteBufCodecs.collection(HashSet::new, IDENNTIFIER_CODEC), + MismatchData::missing, + MismatchData::new + ); public MismatchData(NetworkMismatchData data) { this(data.mismatched(), data.missing()); } - - public static MismatchData decode(FriendlyByteBuf buf) { - var mismatched = buf.readMap( - i -> Identifier.parse(i.readUtf(MAX_LENGTH)), - i -> new Version( - i.readUtf(MAX_LENGTH), - i.readUtf(MAX_LENGTH) - ) - ); - var missing = buf.readCollection(HashSet::new, - i -> Identifier.parse(i.readUtf(MAX_LENGTH)) - ); - return new MismatchData(mismatched, missing); - } - - public void encode(FriendlyByteBuf buf) { - buf.writeMap(mismatched, - (o, k) -> o.writeUtf(k.toString(), MAX_LENGTH), - (o, v) -> { - o.writeUtf(v.received(), MAX_LENGTH); - o.writeUtf(v.had(), MAX_LENGTH); - } - ); - buf.writeCollection(missing, - (o, k) -> o.writeUtf(k.toString(), MAX_LENGTH) - ); - } } \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/network/packets/ModVersions.java b/src/main/java/net/minecraftforge/network/packets/ModVersions.java index 64822a70b2..ebf558218d 100644 --- a/src/main/java/net/minecraftforge/network/packets/ModVersions.java +++ b/src/main/java/net/minecraftforge/network/packets/ModVersions.java @@ -5,9 +5,13 @@ package net.minecraftforge.network.packets; +import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; + +import io.netty.buffer.ByteBuf; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraftforge.fml.ModList; import net.minecraftforge.forgespi.language.IModInfo; @@ -17,9 +21,13 @@ import net.minecraftforge.forgespi.language.IModInfo; * The mod data is stored as follows: [modId -> [modName, modVersion]] */ public record ModVersions(Map mods) { - public static final StreamCodec STREAM_CODEC = StreamCodec.ofMember(ModVersions::encode, ModVersions::decode); - - private static final int MAX_LENGTH = 0x100; + private static final StreamCodec STRING_CODEC = ByteBufCodecs.stringUtf8(0x100); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.map(HashMap::new, STRING_CODEC, StreamCodec.composite( + STRING_CODEC, Info::name, STRING_CODEC, Info::version, Info::new + )), ModVersions::mods, + ModVersions::new + ); public static ModVersions create() { return new ModVersions(ModList.getMods().stream().collect(Collectors.toMap( @@ -28,25 +36,5 @@ public record ModVersions(Map mods) { ))); } - public static ModVersions decode(FriendlyByteBuf buf) { - return new ModVersions(buf.readMap( - o -> o.readUtf(MAX_LENGTH), - o -> new Info( - o.readUtf(MAX_LENGTH), - o.readUtf(MAX_LENGTH) - ) - )); - } - - public void encode(FriendlyByteBuf output) { - output.writeMap(mods, - (o, s) -> o.writeUtf(s, MAX_LENGTH), - (o, p) -> { - o.writeUtf(p.name(), MAX_LENGTH); - o.writeUtf(p.version(), MAX_LENGTH); - } - ); - } - public record Info(String name, String version) { } } \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/network/packets/RegistryData.java b/src/main/java/net/minecraftforge/network/packets/RegistryData.java index 736af10f5f..21caa323c7 100644 --- a/src/main/java/net/minecraftforge/network/packets/RegistryData.java +++ b/src/main/java/net/minecraftforge/network/packets/RegistryData.java @@ -6,20 +6,16 @@ package net.minecraftforge.network.packets; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.Identifier; import net.minecraftforge.registries.ForgeRegistry.Snapshot; public record RegistryData(int token, Identifier name, Snapshot data) { - public static final StreamCodec STREAM_CODEC = StreamCodec.ofMember(RegistryData::encode, RegistryData::decode); - - public void encode(FriendlyByteBuf buf) { - buf.writeVarInt(token); - buf.writeIdentifier(name); - buf.writeBytes(data.getPacketData()); - } - - public static RegistryData decode(FriendlyByteBuf buf) { - return new RegistryData(buf.readVarInt(), buf.readIdentifier(), Snapshot.read(buf)); - } + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.VAR_INT, RegistryData::token, + Identifier.STREAM_CODEC, RegistryData::name, + Snapshot.STREAM_CODEC, RegistryData::data, + RegistryData::new + ); } \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/network/packets/RegistryList.java b/src/main/java/net/minecraftforge/network/packets/RegistryList.java index 531c363e09..f743f26146 100644 --- a/src/main/java/net/minecraftforge/network/packets/RegistryList.java +++ b/src/main/java/net/minecraftforge/network/packets/RegistryList.java @@ -8,6 +8,7 @@ package net.minecraftforge.network.packets; import java.util.List; import net.minecraft.core.Registry; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.Identifier; @@ -19,22 +20,14 @@ public record RegistryList( List normal, List>> datapacks) { - public static final StreamCodec STREAM_CODEC = StreamCodec.ofMember(RegistryList::encode, RegistryList::decode); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.VAR_INT, RegistryList::token, + Identifier.STREAM_CODEC.apply(ByteBufCodecs.list()), RegistryList::normal, + ResourceKey.REGISTRY_STREAM_CODEC.apply(ByteBufCodecs.list()), RegistryList::datapacks, + RegistryList::new + ); public RegistryList(int token) { this(token, RegistryManager.getRegistryNamesForSyncToClient(), List.copyOf(DataPackRegistriesHooks.getSyncedCustomRegistries())); } - - public static RegistryList decode(FriendlyByteBuf buf) { - var token = buf.readVarInt(); - var normal = buf.readList(FriendlyByteBuf::readIdentifier); - List>> datapacks = buf.readList(_ -> ResourceKey.createRegistryKey(buf.readIdentifier())); - return new RegistryList(token, normal, datapacks); - } - - public void encode(FriendlyByteBuf buf) { - buf.writeVarInt(token()); - buf.writeCollection(normal(), FriendlyByteBuf::writeIdentifier); - buf.writeCollection(datapacks(), FriendlyByteBuf::writeResourceKey); - } } \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/registries/DataPackRegistriesHooks.java b/src/main/java/net/minecraftforge/registries/DataPackRegistriesHooks.java index bcfd6e21b9..abf3b3dea1 100644 --- a/src/main/java/net/minecraftforge/registries/DataPackRegistriesHooks.java +++ b/src/main/java/net/minecraftforge/registries/DataPackRegistriesHooks.java @@ -8,9 +8,13 @@ package net.minecraftforge.registries; import net.minecraft.core.Registry; import net.minecraft.core.RegistrySynchronization; import net.minecraft.resources.RegistryDataLoader; +import net.minecraft.resources.RegistryDataLoader.RegistryData; import net.minecraft.resources.RegistryValidator; import net.minecraft.resources.ResourceKey; import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.Nullable; + +import com.mojang.serialization.Codec; import java.util.ArrayList; import java.util.Arrays; @@ -26,7 +30,8 @@ public final class DataPackRegistriesHooks { // Mutable views of vanilla registries private static final List> SYNCHRONIZED_REGISTRIES = new ArrayList<>(); - private static final List> WORLDGEN_REGISTRIES = new ArrayList<>(); + private static final List> WORLD_REGISTRIES = new ArrayList<>(); + private static final List> RELOADABLE_REGISTRIES = new ArrayList<>(); private static final Set>> NETWORKABLE_REGISTRIES = new HashSet<>(); // Out custom registries, things we need to make sure the client has @@ -43,27 +48,43 @@ public final class DataPackRegistriesHooks { } /* Internal forge method, registers a datapack registry codec and folder. */ - static void addRegistryCodec(DataPackRegistryEvent.DataPackRegistryData data) { - RegistryDataLoader.RegistryData loaderData = data.loaderData(); - WORLDGEN_REGISTRIES.add(loaderData); - if (data.networkCodec() != null) { - NETWORKABLE_REGISTRIES.add(loaderData.key()); - SYNCHRONIZED_REGISTRIES_CUSTOM.add(loaderData.key()); - SYNCHRONIZED_REGISTRIES.add(new RegistryDataLoader.RegistryData(loaderData.key(), data.networkCodec(), RegistryValidator.none())); + static void addRegistryCodec(ResourceKey> key, Codec codec, @Nullable Codec network, boolean reloadable, RegistryValidator validator) { + if (reloadable) + RELOADABLE_REGISTRIES.add(new RegistryData<>(key, codec)); + else + WORLD_REGISTRIES.add(new RegistryData<>(key, codec)); + + if (network != null) { + NETWORKABLE_REGISTRIES.add(key); + SYNCHRONIZED_REGISTRIES_CUSTOM.add(key); + SYNCHRONIZED_REGISTRIES.add(new RegistryData<>(key, network, validator)); } } /** - * Captures a mutable view of {@link RegistryDataLoader#WORLDGEN_REGISTRIES} so that we can register modded entries during the registry event. + * Captures a mutable view of {@link RegistryDataLoader#WORLD_REGISTRIES} so that we can register modded entries during the registry event. * All uses should use that field instead of this class. - * @param vanilla The vanilla worldgen registries - * @return An unmodifiable list of worldgen registries + * @param vanilla The vanilla registries + * @return An unmodifiable list of registries */ - public static List> grabWorldgenRegistries(RegistryDataLoader.RegistryData... vanilla) { + public static List> grabWorldRegistries(RegistryData... vanilla) { if (!StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).getCallerClass().equals(RegistryDataLoader.class)) - throw new IllegalCallerException("Attempted to call DataPackRegistriesHooks#grabWorldgenRegistries!"); - WORLDGEN_REGISTRIES.addAll(Arrays.asList(vanilla)); - return Collections.unmodifiableList(WORLDGEN_REGISTRIES); + throw new IllegalCallerException("Attempted to call DataPackRegistriesHooks#grabWorldRegistries!"); + WORLD_REGISTRIES.addAll(Arrays.asList(vanilla)); + return Collections.unmodifiableList(WORLD_REGISTRIES); + } + + /** + * Captures a mutable view of {@link RegistryDataLoader#RELOADABLE_REGISTRIES} so that we can register modded entries during the registry event. + * All uses should use that field instead of this class. + * @param vanilla The vanilla registries + * @return An unmodifiable list of registries + */ + public static List> grabReloadableRegistries(RegistryData... vanilla) { + if (!StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).getCallerClass().equals(RegistryDataLoader.class)) + throw new IllegalCallerException("Attempted to call DataPackRegistriesHooks#grabReloadableRegistries!"); + RELOADABLE_REGISTRIES.addAll(Arrays.asList(vanilla)); + return Collections.unmodifiableList(RELOADABLE_REGISTRIES); } /** diff --git a/src/main/java/net/minecraftforge/registries/DataPackRegistryEvent.java b/src/main/java/net/minecraftforge/registries/DataPackRegistryEvent.java index e29aab2581..cc5a8e65b5 100644 --- a/src/main/java/net/minecraftforge/registries/DataPackRegistryEvent.java +++ b/src/main/java/net/minecraftforge/registries/DataPackRegistryEvent.java @@ -10,7 +10,7 @@ import java.util.ArrayList; import java.util.List; import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.core.Registry; -import net.minecraft.resources.RegistryDataLoader; +import net.minecraft.resources.RegistryValidator; import net.minecraft.resources.ResourceKey; import net.minecraftforge.eventbus.api.bus.EventBus; import net.minecraftforge.eventbus.api.event.MutableEvent; @@ -30,7 +30,7 @@ public sealed interface DataPackRegistryEvent { final class NewRegistry extends MutableEvent implements DataPackRegistryEvent { public static final EventBus BUS = EventBus.create(NewRegistry.class); - private final List> registryDataList = new ArrayList<>(); + private final List> builders = new ArrayList<>(); @ApiStatus.Internal public NewRegistry() {} @@ -47,7 +47,7 @@ public sealed interface DataPackRegistryEvent { * @see #dataPackRegistry(ResourceKey, Codec, Codec) */ public void dataPackRegistry(ResourceKey> registryKey, Codec codec) { - this.dataPackRegistry(registryKey, codec, null); + builder(registryKey, codec); } /** @@ -68,15 +68,56 @@ public sealed interface DataPackRegistryEvent { * @see #dataPackRegistry(ResourceKey, Codec) */ public void dataPackRegistry(ResourceKey> registryKey, Codec codec, @Nullable Codec networkCodec) { - this.registryDataList.add(new DataPackRegistryData<>(new RegistryDataLoader.RegistryData(registryKey, codec), networkCodec)); + builder(registryKey, codec).sync(networkCodec); + } + + public Builder builder(ResourceKey> registryKey, Codec codec) { + var ret = new Builder(registryKey, codec); + builders.add(ret); + return ret; + } + + public static class Builder { + private final ResourceKey> key; + private final Codec codec; + private @Nullable Codec networkCodec; + private boolean reloadable = false; + private RegistryValidator validator = RegistryValidator.none(); + + private Builder(ResourceKey> key, final Codec codec) { + this.key = key; + this.codec = codec; + } + + public Builder sync(Codec codec) { + if (this.networkCodec != null) + throw new IllegalArgumentException("Network codec is already set"); + this.networkCodec = codec; + return this; + } + + public Builder reloadable() { + this.reloadable = true; + return this; + } + + public Builder world() { + this.reloadable = false; + return this; + } + + public Builder validator(RegistryValidator validator) { + this.validator = validator; + return this; + } } void process() { - for (DataPackRegistryData registryData : this.registryDataList) { - DataPackRegistriesHooks.addRegistryCodec(registryData); + for (var builder : this.builders) { + @SuppressWarnings("unchecked") + var typed = (Builder)builder; + DataPackRegistriesHooks.addRegistryCodec(typed.key, typed.codec, typed.networkCodec, typed.reloadable, typed.validator); } } } - - record DataPackRegistryData(RegistryDataLoader.RegistryData loaderData, @Nullable Codec networkCodec) {} } diff --git a/src/main/java/net/minecraftforge/registries/DeferredRegisterData.java b/src/main/java/net/minecraftforge/registries/DeferredRegisterData.java index 3e4a2e2cf7..ac5fe4f827 100644 --- a/src/main/java/net/minecraftforge/registries/DeferredRegisterData.java +++ b/src/main/java/net/minecraftforge/registries/DeferredRegisterData.java @@ -7,7 +7,7 @@ package net.minecraftforge.registries; import net.minecraft.core.Holder; import net.minecraft.core.Registry; -import net.minecraft.core.RegistrySetBuilder.RegistryBootstrap; +import net.minecraft.core.registries.SingleRegistryBootstrap; import net.minecraft.data.worldgen.BootstrapContext; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.Identifier; @@ -67,7 +67,7 @@ import java.util.function.Supplier; * * @param The base registry type */ -public class DeferredRegisterData implements RegistryBootstrap { +public class DeferredRegisterData implements SingleRegistryBootstrap { /** * DeferredRegister factory for data driven registries. This will not create objects during the normal registry events. @@ -299,7 +299,7 @@ public class DeferredRegisterData implements RegistryBootstrap { T value; if (e.getValue() != null) { value = e.getValue().apply(context); - context.register(ro.getKey(), value, this.lifecycle); + context.register(ro.getKey(), value); } else value = lookup.get(ro.getKey()).map(Holder::get).orElse(null); diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistries.java b/src/main/java/net/minecraftforge/registries/ForgeRegistries.java index 9a578f714e..45d5a31606 100644 --- a/src/main/java/net/minecraftforge/registries/ForgeRegistries.java +++ b/src/main/java/net/minecraftforge/registries/ForgeRegistries.java @@ -27,6 +27,7 @@ import net.minecraft.world.entity.ai.village.poi.PoiType; import net.minecraft.world.item.Item; import net.minecraft.world.item.crafting.RecipeSerializer; import net.minecraft.core.particles.ParticleType; +import net.minecraft.core.registries.Registries; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.item.alchemy.Potion; import net.minecraft.stats.StatType; @@ -36,9 +37,7 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.resources.Identifier; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProviderType; -import net.minecraft.world.level.levelgen.carver.WorldCarver; -import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; import net.minecraft.world.level.levelgen.feature.foliageplacers.FoliagePlacerType; import net.minecraft.world.level.levelgen.feature.treedecorators.TreeDecoratorType; import net.minecraftforge.common.Tags; @@ -98,10 +97,8 @@ public class ForgeRegistries { public static final IForgeRegistry ACTIVITIES = active(Keys.ACTIVITIES); // Worldgen - public static final IForgeRegistry> WORLD_CARVERS = active(Keys.WORLD_CARVERS); - public static final IForgeRegistry> FEATURES = active(Keys.FEATURES); public static final IForgeRegistry CHUNK_STATUS = active(Keys.CHUNK_STATUS); - public static final IForgeRegistry> BLOCK_STATE_PROVIDER_TYPES = active(Keys.BLOCK_STATE_PROVIDER_TYPES); + public static final IForgeRegistry> BLOCK_STATE_PROVIDER_TYPES = active(Registries.BLOCK_STATE_PROVIDER_TYPE); public static final IForgeRegistry> FOLIAGE_PLACER_TYPES = active(Keys.FOLIAGE_PLACER_TYPES); public static final IForgeRegistry> TREE_DECORATOR_TYPES = active(Keys.TREE_DECORATOR_TYPES); @@ -142,10 +139,7 @@ public class ForgeRegistries { public static final ResourceKey>> MEMORY_MODULE_TYPES = key("memory_module_type"); public static final ResourceKey>> SENSOR_TYPES = key("sensor_type"); public static final ResourceKey> ACTIVITIES = key("activity"); - public static final ResourceKey>> WORLD_CARVERS = key("worldgen/carver"); - public static final ResourceKey>> FEATURES = key("worldgen/feature"); public static final ResourceKey> CHUNK_STATUS = key("chunk_status"); - public static final ResourceKey>> BLOCK_STATE_PROVIDER_TYPES = key("worldgen/block_state_provider_type"); public static final ResourceKey>> FOLIAGE_PLACER_TYPES = key("worldgen/foliage_placer_type"); public static final ResourceKey>> TREE_DECORATOR_TYPES = key("worldgen/tree_decorator_type"); diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java index 1be1a30af7..04540c834d 100644 --- a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java +++ b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java @@ -43,10 +43,11 @@ import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.google.common.collect.Multimap; -import io.netty.buffer.Unpooled; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.Identifier; import net.minecraft.core.Registry; @@ -794,16 +795,7 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist //Public for tests public Snapshot makeSnapshot() { - Snapshot ret = new Snapshot(); - for (Entry entry : this.ids.entrySet()) { - Integer id = entry.getKey(); - V value = entry.getValue(); - ret.ids.put(getKey(value), id.intValue()); - } - ret.aliases.putAll(this.aliases); - ret.blocked.addAll(this.blocked); - ret.overrides.putAll(getOverrideOwners()); - return ret; + return Snapshot.of(this); } Map getOverrideOwners() { @@ -848,11 +840,42 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist public static class Snapshot { private static final Comparator sorter = Identifier::compareNamespaced; - public final Object2IntMap ids = new Object2IntRBTreeMap<>(sorter); - public final Map aliases = new TreeMap<>(sorter); - public final IntSet blocked = new IntRBTreeSet(); - public final Map overrides = new TreeMap<>(sorter); - private FriendlyByteBuf binary = null; + public final Object2IntMap ids; + public final Map aliases; + public final Map overrides; + public final IntSet blocked; + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.map(_ -> new Object2IntRBTreeMap<>(sorter), Identifier.STREAM_CODEC, ByteBufCodecs.VAR_INT), snap -> snap.ids, + ByteBufCodecs.map(_ -> new TreeMap<>(sorter), Identifier.STREAM_CODEC, Identifier.STREAM_CODEC), snap -> snap.aliases, + ByteBufCodecs.map(_ -> new TreeMap<>(sorter), Identifier.STREAM_CODEC, ByteBufCodecs.stringUtf8(0x100)), snap -> snap.overrides, + ByteBufCodecs.collection(_ -> new IntRBTreeSet(), ByteBufCodecs.VAR_INT), snap -> snap.blocked, + Snapshot::new + ); + + private Snapshot(Object2IntMap ids, Map aliases, Map overrides, IntSet blocked) { + this.ids = ids; + this.aliases = aliases; + this.overrides = overrides; + this.blocked = blocked; + } + + public static Snapshot of(ForgeRegistry reg) { + var ids = new Object2IntRBTreeMap(sorter); + for (Entry entry : reg.ids.entrySet()) + ids.put(reg.getKey(entry.getValue()), entry.getKey().intValue()); + + var aliases = new TreeMap(sorter); + aliases.putAll(reg.aliases); + + var overrides = new TreeMap(sorter); + overrides.putAll(reg.getOverrideOwners()); + + var blocked = new IntRBTreeSet(); + blocked.addAll(reg.blocked); + + return new Snapshot(ids, aliases, overrides, blocked); + } public CompoundTag write() { CompoundTag data = new CompoundTag(); @@ -891,53 +914,32 @@ public class ForgeRegistry implements IForgeRegistryInternal, IForgeRegist } public static Snapshot read(CompoundTag nbt) { - Snapshot ret = new Snapshot(); - if (nbt == null) - return ret; + var ids = new Object2IntRBTreeMap(sorter); + var aliases = new TreeMap(sorter); + var overrides = new TreeMap(sorter); + var blocked = new IntRBTreeSet(); + + if (nbt == null) + return new Snapshot(ids, aliases, overrides, blocked); nbt.getListOrEmpty("ids").compoundStream().forEach(comp -> - ret.ids.put(Identifier.parse(comp.getString("K").orElseThrow()), comp.getIntOr("V", 0)) + ids.put(Identifier.parse(comp.getString("K").orElseThrow()), comp.getIntOr("V", 0)) ); nbt.getListOrEmpty("aliases").compoundStream().forEach(comp -> - ret.aliases.put(Identifier.parse(comp.getString("K").orElseThrow()), Identifier.parse(comp.getString("V").orElseThrow())) + aliases.put(Identifier.parse(comp.getString("K").orElseThrow()), Identifier.parse(comp.getString("V").orElseThrow())) ); nbt.getListOrEmpty("overrides").compoundStream().forEach(comp -> - ret.overrides.put(Identifier.parse(comp.getString("K").orElseThrow()), comp.getString("V").orElseThrow()) + overrides.put(Identifier.parse(comp.getString("K").orElseThrow()), comp.getString("V").orElseThrow()) ); - nbt.getIntArray("blocked").ifPresent(blocked -> { - for (int i : blocked) - ret.blocked.add(i); + nbt.getIntArray("blocked").ifPresent(data -> { + for (int i : data) + blocked.add(i); }); - return ret; - } - - public synchronized FriendlyByteBuf getPacketData() { - if (binary == null) { - FriendlyByteBuf pkt = new FriendlyByteBuf(Unpooled.buffer()); - pkt.writeMap(this.ids, FriendlyByteBuf::writeIdentifier, FriendlyByteBuf::writeVarInt); - pkt.writeMap(this.aliases, FriendlyByteBuf::writeIdentifier, FriendlyByteBuf::writeIdentifier); - pkt.writeMap(this.overrides, FriendlyByteBuf::writeIdentifier, (b,v) -> b.writeUtf(v, 0x100)); - pkt.writeCollection(this.blocked, FriendlyByteBuf::writeVarInt); - this.binary = pkt; - } - - return new FriendlyByteBuf(binary.slice()); - } - - public static Snapshot read(FriendlyByteBuf buf) { - if (buf == null) - return new Snapshot(); - - var ret = new Snapshot(); - ret.ids.putAll(buf.readMap(FriendlyByteBuf::readIdentifier, FriendlyByteBuf::readVarInt)); - ret.aliases.putAll(buf.readMap(FriendlyByteBuf::readIdentifier, FriendlyByteBuf::readIdentifier)); - ret.overrides.putAll(buf.readMap(FriendlyByteBuf::readIdentifier, b -> b.readUtf(0x100))); - ret.blocked.addAll(buf.readList(FriendlyByteBuf::readVarInt)); - return ret; + return new Snapshot(ids, aliases, overrides, blocked); } } diff --git a/src/main/java/net/minecraftforge/registries/GameData.java b/src/main/java/net/minecraftforge/registries/GameData.java index 626daf0ebf..cd53a19a90 100644 --- a/src/main/java/net/minecraftforge/registries/GameData.java +++ b/src/main/java/net/minecraftforge/registries/GameData.java @@ -134,10 +134,7 @@ public class GameData { makeRegistry(Keys.ACTIVITIES).disableSaving().disableSync().create(); // Worldgen - makeRegistry(Keys.WORLD_CARVERS).disableSaving().disableSync().create(); - makeRegistry(Keys.FEATURES).disableSaving().disableSync().create(); makeRegistry(Keys.CHUNK_STATUS, "empty").disableSaving().disableSync().create(); - makeRegistry(Keys.BLOCK_STATE_PROVIDER_TYPES).disableSaving().disableSync().create(); makeRegistry(Keys.FOLIAGE_PLACER_TYPES).disableSaving().disableSync().create(); makeRegistry(Keys.TREE_DECORATOR_TYPES).disableSaving().disableSync().create(); diff --git a/src/main/java/net/minecraftforge/registries/MissingMappingsEvent.java b/src/main/java/net/minecraftforge/registries/MissingMappingsEvent.java index 1ecd66240e..d0ba46465f 100644 --- a/src/main/java/net/minecraftforge/registries/MissingMappingsEvent.java +++ b/src/main/java/net/minecraftforge/registries/MissingMappingsEvent.java @@ -16,9 +16,6 @@ import java.util.Collection; import java.util.List; import java.util.Locale; -/** - * Fired on the {@link net.minecraftforge.common.MinecraftForge#EVENT_BUS forge bus}. - */ public final class MissingMappingsEvent extends MutableEvent { public static final EventBus BUS = EventBus.create(MissingMappingsEvent.class); diff --git a/src/main/java/net/minecraftforge/registries/holdersets/AndHolderSet.java b/src/main/java/net/minecraftforge/registries/holdersets/AndHolderSet.java index c598eb9696..560c0fd950 100644 --- a/src/main/java/net/minecraftforge/registries/holdersets/AndHolderSet.java +++ b/src/main/java/net/minecraftforge/registries/holdersets/AndHolderSet.java @@ -15,7 +15,7 @@ import com.mojang.serialization.MapCodec; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; import net.minecraft.core.Registry; -import net.minecraft.resources.HolderSetCodec; +import net.minecraft.core.registries.codec.HolderSetCodec; import net.minecraft.resources.ResourceKey; import net.minecraftforge.common.ForgeMod; diff --git a/src/main/java/net/minecraftforge/registries/holdersets/AnyHolderSet.java b/src/main/java/net/minecraftforge/registries/holdersets/AnyHolderSet.java index 34d7fd6c0b..6f79d668ed 100644 --- a/src/main/java/net/minecraftforge/registries/holdersets/AnyHolderSet.java +++ b/src/main/java/net/minecraftforge/registries/holdersets/AnyHolderSet.java @@ -88,7 +88,7 @@ public record AnyHolderSet(HolderLookup.RegistryLookup registryLookup) imp @Override public boolean canSerializeIn(HolderOwner holderOwner) { - return this.registryLookup.canSerializeIn(holderOwner); + return this.registryLookup.canSerialize(holderOwner); } @Override diff --git a/src/main/java/net/minecraftforge/registries/holdersets/NotHolderSet.java b/src/main/java/net/minecraftforge/registries/holdersets/NotHolderSet.java index a14caad66a..be703bd86b 100644 --- a/src/main/java/net/minecraftforge/registries/holdersets/NotHolderSet.java +++ b/src/main/java/net/minecraftforge/registries/holdersets/NotHolderSet.java @@ -23,7 +23,7 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; import net.minecraft.core.Registry; -import net.minecraft.resources.HolderSetCodec; +import net.minecraft.core.registries.codec.HolderSetCodec; import net.minecraft.resources.RegistryOps; import net.minecraft.resources.ResourceKey; import net.minecraft.tags.TagKey; @@ -121,7 +121,7 @@ public class NotHolderSet implements ICustomHolderSet { @Override public boolean canSerializeIn(HolderOwner holderOwner) { - return this.registryLookup.canSerializeIn(holderOwner); + return this.registryLookup.canSerialize(holderOwner); } @Override diff --git a/src/main/java/net/minecraftforge/registries/holdersets/OrHolderSet.java b/src/main/java/net/minecraftforge/registries/holdersets/OrHolderSet.java index 3ffd6762ac..65ab4466f4 100644 --- a/src/main/java/net/minecraftforge/registries/holdersets/OrHolderSet.java +++ b/src/main/java/net/minecraftforge/registries/holdersets/OrHolderSet.java @@ -15,7 +15,7 @@ import com.mojang.serialization.MapCodec; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; import net.minecraft.core.Registry; -import net.minecraft.resources.HolderSetCodec; +import net.minecraft.core.registries.codec.HolderSetCodec; import net.minecraft.resources.ResourceKey; import net.minecraftforge.common.ForgeMod; diff --git a/src/main/java/net/minecraftforge/resource/DelegatingPackResources.java b/src/main/java/net/minecraftforge/resource/DelegatingPackResources.java index 5f92b1bbe6..3fa6d62658 100644 --- a/src/main/java/net/minecraftforge/resource/DelegatingPackResources.java +++ b/src/main/java/net/minecraftforge/resource/DelegatingPackResources.java @@ -16,9 +16,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Stream; + import net.minecraft.resources.Identifier; -import net.minecraft.server.packs.AbstractPackResources; +import net.minecraft.server.packs.AbstractPackMetadataResources; import net.minecraft.server.packs.PackLocationInfo; +import net.minecraft.server.packs.PackMetadataResources; import net.minecraft.server.packs.PackResources; import net.minecraft.server.packs.PackType; import net.minecraft.server.packs.metadata.MetadataSectionType; @@ -31,7 +34,7 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; @ApiStatus.Internal -public class DelegatingPackResources extends AbstractPackResources { +public class DelegatingPackResources extends AbstractPackMetadataResources implements PackResources { private final PackMetadataSection packMeta; private final List delegates; private final Map> namespacesAssets; @@ -115,13 +118,13 @@ public class DelegatingPackResources extends AbstractPackResources { private class Supplier implements Pack.ResourcesSupplier { @Override - public PackResources openPrimary(PackLocationInfo p_332103_) { + public PackMetadataResources openMetadata(PackLocationInfo location) { return DelegatingPackResources.this; } @Override - public PackResources openFull(PackLocationInfo p_330351_, Metadata p_333429_) { - return DelegatingPackResources.this; + public Stream openResources(PackLocationInfo location, Metadata metadata) { + return DelegatingPackResources.this.delegates.stream(); } } } diff --git a/src/main/java/net/minecraftforge/resource/ResourcePackLoader.java b/src/main/java/net/minecraftforge/resource/ResourcePackLoader.java index 17a7df9f22..c82170c24f 100644 --- a/src/main/java/net/minecraftforge/resource/ResourcePackLoader.java +++ b/src/main/java/net/minecraftforge/resource/ResourcePackLoader.java @@ -110,7 +110,7 @@ public class ResourcePackLoader { if (!client || mod.showAsResourcePack()) packAcceptor.accept(pack); else - hiddenPacks.add(pack.open()); + pack.open().forEach(hiddenPacks::add); } if (!hiddenPacks.isEmpty()) { diff --git a/src/main/java/net/minecraftforge/server/timings/ForgeTimings.java b/src/main/java/net/minecraftforge/server/timings/ForgeTimings.java index 286a049ed0..00d85fc74e 100644 --- a/src/main/java/net/minecraftforge/server/timings/ForgeTimings.java +++ b/src/main/java/net/minecraftforge/server/timings/ForgeTimings.java @@ -16,9 +16,9 @@ import java.lang.ref.WeakReference; public class ForgeTimings { - private WeakReference object; + private final WeakReference object; - private int[] rawTimingData; + private final int[] rawTimingData; public ForgeTimings(T object, int[] rawTimingData) { diff --git a/src/main/java/net/minecraftforge/server/timings/TimeTracker.java b/src/main/java/net/minecraftforge/server/timings/TimeTracker.java index 2499b92952..ebfad5d987 100644 --- a/src/main/java/net/minecraftforge/server/timings/TimeTracker.java +++ b/src/main/java/net/minecraftforge/server/timings/TimeTracker.java @@ -35,7 +35,7 @@ public class TimeTracker private boolean enabled; private int trackingDuration; - private Map timings = new MapMaker().weakKeys().makeMap(); + private final Map timings = new MapMaker().weakKeys().makeMap(); private WeakReference currentlyTracking; private long trackTime; private long timing; diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index e8e53a3ff5..379dee3bbb 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -5,16 +5,13 @@ public-f net.minecraft.client.Options keyMappings public net.minecraft.client.Options$FieldAccess public net.minecraft.client.color.item.ItemTintSources ID_MAPPER #group protected net.minecraft.client.data.AtlasProvider *() -protected net.minecraft.client.data.AtlasProvider armorTrims()Ljava/util/List; protected net.minecraft.client.data.AtlasProvider bannerPatterns()Ljava/util/List; protected net.minecraft.client.data.AtlasProvider blocksList()Ljava/util/List; -protected net.minecraft.client.data.AtlasProvider extractAllMaterialAssets()Ljava/util/stream/Stream; protected net.minecraft.client.data.AtlasProvider forMapper(Lnet/minecraft/client/renderer/SpriteMapper;)Lnet/minecraft/client/renderer/texture/atlas/SpriteSource; protected net.minecraft.client.data.AtlasProvider forMaterial(Lnet/minecraft/client/resources/model/sprite/SpriteId;)Lnet/minecraft/client/renderer/texture/atlas/SpriteSource; protected net.minecraft.client.data.AtlasProvider guiSprites()Ljava/util/List; protected net.minecraft.client.data.AtlasProvider itemsList()Ljava/util/List; protected net.minecraft.client.data.AtlasProvider noPrefixMapper(Ljava/lang/String;)Ljava/util/List; -protected net.minecraft.client.data.AtlasProvider patternTextures()Ljava/util/List; protected net.minecraft.client.data.AtlasProvider shieldPatterns()Ljava/util/List; protected net.minecraft.client.data.AtlasProvider simpleMapper(Lnet/minecraft/client/renderer/SpriteMapper;)Ljava/util/List; protected net.minecraft.client.data.AtlasProvider storeAtlas(Lnet/minecraft/data/CachedOutput;Lnet/minecraft/resources/Identifier;Ljava/util/List;)Ljava/util/concurrent/CompletableFuture; @@ -100,7 +97,6 @@ protected net.minecraft.client.data.models.BlockModelGenerators createCrossBlock protected net.minecraft.client.data.models.BlockModelGenerators createCrossBlockWithDefaultItem(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/client/data/models/BlockModelGenerators$PlantType;Lnet/minecraft/client/data/models/model/TextureMapping;)V protected net.minecraft.client.data.models.BlockModelGenerators createCustomFence(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;)Lnet/minecraft/client/data/models/blockstates/BlockModelDefinitionGenerator; protected net.minecraft.client.data.models.BlockModelGenerators createDaylightDetector()V -protected net.minecraft.client.data.models.BlockModelGenerators createDirtPath()V protected net.minecraft.client.data.models.BlockModelGenerators createDispenserBlock(Lnet/minecraft/world/level/block/Block;)V protected net.minecraft.client.data.models.BlockModelGenerators createDoor(Lnet/minecraft/world/level/block/Block;)V protected net.minecraft.client.data.models.BlockModelGenerators createDoor(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;)Lnet/minecraft/client/data/models/blockstates/BlockModelDefinitionGenerator; @@ -110,14 +106,14 @@ protected net.minecraft.client.data.models.BlockModelGenerators createDoublePlan protected net.minecraft.client.data.models.BlockModelGenerators createDriedGhastBlock()V protected net.minecraft.client.data.models.BlockModelGenerators createEmptyOrFullDispatch(Lnet/minecraft/world/level/block/state/properties/Property;Ljava/lang/Comparable;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;)Lnet/minecraft/client/data/models/blockstates/PropertyDispatch; protected net.minecraft.client.data.models.BlockModelGenerators createEndPortalFrame()V -protected net.minecraft.client.data.models.BlockModelGenerators createFarmland()V +protected net.minecraft.client.data.models.BlockModelGenerators createFarmland(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/client/resources/model/sprite/Material;Lnet/minecraft/client/resources/model/sprite/Material;Lnet/minecraft/client/data/models/model/ModelTemplate;)V protected net.minecraft.client.data.models.BlockModelGenerators createFence(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;)Lnet/minecraft/client/data/models/blockstates/BlockModelDefinitionGenerator; protected net.minecraft.client.data.models.BlockModelGenerators createFenceGate(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Z)Lnet/minecraft/client/data/models/blockstates/BlockModelDefinitionGenerator; protected net.minecraft.client.data.models.BlockModelGenerators createFire()V protected net.minecraft.client.data.models.BlockModelGenerators createFlatItemModel(Lnet/minecraft/world/item/Item;)Lnet/minecraft/resources/Identifier; +protected net.minecraft.client.data.models.BlockModelGenerators createFlatItemModel(Lnet/minecraft/world/item/Item;Lnet/minecraft/client/resources/model/sprite/Material;)Lnet/minecraft/resources/Identifier; protected net.minecraft.client.data.models.BlockModelGenerators createFlatItemModelWithBlockTexture(Lnet/minecraft/world/item/Item;Lnet/minecraft/world/level/block/Block;)Lnet/minecraft/resources/Identifier; protected net.minecraft.client.data.models.BlockModelGenerators createFlatItemModelWithBlockTexture(Lnet/minecraft/world/item/Item;Lnet/minecraft/world/level/block/Block;Ljava/lang/String;)Lnet/minecraft/resources/Identifier; -protected net.minecraft.client.data.models.BlockModelGenerators createFlatItemModelWithBlockTextureAndOverlay(Lnet/minecraft/world/item/Item;Lnet/minecraft/world/level/block/Block;Ljava/lang/String;)Lnet/minecraft/resources/Identifier; protected net.minecraft.client.data.models.BlockModelGenerators createFloorFireModels(Lnet/minecraft/world/level/block/Block;)Lnet/minecraft/client/data/models/MultiVariant; protected net.minecraft.client.data.models.BlockModelGenerators createFlowerBed(Lnet/minecraft/world/level/block/Block;)V protected net.minecraft.client.data.models.BlockModelGenerators createFrogspawnBlock()V @@ -194,6 +190,8 @@ protected net.minecraft.client.data.models.BlockModelGenerators createRotatedPil protected net.minecraft.client.data.models.BlockModelGenerators createRotatedPillarWithHorizontalVariant(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;)Lnet/minecraft/client/data/models/blockstates/BlockModelDefinitionGenerator; protected net.minecraft.client.data.models.BlockModelGenerators createRotatedPillarWithHorizontalVariant(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/client/data/models/model/TexturedModel$Provider;Lnet/minecraft/client/data/models/model/TexturedModel$Provider;)V protected net.minecraft.client.data.models.BlockModelGenerators createRotatedVariantBlock(Lnet/minecraft/world/level/block/Block;)V +protected net.minecraft.client.data.models.BlockModelGenerators createRotatedVariantBlock(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/client/data/models/model/TexturedModel$Provider;)V +protected net.minecraft.client.data.models.BlockModelGenerators createRotatedVariantBlock(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/resources/Identifier;)V protected net.minecraft.client.data.models.BlockModelGenerators createRotatedVariants(Lnet/minecraft/client/renderer/block/dispatch/Variant;)Lnet/minecraft/client/data/models/MultiVariant; protected net.minecraft.client.data.models.BlockModelGenerators createRotatedVariants(Lnet/minecraft/client/renderer/block/dispatch/Variant;Lnet/minecraft/client/renderer/block/dispatch/Variant;)Lnet/minecraft/client/data/models/MultiVariant; protected net.minecraft.client.data.models.BlockModelGenerators createScaffolding()V @@ -203,6 +201,7 @@ protected net.minecraft.client.data.models.BlockModelGenerators createSculkShrie protected net.minecraft.client.data.models.BlockModelGenerators createSeaPickle()V protected net.minecraft.client.data.models.BlockModelGenerators createSegmentedBlock(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/client/data/models/MultiVariant;Ljava/util/function/Function;Lnet/minecraft/client/data/models/MultiVariant;Ljava/util/function/Function;Lnet/minecraft/client/data/models/MultiVariant;Ljava/util/function/Function;Lnet/minecraft/client/data/models/MultiVariant;Ljava/util/function/Function;)V protected net.minecraft.client.data.models.BlockModelGenerators createShelf(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/Block;)V +protected net.minecraft.client.data.models.BlockModelGenerators createShelfMushroom()V protected net.minecraft.client.data.models.BlockModelGenerators createShulkerBox(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/item/DyeColor;)V protected net.minecraft.client.data.models.BlockModelGenerators createSideFireModels(Lnet/minecraft/world/level/block/Block;)Lnet/minecraft/client/data/models/MultiVariant; protected net.minecraft.client.data.models.BlockModelGenerators createSign(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;)Lnet/minecraft/client/data/models/blockstates/BlockModelDefinitionGenerator; @@ -219,6 +218,8 @@ protected net.minecraft.client.data.models.BlockModelGenerators createSpeleothem protected net.minecraft.client.data.models.BlockModelGenerators createStairs(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;)Lnet/minecraft/client/data/models/blockstates/BlockModelDefinitionGenerator; protected net.minecraft.client.data.models.BlockModelGenerators createStems(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/Block;)V protected net.minecraft.client.data.models.BlockModelGenerators createStonecutter()V +protected net.minecraft.client.data.models.BlockModelGenerators createStrawBed()V +protected net.minecraft.client.data.models.BlockModelGenerators createStrawBed(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;)Lnet/minecraft/client/data/models/blockstates/BlockModelDefinitionGenerator; protected net.minecraft.client.data.models.BlockModelGenerators createStructureBlock()V protected net.minecraft.client.data.models.BlockModelGenerators createSuffixedVariant(Lnet/minecraft/world/level/block/Block;Ljava/lang/String;Lnet/minecraft/client/data/models/model/ModelTemplate;Ljava/util/function/Function;)Lnet/minecraft/resources/Identifier; protected net.minecraft.client.data.models.BlockModelGenerators createSunflower()V @@ -237,6 +238,7 @@ protected net.minecraft.client.data.models.BlockModelGenerators createTrivialCub protected net.minecraft.client.data.models.BlockModelGenerators createTurtleEgg()V protected net.minecraft.client.data.models.BlockModelGenerators createTurtleEggModel(II)Lnet/minecraft/client/renderer/block/dispatch/Variant; protected net.minecraft.client.data.models.BlockModelGenerators createTurtleEggModel(ILjava/lang/String;Lnet/minecraft/client/data/models/model/TextureMapping;)Lnet/minecraft/client/renderer/block/dispatch/Variant; +protected net.minecraft.client.data.models.BlockModelGenerators createTwoLayeredItemModel(Lnet/minecraft/world/item/Item;Lnet/minecraft/client/resources/model/sprite/Material;Lnet/minecraft/client/resources/model/sprite/Material;)Lnet/minecraft/resources/Identifier; protected net.minecraft.client.data.models.BlockModelGenerators createVault()V protected net.minecraft.client.data.models.BlockModelGenerators createVine()V protected net.minecraft.client.data.models.BlockModelGenerators createWall(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;Lnet/minecraft/client/data/models/MultiVariant;)Lnet/minecraft/client/data/models/blockstates/BlockModelDefinitionGenerator; @@ -253,7 +255,6 @@ protected net.minecraft.client.data.models.BlockModelGenerators registerSimpleFl protected net.minecraft.client.data.models.BlockModelGenerators registerSimpleItemModel(Lnet/minecraft/world/item/Item;Lnet/minecraft/resources/Identifier;)V protected net.minecraft.client.data.models.BlockModelGenerators registerSimpleItemModel(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/resources/Identifier;)V protected net.minecraft.client.data.models.BlockModelGenerators registerSimpleTintedItemModel(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/resources/Identifier;Lnet/minecraft/client/color/item/ItemTintSource;)V -protected net.minecraft.client.data.models.BlockModelGenerators registerTwoLayerFlatItemModel(Lnet/minecraft/world/level/block/Block;Ljava/lang/String;)V protected net.minecraft.client.data.models.BlockModelGenerators selectMultifaceProperties(Lnet/minecraft/world/level/block/state/StateHolder;Ljava/util/function/Function;)Ljava/util/Map; protected net.minecraft.client.data.models.BlockModelGenerators shelfCondition(Lnet/minecraft/core/Direction;Ljava/lang/Boolean;Lnet/minecraft/world/level/block/state/properties/SideChainPart;)Lnet/minecraft/client/renderer/block/dispatch/multipart/Condition; protected net.minecraft.client.data.models.BlockModelGenerators variant(Lnet/minecraft/client/renderer/block/dispatch/Variant;)Lnet/minecraft/client/data/models/MultiVariant; @@ -293,6 +294,7 @@ protected net.minecraft.client.data.models.ItemModelGenerators generateDyedItem( protected net.minecraft.client.data.models.ItemModelGenerators generateElytra(Lnet/minecraft/world/item/Item;)V protected net.minecraft.client.data.models.ItemModelGenerators generateFishingRod(Lnet/minecraft/world/item/Item;)V protected net.minecraft.client.data.models.ItemModelGenerators generateFlatItem(Lnet/minecraft/world/item/Item;Lnet/minecraft/client/data/models/model/ModelTemplate;)V +protected net.minecraft.client.data.models.ItemModelGenerators generateFlatItem(Lnet/minecraft/world/item/Item;Lnet/minecraft/resources/Identifier;Lnet/minecraft/client/data/models/model/ModelTemplate;)V protected net.minecraft.client.data.models.ItemModelGenerators generateFlatItem(Lnet/minecraft/world/item/Item;Lnet/minecraft/world/item/Item;Lnet/minecraft/client/data/models/model/ModelTemplate;)V protected net.minecraft.client.data.models.ItemModelGenerators generateGoatHorn(Lnet/minecraft/world/item/Item;)V protected net.minecraft.client.data.models.ItemModelGenerators generateItemWithTintedBaseLayer(Lnet/minecraft/world/item/Item;I)V @@ -309,8 +311,10 @@ protected net.minecraft.client.data.models.ItemModelGenerators generateSpyglass( protected net.minecraft.client.data.models.ItemModelGenerators generateStandardCompassItem(Lnet/minecraft/world/item/Item;)V protected net.minecraft.client.data.models.ItemModelGenerators generateTippedArrow(Lnet/minecraft/world/item/Item;)V protected net.minecraft.client.data.models.ItemModelGenerators generateTrident(Lnet/minecraft/world/item/Item;)V -protected net.minecraft.client.data.models.ItemModelGenerators generateTrimmableItem(Lnet/minecraft/world/item/Item;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/resources/Identifier;Z)V +protected net.minecraft.client.data.models.ItemModelGenerators generateTrimmableArmorSet(Lnet/minecraft/world/item/Item;Lnet/minecraft/world/item/Item;Lnet/minecraft/world/item/Item;Lnet/minecraft/world/item/Item;ZLjava/util/Map;)V +protected net.minecraft.client.data.models.ItemModelGenerators generateTrimmableItem(Lnet/minecraft/world/item/Item;Lnet/minecraft/resources/Identifier;ZLjava/util/Map;)V protected net.minecraft.client.data.models.ItemModelGenerators generateTwoLayerDyedItem(Lnet/minecraft/world/item/Item;)V +protected net.minecraft.client.data.models.ItemModelGenerators prefixForSlotTrim(Ljava/lang/String;)Lnet/minecraft/resources/Identifier; #endgroup protected net.minecraft.client.data.models.ItemModelGenerators itemModelOutput protected net.minecraft.client.data.models.ItemModelGenerators modelOutput @@ -397,24 +401,43 @@ public net.minecraft.client.renderer.RenderPipelines ALPHA_CUTOUT_THRESHOLD_DEFA public net.minecraft.client.renderer.RenderPipelines BEACON_BEAM_SNIPPET public net.minecraft.client.renderer.RenderPipelines BLOCK_SNIPPET public net.minecraft.client.renderer.RenderPipelines CLOUDS_SNIPPET +public net.minecraft.client.renderer.RenderPipelines CRUMBLING_SNIPPET public net.minecraft.client.renderer.RenderPipelines DEBUG_FILLED_SNIPPET +public net.minecraft.client.renderer.RenderPipelines DEBUG_POINTS_SNIPPET +public net.minecraft.client.renderer.RenderPipelines DRAGON_RAYS_SNIPPET public net.minecraft.client.renderer.RenderPipelines END_PORTAL_SNIPPET +public net.minecraft.client.renderer.RenderPipelines ENERGY_SWIRL_SNIPPET public net.minecraft.client.renderer.RenderPipelines ENTITY_EMISSIVE_SNIPPET +public net.minecraft.client.renderer.RenderPipelines ENTITY_NO_LIGHTMAP_SNIPPET +public net.minecraft.client.renderer.RenderPipelines ENTITY_SHADOW_SNIPPET public net.minecraft.client.renderer.RenderPipelines ENTITY_SNIPPET +public net.minecraft.client.renderer.RenderPipelines EYES_SNIPPET public net.minecraft.client.renderer.RenderPipelines GENERIC_BLOCKS_SNIPPET public net.minecraft.client.renderer.RenderPipelines GLOBALS_SNIPPET public net.minecraft.client.renderer.RenderPipelines GUI_SNIPPET public net.minecraft.client.renderer.RenderPipelines GUI_TEXTURED_SNIPPET public net.minecraft.client.renderer.RenderPipelines GUI_TEXT_SNIPPET public net.minecraft.client.renderer.RenderPipelines ITEM_SNIPPET +public net.minecraft.client.renderer.RenderPipelines LIGHTNING_SNIPPET public net.minecraft.client.renderer.RenderPipelines LINES_SNIPPET +public net.minecraft.client.renderer.RenderPipelines LIT_BLOCKS_SNIPPET public net.minecraft.client.renderer.RenderPipelines MATRICES_FOG_LIGHT_DIR_SNIPPET public net.minecraft.client.renderer.RenderPipelines MATRICES_FOG_SNIPPET +public net.minecraft.client.renderer.RenderPipelines MULTIDRAW_TERRAIN_SNIPPET +public net.minecraft.client.renderer.RenderPipelines OIT_CLOUDS_SNIPPET +public net.minecraft.client.renderer.RenderPipelines OIT_DEBUG_FILLED_SNIPPET +public net.minecraft.client.renderer.RenderPipelines OIT_ENTITY_SNIPPET +public net.minecraft.client.renderer.RenderPipelines OIT_ITEM_SNIPPET +public net.minecraft.client.renderer.RenderPipelines OIT_LINES_SNIPPET +public net.minecraft.client.renderer.RenderPipelines OIT_PARTICLE_SNIPPET +public net.minecraft.client.renderer.RenderPipelines OIT_SNIPPET +public net.minecraft.client.renderer.RenderPipelines OPTIONAL_PIPELINES_BY_LOCATION public net.minecraft.client.renderer.RenderPipelines OUTLINE_SNIPPET public net.minecraft.client.renderer.RenderPipelines PARTICLE_SNIPPET public net.minecraft.client.renderer.RenderPipelines PIPELINES_BY_LOCATION public net.minecraft.client.renderer.RenderPipelines TERRAIN_SNIPPET public net.minecraft.client.renderer.RenderPipelines TEXT_SNIPPET +public net.minecraft.client.renderer.RenderPipelines WATER_MASK_SNIPPET public net.minecraft.client.renderer.RenderPipelines WEATHER_SNIPPET public net.minecraft.client.renderer.RenderPipelines WORLD_TEXT_SNIPPET #endgroup @@ -458,7 +481,6 @@ protected net.minecraft.core.MappedRegistry getOrCreateHolderOrThrow(Lnet/minecr protected net.minecraft.core.MappedRegistry getOrCreateTagForRegistration(Lnet/minecraft/tags/TagKey;)Lnet/minecraft/core/HolderSet$Named; protected net.minecraft.core.MappedRegistry unregisteredIntrusiveHolders protected net.minecraft.core.MappedRegistry$TagSet -public net.minecraft.core.RegistrySetBuilder$LazyHolder bindValue(Ljava/lang/Object;)V public net.minecraft.core.particles.SimpleParticleType (Z)V protected net.minecraft.data.loot.BlockLootSubProvider createPotFlowerItemTable(Lnet/minecraft/world/level/ItemLike;)Lnet/minecraft/world/level/storage/loot/LootTable$Builder; protected net.minecraft.data.loot.BlockLootSubProvider createSilkTouchOnlyTable(Lnet/minecraft/world/level/ItemLike;)Lnet/minecraft/world/level/storage/loot/LootTable$Builder; @@ -488,7 +510,6 @@ protected net.minecraft.data.recipes.RecipeProvider smeltingResultFromBase(Lnet/ protected net.minecraft.data.recipes.RecipeProvider tilesBuilder(Lnet/minecraft/data/recipes/RecipeCategory;Lnet/minecraft/world/level/ItemLike;Lnet/minecraft/world/item/crafting/Ingredient;)Lnet/minecraft/data/recipes/RecipeBuilder; protected net.minecraft.data.recipes.RecipeProvider wallBuilder(Lnet/minecraft/data/recipes/RecipeCategory;Lnet/minecraft/world/level/ItemLike;Lnet/minecraft/world/item/crafting/Ingredient;)Lnet/minecraft/data/recipes/RecipeBuilder; #endgroup -protected net.minecraft.data.recipes.packs.VanillaRecipeProvider (Lnet/minecraft/core/HolderLookup$Provider;Lnet/minecraft/data/recipes/RecipeOutput;)V public net.minecraft.data.recipes.packs.VanillaRecipeProvider COAL_SMELTABLES public net.minecraft.data.recipes.packs.VanillaRecipeProvider COPPER_SMELTABLES public net.minecraft.data.recipes.packs.VanillaRecipeProvider DIAMOND_SMELTABLES @@ -534,7 +555,6 @@ protected net.minecraft.world.entity.monster.skeleton.Parched getStepSound()Lnet protected net.minecraft.world.entity.monster.skeleton.Skeleton getStepSound()Lnet/minecraft/sounds/SoundEvent; protected net.minecraft.world.entity.monster.skeleton.Stray getStepSound()Lnet/minecraft/sounds/SoundEvent; protected net.minecraft.world.entity.monster.skeleton.WitherSkeleton getStepSound()Lnet/minecraft/sounds/SoundEvent; -protected net.minecraft.world.entity.monster.zombie.Zombie conversionTime public net.minecraft.world.entity.player.Player closeContainer()V protected net.minecraft.world.entity.projectile.Projectile (Lnet/minecraft/world/entity/EntityType;Lnet/minecraft/world/level/Level;)V public net.minecraft.world.entity.raid.Raid$RaiderType @@ -564,8 +584,6 @@ public net.minecraft.world.item.CreativeModeTabs TOOLS_AND_UTILITIES #endgroup private-f net.minecraft.world.item.ItemDisplayContext id public net.minecraft.world.item.ItemStackLinkedSet TYPE_AND_TAG -public net.minecraft.world.item.alchemy.PotionBrewing$Mix -public net.minecraft.world.item.alchemy.PotionBrewing$Mix ingredient public net.minecraft.world.item.context.BlockPlaceContext (Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/phys/BlockHitResult;)V public net.minecraft.world.item.context.UseOnContext (Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/phys/BlockHitResult;)V public-f net.minecraft.world.item.crafting.Ingredient @@ -585,9 +603,7 @@ protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder grassColor protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder grassColorOverride protected net.minecraft.world.level.biome.BiomeSpecialEffects$Builder waterColor #endgroup -protected net.minecraft.world.level.biome.MobSpawnSettings$Builder creatureGenerationProbability protected net.minecraft.world.level.biome.MobSpawnSettings$Builder mobSpawnCosts -protected net.minecraft.world.level.biome.MobSpawnSettings$Builder spawners #group public net.minecraft.world.level.block.Block public net.minecraft.world.level.block.AttachedStemBlock (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/tags/TagKey;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.AzaleaBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V @@ -599,6 +615,7 @@ public net.minecraft.world.level.block.BigDripleafBlock (Lnet/minecraft/wo public net.minecraft.world.level.block.BigDripleafStemBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.BlastFurnaceBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.BushBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.BushBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;I)V public net.minecraft.world.level.block.ButtonBlock (Lnet/minecraft/world/level/block/state/properties/BlockSetType;ILnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.CactusBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.CakeBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V @@ -615,7 +632,6 @@ public net.minecraft.world.level.block.CraftingTableBlock (Lnet/minecraft/ public net.minecraft.world.level.block.CreakingHeartBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.CropBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.DecoratedPotBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V -public net.minecraft.world.level.block.DirtPathBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.DispenserBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.DoorBlock (Lnet/minecraft/world/level/block/state/properties/BlockSetType;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.DryVegetationBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V @@ -624,8 +640,8 @@ public net.minecraft.world.level.block.EndGatewayBlock (Lnet/minecraft/wor public net.minecraft.world.level.block.EndPortalBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.EndRodBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.EnderChestBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V -public net.minecraft.world.level.block.FarmlandBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V -public net.minecraft.world.level.block.FlowerBedBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.FarmlandBlock (Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.FlowerBedBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;I)V public net.minecraft.world.level.block.FurnaceBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.GrindstoneBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.HalfTransparentBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V @@ -646,6 +662,7 @@ public net.minecraft.world.level.block.NetherFungusBlock (Lnet/minecraft/r public net.minecraft.world.level.block.NetherRootsBlock (Lnet/minecraft/tags/TagKey;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.NetherWartBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.NyliumBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V +public net.minecraft.world.level.block.PathBlock (Lnet/minecraft/world/level/block/Block;Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.PlayerHeadBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.PlayerWallHeadBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V public net.minecraft.world.level.block.PoweredRailBlock (Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;)V @@ -723,7 +740,6 @@ protected net.minecraft.world.level.levelgen.Aquifer$NoiseBasedAquifer minGridY protected net.minecraft.world.level.levelgen.Aquifer$NoiseBasedAquifer minGridZ protected net.minecraft.world.level.levelgen.Aquifer$NoiseBasedAquifer shouldScheduleFluidUpdate protected net.minecraft.world.level.levelgen.Aquifer$NoiseBasedAquifer similarity(II)D -protected net.minecraft.world.level.levelgen.Beardifier getBeardContribution(IIII)D private-f net.minecraft.world.level.levelgen.DebugLevelSource ALL_BLOCKS private-f net.minecraft.world.level.levelgen.DebugLevelSource GRID_HEIGHT private-f net.minecraft.world.level.levelgen.DebugLevelSource GRID_WIDTH @@ -739,17 +755,10 @@ public net.minecraft.world.level.levelgen.NoiseGeneratorSettings overworld(Lnet/ public net.minecraft.world.level.levelgen.feature.featuresize.FeatureSizeType (Lcom/mojang/serialization/MapCodec;)V public net.minecraft.world.level.levelgen.feature.foliageplacers.FoliagePlacerType (Lcom/mojang/serialization/MapCodec;)V public net.minecraft.world.level.levelgen.feature.rootplacers.RootPlacerType (Lcom/mojang/serialization/MapCodec;)V -public net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProviderType (Lcom/mojang/serialization/MapCodec;)V public net.minecraft.world.level.levelgen.feature.treedecorators.TreeDecoratorType (Lcom/mojang/serialization/MapCodec;)V public net.minecraft.world.level.levelgen.feature.trunkplacers.TrunkPlacerType (Lcom/mojang/serialization/MapCodec;)V protected net.minecraft.world.level.portal.PortalForcer level public net.minecraft.world.level.storage.LevelResource (Ljava/lang/String;)V private-f net.minecraft.world.level.storage.loot.LootPool bonusRolls private-f net.minecraft.world.level.storage.loot.LootPool rolls -public net.minecraft.world.level.storage.loot.functions.LootItemConditionalFunction simpleBuilder(Ljava/util/function/Function;)Lnet/minecraft/world/level/storage/loot/functions/LootItemConditionalFunction$Builder; -public net.minecraft.world.level.storage.loot.functions.ModifyContainerContents (Ljava/util/List;Lnet/minecraft/world/level/storage/loot/ContainerComponentManipulator;Lnet/minecraft/world/level/storage/loot/functions/LootItemFunction;)V -public net.minecraft.world.level.storage.loot.functions.SetFireworksFunction (Ljava/util/List;Ljava/util/Optional;Ljava/util/Optional;)V -public net.minecraft.world.level.storage.loot.functions.SetItemFunction (Ljava/util/List;Lnet/minecraft/core/Holder;)V -public net.minecraft.world.level.storage.loot.functions.SetWritableBookPagesFunction (Ljava/util/List;Ljava/util/List;Lnet/minecraft/world/level/storage/loot/functions/ListOperation;)V -public net.minecraft.world.level.storage.loot.functions.SetWrittenBookPagesFunction (Ljava/util/List;Ljava/util/List;Lnet/minecraft/world/level/storage/loot/functions/ListOperation;)V -public net.minecraft.world.level.storage.loot.functions.ToggleTooltips (Ljava/util/List;Ljava/util/Map;)V \ No newline at end of file +public net.minecraft.world.level.storage.loot.functions.LootItemConditionalFunction simpleBuilder(Ljava/util/function/Function;)Lnet/minecraft/world/level/storage/loot/functions/LootItemConditionalFunction$Builder; \ No newline at end of file diff --git a/src/test/generated/biome_test/data/biome_test/worldgen/configured_feature/configured.json b/src/test/generated/biome_test/data/biome_test/worldgen/configured_feature/configured.json deleted file mode 100644 index b3f605f04e..0000000000 --- a/src/test/generated/biome_test/data/biome_test/worldgen/configured_feature/configured.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "minecraft:no_op", - "config": {} -} \ No newline at end of file diff --git a/src/test/generated/biome_test/data/biome_test/worldgen/feature/configured.json b/src/test/generated/biome_test/data/biome_test/worldgen/feature/configured.json new file mode 100644 index 0000000000..a80af9fbe3 --- /dev/null +++ b/src/test/generated/biome_test/data/biome_test/worldgen/feature/configured.json @@ -0,0 +1,3 @@ +{ + "type": "minecraft:no_op" +} \ No newline at end of file diff --git a/src/test/generated/client_command_test/data/forge/test_instance/client_command_test/client_command_test.json b/src/test/generated/client_command_test/data/forge/test_instance/client_command_test/client_command_test.json deleted file mode 100644 index 31fe155def..0000000000 --- a/src/test/generated/client_command_test/data/forge/test_instance/client_command_test/client_command_test.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "minecraft:function", - "environment": "minecraft:default", - "function": "forge:client_command_test/client_command_test", - "max_ticks": 100, - "structure": "forge:empty3x3x3" -} \ No newline at end of file diff --git a/src/test/generated/conditional_loot_test/data/conditional_loot_test/loot_table/blocks/test.json b/src/test/generated/conditional_loot_test/data/conditional_loot_test/loot_table/blocks/test.json index e31ac7bd9e..1914c206df 100644 --- a/src/test/generated/conditional_loot_test/data/conditional_loot_test/loot_table/blocks/test.json +++ b/src/test/generated/conditional_loot_test/data/conditional_loot_test/loot_table/blocks/test.json @@ -11,7 +11,7 @@ "forge:condition": { "type": "forge:false" }, - "rolls": 1.0 + "rolls": 1 }, { "entries": [ @@ -23,7 +23,7 @@ "forge:condition": { "type": "forge:true" }, - "rolls": 1.0 + "rolls": 1 } ], "random_sequence": "conditional_loot_test:blocks/test" diff --git a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/conditional_doesnt_load_empty.json b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/conditional_doesnt_load_empty.json index 1af31920e2..e0f4561042 100644 --- a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/conditional_doesnt_load_empty.json +++ b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/conditional_doesnt_load_empty.json @@ -1,39 +1,35 @@ { - "forge:conditional": [ - { - "parent": "minecraft:recipes/root", - "criteria": { - "has_dirt": { - "conditions": { - "items": [ - { - "items": "minecraft:dirt" - } - ] - }, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": { - "recipe": "minecraft:diamond_block" - }, - "trigger": "minecraft:recipe_unlocked" - } - }, - "forge:condition": { - "type": "forge:false" - }, - "requirements": [ - [ - "has_the_recipe", - "has_dirt" + "parent": "minecraft:recipes/root", + "criteria": { + "has_dirt": { + "conditions": { + "items": [ + { + "items": "minecraft:dirt" + } ] - ], - "rewards": { - "recipes": [ - "minecraft:diamond_block" - ] - } + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipes": "minecraft:diamond_block" + }, + "trigger": "minecraft:recipe_unlocked" } - ] + }, + "forge:condition": { + "type": "forge:false" + }, + "requirements": [ + [ + "has_the_recipe", + "has_dirt" + ] + ], + "rewards": { + "recipes": [ + "minecraft:diamond_block" + ] + } } \ No newline at end of file diff --git a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/conditional_recipe_choice.json b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/conditional_recipe_choice.json index 1c856d2f82..783791959d 100644 --- a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/conditional_recipe_choice.json +++ b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/conditional_recipe_choice.json @@ -1,74 +1,76 @@ { - "forge:conditional": [ - { - "parent": "minecraft:recipes/root", - "criteria": { - "has_dirt": { - "conditions": { - "items": [ - { - "items": "minecraft:dirt" - } - ] - }, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": { - "recipe": "minecraft:diamond_block" - }, - "trigger": "minecraft:recipe_unlocked" - } + "parent": "minecraft:recipes/root", + "criteria": { + "has_dirt": { + "conditions": { + "items": [ + { + "items": "minecraft:dirt" + } + ] }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipes": "minecraft:diamond_block" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "forge:children": [ + { "forge:condition": { "type": "forge:false" - }, - "requirements": [ - [ - "has_the_recipe", - "has_dirt" - ] - ], - "rewards": { - "recipes": [ - "minecraft:diamond_block" - ] } }, { - "parent": "minecraft:recipes/root", - "criteria": { - "has_oak_log": { - "conditions": { - "items": [ - { - "items": "minecraft:oak_log" - } - ] + "child": { + "parent": "minecraft:recipes/root", + "criteria": { + "has_oak_log": { + "conditions": { + "items": [ + { + "items": "minecraft:oak_log" + } + ] + }, + "trigger": "minecraft:inventory_changed" }, - "trigger": "minecraft:inventory_changed" + "has_the_recipe": { + "conditions": { + "recipes": "minecraft:diamond_block" + }, + "trigger": "minecraft:recipe_unlocked" + } }, - "has_the_recipe": { - "conditions": { - "recipe": "minecraft:diamond_block" - }, - "trigger": "minecraft:recipe_unlocked" + "requirements": [ + [ + "has_the_recipe", + "has_oak_log" + ] + ], + "rewards": { + "recipes": [ + "minecraft:diamond_block" + ] } }, "forge:condition": { "type": "forge:true" - }, - "requirements": [ - [ - "has_the_recipe", - "has_oak_log" - ] - ], - "rewards": { - "recipes": [ - "minecraft:diamond_block" - ] } } - ] + ], + "requirements": [ + [ + "has_the_recipe", + "has_dirt" + ] + ], + "rewards": { + "recipes": [ + "minecraft:diamond_block" + ] + } } \ No newline at end of file diff --git a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/cooking_false_conditions.json b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/cooking_false_conditions.json index 1af31920e2..e0f4561042 100644 --- a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/cooking_false_conditions.json +++ b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/cooking_false_conditions.json @@ -1,39 +1,35 @@ { - "forge:conditional": [ - { - "parent": "minecraft:recipes/root", - "criteria": { - "has_dirt": { - "conditions": { - "items": [ - { - "items": "minecraft:dirt" - } - ] - }, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": { - "recipe": "minecraft:diamond_block" - }, - "trigger": "minecraft:recipe_unlocked" - } - }, - "forge:condition": { - "type": "forge:false" - }, - "requirements": [ - [ - "has_the_recipe", - "has_dirt" + "parent": "minecraft:recipes/root", + "criteria": { + "has_dirt": { + "conditions": { + "items": [ + { + "items": "minecraft:dirt" + } ] - ], - "rewards": { - "recipes": [ - "minecraft:diamond_block" - ] - } + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipes": "minecraft:diamond_block" + }, + "trigger": "minecraft:recipe_unlocked" } - ] + }, + "forge:condition": { + "type": "forge:false" + }, + "requirements": [ + [ + "has_the_recipe", + "has_dirt" + ] + ], + "rewards": { + "recipes": [ + "minecraft:diamond_block" + ] + } } \ No newline at end of file diff --git a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/cooking_true_conditions.json b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/cooking_true_conditions.json index 96d405ee5e..ff08955e27 100644 --- a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/cooking_true_conditions.json +++ b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/cooking_true_conditions.json @@ -1,39 +1,35 @@ { - "forge:conditional": [ - { - "parent": "minecraft:recipes/root", - "criteria": { - "has_bee_nest": { - "conditions": { - "items": [ - { - "items": "minecraft:bee_nest" - } - ] - }, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": { - "recipe": "minecraft:diamond_block" - }, - "trigger": "minecraft:recipe_unlocked" - } - }, - "forge:condition": { - "type": "forge:true" - }, - "requirements": [ - [ - "has_the_recipe", - "has_bee_nest" + "parent": "minecraft:recipes/root", + "criteria": { + "has_bee_nest": { + "conditions": { + "items": [ + { + "items": "minecraft:bee_nest" + } ] - ], - "rewards": { - "recipes": [ - "minecraft:diamond_block" - ] - } + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipes": "minecraft:diamond_block" + }, + "trigger": "minecraft:recipe_unlocked" } - ] + }, + "forge:condition": { + "type": "forge:true" + }, + "requirements": [ + [ + "has_the_recipe", + "has_bee_nest" + ] + ], + "rewards": { + "recipes": [ + "minecraft:diamond_block" + ] + } } \ No newline at end of file diff --git a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shaped_false_conditions.json b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shaped_false_conditions.json index 1af31920e2..e0f4561042 100644 --- a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shaped_false_conditions.json +++ b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shaped_false_conditions.json @@ -1,39 +1,35 @@ { - "forge:conditional": [ - { - "parent": "minecraft:recipes/root", - "criteria": { - "has_dirt": { - "conditions": { - "items": [ - { - "items": "minecraft:dirt" - } - ] - }, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": { - "recipe": "minecraft:diamond_block" - }, - "trigger": "minecraft:recipe_unlocked" - } - }, - "forge:condition": { - "type": "forge:false" - }, - "requirements": [ - [ - "has_the_recipe", - "has_dirt" + "parent": "minecraft:recipes/root", + "criteria": { + "has_dirt": { + "conditions": { + "items": [ + { + "items": "minecraft:dirt" + } ] - ], - "rewards": { - "recipes": [ - "minecraft:diamond_block" - ] - } + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipes": "minecraft:diamond_block" + }, + "trigger": "minecraft:recipe_unlocked" } - ] + }, + "forge:condition": { + "type": "forge:false" + }, + "requirements": [ + [ + "has_the_recipe", + "has_dirt" + ] + ], + "rewards": { + "recipes": [ + "minecraft:diamond_block" + ] + } } \ No newline at end of file diff --git a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shaped_true_conditions.json b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shaped_true_conditions.json index 83bf177ead..c31446dd18 100644 --- a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shaped_true_conditions.json +++ b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shaped_true_conditions.json @@ -1,39 +1,35 @@ { - "forge:conditional": [ - { - "parent": "minecraft:recipes/root", - "criteria": { - "has_oak_log": { - "conditions": { - "items": [ - { - "items": "minecraft:oak_log" - } - ] - }, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": { - "recipe": "minecraft:diamond_block" - }, - "trigger": "minecraft:recipe_unlocked" - } - }, - "forge:condition": { - "type": "forge:true" - }, - "requirements": [ - [ - "has_the_recipe", - "has_oak_log" + "parent": "minecraft:recipes/root", + "criteria": { + "has_oak_log": { + "conditions": { + "items": [ + { + "items": "minecraft:oak_log" + } ] - ], - "rewards": { - "recipes": [ - "minecraft:diamond_block" - ] - } + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipes": "minecraft:diamond_block" + }, + "trigger": "minecraft:recipe_unlocked" } - ] + }, + "forge:condition": { + "type": "forge:true" + }, + "requirements": [ + [ + "has_the_recipe", + "has_oak_log" + ] + ], + "rewards": { + "recipes": [ + "minecraft:diamond_block" + ] + } } \ No newline at end of file diff --git a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shapeless_false_conditions.json b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shapeless_false_conditions.json index 171ff54bd3..d3244553cc 100644 --- a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shapeless_false_conditions.json +++ b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shapeless_false_conditions.json @@ -1,39 +1,35 @@ { - "forge:conditional": [ - { - "parent": "minecraft:recipes/root", - "criteria": { - "has_redstone_ore": { - "conditions": { - "items": [ - { - "items": "minecraft:redstone_ore" - } - ] - }, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": { - "recipe": "minecraft:diamond_block" - }, - "trigger": "minecraft:recipe_unlocked" - } - }, - "forge:condition": { - "type": "forge:false" - }, - "requirements": [ - [ - "has_the_recipe", - "has_redstone_ore" + "parent": "minecraft:recipes/root", + "criteria": { + "has_redstone_ore": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone_ore" + } ] - ], - "rewards": { - "recipes": [ - "minecraft:diamond_block" - ] - } + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipes": "minecraft:diamond_block" + }, + "trigger": "minecraft:recipe_unlocked" } - ] + }, + "forge:condition": { + "type": "forge:false" + }, + "requirements": [ + [ + "has_the_recipe", + "has_redstone_ore" + ] + ], + "rewards": { + "recipes": [ + "minecraft:diamond_block" + ] + } } \ No newline at end of file diff --git a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shapeless_true_conditions.json b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shapeless_true_conditions.json index fc2260cf26..68c3a25c84 100644 --- a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shapeless_true_conditions.json +++ b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/shapeless_true_conditions.json @@ -1,39 +1,35 @@ { - "forge:conditional": [ - { - "parent": "minecraft:recipes/root", - "criteria": { - "has_redstone_ore": { - "conditions": { - "items": [ - { - "items": "minecraft:redstone_ore" - } - ] - }, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": { - "recipe": "minecraft:diamond_block" - }, - "trigger": "minecraft:recipe_unlocked" - } - }, - "forge:condition": { - "type": "forge:true" - }, - "requirements": [ - [ - "has_the_recipe", - "has_redstone_ore" + "parent": "minecraft:recipes/root", + "criteria": { + "has_redstone_ore": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone_ore" + } ] - ], - "rewards": { - "recipes": [ - "minecraft:diamond_block" - ] - } + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipes": "minecraft:diamond_block" + }, + "trigger": "minecraft:recipe_unlocked" } - ] + }, + "forge:condition": { + "type": "forge:true" + }, + "requirements": [ + [ + "has_the_recipe", + "has_redstone_ore" + ] + ], + "rewards": { + "recipes": [ + "minecraft:diamond_block" + ] + } } \ No newline at end of file diff --git a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/singe_item_true_conditions.json b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/singe_item_true_conditions.json index fc2260cf26..68c3a25c84 100644 --- a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/singe_item_true_conditions.json +++ b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/singe_item_true_conditions.json @@ -1,39 +1,35 @@ { - "forge:conditional": [ - { - "parent": "minecraft:recipes/root", - "criteria": { - "has_redstone_ore": { - "conditions": { - "items": [ - { - "items": "minecraft:redstone_ore" - } - ] - }, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": { - "recipe": "minecraft:diamond_block" - }, - "trigger": "minecraft:recipe_unlocked" - } - }, - "forge:condition": { - "type": "forge:true" - }, - "requirements": [ - [ - "has_the_recipe", - "has_redstone_ore" + "parent": "minecraft:recipes/root", + "criteria": { + "has_redstone_ore": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone_ore" + } ] - ], - "rewards": { - "recipes": [ - "minecraft:diamond_block" - ] - } + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipes": "minecraft:diamond_block" + }, + "trigger": "minecraft:recipe_unlocked" } - ] + }, + "forge:condition": { + "type": "forge:true" + }, + "requirements": [ + [ + "has_the_recipe", + "has_redstone_ore" + ] + ], + "rewards": { + "recipes": [ + "minecraft:diamond_block" + ] + } } \ No newline at end of file diff --git a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/single_item_false_conditions.json b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/single_item_false_conditions.json index 1af31920e2..e0f4561042 100644 --- a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/single_item_false_conditions.json +++ b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/single_item_false_conditions.json @@ -1,39 +1,35 @@ { - "forge:conditional": [ - { - "parent": "minecraft:recipes/root", - "criteria": { - "has_dirt": { - "conditions": { - "items": [ - { - "items": "minecraft:dirt" - } - ] - }, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": { - "recipe": "minecraft:diamond_block" - }, - "trigger": "minecraft:recipe_unlocked" - } - }, - "forge:condition": { - "type": "forge:false" - }, - "requirements": [ - [ - "has_the_recipe", - "has_dirt" + "parent": "minecraft:recipes/root", + "criteria": { + "has_dirt": { + "conditions": { + "items": [ + { + "items": "minecraft:dirt" + } ] - ], - "rewards": { - "recipes": [ - "minecraft:diamond_block" - ] - } + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipes": "minecraft:diamond_block" + }, + "trigger": "minecraft:recipe_unlocked" } - ] + }, + "forge:condition": { + "type": "forge:false" + }, + "requirements": [ + [ + "has_the_recipe", + "has_dirt" + ] + ], + "rewards": { + "recipes": [ + "minecraft:diamond_block" + ] + } } \ No newline at end of file diff --git a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/tag_empty_condition_doesnt_load.json b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/tag_empty_condition_doesnt_load.json index b35b2444a6..b5e108aec8 100644 --- a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/tag_empty_condition_doesnt_load.json +++ b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/tag_empty_condition_doesnt_load.json @@ -1,40 +1,36 @@ { - "forge:conditional": [ - { - "parent": "minecraft:recipes/root", - "criteria": { - "has_iron_ore": { - "conditions": { - "items": [ - { - "items": "minecraft:iron_ore" - } - ] - }, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": { - "recipe": "minecraft:diamond_block" - }, - "trigger": "minecraft:recipe_unlocked" - } - }, - "forge:condition": { - "type": "forge:tag_empty", - "tag": "minecraft:dirt" - }, - "requirements": [ - [ - "has_the_recipe", - "has_iron_ore" + "parent": "minecraft:recipes/root", + "criteria": { + "has_iron_ore": { + "conditions": { + "items": [ + { + "items": "minecraft:iron_ore" + } ] - ], - "rewards": { - "recipes": [ - "minecraft:diamond_block" - ] - } + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipes": "minecraft:diamond_block" + }, + "trigger": "minecraft:recipe_unlocked" } - ] + }, + "forge:condition": { + "type": "forge:tag_empty", + "tag": "minecraft:dirt" + }, + "requirements": [ + [ + "has_the_recipe", + "has_iron_ore" + ] + ], + "rewards": { + "recipes": [ + "minecraft:diamond_block" + ] + } } \ No newline at end of file diff --git a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/tag_empty_condition_loads.json b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/tag_empty_condition_loads.json index ee90712df1..bbabb949a8 100644 --- a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/tag_empty_condition_loads.json +++ b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/tag_empty_condition_loads.json @@ -1,40 +1,36 @@ { - "forge:conditional": [ - { - "parent": "minecraft:recipes/root", - "criteria": { - "has_gold_ore": { - "conditions": { - "items": [ - { - "items": "minecraft:gold_ore" - } - ] - }, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": { - "recipe": "minecraft:diamond_block" - }, - "trigger": "minecraft:recipe_unlocked" - } - }, - "forge:condition": { - "type": "forge:tag_empty", - "tag": "conditional_recipe:empty_tag_for_testing" - }, - "requirements": [ - [ - "has_the_recipe", - "has_gold_ore" + "parent": "minecraft:recipes/root", + "criteria": { + "has_gold_ore": { + "conditions": { + "items": [ + { + "items": "minecraft:gold_ore" + } ] - ], - "rewards": { - "recipes": [ - "minecraft:diamond_block" - ] - } + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipes": "minecraft:diamond_block" + }, + "trigger": "minecraft:recipe_unlocked" } - ] + }, + "forge:condition": { + "type": "forge:tag_empty", + "tag": "conditional_recipe:empty_tag_for_testing" + }, + "requirements": [ + [ + "has_the_recipe", + "has_gold_ore" + ] + ], + "rewards": { + "recipes": [ + "minecraft:diamond_block" + ] + } } \ No newline at end of file diff --git a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/test_encode_all_conditions.json b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/test_encode_all_conditions.json index 7690a734b0..bf80f9fd3e 100644 --- a/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/test_encode_all_conditions.json +++ b/src/test/generated/conditional_recipe/data/conditional_recipe/advancement/recipes/test_encode_all_conditions.json @@ -1,67 +1,63 @@ { - "forge:conditional": [ - { - "parent": "minecraft:recipes/root", - "criteria": { - "has_dirt": { - "conditions": { - "items": [ - { - "items": "minecraft:dirt" - } - ] - }, - "trigger": "minecraft:inventory_changed" - }, - "has_the_recipe": { - "conditions": { - "recipe": "minecraft:diamond_block" - }, - "trigger": "minecraft:recipe_unlocked" - } - }, - "forge:condition": { - "type": "forge:and", - "values": [ + "parent": "minecraft:recipes/root", + "criteria": { + "has_dirt": { + "conditions": { + "items": [ { - "type": "forge:or", - "values": [ - { - "type": "forge:not", - "value": { - "type": "forge:mod_loaded", - "modid": "minecraft" - } - }, - { - "type": "forge:item_exists", - "item": "minecraft:dirt" - }, - { - "type": "forge:true" - }, - { - "type": "forge:tag_empty", - "tag": "minecraft:dirt" - } - ] - }, - { - "type": "forge:false" + "items": "minecraft:dirt" } ] }, - "requirements": [ - [ - "has_the_recipe", - "has_dirt" - ] - ], - "rewards": { - "recipes": [ - "minecraft:diamond_block" - ] - } + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipes": "minecraft:diamond_block" + }, + "trigger": "minecraft:recipe_unlocked" } - ] + }, + "forge:condition": { + "type": "forge:and", + "values": [ + { + "type": "forge:or", + "values": [ + { + "type": "forge:not", + "value": { + "type": "forge:mod_loaded", + "modid": "minecraft" + } + }, + { + "type": "forge:item_exists", + "item": "minecraft:dirt" + }, + { + "type": "forge:true" + }, + { + "type": "forge:tag_empty", + "tag": "minecraft:dirt" + } + ] + }, + { + "type": "forge:false" + } + ] + }, + "requirements": [ + [ + "has_the_recipe", + "has_dirt" + ] + ], + "rewards": { + "recipes": [ + "minecraft:diamond_block" + ] + } } \ No newline at end of file diff --git a/src/test/generated/conditional_recipe/data/conditional_recipe/recipe/cooking_false_conditions.json b/src/test/generated/conditional_recipe/data/conditional_recipe/recipe/cooking_false_conditions.json index 20abbe0ff3..0d6b2c6883 100644 --- a/src/test/generated/conditional_recipe/data/conditional_recipe/recipe/cooking_false_conditions.json +++ b/src/test/generated/conditional_recipe/data/conditional_recipe/recipe/cooking_false_conditions.json @@ -7,6 +7,7 @@ { "recipe": { "type": "minecraft:smelting", + "cookingtime": 200, "experience": 0.1, "ingredient": "minecraft:dirt", "result": { diff --git a/src/test/generated/conditional_recipe/data/conditional_recipe/recipe/cooking_true_conditions.json b/src/test/generated/conditional_recipe/data/conditional_recipe/recipe/cooking_true_conditions.json index 2cba199ad6..25f470c5b2 100644 --- a/src/test/generated/conditional_recipe/data/conditional_recipe/recipe/cooking_true_conditions.json +++ b/src/test/generated/conditional_recipe/data/conditional_recipe/recipe/cooking_true_conditions.json @@ -7,6 +7,7 @@ { "recipe": { "type": "minecraft:smelting", + "cookingtime": 200, "experience": 0.1, "ingredient": "minecraft:bee_nest", "result": { diff --git a/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/compound_ingredient.json b/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/compound_ingredient.json index e790a36545..1d871c440f 100644 --- a/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/compound_ingredient.json +++ b/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/compound_ingredient.json @@ -13,7 +13,7 @@ }, "has_the_recipe": { "conditions": { - "recipe": "custom_ingredients:compound_ingredient" + "recipes": "custom_ingredients:compound_ingredient" }, "trigger": "minecraft:recipe_unlocked" } diff --git a/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/difference_ingredient.json b/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/difference_ingredient.json index 76023b312f..6d83228b86 100644 --- a/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/difference_ingredient.json +++ b/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/difference_ingredient.json @@ -13,7 +13,7 @@ }, "has_the_recipe": { "conditions": { - "recipe": "custom_ingredients:difference_ingredient" + "recipes": "custom_ingredients:difference_ingredient" }, "trigger": "minecraft:recipe_unlocked" } diff --git a/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/intersection_ingredient.json b/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/intersection_ingredient.json index 7007749f42..5d1ec653d2 100644 --- a/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/intersection_ingredient.json +++ b/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/intersection_ingredient.json @@ -13,7 +13,7 @@ }, "has_the_recipe": { "conditions": { - "recipe": "custom_ingredients:intersection_ingredient" + "recipes": "custom_ingredients:intersection_ingredient" }, "trigger": "minecraft:recipe_unlocked" } diff --git a/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/partial_nbt_damage_only.json b/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/partial_nbt_damage_only.json index a386e76d1e..c4bfe05613 100644 --- a/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/partial_nbt_damage_only.json +++ b/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/partial_nbt_damage_only.json @@ -13,7 +13,7 @@ }, "has_the_recipe": { "conditions": { - "recipe": "custom_ingredients:partial_nbt_damage_only" + "recipes": "custom_ingredients:partial_nbt_damage_only" }, "trigger": "minecraft:recipe_unlocked" } diff --git a/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/partial_nbt_name_only.json b/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/partial_nbt_name_only.json index 91a2e6698e..21d8522495 100644 --- a/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/partial_nbt_name_only.json +++ b/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/partial_nbt_name_only.json @@ -13,7 +13,7 @@ }, "has_the_recipe": { "conditions": { - "recipe": "custom_ingredients:partial_nbt_name_only" + "recipes": "custom_ingredients:partial_nbt_name_only" }, "trigger": "minecraft:recipe_unlocked" } diff --git a/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/strict_nbt_ingredient.json b/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/strict_nbt_ingredient.json index b385e37c70..683b05b79b 100644 --- a/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/strict_nbt_ingredient.json +++ b/src/test/generated/custom_ingredients/data/custom_ingredients/advancement/recipes/misc/strict_nbt_ingredient.json @@ -13,7 +13,7 @@ }, "has_the_recipe": { "conditions": { - "recipe": "custom_ingredients:strict_nbt_ingredient" + "recipes": "custom_ingredients:strict_nbt_ingredient" }, "trigger": "minecraft:recipe_unlocked" } diff --git a/src/test/generated/data/datapack_builtin_entries_provider_test/forge/biome_modifier/mossy_stone_modifier.json b/src/test/generated/data/datapack_builtin_entries_provider_test/forge/biome_modifier/mossy_stone_modifier.json new file mode 100644 index 0000000000..e84a3fe877 --- /dev/null +++ b/src/test/generated/data/datapack_builtin_entries_provider_test/forge/biome_modifier/mossy_stone_modifier.json @@ -0,0 +1,6 @@ +{ + "type": "forge:add_features", + "biomes": "#minecraft:is_overworld", + "features": "datapack_builtin_entries_provider_test:mossy_stone", + "step": "underground_ores" +} \ No newline at end of file diff --git a/src/test/generated/data/datapack_builtin_entries_provider_test/worldgen/feature/mossy_stone.json b/src/test/generated/data/datapack_builtin_entries_provider_test/worldgen/feature/mossy_stone.json new file mode 100644 index 0000000000..0007320161 --- /dev/null +++ b/src/test/generated/data/datapack_builtin_entries_provider_test/worldgen/feature/mossy_stone.json @@ -0,0 +1,23 @@ +{ + "type": "minecraft:ore", + "discard_chance_on_air_exposure": 0.0, + "size": 5, + "targets": [ + { + "state": "minecraft:mossy_stone_bricks", + "target": { + "predicate_type": "minecraft:any_of", + "rules": [ + { + "predicate_type": "minecraft:tag_match", + "tag": "minecraft:stone_ore_replaceables" + }, + { + "predicate_type": "minecraft:tag_match", + "tag": "minecraft:deepslate_ore_replaceables" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/src/test/generated/data/datapack_builtin_entries_provider_test/worldgen/placed_feature/mossy_stone.json b/src/test/generated/data/datapack_builtin_entries_provider_test/worldgen/placed_feature/mossy_stone.json new file mode 100644 index 0000000000..cfd8ace2f6 --- /dev/null +++ b/src/test/generated/data/datapack_builtin_entries_provider_test/worldgen/placed_feature/mossy_stone.json @@ -0,0 +1,27 @@ +{ + "feature": "datapack_builtin_entries_provider_test:mossy_stone", + "placement": [ + { + "type": "minecraft:count", + "count": 8 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:height_range", + "height": { + "type": "minecraft:uniform", + "max_inclusive": { + "absolute": 64 + }, + "min_inclusive": { + "absolute": -64 + } + } + }, + { + "type": "minecraft:biome" + } + ] +} \ No newline at end of file diff --git a/src/test/generated/datapack_builtin_entries_provider_test/data/datapack_builtin_entries_provider_test/worldgen/configured_feature/mossy_stone.json b/src/test/generated/datapack_builtin_entries_provider_test/data/datapack_builtin_entries_provider_test/worldgen/configured_feature/mossy_stone.json deleted file mode 100644 index 417d81d442..0000000000 --- a/src/test/generated/datapack_builtin_entries_provider_test/data/datapack_builtin_entries_provider_test/worldgen/configured_feature/mossy_stone.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "type": "minecraft:ore", - "config": { - "discard_chance_on_air_exposure": 0.0, - "size": 5, - "targets": [ - { - "state": { - "Name": "minecraft:mossy_cobblestone" - }, - "target": { - "predicate_type": "minecraft:tag_match", - "tag": "minecraft:stone_ore_replaceables" - } - }, - { - "state": { - "Name": "minecraft:mossy_cobblestone" - }, - "target": { - "predicate_type": "minecraft:tag_match", - "tag": "minecraft:deepslate_ore_replaceables" - } - } - ] - } -} \ No newline at end of file diff --git a/src/test/generated/datapack_builtin_entries_provider_test/data/datapack_builtin_entries_provider_test/worldgen/feature/mossy_stone.json b/src/test/generated/datapack_builtin_entries_provider_test/data/datapack_builtin_entries_provider_test/worldgen/feature/mossy_stone.json new file mode 100644 index 0000000000..0007320161 --- /dev/null +++ b/src/test/generated/datapack_builtin_entries_provider_test/data/datapack_builtin_entries_provider_test/worldgen/feature/mossy_stone.json @@ -0,0 +1,23 @@ +{ + "type": "minecraft:ore", + "discard_chance_on_air_exposure": 0.0, + "size": 5, + "targets": [ + { + "state": "minecraft:mossy_stone_bricks", + "target": { + "predicate_type": "minecraft:any_of", + "rules": [ + { + "predicate_type": "minecraft:tag_match", + "tag": "minecraft:stone_ore_replaceables" + }, + { + "predicate_type": "minecraft:tag_match", + "tag": "minecraft:deepslate_ore_replaceables" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/bamboo_silk.json b/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/bamboo_silk.json index 67e50d49e9..9ee4b4103c 100644 --- a/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/bamboo_silk.json +++ b/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/bamboo_silk.json @@ -2,7 +2,7 @@ "type": "global_loot_test:silk_touch_bamboo", "conditions": [ { - "condition": "minecraft:match_tool", + "type": "minecraft:match_tool", "predicate": { "items": "minecraft:bamboo" } diff --git a/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/multiply_loot.json b/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/multiply_loot.json index 1b638b2e37..57bf4014b4 100644 --- a/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/multiply_loot.json +++ b/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/multiply_loot.json @@ -2,7 +2,7 @@ "type": "global_loot_test:multiply_loot", "conditions": [ { - "condition": "forge:loot_table_id", + "type": "forge:loot_table_id", "loot_table_id": "global_loot_test:blocks/test" } ] diff --git a/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/smelting.json b/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/smelting.json index be432ec44f..04ff6d6d6e 100644 --- a/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/smelting.json +++ b/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/smelting.json @@ -2,7 +2,7 @@ "type": "global_loot_test:smelting", "conditions": [ { - "condition": "minecraft:match_tool", + "type": "minecraft:match_tool", "predicate": { "predicates": { "minecraft:enchantments": [ diff --git a/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/wheat_harvest.json b/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/wheat_harvest.json index 87b8ed0091..f3335fa5c4 100644 --- a/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/wheat_harvest.json +++ b/src/test/generated/global_loot_test/data/global_loot_test/loot_modifiers/wheat_harvest.json @@ -2,14 +2,14 @@ "type": "global_loot_test:wheat_harvest", "conditions": [ { - "condition": "minecraft:match_tool", + "type": "minecraft:match_tool", "predicate": { "items": "#c:tools/shear" } }, { - "block": "minecraft:wheat", - "condition": "minecraft:block_state_property" + "type": "minecraft:match_block", + "blocks": "minecraft:wheat" } ], "numSeeds": 3, diff --git a/src/test/generated/global_loot_test/data/global_loot_test/loot_table/blocks/test.json b/src/test/generated/global_loot_test/data/global_loot_test/loot_table/blocks/test.json index 8004016926..2c312b6be1 100644 --- a/src/test/generated/global_loot_test/data/global_loot_test/loot_table/blocks/test.json +++ b/src/test/generated/global_loot_test/data/global_loot_test/loot_table/blocks/test.json @@ -2,18 +2,16 @@ "type": "minecraft:block", "pools": [ { - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ], + "condition": { + "type": "minecraft:survives_explosion" + }, "entries": [ { "type": "minecraft:item", "name": "global_loot_test:test" } ], - "rolls": 1.0 + "rolls": 1 } ], "random_sequence": "global_loot_test:blocks/test" diff --git a/src/test/generated/loot_events/data/loot_events/loot_table/blocks/test.json b/src/test/generated/loot_events/data/loot_events/loot_table/blocks/test.json index 95deedae5d..82d21a3d44 100644 --- a/src/test/generated/loot_events/data/loot_events/loot_table/blocks/test.json +++ b/src/test/generated/loot_events/data/loot_events/loot_table/blocks/test.json @@ -2,18 +2,16 @@ "type": "minecraft:block", "pools": [ { - "conditions": [ - { - "condition": "minecraft:survives_explosion" - } - ], + "condition": { + "type": "minecraft:survives_explosion" + }, "entries": [ { "type": "minecraft:item", "name": "minecraft:apple" } ], - "rolls": 1.0 + "rolls": 1 } ], "random_sequence": "loot_events:blocks/test" diff --git a/src/test/generated/mdk_datagen/pack.mcmeta b/src/test/generated/mdk_datagen/pack.mcmeta index e0bd3459be..49a62e002b 100644 --- a/src/test/generated/mdk_datagen/pack.mcmeta +++ b/src/test/generated/mdk_datagen/pack.mcmeta @@ -1,10 +1,7 @@ { "pack": { "description": "${mod_id} resources", - "max_format": 107, - "min_format": [ - 107, - 1 - ] + "max_format": 121, + "min_format": 121 } } \ No newline at end of file diff --git a/src/test/generated/model_render_type/assets/model_render_type/blockstates/cutout_block.json b/src/test/generated/model_render_type/assets/model_render_type/blockstates/cutout_block.json deleted file mode 100644 index c7ff378f4d..0000000000 --- a/src/test/generated/model_render_type/assets/model_render_type/blockstates/cutout_block.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "model_render_type:block/cutout_block" - } - } -} \ No newline at end of file diff --git a/src/test/generated/model_render_type/assets/model_render_type/blockstates/old_leaves.json b/src/test/generated/model_render_type/assets/model_render_type/blockstates/old_leaves.json deleted file mode 100644 index f182f53462..0000000000 --- a/src/test/generated/model_render_type/assets/model_render_type/blockstates/old_leaves.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "variants": { - "": { - "model": "model_render_type:block/old_leaves" - } - } -} \ No newline at end of file diff --git a/src/test/generated/model_render_type/assets/model_render_type/items/cutout_block.json b/src/test/generated/model_render_type/assets/model_render_type/items/cutout_block.json deleted file mode 100644 index 85cc44c55d..0000000000 --- a/src/test/generated/model_render_type/assets/model_render_type/items/cutout_block.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "model": { - "type": "minecraft:model", - "model": "model_render_type:item/cutout_block" - } -} \ No newline at end of file diff --git a/src/test/generated/model_render_type/assets/model_render_type/items/old_leaves.json b/src/test/generated/model_render_type/assets/model_render_type/items/old_leaves.json deleted file mode 100644 index 3515428b0d..0000000000 --- a/src/test/generated/model_render_type/assets/model_render_type/items/old_leaves.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "model": { - "type": "minecraft:model", - "model": "model_render_type:block/old_leaves" - } -} \ No newline at end of file diff --git a/src/test/generated/model_render_type/assets/model_render_type/models/block/cutout_block.json b/src/test/generated/model_render_type/assets/model_render_type/models/block/cutout_block.json deleted file mode 100644 index fc44df711c..0000000000 --- a/src/test/generated/model_render_type/assets/model_render_type/models/block/cutout_block.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "parent": "minecraft:block/cross", - "render_type": "minecraft:cutout", - "render_type_fast": "minecraft:solid", - "textures": { - "cross": "minecraft:block/acacia_sapling" - } -} \ No newline at end of file diff --git a/src/test/generated/model_render_type/assets/model_render_type/models/block/old_leaves.json b/src/test/generated/model_render_type/assets/model_render_type/models/block/old_leaves.json deleted file mode 100644 index 362976935c..0000000000 --- a/src/test/generated/model_render_type/assets/model_render_type/models/block/old_leaves.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "parent": "minecraft:block/leaves", - "render_type": "minecraft:cutout_mipped", - "textures": { - "all": "minecraft:block/oak_leaves" - } -} \ No newline at end of file diff --git a/src/test/generated/model_render_type/assets/model_render_type/models/item/cutout_block.json b/src/test/generated/model_render_type/assets/model_render_type/models/item/cutout_block.json deleted file mode 100644 index 89e557914e..0000000000 --- a/src/test/generated/model_render_type/assets/model_render_type/models/item/cutout_block.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "minecraft:item/generated", - "textures": { - "layer0": "minecraft:block/acacia_sapling" - } -} \ No newline at end of file diff --git a/src/test/generated/model_render_type/data/forge/test_instance/model_render_type/old_leaves_render_type.json b/src/test/generated/model_render_type/data/forge/test_instance/model_render_type/old_leaves_render_type.json deleted file mode 100644 index c12568f614..0000000000 --- a/src/test/generated/model_render_type/data/forge/test_instance/model_render_type/old_leaves_render_type.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "minecraft:function", - "environment": "minecraft:default", - "function": "forge:model_render_type/old_leaves_render_type", - "max_ticks": 100, - "structure": "forge:empty3x3x3" -} \ No newline at end of file diff --git a/src/test/generated/model_render_type/data/forge/test_instance/model_render_type/type_from_model.json b/src/test/generated/model_render_type/data/forge/test_instance/model_render_type/type_from_model.json deleted file mode 100644 index 4db9045097..0000000000 --- a/src/test/generated/model_render_type/data/forge/test_instance/model_render_type/type_from_model.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "minecraft:function", - "environment": "minecraft:default", - "function": "forge:model_render_type/type_from_model", - "max_ticks": 100, - "structure": "forge:empty3x3x3" -} \ No newline at end of file diff --git a/src/test/generated/plant_type_placement/data/forge/test_instance/plant_type_placement/vegetation.json b/src/test/generated/plant_type_placement/data/forge/test_instance/plant_type_placement/vegetation.json index 6092eb1805..2d8c4a176c 100644 --- a/src/test/generated/plant_type_placement/data/forge/test_instance/plant_type_placement/vegetation.json +++ b/src/test/generated/plant_type_placement/data/forge/test_instance/plant_type_placement/vegetation.json @@ -3,5 +3,5 @@ "environment": "minecraft:default", "function": "forge:plant_type_placement/vegetation", "max_ticks": 100, - "structure": "forge:empty11x3x33" + "structure": "forge:empty11x3x34" } \ No newline at end of file diff --git a/src/test/generated/test_helper_mod/pack.mcmeta b/src/test/generated/test_helper_mod/pack.mcmeta index 46d7c8bc4e..6e1ab7b360 100644 --- a/src/test/generated/test_helper_mod/pack.mcmeta +++ b/src/test/generated/test_helper_mod/pack.mcmeta @@ -1,10 +1,7 @@ { "pack": { "description": "Forge tests resource pack", - "max_format": 107, - "min_format": [ - 107, - 1 - ] + "max_format": 121, + "min_format": 121 } } \ No newline at end of file diff --git a/src/test/java/net/minecraftforge/debug/client/FluidBucketModelTest.java b/src/test/java/net/minecraftforge/debug/client/FluidBucketModelTest.java index c5e117e7eb..5952b2a3d8 100644 --- a/src/test/java/net/minecraftforge/debug/client/FluidBucketModelTest.java +++ b/src/test/java/net/minecraftforge/debug/client/FluidBucketModelTest.java @@ -83,7 +83,7 @@ public class FluidBucketModelTest extends BaseTestMod { .replaceable() .noCollision() .strength(100) - .pushReaction(PushReaction.DESTROY) + .pushReaction(PushReaction.POPPED) .noLootTable() .liquid() .sound(SoundType.EMPTY) diff --git a/src/test/java/net/minecraftforge/debug/client/ModelRenderLayerTest.java b/src/test/java/net/minecraftforge/debug/client/ModelRenderLayerTest.java deleted file mode 100644 index d9a8f6d0fe..0000000000 --- a/src/test/java/net/minecraftforge/debug/client/ModelRenderLayerTest.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (c) Forge Development LLC and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.minecraftforge.debug.client; -/* - This should no longer be necessary in 26.1 as Material's now define their layers. - -import net.minecraft.client.Minecraft; -import net.minecraft.client.data.models.BlockModelGenerators; -import net.minecraft.client.data.models.ItemModelGenerators; -import net.minecraft.client.data.models.model.ItemModelUtils; -import net.minecraft.client.data.models.model.ModelTemplates; -import net.minecraft.client.data.models.model.TextureMapping; -import net.minecraft.client.renderer.chunk.ChunkSectionLayer; -import net.minecraft.core.registries.Registries; -import net.minecraft.data.CachedOutput; -import net.minecraft.data.DataProvider; -import net.minecraft.data.PackOutput; -import net.minecraft.gametest.framework.GameTestHelper; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.LeavesBlock; -import net.minecraft.world.level.block.SaplingBlock; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.TintedParticleLeavesBlock; -import net.minecraft.world.level.block.grower.TreeGrower; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.material.MapColor; -import net.minecraft.world.level.material.PushReaction; -import net.minecraftforge.client.model.data.ModelData; -import net.minecraftforge.data.event.GatherDataEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.gametest.GameTest; -import net.minecraftforge.gametest.GameTestNamespace; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.RegistryObject; -import net.minecraftforge.test.BaseTestMod; - -import java.nio.file.Path; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import com.google.gson.JsonElement; - -@Mod(ModelRenderLayerTest.MODID) -@GameTestNamespace("forge") -public class ModelRenderLayerTest extends BaseTestMod { - public static final String MODID = "model_render_type"; - private static final String BLOCK_NAME = "cutout_block"; - - private static final DeferredRegister BLOCKS = DeferredRegister.create(Registries.BLOCK, MODID); - public static final RegistryObject BLOCK = BLOCKS.register(BLOCK_NAME, - () -> new SaplingBlock( - TreeGrower.ACACIA, - BlockBehaviour.Properties.of() - .setId(BLOCKS.key(BLOCK_NAME)) - .mapColor(MapColor.PLANT) - .noCollision() - .randomTicks() - .instabreak() - .sound(SoundType.GRASS) - .pushReaction(PushReaction.DESTROY) - ) - ); - - private static final String OLD_LEAVES_NAME = "old_leaves"; - private static final BlockBehaviour.StatePredicate FALSE = (state, level, pos) -> false; - public static final RegistryObject OLD_LEAVES = BLOCKS.register(OLD_LEAVES_NAME, - () -> new TintedParticleLeavesBlock( - 0.01F, - BlockBehaviour.Properties.of() - .setId(BLOCKS.key(OLD_LEAVES_NAME)) - .mapColor(MapColor.PLANT) - .strength(0.2F) - .randomTicks() - .sound(SoundType.GRASS) - .noOcclusion() - .isSuffocating(FALSE) - .isViewBlocking(FALSE) - .ignitedByLava() - .pushReaction(PushReaction.DESTROY) - .isRedstoneConductor(FALSE) - ) - ); - - private static final DeferredRegister ITEMS = DeferredRegister.create(Registries.ITEM, MODID); - public static final RegistryObject ITEM = ITEMS.register(BLOCK_NAME, () -> new BlockItem(BLOCK.get(), new Item.Properties().setId(ITEMS.key(BLOCK_NAME)))); - public static final RegistryObject OLD_LEAVES_ITEM = ITEMS.register(OLD_LEAVES_NAME, () -> new BlockItem(OLD_LEAVES.get(), new Item.Properties().setId(ITEMS.key(OLD_LEAVES_NAME)))); - - public ModelRenderLayerTest(FMLJavaModLoadingContext context) { - super(context, false, true); - GatherDataEvent.getBus(modBus).addListener(this::gatherData); - testItem(lookup -> new ItemStack(ITEM.get())); - } - - public void gatherData(GatherDataEvent event) { - var out = event.getGenerator().getPackOutput(); - event.getGenerator().addProvider(event.includeClient(), new ModelProvider(out)); - } - - @GameTest - public static void type_from_model(GameTestHelper helper) { - var manager = Minecraft.getInstance().getModelManager(); - - var model = manager.getBlockModelShaper().getBlockModel(BLOCK.get().defaultBlockState()); - helper.assertValueNotEqual(manager.getMissingBlockStateModel(), model, BLOCK_NAME, "Failed to retreive block model"); - - var state = BLOCK.get().defaultBlockState(); - var random = helper.getLevel().random; - boolean originalRenderState = ItemBlockRenderTypes.isFancy(); - helper.addCleanup(passed -> ItemBlockRenderTypes.setCutoutLeaves(originalRenderState)); - - ItemBlockRenderTypes.setCutoutLeaves(true); - var layer = model.getRenderTypes(state, random, ModelData.EMPTY); - helper.assertTrue(layer.contains(ChunkSectionLayer.CUTOUT), "Block model does not contain the correct render type for fancy graphics. Expected: cutout"); - - ItemBlockRenderTypes.setCutoutLeaves(false); - layer = model.getRenderTypes(state, random, ModelData.EMPTY); - helper.assertTrue(layer.contains(ChunkSectionLayer.SOLID), "Block model does not contain the correct render type for fast graphics. Expected: solid"); - - helper.succeed(); - } - - @GameTest - public static void old_leaves_render_type(GameTestHelper helper) { - var manager = Minecraft.getInstance().getModelManager(); - - - var state = OLD_LEAVES.get().defaultBlockState(); - var model = manager.getBlockModelShaper().getBlockModel(state); - helper.assertValueNotEqual(manager.getMissingBlockStateModel(), model, OLD_LEAVES_NAME, "Failed to retreive block model"); - - var random = helper.getLevel().random; - boolean originalRenderState = ItemBlockRenderTypes.isFancy(); - helper.addCleanup(passed -> ItemBlockRenderTypes.setCutoutLeaves(originalRenderState)); - - ItemBlockRenderTypes.setCutoutLeaves(true); - var layer = model.getRenderTypes(state, random, ModelData.EMPTY); - helper.assertTrue(layer.contains(ChunkSectionLayer.CUTOUT), "Block model does not contain the correct render type for fancy graphics. Expected: cutout_mipped"); - - ItemBlockRenderTypes.setCutoutLeaves(false); - layer = model.getRenderTypes(state, random, ModelData.EMPTY); - helper.assertTrue(layer.contains(ChunkSectionLayer.SOLID), "Block model does not contain the correct render type for fast graphics. Expected: solid"); - - helper.succeed(); - } - - public class ModelProvider extends net.minecraft.client.data.models.ModelProvider { - public ModelProvider(PackOutput output) { - super(output); - } - - protected Stream getKnownBlocks() { - return Stream.of(BLOCK.get()); - } - - protected Stream getKnownItems() { - return Stream.of(ITEM.get()); - } - - protected BlockModelGenerators getBlockModelGenerators(BlockStateGeneratorCollector blocks, ItemInfoCollector items, SimpleModelCollector models) { - return new BlockModelGenerators(blocks, items, models) { - @Override - public void run() { - // CUTOUT BLOCK - var textures = PlantType.NOT_TINTED.getTextureMapping(Blocks.ACACIA_SAPLING); - var cutout = PlantType.NOT_TINTED.getCross().create(BLOCK.get(), textures, (name, model) -> { - var json = model.get().getAsJsonObject(); - json.addProperty("render_type", "minecraft:cutout"); - json.addProperty("render_type_fast", "minecraft:solid"); - this.modelOutput.accept(name, () -> json); - }); - this.blockStateOutput.accept(createSimpleBlock(BLOCK.get(), variant(plainModel(cutout)))); - - var item = ModelTemplates.FLAT_ITEM.create(ITEM.get(), TextureMapping.layer0(Blocks.ACACIA_SAPLING), this.modelOutput); - this.itemModelOutput.accept(ITEM.get(), ItemModelUtils.plainModel(item)); - - - // OLD LEAVES - var oldLeavesCutout = ModelTemplates.LEAVES.create(OLD_LEAVES.get(), TextureMapping.cube(Blocks.OAK_LEAVES), (name, model) -> { - var json = model.get().getAsJsonObject(); - json.addProperty("render_type", "minecraft:cutout_mipped"); - this.modelOutput.accept(name, () -> json); - }); - this.blockStateOutput.accept(createSimpleBlock(OLD_LEAVES.get(), variant(plainModel(oldLeavesCutout)))); - - this.itemModelOutput.accept(OLD_LEAVES_ITEM.get(), ItemModelUtils.plainModel(oldLeavesCutout)); - } - }; - } - - protected ItemModelGenerators getItemModelGenerators(ItemInfoCollector items, SimpleModelCollector models) { - return new ItemModelGenerators(items, models) { - public void run() { - } - }; - } - - static CompletableFuture saveAll(CachedOutput p_378816_, Function p_377914_, Map> p_377836_) { - return DataProvider.saveAll(p_378816_, Supplier::get, p_377914_, p_377836_); - } - } -} -*/ diff --git a/src/test/java/net/minecraftforge/debug/client/RenderFrameLayerTest.java b/src/test/java/net/minecraftforge/debug/client/RenderFrameLayerTest.java index 7289f76007..c00d5aded7 100644 --- a/src/test/java/net/minecraftforge/debug/client/RenderFrameLayerTest.java +++ b/src/test/java/net/minecraftforge/debug/client/RenderFrameLayerTest.java @@ -5,7 +5,6 @@ package net.minecraftforge.debug.client; -import net.minecraft.client.DeltaTracker; import net.minecraft.client.renderer.LevelTargetBundle; import net.minecraft.client.renderer.state.level.LevelRenderState; import net.minecraftforge.client.FramePassManager; @@ -55,7 +54,7 @@ public class RenderFrameLayerTest extends BaseTestMod { public static void renderTest(AddFramePassEvent event) { FramePassManager.PassDefinition def = new FramePassManager.PassDefinition() { @Override - public void extracts(LevelTargetBundle bundle, FramePass pass, DeltaTracker dt) { + public void extracts(LevelTargetBundle bundle, FramePass pass, LevelRenderState state) { bundle.main = pass.readsAndWrites(bundle.main); } @@ -76,7 +75,7 @@ public class RenderFrameLayerTest extends BaseTestMod { event.addPass(rl(MODID), def); FramePassManager.PassDefinition def2 = new FramePassManager.PassDefinition() { @Override - public void extracts(@NotNull LevelTargetBundle bundle, FramePass pass, DeltaTracker dt) { + public void extracts(@NotNull LevelTargetBundle bundle, FramePass pass, LevelRenderState state) { bundle.main = pass.readsAndWrites(bundle.main); } diff --git a/src/test/java/net/minecraftforge/debug/gameplay/biome/BiomeTestMod.java b/src/test/java/net/minecraftforge/debug/gameplay/biome/BiomeTestMod.java index f1bbd2ef06..dc4215b7f5 100644 --- a/src/test/java/net/minecraftforge/debug/gameplay/biome/BiomeTestMod.java +++ b/src/test/java/net/minecraftforge/debug/gameplay/biome/BiomeTestMod.java @@ -9,9 +9,8 @@ import net.minecraft.core.HolderSet; import net.minecraft.core.registries.Registries; import net.minecraft.tags.BiomeTags; import net.minecraft.world.level.levelgen.GenerationStep; -import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; import net.minecraft.world.level.levelgen.feature.Feature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; +import net.minecraft.world.level.levelgen.feature.NoOpFeature; import net.minecraft.world.level.levelgen.placement.PlacedFeature; import net.minecraftforge.common.world.BiomeModifier; import net.minecraftforge.common.world.ForgeBiomeModifiers; @@ -27,10 +26,8 @@ import java.util.List; public class BiomeTestMod extends BaseTestMod { public static final String MOD_ID = "biome_test"; - public static final DeferredRegisterData> CONFIGURED_FEATURES = DeferredRegisterData.create(Registries.CONFIGURED_FEATURE, MOD_ID); - private static final RegistryObject> CONFIGURED = CONFIGURED_FEATURES.register("configured", () -> - new ConfiguredFeature<>(Feature.NO_OP, NoneFeatureConfiguration.INSTANCE) - ); + public static final DeferredRegisterData CONFIGURED_FEATURES = DeferredRegisterData.create(Registries.FEATURE, MOD_ID); + private static final RegistryObject CONFIGURED = CONFIGURED_FEATURES.register("configured", () -> new NoOpFeature()); public static final DeferredRegisterData PLACED_FEATURES = DeferredRegisterData.create(Registries.PLACED_FEATURE, MOD_ID); private static final RegistryObject PLACED = PLACED_FEATURES.register("placed", () -> diff --git a/src/test/java/net/minecraftforge/debug/gameplay/block/CrafterBlockTest.java b/src/test/java/net/minecraftforge/debug/gameplay/block/CrafterBlockTest.java index a961b85cde..ba53fdac39 100644 --- a/src/test/java/net/minecraftforge/debug/gameplay/block/CrafterBlockTest.java +++ b/src/test/java/net/minecraftforge/debug/gameplay/block/CrafterBlockTest.java @@ -8,8 +8,6 @@ package net.minecraftforge.debug.gameplay.block; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import com.mojang.serialization.MapCodec; - import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.FrontAndTop; @@ -84,8 +82,6 @@ public class CrafterBlockTest extends BaseTestMod { } private static class SimpleIItemHandlerBlock extends BaseEntityBlock { - private static final MapCodec CODEC = simpleCodec(SimpleIItemHandlerBlock::new); - protected SimpleIItemHandlerBlock(Properties props) { super(props); } @@ -94,11 +90,6 @@ public class CrafterBlockTest extends BaseTestMod { public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { return IITEM_BLOCK_TYPE.get().create(pos, state); } - - @Override - protected MapCodec codec() { - return CODEC; - } } private static class SimpleIItemHandler extends BlockEntity { diff --git a/src/test/java/net/minecraftforge/debug/gameplay/block/PlantTypePlacementTest.java b/src/test/java/net/minecraftforge/debug/gameplay/block/PlantTypePlacementTest.java index b62099e71f..41bd496377 100644 --- a/src/test/java/net/minecraftforge/debug/gameplay/block/PlantTypePlacementTest.java +++ b/src/test/java/net/minecraftforge/debug/gameplay/block/PlantTypePlacementTest.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Map; import java.util.function.Consumer; import java.util.stream.Collectors; + import static net.minecraft.world.level.block.Blocks.*; @GameTestNamespace("forge") @@ -65,7 +66,7 @@ public class PlantTypePlacementTest extends BaseTestMod { // VegitationBlock has no direct creations map.put(AttachedStemBlock.class, of(this::farmland, ATTACHED_MELON_STEM, ATTACHED_PUMPKIN_STEM)); map.put(AzaleaBlock.class, of(this::simple, AZALEA, FLOWERING_AZALEA)); - map.put(BushBlock.class, of(this::vegetation, BUSH)); + map.put(BushBlock.class, of(this::vegetation, BUSH, RED_SHRUB)); map.put(CactusFlowerBlock.class, of(this::cactus_flower, CACTUS_FLOWER)); map.put(CropBlock.class, of(this::farmland, WHEAT)); @@ -98,7 +99,7 @@ public class PlantTypePlacementTest extends BaseTestMod { map.put(NetherWartBlock.class, of(this::simple, NETHER_WART)); map.put(NetherRootsBlock.class, of(this::simple, CRIMSON_ROOTS, WARPED_ROOTS)); - map.put(SaplingBlock.class, of(this::vegetation, ACACIA_SAPLING, BIRCH_SAPLING, CHERRY_SAPLING, DARK_OAK_SAPLING, JUNGLE_SAPLING, OAK_SAPLING, PALE_OAK_SAPLING, SPRUCE_SAPLING)); + map.put(SaplingBlock.class, of(this::vegetation, ACACIA_SAPLING, BIRCH_SAPLING, CHERRY_SAPLING, DARK_OAK_SAPLING, JUNGLE_SAPLING, OAK_SAPLING, PALE_OAK_SAPLING, POPLAR_SAPLING, SPRUCE_SAPLING)); map.put(MangrovePropaguleBlock.class, of(this::vegetation, MANGROVE_PROPAGULE)); map.put(SeagrassBlock.class, of(this::todo, SEAGRASS)); @@ -270,7 +271,7 @@ public class PlantTypePlacementTest extends BaseTestMod { helper.succeed(); } - @GameTest(structure = "forge:empty11x3x33") // vegetation(11) * 32 plants + @GameTest(structure = "forge:empty11x3x34") // vegetation(11) * 33 plants + 1 public void vegetation(GameTestHelper helper) { var plants = plants( BushBlock.class, // 1 @@ -278,7 +279,7 @@ public class PlantTypePlacementTest extends BaseTestMod { FlowerBedBlock.class, // 2 FlowerBlock.class, // 14 EyeblossomBlock.class, // 2 - SaplingBlock.class, // 8 + SaplingBlock.class, // 9 SweetBerryBushBlock.class, // 1 MangrovePropaguleBlock.class, // 1 TallGrassBlock.class // 2 diff --git a/src/test/java/net/minecraftforge/debug/gameplay/crafting/ConditionalRecipeTest.java b/src/test/java/net/minecraftforge/debug/gameplay/crafting/ConditionalRecipeTest.java index f6e849c1d7..a453473378 100644 --- a/src/test/java/net/minecraftforge/debug/gameplay/crafting/ConditionalRecipeTest.java +++ b/src/test/java/net/minecraftforge/debug/gameplay/crafting/ConditionalRecipeTest.java @@ -5,20 +5,24 @@ package net.minecraftforge.debug.gameplay.crafting; +import java.util.Set; import java.util.concurrent.CompletableFuture; +import net.minecraft.advancements.Advancement; import net.minecraft.core.HolderLookup; -import net.minecraft.core.HolderLookup.Provider; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.MultiRegistryBootstrap; import net.minecraft.core.registries.Registries; import net.minecraft.data.PackOutput; import net.minecraft.data.recipes.RecipeCategory; -import net.minecraft.data.recipes.RecipeOutput; import net.minecraft.data.recipes.RecipeProvider; import net.minecraft.data.recipes.SimpleCookingRecipeBuilder; import net.minecraft.data.recipes.SingleItemRecipeBuilder; import net.minecraft.data.tags.VanillaItemTagsProvider; +import net.minecraft.data.worldgen.BootstrapContext; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.references.ItemIds; +import net.minecraft.resources.ResourceKey; import net.minecraft.tags.ItemTags; import net.minecraft.tags.TagKey; import net.minecraft.world.item.ItemStack; @@ -34,6 +38,7 @@ import net.minecraftforge.common.crafting.ConditionalRecipe; import net.minecraftforge.common.crafting.SimpleCraftingContainer; import net.minecraftforge.common.crafting.conditions.IConditionBuilder; import net.minecraftforge.common.data.ExistingFileHelper; +import net.minecraftforge.common.data.RegistryDataBuilder; import net.minecraftforge.data.event.GatherDataEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; @@ -53,7 +58,14 @@ public class ConditionalRecipeTest extends BaseTestMod { public void gatherData(GatherDataEvent event) { var gen = event.getGenerator(); - gen.addProvider(event.includeServer(), new Recipes.Runner(gen.getPackOutput(), event.getLookupProvider())); + + var registries = RegistryDataBuilder.of() + .name(modid()) + .reloadable(set -> set + .add(Recipes.create()) + ); + + gen.addProvider(event.includeServer(), registries.reloadableGenerator(gen.getPackOutput())); gen.addProvider(event.includeServer(), new TestItemTags(gen.getPackOutput(), event.getLookupProvider(), event.getExistingFileHelper())); } @@ -181,14 +193,28 @@ public class ConditionalRecipeTest extends BaseTestMod { } public static class Recipes extends RecipeProvider implements IConditionBuilder { - public Recipes(HolderLookup.Provider lookup, RecipeOutput gen) { - super(lookup, gen); + public static MultiRegistryBootstrap create() { + return new MultiRegistryBootstrap() { + @Override + public Set>> requestedRegistries() { + return Set.of(Registries.RECIPE, Registries.ADVANCEMENT); + } + + @Override + public void run(BootstrapGetter registries) { + new Recipes(registries.get(Registries.RECIPE), registries.get(Registries.ADVANCEMENT)).buildRecipes(); + } + }; + } + + public Recipes(final BootstrapContext> recipeOutput, final BootstrapContext advancementOutput) { + super(recipeOutput, advancementOutput); } @Override protected void buildRecipes() { // TODO: Move this to a Condition test instead of using recipe encoders. - ConditionalRecipe.builder() + ConditionalRecipe.builder(this.output) .condition( and ( or ( @@ -211,7 +237,7 @@ public class ConditionalRecipeTest extends BaseTestMod { ) .save(this.output, rl("test_encode_all_conditions")); - ConditionalRecipe.builder() + ConditionalRecipe.builder(this.output) .condition(FALSE()) .recipe( shaped(RecipeCategory.MISC, Blocks.DIAMOND_BLOCK, 64) @@ -224,7 +250,7 @@ public class ConditionalRecipeTest extends BaseTestMod { ) .save(this.output, rl("shaped_false_conditions")); - ConditionalRecipe.builder() + ConditionalRecipe.builder(this.output) .condition(TRUE()) .recipe( shaped(RecipeCategory.MISC, Blocks.DIAMOND_BLOCK, 64) @@ -237,7 +263,7 @@ public class ConditionalRecipeTest extends BaseTestMod { ) .save(this.output, rl("shaped_true_conditions")); - ConditionalRecipe.builder() + ConditionalRecipe.builder(this.output) .condition(FALSE()) .recipe( shapeless(RecipeCategory.MISC, Blocks.DIAMOND_BLOCK) @@ -249,7 +275,7 @@ public class ConditionalRecipeTest extends BaseTestMod { ) .save(this.output, rl("shapeless_false_conditions")); - ConditionalRecipe.builder() + ConditionalRecipe.builder(this.output) .condition(TRUE()) .recipe( shapeless(RecipeCategory.MISC, Blocks.DIAMOND_BLOCK) @@ -262,7 +288,7 @@ public class ConditionalRecipeTest extends BaseTestMod { ) .save(this.output, rl("shapeless_true_conditions")); - ConditionalRecipe.builder() + ConditionalRecipe.builder(this.output) .condition(FALSE()) .recipe( SimpleCookingRecipeBuilder.smelting(Ingredient.of(Blocks.DIRT), RecipeCategory.MISC, CookingBookCategory.MISC, Blocks.DIAMOND_BLOCK, 0.1F, 200) @@ -271,7 +297,7 @@ public class ConditionalRecipeTest extends BaseTestMod { ) .save(this.output, rl("cooking_false_conditions")); - ConditionalRecipe.builder() + ConditionalRecipe.builder(this.output) .condition(TRUE()) .recipe( SimpleCookingRecipeBuilder.smelting(Ingredient.of(Blocks.BEE_NEST), RecipeCategory.MISC, CookingBookCategory.MISC, Blocks.DIAMOND_BLOCK, 0.1F, 200) @@ -280,7 +306,7 @@ public class ConditionalRecipeTest extends BaseTestMod { ) .save(this.output, rl("cooking_true_conditions")); - ConditionalRecipe.builder() + ConditionalRecipe.builder(this.output) .condition(FALSE()) .recipe( SingleItemRecipeBuilder.stonecutting(Ingredient.of(Blocks.DIRT), RecipeCategory.MISC, Blocks.DIAMOND_BLOCK, 1) @@ -289,7 +315,7 @@ public class ConditionalRecipeTest extends BaseTestMod { ) .save(this.output, rl("single_item_false_conditions")); - ConditionalRecipe.builder() + ConditionalRecipe.builder(this.output) .condition(TRUE()) .recipe( SingleItemRecipeBuilder.stonecutting(Ingredient.of(Blocks.REDSTONE_ORE), RecipeCategory.MISC, Blocks.DIAMOND_BLOCK, 1) @@ -302,7 +328,7 @@ public class ConditionalRecipeTest extends BaseTestMod { // TODO SmithingTrimRecipeBuilder - ConditionalRecipe.builder() + ConditionalRecipe.builder(this.output) .condition(FALSE()) .recipe( shaped(RecipeCategory.MISC, Blocks.DIAMOND_BLOCK, 64) @@ -323,7 +349,7 @@ public class ConditionalRecipeTest extends BaseTestMod { ) .save(this.output, rl("conditional_recipe_choice")); - ConditionalRecipe.builder() + ConditionalRecipe.builder(this.output) .condition(FALSE()) .recipe( shapeless(RecipeCategory.MISC, Blocks.DIAMOND_BLOCK, 64) @@ -333,7 +359,7 @@ public class ConditionalRecipeTest extends BaseTestMod { ) .save(this.output, rl("conditional_doesnt_load_empty")); - ConditionalRecipe.builder() + ConditionalRecipe.builder(this.output) .condition(tagEmpty(ItemTags.DIRT)) .recipe( shapeless(RecipeCategory.MISC, Blocks.DIAMOND_BLOCK) @@ -345,7 +371,7 @@ public class ConditionalRecipeTest extends BaseTestMod { ) .save(this.output, rl("tag_empty_condition_doesnt_load")); - ConditionalRecipe.builder() + ConditionalRecipe.builder(this.output) .condition(tagEmpty(TagKey.create(Registries.ITEM, rl("empty_tag_for_testing")))) .recipe( shapeless(RecipeCategory.MISC, Blocks.DIAMOND_BLOCK) @@ -357,22 +383,6 @@ public class ConditionalRecipeTest extends BaseTestMod { ) .save(this.output, rl("tag_empty_condition_loads")); } - - public static class Runner extends RecipeProvider.Runner { - protected Runner(PackOutput output, CompletableFuture registries) { - super(output, registries); - } - - @Override - public String getName() { - return ConditionalRecipeTest.class.getSimpleName() + "-Recipes"; - } - - @Override - protected RecipeProvider createRecipeProvider(Provider registries, RecipeOutput output) { - return new Recipes(registries, output); - } - } } } diff --git a/src/test/java/net/minecraftforge/debug/gameplay/crafting/CustomIngredientsTest.java b/src/test/java/net/minecraftforge/debug/gameplay/crafting/CustomIngredientsTest.java index 68bd6ae49a..2565cfd536 100644 --- a/src/test/java/net/minecraftforge/debug/gameplay/crafting/CustomIngredientsTest.java +++ b/src/test/java/net/minecraftforge/debug/gameplay/crafting/CustomIngredientsTest.java @@ -5,20 +5,24 @@ package net.minecraftforge.debug.gameplay.crafting; +import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.function.Function; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraft.advancements.Advancement; +import net.minecraft.core.HolderGetter; import net.minecraft.core.HolderLookup; -import net.minecraft.core.HolderLookup.Provider; +import net.minecraft.core.Registry; import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.MultiRegistryBootstrap; import net.minecraft.core.registries.Registries; import net.minecraft.data.PackOutput; import net.minecraft.data.recipes.RecipeCategory; -import net.minecraft.data.recipes.RecipeOutput; import net.minecraft.data.recipes.RecipeProvider; import net.minecraft.data.recipes.ShapedRecipeBuilder; import net.minecraft.data.tags.VanillaItemTagsProvider; +import net.minecraft.data.worldgen.BootstrapContext; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.nbt.CompoundTag; import net.minecraft.references.BlockItemIds; @@ -38,6 +42,7 @@ import net.minecraftforge.common.crafting.SimpleCraftingContainer; import net.minecraftforge.common.crafting.conditions.IConditionBuilder; import net.minecraftforge.common.crafting.ingredients.IIngredientBuilder; import net.minecraftforge.common.data.ExistingFileHelper; +import net.minecraftforge.common.data.RegistryDataBuilder; import net.minecraftforge.common.util.INBTBuilder; import net.minecraftforge.data.event.GatherDataEvent; import net.minecraftforge.fml.common.Mod; @@ -67,8 +72,14 @@ public class CustomIngredientsTest extends BaseTestMod implements INBTBuilder { var look = event.getLookupProvider(); var exist = event.getExistingFileHelper(); + var registries = RegistryDataBuilder.of() + .name(modid()) + .reloadable(set -> set + .add(Recipes.create()) + ); + gen.addProvider(event.includeServer(), registries.reloadableGenerator(gen.getPackOutput())); + gen.addProvider(event.includeServer(), new ItemTagsGen(out, look, exist)); - gen.addProvider(event.includeServer(), new Recipes.Runner(out, event.getLookupProvider())); } private static TagKey tag(String name) { @@ -235,8 +246,25 @@ public class CustomIngredientsTest extends BaseTestMod implements INBTBuilder { } private static class Recipes extends RecipeProvider implements IConditionBuilder, IIngredientBuilder, INBTBuilder { - public Recipes(HolderLookup.Provider lookup, RecipeOutput gen) { - super(lookup, gen); + public static MultiRegistryBootstrap create() { + return new MultiRegistryBootstrap() { + @Override + public Set>> requestedRegistries() { + return Set.of(Registries.RECIPE, Registries.ADVANCEMENT); + } + + @Override + public void run(BootstrapGetter registries) { + new Recipes(registries.get(Registries.RECIPE), registries.get(Registries.ADVANCEMENT)).buildRecipes(); + } + }; + } + + private final HolderGetter items; + + public Recipes(final BootstrapContext> recipeOutput, final BootstrapContext advancementOutput) { + super(recipeOutput, advancementOutput); + this.items = recipeOutput.lookup(Registries.ITEM); } private ShapedRecipeBuilder shaped() { @@ -251,7 +279,6 @@ public class CustomIngredientsTest extends BaseTestMod implements INBTBuilder { protected void buildRecipes() { var hasName = getHasName(Items.DIRT); var has = has(Items.DIRT); - var items = this.registries.lookup(Registries.ITEM).get(); // contains NBT match - should match a stone pickaxe that lost 3 durability, regardless of setting its name shaped() @@ -328,21 +355,5 @@ public class CustomIngredientsTest extends BaseTestMod implements INBTBuilder { .unlockedBy(hasName, has) .save(this.output, rk("difference_ingredient")); } - - public static class Runner extends RecipeProvider.Runner { - protected Runner(PackOutput output, CompletableFuture registries) { - super(output, registries); - } - - @Override - public String getName() { - return CustomIngredientsTest.class.getSimpleName() + "-Recipes"; - } - - @Override - protected RecipeProvider createRecipeProvider(Provider registries, RecipeOutput output) { - return new Recipes(registries, output); - } - } } } diff --git a/src/test/java/net/minecraftforge/debug/gameplay/criterion/BreakWithItemCriterion.java b/src/test/java/net/minecraftforge/debug/gameplay/criterion/BreakWithItemCriterion.java index 669a39095b..358d9489f4 100644 --- a/src/test/java/net/minecraftforge/debug/gameplay/criterion/BreakWithItemCriterion.java +++ b/src/test/java/net/minecraftforge/debug/gameplay/criterion/BreakWithItemCriterion.java @@ -10,14 +10,15 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import org.jspecify.annotations.NullMarked; import net.minecraft.advancements.predicates.BlockPredicate; -import net.minecraft.advancements.predicates.ContextAwarePredicate; import net.minecraft.advancements.predicates.ItemPredicate; import net.minecraft.advancements.triggers.Criterion; import net.minecraft.advancements.triggers.SimpleCriterionTrigger; import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; import java.util.Optional; @@ -50,7 +51,7 @@ public final class BreakWithItemCriterion extends SimpleCriterionTrigger player() { + public Optional> player() { return Optional.empty(); } } diff --git a/src/test/java/net/minecraftforge/debug/gameplay/criterion/CriterionTest.java b/src/test/java/net/minecraftforge/debug/gameplay/criterion/CriterionTest.java index e6f38e19cf..39f786787d 100644 --- a/src/test/java/net/minecraftforge/debug/gameplay/criterion/CriterionTest.java +++ b/src/test/java/net/minecraftforge/debug/gameplay/criterion/CriterionTest.java @@ -13,10 +13,14 @@ import net.minecraft.advancements.predicates.BlockPredicate; import net.minecraft.advancements.predicates.ItemPredicate; import net.minecraft.advancements.triggers.CriterionTrigger; import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderGetter; import net.minecraft.core.HolderLookup; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; +import net.minecraft.data.advancements.AdvancementProvider; +import net.minecraft.data.advancements.AdvancementSubProvider; import net.minecraft.data.tags.VanillaItemTagsProvider; +import net.minecraft.data.worldgen.BootstrapContext; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.network.chat.Component; import net.minecraft.references.ItemIds; @@ -24,11 +28,13 @@ import net.minecraft.resources.Identifier; import net.minecraft.server.level.ServerPlayer; import net.minecraft.tags.TagKey; import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraftforge.common.Tags; -import net.minecraftforge.common.data.ForgeAdvancementProvider; +import net.minecraftforge.common.data.RegistryDataBuilder; import net.minecraftforge.data.event.GatherDataEvent; import net.minecraftforge.event.level.BlockEvent; import net.minecraftforge.fml.common.Mod; @@ -49,6 +55,7 @@ public final class CriterionTest extends BaseTestMod { public static final RegistryObject CRITERION = TRIGGERS.register("criterion", BreakWithItemCriterion::new); public static final String TEST_CRITERION_ID = "break_glass_with_fish"; public static final Identifier TEST_ADVANCEMENT_ID = Identifier.fromNamespaceAndPath(MOD_ID, TEST_CRITERION_ID); + private static final TagKey TAG = TagKey.create(Registries.ITEM, Identifier.fromNamespaceAndPath(MOD_ID, "fish")); public CriterionTest(FMLJavaModLoadingContext context) { super(context, false, true); @@ -102,12 +109,19 @@ public final class CriterionTest extends BaseTestMod { } private void gatherData(GatherDataEvent event) { - var tag = TagKey.create(Registries.ITEM, Identifier.fromNamespaceAndPath(MOD_ID, "fish")); + + var registries = RegistryDataBuilder.of() + .name(modid()) + .reloadable(set -> set + .add(Registries.ADVANCEMENT, new AdvancementProvider(List.of( + Advancements::new + ))) + ); event.getGenerator().addProvider(true, new VanillaItemTagsProvider(event.getGenerator().getPackOutput(), event.getLookupProvider(), MOD_ID, event.getExistingFileHelper()) { @Override protected void addTags(HolderLookup.Provider lookup) { - this.tag(tag) + this.tag(TAG) .add(ItemIds.COD) .add(ItemIds.SALMON) .add(ItemIds.TROPICAL_FISH) @@ -118,34 +132,39 @@ public final class CriterionTest extends BaseTestMod { } }); - var STORY_ROOT = new AdvancementHolder(Identifier.fromNamespaceAndPath("minecraft", "story/root"), null); - event.getGenerator().addProvider(true, - new ForgeAdvancementProvider( - event.getGenerator().getPackOutput(), - event.getLookupProvider(), - event.getExistingFileHelper(), - List.of(((registries, saver, _) -> { - var blocks = registries.lookup(Registries.BLOCK).get(); - var items = registries.lookup(Registries.ITEM).get(); - saver.accept(new Advancement.Builder() - .display(Items.COD, - Component.literal("Fish vs Glass"), - Component.literal("Fish wins!"), - null, - AdvancementType.TASK, - true, true, false - ) - .parent(STORY_ROOT) - .requirements(AdvancementRequirements.Strategy.AND) - .addCriterion(TEST_CRITERION_ID, CRITERION.get().instance( - BlockPredicate.Builder.block().of(blocks, Tags.Blocks.GLASS_BLOCKS).build(), - ItemPredicate.Builder.item().of(items, tag).build(), - true - )) - .build(TEST_ADVANCEMENT_ID)); - })) - ) - ); + event.getGenerator().addProvider(true, registries.reloadableGenerator(event.getGenerator().getPackOutput())); + } + + private static class Advancements extends AdvancementSubProvider { + private final HolderGetter blocks; + private final HolderGetter items; + + public Advancements(final BootstrapContext output) { + super(output); + this.blocks = output.lookup(Registries.BLOCK); + this.items = output.lookup(Registries.ITEM); + } + + @Override + public void generate() { + var STORY_ROOT = new AdvancementHolder(Identifier.fromNamespaceAndPath("minecraft", "story/root"), null); + + new Advancement.Builder() + .display(Items.COD, + Component.literal("Fish vs Glass"), + Component.literal("Fish wins!"), + AdvancementType.TASK, + true, true, false + ) + .parent(STORY_ROOT) + .requirements(AdvancementRequirements.Strategy.AND) + .addCriterion(TEST_CRITERION_ID, CRITERION.get().instance( + BlockPredicate.Builder.block().of(blocks, Tags.Blocks.GLASS_BLOCKS).build(), + ItemPredicate.Builder.item().of(items, TAG).build(), + true + )) + .save(this.output, TEST_ADVANCEMENT_ID); + } } } diff --git a/src/test/java/net/minecraftforge/debug/gameplay/data/DatapackBuiltinEntriesProviderTest.java b/src/test/java/net/minecraftforge/debug/gameplay/data/DatapackBuiltinEntriesProviderTest.java index 991fc8b608..3b331282fc 100644 --- a/src/test/java/net/minecraftforge/debug/gameplay/data/DatapackBuiltinEntriesProviderTest.java +++ b/src/test/java/net/minecraftforge/debug/gameplay/data/DatapackBuiltinEntriesProviderTest.java @@ -6,7 +6,6 @@ package net.minecraftforge.debug.gameplay.data; import net.minecraft.core.HolderSet; -import net.minecraft.core.RegistrySetBuilder; import net.minecraft.core.registries.Registries; import net.minecraft.data.worldgen.BootstrapContext; import net.minecraft.resources.ResourceKey; @@ -16,12 +15,12 @@ import net.minecraft.tags.BlockTags; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.levelgen.GenerationStep; import net.minecraft.world.level.levelgen.VerticalAnchor; -import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; import net.minecraft.world.level.levelgen.feature.Feature; -import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration; +import net.minecraft.world.level.levelgen.feature.OreFeature; import net.minecraft.world.level.levelgen.placement.*; +import net.minecraft.world.level.levelgen.structure.templatesystem.AnyOfRuleTest; import net.minecraft.world.level.levelgen.structure.templatesystem.TagMatchTest; -import net.minecraftforge.common.data.DatapackBuiltinEntriesProvider; +import net.minecraftforge.common.data.RegistryDataBuilder; import net.minecraftforge.common.world.BiomeModifier; import net.minecraftforge.common.world.ForgeBiomeModifiers; import net.minecraftforge.data.event.GatherDataEvent; @@ -31,24 +30,16 @@ import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.test.BaseTestMod; import java.util.*; -import java.util.function.Supplier; @Mod(DatapackBuiltinEntriesProviderTest.MOD_ID) public class DatapackBuiltinEntriesProviderTest extends BaseTestMod { public static final String MOD_ID = "datapack_builtin_entries_provider_test"; // Vanilla registry entries - public static final ResourceKey> MOSSY_STONE_FEATURE = ResourceKey.create(Registries.CONFIGURED_FEATURE, Identifier.fromNamespaceAndPath(MOD_ID, "mossy_stone")); + public static final ResourceKey MOSSY_STONE_FEATURE = ResourceKey.create(Registries.FEATURE, Identifier.fromNamespaceAndPath(MOD_ID, "mossy_stone")); public static final ResourceKey MOSSY_STONE_PLACEMENT = ResourceKey.create(Registries.PLACED_FEATURE, Identifier.fromNamespaceAndPath(MOD_ID, "mossy_stone")); // Forge registry entries public static final ResourceKey MOSSY_STONE_MODIFIER = ResourceKey.create(ForgeRegistries.Keys.BIOME_MODIFIERS, Identifier.fromNamespaceAndPath(MOD_ID, "mossy_stone_modifier")); - // The ore targets - public static final Supplier> MOSSY_STONE_TARGETS = () -> { - return List.of( - OreConfiguration.target(new TagMatchTest(BlockTags.STONE_ORE_REPLACEABLES), Blocks.MOSSY_COBBLESTONE.defaultBlockState()), - OreConfiguration.target(new TagMatchTest(BlockTags.DEEPSLATE_ORE_REPLACEABLES), Blocks.MOSSY_COBBLESTONE.defaultBlockState()) - ); - }; public DatapackBuiltinEntriesProviderTest(FMLJavaModLoadingContext context) { super(context, false, true); @@ -57,35 +48,34 @@ public class DatapackBuiltinEntriesProviderTest extends BaseTestMod { private void gatherData(GatherDataEvent event) { var gen = event.getGenerator(); - var packOutput = gen.getPackOutput(); /* Adds the DataPackBuiltinEntriesProvider to the data generator * If the registry is not correctly patched (it does only include the vanilla registries), the provider will fail with an exception * Reason: The RegistrySetBuilder creates a full patched registry including a lookup for all registries * For the lookup a cloner is needed, which is not available for forge registries */ - gen.addProvider(event.includeServer(), new DatapackBuiltinEntriesProvider(packOutput, event.getLookupProvider(), this.createProvider(), Set.of(MOD_ID))); - } - - // Creates the registry builder for 2 vanilla and 1 forge registry - private RegistrySetBuilder createProvider() { - var builder = new RegistrySetBuilder(); - builder.add(Registries.CONFIGURED_FEATURE, c -> this.createFeature(c)); - builder.add(Registries.PLACED_FEATURE, this::createPlacement); - builder.add(ForgeRegistries.Keys.BIOME_MODIFIERS, this::createModifier); - return builder; + var registries = RegistryDataBuilder.of() + .name(modid()) + .world(set -> set + .add(Registries.FEATURE, this::createFeature) + .add(Registries.PLACED_FEATURE, this::createPlacement) + .add(ForgeRegistries.Keys.BIOME_MODIFIERS, this::createModifier) + ); + gen.addProvider(event.includeServer(), registries.worldGenerator(gen.getPackOutput())); } // Registers the mossy stone feature - private void createFeature(BootstrapContext> context) { - context.register(MOSSY_STONE_FEATURE, new ConfiguredFeature<>( - Feature.ORE, - new OreConfiguration(MOSSY_STONE_TARGETS.get(), 5) + private void createFeature(BootstrapContext context) { + context.register(MOSSY_STONE_FEATURE, new OreFeature( + new AnyOfRuleTest(List.of( + new TagMatchTest(BlockTags.STONE_ORE_REPLACEABLES), + new TagMatchTest(BlockTags.DEEPSLATE_ORE_REPLACEABLES) + )), Blocks.MOSSY_STONE_BRICKS.defaultBlockState(), 5 )); } // Registers the mossy stone placement private void createPlacement(BootstrapContext context) { - var featureRegistry = context.lookup(Registries.CONFIGURED_FEATURE); + var featureRegistry = context.lookup(Registries.FEATURE); context.register(MOSSY_STONE_PLACEMENT, new PlacedFeature( featureRegistry.getOrThrow(MOSSY_STONE_FEATURE), List.of(CountPlacement.of(8), InSquarePlacement.spread(), HeightRangePlacement.uniform(VerticalAnchor.absolute(-64), VerticalAnchor.absolute(64)), BiomeFilter.biome()) diff --git a/src/test/java/net/minecraftforge/debug/gameplay/item/PreventItemDamageTest.java b/src/test/java/net/minecraftforge/debug/gameplay/item/PreventItemDamageTest.java index 5c804f61b2..3c2cfa0784 100644 --- a/src/test/java/net/minecraftforge/debug/gameplay/item/PreventItemDamageTest.java +++ b/src/test/java/net/minecraftforge/debug/gameplay/item/PreventItemDamageTest.java @@ -125,7 +125,7 @@ public class PreventItemDamageTest extends BaseTestMod { // test hurt and break var damaged = helper.flag("damaged shield"); - shield.hurtAndBreak(1, helper.getLevel(), player, damaged::set); + shield.hurtAndBreak(1, helper.getLevel(), player, stack -> damaged.set(stack.getItem())); damaged.assertEquals(FAKE_SHIELD.get(), "Fake shield was not damaged! Check IForgeItem#damageItem."); helper.assertValueEqual(initialDamage + 1, shield.getDamageValue(), "shield damage value", "Fake shield did not take precisely 1 damage! Check IForgeItem#damageItem."); @@ -160,9 +160,9 @@ public class PreventItemDamageTest extends BaseTestMod { } @Override - public int damageItem(ItemStack stack, int damage, ServerLevel level, @Nullable ServerPlayer player, boolean canBreak, Consumer onBroken) { + public int damageItem(ItemStack stack, int damage, ServerLevel level, @Nullable ServerPlayer player, boolean canBreak, Consumer onBroken) { if (canBreak) { - onBroken.accept(this); + onBroken.accept(stack); return 1; } diff --git a/src/test/java/net/minecraftforge/debug/gameplay/level/TrySleepTest.java b/src/test/java/net/minecraftforge/debug/gameplay/level/TrySleepTest.java index 6010a38474..7ec9375581 100644 --- a/src/test/java/net/minecraftforge/debug/gameplay/level/TrySleepTest.java +++ b/src/test/java/net/minecraftforge/debug/gameplay/level/TrySleepTest.java @@ -75,7 +75,7 @@ public class TrySleepTest extends BaseTestMod { private static void setTimeAndTest(GameTestHelper helper, ResourceKey time, BlockPos bed, Player player, boolean shouldBeSleeping, String err) { var manager = helper.getLevel().clockManager(); var overworld = helper.getLevel().registryAccess().getOrThrow(WorldClocks.OVERWORLD); - var origTime = manager.getTotalTicks(overworld); + var origTime = manager.getInstance(overworld).totalTicks(); player.setPos(Vec3.atBottomCenterOf(helper.absolutePos(bed))); manager.moveToTimeMarker(overworld, time); diff --git a/src/test/java/net/minecraftforge/debug/gameplay/loot/ConditionalLootPools.java b/src/test/java/net/minecraftforge/debug/gameplay/loot/ConditionalLootPools.java index 257ada2f9b..f5e184c870 100644 --- a/src/test/java/net/minecraftforge/debug/gameplay/loot/ConditionalLootPools.java +++ b/src/test/java/net/minecraftforge/debug/gameplay/loot/ConditionalLootPools.java @@ -6,10 +6,10 @@ package net.minecraftforge.debug.gameplay.loot; import net.minecraft.core.BlockPos; -import net.minecraft.core.HolderLookup; -import net.minecraft.data.PackOutput; +import net.minecraft.core.registries.Registries; import net.minecraft.data.loot.BlockLootSubProvider; import net.minecraft.data.loot.LootTableProvider; +import net.minecraft.data.loot.LootTableSubProvider; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.network.chat.Component; import net.minecraft.world.flag.FeatureFlags; @@ -21,11 +21,12 @@ import net.minecraft.world.level.storage.loot.LootPool; import net.minecraft.world.level.storage.loot.LootTable; import net.minecraft.world.level.storage.loot.entries.LootItem; import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; -import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; +import net.minecraft.world.level.storage.loot.providers.number.ints.ContextIntProviders; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.test.BaseTestMod; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.common.crafting.conditions.IConditionBuilder; +import net.minecraftforge.common.data.RegistryDataBuilder; import net.minecraftforge.data.event.GatherDataEvent; import net.minecraftforge.gametest.GameTest; import net.minecraftforge.gametest.GameTestNamespace; @@ -35,7 +36,6 @@ import net.minecraftforge.registries.RegistryObject; import java.util.List; import java.util.Set; -import java.util.concurrent.CompletableFuture; @GameTestNamespace("forge") @Mod(ConditionalLootPools.MODID) @@ -51,7 +51,15 @@ public class ConditionalLootPools extends BaseTestMod { } public void gatherData(GatherDataEvent event) { - event.getGenerator().addProvider(event.includeServer(), new LootProvider(event.getGenerator().getPackOutput(), event.getLookupProvider())); + var registries = RegistryDataBuilder.of() + .name(MODID) + .reloadable(set -> set + .add(Registries.LOOT_TABLE, new LootTableProvider(Set.of(), List.of( + new LootTableProvider.SubProviderEntry(BlockLoot::new, LootContextParamSets.BLOCK) + ))) + ); + + event.getGenerator().addProvider(event.includeServer(), registries.reloadableGenerator(event.getGenerator().getPackOutput())); } @GameTest @@ -68,17 +76,9 @@ public class ConditionalLootPools extends BaseTestMod { helper.succeed(); } - private static class LootProvider extends LootTableProvider { - public LootProvider(PackOutput out, CompletableFuture lookup) { - super(out, Set.of(), List.of( - new LootTableProvider.SubProviderEntry(BlockLoot::new, LootContextParamSets.BLOCK) - ), lookup); - } - } - private static class BlockLoot extends BlockLootSubProvider implements IConditionBuilder { - public BlockLoot(HolderLookup.Provider lookup) { - super(Set.of(), FeatureFlags.REGISTRY.allFlags(), lookup); + public BlockLoot(final LootTableSubProvider.Context output) { + super(Set.of(), FeatureFlags.REGISTRY.allFlags(), output); } @Override @@ -92,13 +92,13 @@ public class ConditionalLootPools extends BaseTestMod { .withPool( LootPool.lootPool() .when(FALSE()) - .setRolls(ConstantValue.exactly(1.0F)) + .setRolls(ContextIntProviders.exactly(1)) .add(LootItem.lootTableItem(Items.DIAMOND_BLOCK)) ) .withPool( LootPool.lootPool() .when(TRUE()) - .setRolls(ConstantValue.exactly(1.0F)) + .setRolls(ContextIntProviders.exactly(1)) .add(LootItem.lootTableItem(Items.GOLDEN_APPLE)) ) ); diff --git a/src/test/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java b/src/test/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java index eedf7503d1..71476f76d3 100644 --- a/src/test/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java +++ b/src/test/java/net/minecraftforge/debug/gameplay/loot/GlobalLootModifiersTest.java @@ -16,7 +16,6 @@ import net.minecraft.advancements.predicates.ItemPredicate; import net.minecraft.advancements.predicates.MinMaxBounds; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; -import net.minecraft.core.RegistrySetBuilder; import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.predicates.DataComponentPredicates; import net.minecraft.core.component.predicates.EnchantmentsPredicate; @@ -29,7 +28,8 @@ import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.data.PackOutput; import net.minecraft.data.loot.BlockLootSubProvider; import net.minecraft.data.loot.LootTableProvider; -import net.minecraft.data.registries.RegistryPatchGenerator; +import net.minecraft.data.loot.LootTableSubProvider; +import net.minecraft.data.worldgen.BootstrapContext; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.Identifier; @@ -52,12 +52,12 @@ import net.minecraft.world.level.storage.loot.LootParams; import net.minecraft.world.level.storage.loot.LootTable; import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import net.minecraft.world.level.storage.loot.predicates.LootItemBlockStatePropertyCondition; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import net.minecraft.world.level.storage.loot.predicates.MatchBlock; import net.minecraft.world.level.storage.loot.predicates.MatchTool; import net.minecraftforge.common.Tags; import net.minecraftforge.common.crafting.conditions.IConditionBuilder; -import net.minecraftforge.common.data.DatapackBuiltinEntriesProvider; +import net.minecraftforge.common.data.RegistryDataBuilder; import net.minecraftforge.common.data.GlobalLootModifierProvider; import net.minecraftforge.common.loot.IGlobalLootModifier; import net.minecraftforge.common.loot.LootModifier; @@ -93,15 +93,6 @@ public class GlobalLootModifiersTest extends BaseTestMod { } private static final ResourceKey SMELT = ResourceKey.create(Registries.ENCHANTMENT, Identifier.fromNamespaceAndPath(MODID, "smelt")); - private static final Supplier ENCHANTMENTS = () -> new RegistrySetBuilder() - .add(Registries.ENCHANTMENT, ctx -> { - ctx.register(SMELT, Enchantment.enchantment( - Enchantment.definition( - ctx.lookup(Registries.ITEM).getOrThrow(ItemTags.MINING_LOOT_ENCHANTABLE), 1, 1, - Enchantment.constantCost(15), Enchantment.constantCost(15), 5, EquipmentSlotGroup.MAINHAND - ) - ).build(SMELT.identifier())); - }); private static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID); private static final RegistryObject TEST_BLOCK = BLOCKS.register("test", () -> new Block(name(MODID, "test", BlockBehaviour.Properties.of()))); @@ -127,12 +118,29 @@ public class GlobalLootModifiersTest extends BaseTestMod { public void runData(GatherDataEvent event) { var out = event.getGenerator().getPackOutput(); - var lookup = event.getLookupProvider(); - var patched = RegistryPatchGenerator.createLookup(lookup, ENCHANTMENTS.get()) - .thenApply(RegistrySetBuilder.PatchedRegistries::patches); - event.getGenerator().addProvider(event.includeServer(), new DatapackBuiltinEntriesProvider(out, lookup, ENCHANTMENTS.get(), Set.of(MODID))); - event.getGenerator().addProvider(event.includeServer(), new ModifierProvider(out, MODID, patched)); - event.getGenerator().addProvider(event.includeServer(), new LootProvider(out, lookup)); + + var registries = RegistryDataBuilder.of() + .name(MODID) + .world(set -> set + .add(Registries.ENCHANTMENT, this::enchantments) + ) + .reloadable(set -> set + .add(Registries.LOOT_TABLE, new LootProvider()) + ); + + event.getGenerator().addProvider(event.includeServer(), registries.worldGenerator(out)); + event.getGenerator().addProvider(event.includeServer(), registries.reloadableGenerator(out)); + + event.getGenerator().addProvider(event.includeServer(), new ModifierProvider(out, MODID, registries.reloadableFull())); + } + + private void enchantments(BootstrapContext ctx) { + ctx.register(SMELT, Enchantment.enchantment( + Enchantment.definition( + ctx.lookup(Registries.ITEM).getOrThrow(ItemTags.MINING_LOOT_ENCHANTABLE), 1, 1, + Enchantment.constantCost(15), Enchantment.constantCost(15), 5, EquipmentSlotGroup.MAINHAND + ) + ).build(SMELT.identifier())); } // Tests the Enchantment condition, as well as the ability to completely override the returned values. @@ -211,6 +219,7 @@ public class GlobalLootModifiersTest extends BaseTestMod { @Override protected void start(HolderLookup.Provider registries) { + var blocks = registries.lookupOrThrow(Registries.BLOCK); var smelt = registries.lookupOrThrow(Registries.ENCHANTMENT).getOrThrow(SMELT); var items = registries.lookupOrThrow(Registries.ITEM); @@ -238,7 +247,7 @@ public class GlobalLootModifiersTest extends BaseTestMod { new LootItemCondition[] { // the #c:tools_shear tag is used here to test parsing of tags in LootModiferManager MatchTool.toolMatches(ItemPredicate.Builder.item().of(items, Tags.Items.TOOLS_SHEAR)).build(), - LootItemBlockStatePropertyCondition.hasBlockStateProperties(Blocks.WHEAT).build() + MatchBlock.blockMatches(blocks, Blocks.WHEAT).build() }, 3, Items.WHEAT_SEEDS, Items.WHEAT) ); @@ -260,15 +269,15 @@ public class GlobalLootModifiersTest extends BaseTestMod { } private static class LootProvider extends LootTableProvider { - public LootProvider(PackOutput out, CompletableFuture lookup) { - super(out, Set.of(), List.of( + public LootProvider() { + super(Set.of(), List.of( new LootTableProvider.SubProviderEntry(BlockLoot::new, LootContextParamSets.BLOCK) - ), lookup); + )); } private static class BlockLoot extends BlockLootSubProvider implements IConditionBuilder { - public BlockLoot(HolderLookup.Provider lookup) { - super(Set.of(), FeatureFlags.REGISTRY.allFlags(), lookup); + public BlockLoot(final LootTableSubProvider.Context output) { + super(Set.of(), FeatureFlags.REGISTRY.allFlags(), output); } @Override @@ -342,7 +351,7 @@ public class GlobalLootModifiersTest extends BaseTestMod { @NotNull @Override public ObjectArrayList doApply(LootTable table, ObjectArrayList generatedLoot, LootContext context) { - var ctxTool = context.getOptionalParameter(LootContextParams.TOOL); + var ctxTool = context.getOptional(LootContextParams.TOOL); //return early if silk-touch is already applied (otherwise we'll get stuck in an infinite loop). var silk = context.getLevel().holderLookup(Registries.ENCHANTMENT).getOrThrow(Enchantments.SILK_TOUCH); var silkLevel = EnchantmentHelper.getItemEnchantmentLevel(silk, ctxTool); diff --git a/src/test/java/net/minecraftforge/debug/gameplay/loot/LootEventsTest.java b/src/test/java/net/minecraftforge/debug/gameplay/loot/LootEventsTest.java index feecc983ff..db4b1e2a4d 100644 --- a/src/test/java/net/minecraftforge/debug/gameplay/loot/LootEventsTest.java +++ b/src/test/java/net/minecraftforge/debug/gameplay/loot/LootEventsTest.java @@ -7,16 +7,14 @@ package net.minecraftforge.debug.gameplay.loot; import java.util.List; import java.util.Set; -import java.util.concurrent.CompletableFuture; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import net.minecraft.core.BlockPos; -import net.minecraft.core.HolderLookup; -import net.minecraft.data.PackOutput; +import net.minecraft.core.registries.Registries; import net.minecraft.data.loot.BlockLootSubProvider; import net.minecraft.data.loot.LootTableProvider; +import net.minecraft.data.loot.LootTableSubProvider; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.network.chat.Component; import net.minecraft.world.flag.FeatureFlags; @@ -28,8 +26,9 @@ import net.minecraft.world.level.storage.loot.LootPool; import net.minecraft.world.level.storage.loot.entries.LootItem; import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction; import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; -import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; +import net.minecraft.world.level.storage.loot.providers.number.ints.ContextIntProviders; import net.minecraftforge.common.crafting.conditions.IConditionBuilder; +import net.minecraftforge.common.data.RegistryDataBuilder; import net.minecraftforge.data.event.GatherDataEvent; import net.minecraftforge.event.LootTableLoadEvent; import net.minecraftforge.fml.common.Mod; @@ -58,9 +57,13 @@ public class LootEventsTest extends BaseTestMod { } public void gatherData(GatherDataEvent event) { - var out = event.getGenerator().getPackOutput(); - var lookup = event.getLookupProvider(); - event.getGenerator().addProvider(event.includeServer(), new LootProvider(out, lookup)); + var registries = RegistryDataBuilder.of() + .name(MODID) + .reloadable(set -> set + .add(Registries.LOOT_TABLE, new LootProvider()) + ); + + event.getGenerator().addProvider(event.includeServer(), registries.reloadableGenerator(event.getGenerator().getPackOutput())); } @GameTest @@ -84,9 +87,9 @@ public class LootEventsTest extends BaseTestMod { event.getTable().removePool(0); event.getTable().addPool( LootPool.lootPool() - .setRolls(ConstantValue.exactly(1f)) + .setRolls(ContextIntProviders.exactly(1)) .add(LootItem.lootTableItem(Items.GOLDEN_APPLE)) - .apply(SetItemCountFunction.setCount(ConstantValue.exactly(1))) + .apply(SetItemCountFunction.setCount(ContextIntProviders.exactly(1))) .build() ); } @@ -94,15 +97,15 @@ public class LootEventsTest extends BaseTestMod { } private static class LootProvider extends LootTableProvider { - public LootProvider(PackOutput out, CompletableFuture lookup) { - super(out, Set.of(), List.of( + public LootProvider() { + super(Set.of(), List.of( new LootTableProvider.SubProviderEntry(BlockLoot::new, LootContextParamSets.BLOCK) - ), lookup); + )); } private static class BlockLoot extends BlockLootSubProvider implements IConditionBuilder { - public BlockLoot(HolderLookup.Provider lookup) { - super(Set.of(), FeatureFlags.REGISTRY.allFlags(), lookup); + public BlockLoot(final LootTableSubProvider.Context output) { + super(Set.of(), FeatureFlags.REGISTRY.allFlags(), output); } @Override diff --git a/src/test/java/net/minecraftforge/test/BaseTestMod.java b/src/test/java/net/minecraftforge/test/BaseTestMod.java index 23721ee51d..aaae9c0a76 100644 --- a/src/test/java/net/minecraftforge/test/BaseTestMod.java +++ b/src/test/java/net/minecraftforge/test/BaseTestMod.java @@ -15,24 +15,25 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Function; +import java.util.stream.Collectors; -import com.mojang.serialization.Lifecycle; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.core.Holder; import net.minecraft.core.HolderLookup; import net.minecraft.core.Registry; +import net.minecraft.core.RegistrySetBuilder; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; -import net.minecraft.data.registries.VanillaRegistries; import net.minecraft.gametest.framework.FunctionGameTestInstance; import net.minecraft.gametest.framework.TestData; import net.minecraft.gametest.framework.TestEnvironmentDefinition; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.Identifier; +import net.minecraft.resources.RegistryDataLoader; import net.minecraft.world.item.CreativeModeTab.TabVisibility; import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraftforge.common.data.DatapackBuiltinEntriesProvider; +import net.minecraftforge.common.data.RegistryDataBuilder; import net.minecraftforge.data.event.GatherDataEvent; import net.minecraftforge.event.BuildCreativeModeTabContentsEvent; import net.minecraftforge.eventbus.api.bus.BusGroup; @@ -168,31 +169,32 @@ public abstract class BaseTestMod { var gen = event.getGenerator(); var packOutput = gen.getPackOutput(); - var registrySet = VanillaRegistries.builder(); + var data = populate(this.dataRegistries); + if (data.hasWorld) + gen.addProvider(event.includeServer(), data.builder.worldGenerator(packOutput)); + if (data.hasReload) + gen.addProvider(event.includeServer(), data.builder.reloadableGenerator(packOutput)); + } + + private record RegistryData(RegistryDataBuilder builder, boolean hasWorld, boolean hasReload) {} + private RegistryData populate(List>, DeferredRegisterData>> registries) { + var reloadableRegistries = RegistryDataLoader.RELOADABLE_REGISTRIES.stream().map(RegistryDataLoader.RegistryData::key).collect(Collectors.toSet()); + var dataBuilder = RegistryDataBuilder.of().name(modid()); + + RegistrySetBuilder world = null, reload = null; for (var level : this.dataRegistries) { - for (var reg : level.values()) - registrySet.add(reg); - } - - var toDump = new HashSet>(); - for (var reg : myDataRegistries) { - for (var entry : reg.getEntries()) - toDump.add(entry.getKey()); - } - - var modid = modid(); - gen.addProvider(event.includeServer(), new DatapackBuiltinEntriesProvider(packOutput, event.getLookupProvider(), registrySet, modid) { - @Override - public String getName() { - return "Data Registries: " + modid; + world = new RegistrySetBuilder(); + reload = new RegistrySetBuilder(); + for (var reg : level.values()) { + if (reloadableRegistries.contains(reg.getRegistryKey())) + reload.add(reg); + else + world.add(reg); } - - @Override - protected boolean shouldDump(ResourceKey key) { - return toDump.contains(key); - } - }); + dataBuilder.layer(world, reload); + } + return new RegistryData(dataBuilder, world != null && !world.getEntryKeys().isEmpty(), reload != null && !reload.getEntryKeys().isEmpty()); } protected void registerTestFunctions(RegisterEvent event) { @@ -204,20 +206,15 @@ public abstract class BaseTestMod { } protected void generateGameTests(GatherDataEvent event) { - if (!event.includeServer()) + if (!event.includeServer() || tests.isEmpty()) return; var gen = event.getGenerator(); var packOutput = gen.getPackOutput(); - var registrySet = VanillaRegistries.builder(); + var data = this.populate(this.dataRegistries); - for (var level : this.dataRegistries) { - for (var reg : level.values()) - registrySet.add(reg); - } - - registrySet - .add(Registries.TEST_INSTANCE, Lifecycle.stable(), ctx -> { + var registrySet = new RegistrySetBuilder() + .add(Registries.TEST_INSTANCE, ctx -> { var envs = ctx.lookup(Registries.TEST_ENVIRONMENT); for (var entry : tests.entrySet()) { var rdata = entry.getValue().data(); @@ -225,6 +222,7 @@ public abstract class BaseTestMod { var edata = new TestData>>( env, + rdata.dimension(), rdata.structure(), rdata.maxTicks(), rdata.setupTicks(), @@ -247,18 +245,9 @@ public abstract class BaseTestMod { } }); - var modid = modid(); - gen.addProvider(event.includeServer(), new DatapackBuiltinEntriesProvider(packOutput, event.getLookupProvider(), registrySet, modid) { - @Override - public String getName() { - return "Game Tests: " + modid; - } - - @Override - protected boolean shouldDump(ResourceKey key) { - return tests.containsKey(key.identifier()); - } - }); + data.builder.world(registrySet); + data.builder.name("Game Tests: " + modid()); + gen.addProvider(event.includeServer(), data.builder.worldGenerator(packOutput)); } @SuppressWarnings("unchecked")